import {createRequire} from 'node:module'; import {spawn} from 'node:child_process'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; import assert from 'node:assert/strict'; const require=createRequire(import.meta.url); const {startAgentControl}=require('../apps/browser/agent-control.cjs'); const {startInspector}=require('../apps/browser/inspection.cjs'); const root=path.resolve('dist/win-unpacked'); if(process.platform!=='win32')throw Error('Windows package verification requires Windows'); const {extractFile}=require('@electron/asar'); for(const file of ['apps/browser/policy-assignment.cjs','packages/core/policy-groups.mjs','apps/browser/tab-registry.cjs','apps/browser/agent-adapters.cjs','apps/browser/agent-control.cjs','apps/browser/password-fill.cjs','apps/browser/diagnostics.cjs','packages/core/diagnostics.mjs','packages/core/security.mjs'])assert.deepEqual(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)),await fs.readFile(file),`Packaged device/session policy source is stale: ${file}`); for(const file of ['apps/browser/main.cjs','apps/browser/preload.cjs','apps/browser/site-preload.cjs','apps/browser/clipboard-deny.cjs','apps/browser/clipboard-guard.cjs','apps/browser/clipboard-dom.cjs','apps/browser/page-clipboard-guard.cjs','apps/browser/startup-security.cjs','apps/browser/visual-capture.cjs','apps/browser/renderer.js','apps/browser/index.html','apps/browser/style.css','packages/core/clipboard.mjs']){ assert.deepEqual(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)),await fs.readFile(file),`Packaged source is stale: ${file}`); } for(const file of ['apps/browser/inspection.cjs','apps/browser/managed-settings.cjs','apps/browser/management-channel.cjs','apps/browser/enterprise-inspection.cjs','apps/browser/icap-client.cjs','apps/browser/network-posture.cjs','apps/browser/download-gate.cjs','packages/core/enterprise.mjs','packages/core/semantic.mjs','packages/core/managed-settings.mjs','packages/core/policy-channel.cjs','packages/core/policy.mjs'])assert.ok(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)).equals(await fs.readFile(file)),`Packaged source is stale: ${file}`); for(const file of ['semantic.py','engine.py','server.py','windows_containment.py','windows_appcontainer.py','sandbox_worker.py','provision_runtime_acl.py'])assert.deepEqual(await fs.readFile(path.join(root,'resources/inspector',file)),await fs.readFile(path.join('apps/inspector',file)),`Packaged inspector is stale: ${file}`); const temporary=await fs.mkdtemp(path.join(os.tmpdir(),'safetynet-package-')); for(const file of ['apps/browser/bookmarks.cjs','packages/core/bookmarks.mjs'])assert.ok(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)).equals(await fs.readFile(file)),`Packaged bookmark source is stale: ${file}`); function run(executable,args,input,timeoutMs=15000){return new Promise((resolve,reject)=>{ const child=spawn(executable,args,{stdio:['pipe','pipe','pipe'],windowsHide:true,env:{...process.env,PYTHONDONTWRITEBYTECODE:'1'}});let output='',errors=''; const timer=setTimeout(()=>{child.kill();reject(Error('Package verification timed out'));},timeoutMs); child.on('error',reject);child.stdout.on('data',data=>output+=data);child.stderr.on('data',data=>errors+=data); child.on('close',code=>{clearTimeout(timer);resolve({code,output,errors});});child.stdin.end(input); });} let service; try{ const inspectorBytecode=path.join(root,'resources/inspector/__pycache__'); const bytecodeExists=()=>fs.stat(inspectorBytecode).then(()=>true,error=>{if(error.code==='ENOENT')return false;throw error;}); assert.equal(await bytecodeExists(),false,'Package must start with no inspector bytecode cache'); const packagedInspector=startInspector(path.join(root,'resources'),true); assert.ok(packagedInspector,'Packaged inspector runtime is missing'); try{ const verdict=await packagedInspector.inspect(Buffer.from('Public package verification text'),{dlp:{maxBytes:1048576,rules:[],semantic:{enabled:false}}}); assert.equal(verdict.decision,'allow','Packaged contained inspector failed'); assert.equal(verdict.coverage.complete,true); }finally{packagedInspector.stop();} const semanticPath=path.join(root,'resources/semantic'); const actual=await run(path.join(root,'resources/python/python.exe'),['-c','import sys; sys.path.insert(0,sys.argv[1]); from semantic import NativeSemanticModel; m=NativeSemanticModel(sys.argv[2],sys.argv[3]); vectors=m.text_vectors("Public information about weather forecasting."); assert len(vectors)>=1 and len(vectors[0])==768; m.close(); print("Offline packaged semantic CPU inference verified.")',path.join(root,'resources/inspector'),path.join(semanticPath,'models'),path.join(semanticPath,'searchi-gemma-worker.exe')],undefined,45000); assert.equal(actual.code,0,'Packaged offline semantic inference failed');assert.ok(actual.output.includes('Offline packaged semantic CPU inference verified.')); service=await startAgentControl({authorize:async()=>({allowed:true,role:'agent',scopes:['sessions:list']}),audit:async()=>{},actions:{sessions:async()=>[{id:'managed',url:'https://example.test/'}]}}); const encrypted=await run(path.join(root,'resources/python/python.exe'),[path.join(root,'resources/inspector/dpapi.py'),'protect'],JSON.stringify({address:service.address,token:service.token})); assert.equal(encrypted.code,0,'Packaged DPAPI failed'); const connection=path.join(temporary,'connection.json'),request=path.join(temporary,'request.json'); await fs.writeFile(connection,JSON.stringify({format:'windows-dpapi-v1',protectedConnection:encrypted.output})); await fs.writeFile(request,JSON.stringify({action:'sessions'})); const result=await run(path.join(root,'SafetyNet.exe'),[`--agent-connection=${connection}`,`--agent-action=${request}`]); assert.equal(result.code,0,'Packaged agent helper failed');assert.equal(JSON.parse(result.output).result[0].id,'managed');assert.equal(result.output.includes(service.token),false); assert.equal(await bytecodeExists(),false,'Cold packaged startup must not create inspector bytecode files'); console.log('Packaged security sources, Windows-contained inspector, offline EmbeddingGemma 2 CPU inference, Windows agent helper and bundled DPAPI runtime passed.'); }finally{ await service?.close(); if(!temporary.startsWith(path.join(os.tmpdir(),'safetynet-package-')))throw Error('Unexpected temporary directory'); await fs.rm(temporary,{recursive:true,force:true}); }