34 lines
2.4 KiB
JavaScript
34 lines
2.4 KiB
JavaScript
'use strict';
|
|
const {createFramedChannel}=require('./framed-channel.cjs');
|
|
const {runProductionProcess}=require('./production-entry.cjs');
|
|
const {createProductionBroker}=require('./production-factory.cjs');
|
|
const {createServiceFactory}=require('./service-bootstrap.cjs');
|
|
const {createServiceCommitGate}=require('./service-commit-gate.cjs');
|
|
const {createServiceStoreClient}=require('./service-store-client.cjs');
|
|
const {createWfpRevalidation}=require('./wfp-revalidation.cjs');
|
|
// Fixed service entry only. Native pipe peer authentication and protected store
|
|
// authorization precede policy verification; IPC cannot nominate files or keys.
|
|
function runServiceProcess({channel,store=createServiceStoreClient(),factory=createProductionBroker,readTopology=async()=>{throw Error('native-topology-unavailable');}}={}){
|
|
if(!channel?.connected||typeof store.snapshot!=='function'||typeof store.envelopes!=='function'||typeof store.commit!=='function')throw Error('broker-bootstrap-invalid');
|
|
let live=true,handle;
|
|
const topology=createWfpRevalidation({readTopology,quarantine:()=>{live=false;void handle?.close();}});
|
|
channel.once('disconnect',()=>{live=false;topology.close();});
|
|
const gate=createServiceCommitGate({current:()=>live&&channel.connected,commitState:request=>store.commit(request)});
|
|
const wrapped=createServiceFactory({factory:async(...args)=>{
|
|
if(!await topology.start()||!live||!channel.connected)throw Error('broker-bootstrap-invalid');
|
|
return factory(...args);
|
|
},loadTrust:async parsed=>{
|
|
const snapshot=await store.snapshot();if(!live||!channel.connected)throw Error('broker-bootstrap-invalid');
|
|
const envelopes=await store.envelopes();if(!live||!channel.connected)throw Error('broker-bootstrap-invalid');
|
|
return gate.prepare({...envelopes,releaseAnchor:snapshot.releaseAnchor,authenticatedSid:snapshot.authenticatedSid,state:snapshot.acceptanceState,policyEnvelope:parsed.envelope});
|
|
}});
|
|
handle=runProductionProcess(wrapped,channel);
|
|
const originalClose=handle.close;
|
|
return {...handle,close:()=>{live=false;topology.close();return originalClose();}};
|
|
}
|
|
if(require.main===module){
|
|
if(process.argv.length!==3||process.argv[2]!=='--service-stdio'){process.exitCode=5;}
|
|
else{try{const channel=createFramedChannel({readable:process.stdin,writable:process.stdout,inboundFirstLimit:2097152,outboundFirstLimit:65536});runServiceProcess({channel});}catch{process.exitCode=5;}}
|
|
}
|
|
module.exports={runServiceProcess};
|