29 lines
2.8 KiB
JavaScript
29 lines
2.8 KiB
JavaScript
import test from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import {mkdtemp,mkdir,copyFile,readFile,writeFile,rm} from 'node:fs/promises';
|
||
|
|
import {tmpdir} from 'node:os';
|
||
|
|
import path from 'node:path';
|
||
|
|
import {createHash} from 'node:crypto';
|
||
|
|
import {fork} from 'node:child_process';
|
||
|
|
import {createRequire} from 'node:module';
|
||
|
|
import {BROKER_RUNTIME} from '../scripts/provision-broker-runtime.mjs';
|
||
|
|
const {createBrokerSupervisor}=createRequire(import.meta.url)('../apps/browser/broker-supervisor.cjs');
|
||
|
|
test('actual pinned bundled Node private IPC startup and confirmed terminal shutdown',{skip:process.platform!=='win32'||process.env.SAFETYNET_BROKER_SUPERVISOR_NATIVE!=='1'},async()=>{
|
||
|
|
const runtime=path.resolve('.runtime/windows/broker/node.exe');
|
||
|
|
const hash=bytes=>createHash('sha256').update(bytes).digest('hex');
|
||
|
|
assert.equal(hash(await readFile(runtime)),BROKER_RUNTIME.executableSha256);
|
||
|
|
const root=await mkdtemp(path.join(tmpdir(),'safetynet-supervisor-'));
|
||
|
|
let child,exited=false,quarantines=0; const savedOptions=process.env.NODE_OPTIONS; process.env.NODE_OPTIONS="--require C:/safetynet-nonexistent-injection.cjs";
|
||
|
|
try{
|
||
|
|
await mkdir(path.join(root,'apps/network-broker'),{recursive:true});await copyFile(runtime,path.join(root,'node.exe'));
|
||
|
|
const fixture=`'use strict';if(process.version!=='v${BROKER_RUNTIME.version}'||process.env.NODE_OPTIONS||process.env.NODE_PATH||process.env.ELECTRON_RUN_AS_NODE)process.exit(91);process.on('message',m=>{if(m.type==='start')process.send({type:'ready',version:1,generation:m.generation,policyVersion:m.policyVersion,authMode:'basic',sequence:0,port:m.config.brokerPort,credentials:{username:'safetynet-'+ 'a'.repeat(32),password:'b'.repeat(43)}});});setInterval(()=>{},1000);`;
|
||
|
|
await writeFile(path.join(root,'apps/network-broker/production-entry.cjs'),fixture);
|
||
|
|
const supervisor=createBrokerSupervisor({resourceRoot:root,verifyPackage:async target=>target===root&&hash(await readFile(path.join(target,'node.exe')))===BROKER_RUNTIME.executableSha256&&await readFile(path.join(target,'apps/network-broker/production-entry.cjs'),'utf8')===fixture,persistAudit:()=>{throw Error();},acceptCertificate:()=>false,onQuarantine:()=>quarantines++,spawn:(...args)=>{assert.equal(args[2].env.NODE_OPTIONS,undefined);child=fork(...args);child.once('exit',()=>{exited=true;});return child;}});
|
||
|
|
const ready=await supervisor.start({policyVersion:1,port:43871,config:{brokerPort:43871}});assert.equal(ready.port,43871);
|
||
|
|
await supervisor.close();assert.equal(exited,true);assert.notEqual(child.exitCode===null&&child.signalCode===null,true);assert.equal(quarantines,0);
|
||
|
|
}finally{
|
||
|
|
if(savedOptions===undefined)delete process.env.NODE_OPTIONS;else process.env.NODE_OPTIONS=savedOptions;
|
||
|
|
if(child&&!exited){child.kill('SIGKILL');await new Promise(resolve=>child.once('exit',resolve));}
|
||
|
|
await rm(root,{recursive:true,force:true});
|
||
|
|
}
|
||
|
|
});
|