Files
safetynet/apps/network-broker/service-entry.cjs
T

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};