Files
safetynet/scripts/electron-smoke.cjs

371 lines
53 KiB
JavaScript

const {app,BrowserWindow}=require('electron');
const fs=require('node:fs'),path=require('node:path'),assert=require('node:assert/strict');
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'smoke-entry.txt'),'Electron JavaScript started.\n');
app.setPath('userData',process.env.SAFETYNET_SMOKE_USERDATA);
app.disableHardwareAcceleration();
require('../apps/browser/main.cjs');
const wait=ms=>new Promise(r=>setTimeout(r,ms));
const log=message=>fs.appendFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'smoke-entry.txt'),message+'\n');
app.whenReady().then(async()=>{
try{
fs.appendFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'smoke-entry.txt'),'Electron ready.\n');
let win;
for(let n=0;n<100;n++){win=BrowserWindow.getAllWindows()[0];if(win&&!win.webContents.isLoading()&&win.webContents.getURL().endsWith('index.html'))break;await wait(100);}
await wait(300);
log('Reading initial shell state: '+win.webContents.getURL());
const initial=await win.webContents.executeJavaScript('window.safetynet.state()');assert.equal(initial.data.ready,false);
assert.equal((await win.webContents.executeJavaScript('window.safetynet.vaultCreate("fixture-master-password-only")')).ok,false,'Unenrolled vault access was allowed');
log('Starting enrollment');
const input={server:process.env.SAFETYNET_SMOKE_SERVER,code:process.env.SAFETYNET_SMOKE_CODE};
const result=await win.webContents.executeJavaScript(`window.safetynet.enroll(${JSON.stringify(input)})`);assert.equal(result.ok,true,result.error);assert.equal(result.data.ready,true);assert.equal(result.data.brand.name,'Acme Secure Browser');
await wait(600);
log('Enrollment passed; testing managed page');
const page=win.contentView.children.find(v=>v.webContents!==win.webContents).webContents;
log('Managed page URL: '+page.getURL());
const url=process.env.SAFETYNET_SMOKE_SINK;
const publicResult=await page.executeJavaScript(`fetch(${JSON.stringify(url+'/sink')},{method:'POST',body:'Public information'}).then(r=>r.text()).catch(e=>({error:e.message}))`);
log('Public request: '+JSON.stringify(publicResult));assert.equal(publicResult,'received');
const blocked=await page.executeJavaScript(`fetch(${JSON.stringify(url+'/sink')},{method:'POST',body:'Secret Roadmap'}).then(()=>false).catch(()=>true)`);assert.equal(blocked,true);
const counts=await (await fetch(url+'/count')).json();assert.equal(counts.posts,1,'Secret payload reached the destination');
log('Request blocking passed');
// Use the already attached privileged page guard; no additional debugging port.
const fileAuditHeaders={authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`};
const filePriorIds=new Set((await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:fileAuditHeaders})).json()).events.map(e=>e.id));
await page.executeJavaScript('(()=>{const input=document.createElement("input");input.type="file";input.id="native-upload-fixture";document.body.append(input);})()');
const fileDocument=await page.debugger.sendCommand('DOM.getDocument');
const fileNode=await page.debugger.sendCommand('DOM.querySelector',{nodeId:fileDocument.root.nodeId,selector:'#native-upload-fixture'});
async function nativeFileUpload(file){await page.debugger.sendCommand('DOM.setFileInputFiles',{nodeId:fileNode.nodeId,files:[file]});return page.executeJavaScript(`(()=>{const data=new FormData();data.append('file',document.getElementById('native-upload-fixture').files[0]);return fetch(${JSON.stringify(url+'/file-upload-sink')},{method:'POST',body:data}).then(r=>r.text()).catch(()=>false);})()`);}
const fileBefore=(await (await fetch(url+'/count')).json()).fileUploadRequests;
assert.equal(await nativeFileUpload(process.env.SAFETYNET_SMOKE_PUBLIC_UPLOAD),'file received','Clean native file upload was blocked');
const fileAfter=(await (await fetch(url+'/count')).json());assert.equal(fileAfter.fileUploadRequests,fileBefore+1);assert.equal(fileAfter.fileUploadExact,true,'Actual file bytes differed at receiver');
assert.equal(await nativeFileUpload(process.env.SAFETYNET_SMOKE_SECRET_UPLOAD),false,'Confidential native file upload escaped');
assert.equal((await (await fetch(url+'/count')).json()).fileUploadRequests,fileBefore+1,'Blocked native file upload reached receiver');
let fileEvents;await clipboardWait(async()=>{fileEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:fileAuditHeaders})).json()).events.filter(e=>!filePriorIds.has(e.id));return fileEvents.some(e=>e.kind==='upload.authorized')&&fileEvents.some(e=>e.kind==='upload.block'&&e.metadata.ruleId==='secret-roadmap');});
const fileAuditText=JSON.stringify(fileEvents),fileCrypto=require('node:crypto');
for(const fixture of [process.env.SAFETYNET_SMOKE_PUBLIC_UPLOAD,process.env.SAFETYNET_SMOKE_SECRET_UPLOAD]){const bytes=fs.readFileSync(fixture);assert.equal(fileAuditText.includes(bytes.toString('utf8').trim()),false,'File contents entered ordinary audit');assert.equal(fileAuditText.includes(fileCrypto.createHash('sha256').update(bytes).digest('hex')),false,'File hash entered ordinary request audit');bytes.fill(0);}
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'native-file-upload-proof.json'),JSON.stringify({actualElectron:true,cleanFileReceivedExactlyOnce:true,exactFileBytesPreserved:true,secretFileNeverReachedReceiver:true,contentsAndHashesAbsentFromAudit:true,traceIds:fileEvents.map(e=>e.metadata.traceId).filter(Boolean)},null,2));
await page.executeJavaScript('document.getElementById("native-upload-fixture").remove()');
log('Managed native file upload receiver and confidentiality proof passed');
// Native Chromium header inspection must run before the dedicated receiver sees bytes.
const headerAuditHeaders={authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`};
const headerPriorIds=new Set((await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:headerAuditHeaders})).json()).events.map(e=>e.id));
const headerBefore=(await (await fetch(url+'/count')).json()).headerRequests;
assert.equal(await page.executeJavaScript(`fetch(${JSON.stringify(url+'/header-sink')},{headers:{'X-SafetyNet-Test':'Secret Roadmap'}}).then(()=>false).catch(()=>true)`),true,'Secret custom header escaped inspection');
assert.equal((await (await fetch(url+'/count')).json()).headerRequests,headerBefore,'Blocked header request reached receiver');
assert.equal(await page.executeJavaScript(`fetch(${JSON.stringify(url+'/header-sink')},{headers:{'X-SafetyNet-Test':'Public header fixture'}}).then(r=>r.text())`),'header received','Clean custom header was blocked');
assert.equal((await (await fetch(url+'/count')).json()).headerRequests,headerBefore+1,'Clean header request did not arrive exactly once');
let headerEvents,headerDecision;
await clipboardWait(async()=>{headerEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:headerAuditHeaders})).json()).events;headerDecision=headerEvents.find(e=>!headerPriorIds.has(e.id)&&e.kind==='dlp.block'&&e.metadata.ruleId==='secret-roadmap'&&(!process.env.SAFETYNET_TEST_OTLP_ENDPOINT||e.metadata.traceId));return !!headerDecision;});
assert.equal(JSON.stringify(headerEvents).includes('Secret Roadmap'),false,'Header secret appeared in audit');
assert.equal(JSON.stringify(headerEvents).includes('Public header fixture'),false,'Allowed header value appeared in audit');
assert.equal(JSON.stringify(headerEvents).includes('X-SafetyNet-Test'),false,'Header name appeared in audit');
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'request-headers-native-proof.json'),JSON.stringify({actualElectron:true,blockedHeaderNeverReachedReceiver:true,cleanHeaderReceivedOnce:true,headerNamesAndValuesAbsentFromAudit:true,traceId:headerDecision.metadata.traceId},null,2));
log('Native custom header DLP blocks before transmission and preserves clean requests');
// Real Chromium gestures and the Windows clipboard: never execute fixture commands.
const {clipboard}=require('electron');
const originalClipboardText=await clipboard.readText();
const clipboardSentinel='SafetyNet public clipboard fixture';
async function clipboardKey(key,shift=false){page.focus();page.sendInputEvent({type:'keyDown',keyCode:key,modifiers:shift?['shift']:['control']});page.sendInputEvent({type:'keyUp',keyCode:key,modifiers:shift?['shift']:['control']});await wait(800);await clipboardWait(async()=>!(await win.webContents.executeJavaScript('window.safetynet.state()')).data.clipboardPending);}
async function clipboardWait(predicate,stage='Native fixture'){for(let attempt=0;attempt<200;attempt++){if(await predicate())return;await wait(100);}throw Error(`${stage} operation timed out`);}
async function selectClipboardText(text){await page.executeJavaScript(`(()=>{let node=document.getElementById('clipboard-source');if(!node){node=document.createElement('pre');node.id='clipboard-source';document.body.append(node)}node.textContent=${JSON.stringify(text)};const range=document.createRange();range.selectNodeContents(node);const selection=getSelection();selection.removeAllRanges();selection.addRange(range);})()`);}
try{
await clipboard.writeText(clipboardSentinel);
await selectClipboardText('Public code example');await clipboardKey('C');
await clipboardWait(async()=>await clipboard.readText()==='Public code example');
assert.equal(await clipboard.readText(),'Public code example','Allowed native copy failed');
await clipboard.writeText(clipboardSentinel);await selectClipboardText('Secret Roadmap');await clipboardKey('C');
assert.equal(await clipboard.readText(),clipboardSentinel,'Blocked secret reached OS clipboard');
await selectClipboardText('powershell -NoProfile -EncodedCommand VABFAFMAVAA=');await clipboardKey('C');
assert.equal(await clipboard.readText(),clipboardSentinel,'ClickFix command reached OS clipboard');
await selectClipboardText('SAFETYNET_BLOCK_TEST');await clipboardKey('C');
assert.equal(await clipboard.readText(),clipboardSentinel,'YARA-blocked clipboard text reached OS clipboard');
await page.executeJavaScript("document.addEventListener('copy',event=>{event.clipboardData.setData('text/plain','Secret Roadmap');event.preventDefault()},{once:true})");
await selectClipboardText('Public selection despite hostile copy handler');await clipboardKey('C');
assert.equal((await clipboard.readText()).includes('Secret Roadmap'),false,'Page copy handler bypassed inspection');
await clipboard.writeText(clipboardSentinel);
await page.executeJavaScript("(()=>{const e=document.getElementById('public-input');e.value='';e.focus()})()");await clipboardKey('V');
await clipboardWait(async()=>await page.executeJavaScript('document.getElementById("public-input").value')===clipboardSentinel);
assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),clipboardSentinel,'Allowed native paste failed');
await clipboard.writeText('Secret Roadmap');await clipboardKey('V');
assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),clipboardSentinel,'Secret was inserted by native paste');
await page.executeJavaScript("(()=>{const e=document.getElementById('public-input');e.value='Secret Roadmap';e.focus();e.select()})()");await clipboard.writeText(clipboardSentinel);await clipboardKey('X');
assert.equal(await clipboard.readText(),clipboardSentinel,'Blocked cut wrote OS clipboard');assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),'Secret Roadmap','Blocked cut deleted source');
await page.executeJavaScript("(()=>{const e=document.getElementById('public-input');e.value='Public cut sample';e.focus();e.select()})()");await clipboardKey('Delete',true);
assert.equal(await clipboard.readText(),'Public cut sample','Allowed Shift+Delete cut failed');assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),'','Allowed cut preserved deleted selection');
await clipboardKey('Insert',true);
assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),'Public cut sample','Allowed Shift+Insert paste failed');
await clipboard.writeText(clipboardSentinel);
// Programmatic legacy copy must not acquire the native user gesture capability.
await selectClipboardText('Secret Roadmap');await page.executeJavaScript("document.execCommand('copy')",true);await wait(250);
assert.equal(await clipboard.readText(),clipboardSentinel,'Legacy scripted copy bypassed clipboard gate');
const clipboardEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:{authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`}})).json()).events.filter(event=>event.kind.startsWith('clipboard.'));
assert.ok(clipboardEvents.some(event=>event.kind==='clipboard.block'),'Clipboard blocks were not centrally audited');
assert.equal(JSON.stringify(clipboardEvents).includes('Secret Roadmap'),false,'Clipboard contents appeared in audit records');
assert.equal(JSON.stringify(clipboardEvents).includes('VABFAFMAVAA='),false,'Command contents appeared in audit records');
log('Native clipboard: safe copy/paste allowed, confidential copy/paste/cut held, ClickFix execution command and hostile copy handler blocked');
}finally{await clipboard.writeText(originalClipboardText);await page.executeJavaScript("document.getElementById('clipboard-source')?.remove();document.getElementById('public-input').value=''");}
const connection=await win.webContents.executeJavaScript('window.safetynet.agentConnection()');assert.equal(connection.ok,true,connection.error);
const agentRequest=path.join(process.env.SAFETYNET_SMOKE_USERDATA,'agent-request.json');
let agentWindowStarted=Date.now(),agentCalls=0;
async function localAgent(body){
if(++agentCalls>20){const remaining=Math.max(0,61000-(Date.now()-agentWindowStarted));await wait(Math.min(remaining,30000));if(remaining>30000)await wait(remaining-30000);agentWindowStarted=Date.now();agentCalls=1;}
fs.writeFileSync(agentRequest,JSON.stringify(body));
const child=require('node:child_process').spawn(process.execPath,['scripts/agent-client.cjs','--connection',connection.data.credentialPath,'--request',agentRequest],{stdio:['ignore','pipe','pipe'],windowsHide:true});let output='',errors='';child.stdout.on('data',c=>output+=c);child.stderr.on('data',c=>errors+=c);
const exit=await new Promise((resolve,reject)=>{child.on('exit',resolve);child.on('error',reject);});return {exit,output,errors};
}
const sessionResult=await localAgent({action:'sessions'});assert.equal(sessionResult.exit,0,sessionResult.errors);const sessionId=JSON.parse(sessionResult.output).result[0].id;assert.match(sessionId,/^[0-9a-f-]{36}$/i);assert.equal(sessionId,(await win.webContents.executeJavaScript('window.safetynet.state()')).data.activeTabId);
const readResult=await localAgent({action:'read',args:{sessionId}});assert.equal(readResult.exit,0,readResult.errors);assert.equal(readResult.output.includes('never-export-this'),false);
const typeResult=await localAgent({action:'type',args:{sessionId,selector:'#public-input',text:'Agent typed public text'}});assert.equal(typeResult.exit,0,typeResult.errors);assert.equal(await page.executeJavaScript('document.getElementById("public-input").value'),'Agent typed public text');
const deniedType=await localAgent({action:'type',args:{sessionId,selector:'#private-input',text:'forbidden'}});assert.equal(deniedType.exit,1);
const inspectResult=await localAgent({action:'inspect',args:{sessionId}});assert.equal(inspectResult.exit,0,inspectResult.errors);const inspected=JSON.parse(inspectResult.output).result;assert.ok(inspected.controls.some(control=>control.selector==='#public-input'&&control.value==='Agent typed public text'));assert.equal(inspectResult.output.includes('never-export-this'),false);
const scrollResult=await localAgent({action:'scroll',args:{sessionId,x:0,y:100}});assert.equal(scrollResult.exit,0,scrollResult.errors);
log('Authenticated agent sessions, sanitized read, type and sensitive-field denial passed');
let structuredAgentEvents;
await clipboardWait(async()=>{structuredAgentEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:{authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`}})).json()).events.filter(e=>e.metadata.agent);return structuredAgentEvents.some(e=>e.metadata.agent.action==='read'&&e.metadata.agent.outcome==='completed')&&structuredAgentEvents.some(e=>e.metadata.agent.action==='type'&&e.kind==='agent.denied'&&['denied','failed'].includes(e.metadata.agent.outcome));},'Structured agent audit');
const completedRead=structuredAgentEvents.find(e=>e.metadata.agent.action==='read'&&e.metadata.agent.outcome==='completed');
assert.equal(completedRead.metadata.agent.scope,'browser:read');assert.equal(completedRead.metadata.agent.sessionId,sessionId);
assert.equal(await page.executeJavaScript('document.getElementById("private-input").value'),'never-export-this','Blocked agent changed a sensitive field');
const blockedType=structuredAgentEvents.find(e=>e.metadata.agent.action==='type'&&e.kind==='agent.denied'&&['denied','failed'].includes(e.metadata.agent.outcome));
const serializedAgentEvents=JSON.stringify(structuredAgentEvents);
for(const privateValue of ['Agent typed public text','never-export-this','forbidden'])assert.equal(serializedAgentEvents.includes(privateValue),false,'Agent arguments reached durable audit');
assert.ok(structuredAgentEvents.every(e=>!Object.hasOwn(e.metadata.agent,'principalId')),'Shared capability fabricated individual identity');
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'structured-agent-audit-native-proof.json'),JSON.stringify({actualElectron:true,completedReadHasScopeAndSession:true,blockedActionRecorded:true,blockedActionOutcome:blockedType.metadata.agent.outcome,sensitiveFieldUnchanged:true,noArgumentsOrFabricatedIdentity:true,traceId:completedRead.metadata.traceId,eventId:completedRead.id},null,2));
async function agentApp(action,args={}){const response=await localAgent({action,args});assert.equal(response.exit,0,response.errors);return JSON.parse(response.output).result;}
await agentApp('select',{sessionId,selector:'#public-select',value:'two'});assert.equal(await page.executeJavaScript('document.getElementById("public-select").value'),'two');
const lockedSelect=await localAgent({action:'select',args:{sessionId,selector:'#public-select',value:'locked'}});assert.equal(lockedSelect.exit,1);
await agentApp('check',{sessionId,selector:'#public-checkbox',checked:true});assert.equal(await page.executeJavaScript('document.getElementById("public-checkbox").checked'),true);
await agentApp('check',{sessionId,selector:'#public-checkbox',checked:false});assert.equal(await page.executeJavaScript('document.getElementById("public-checkbox").checked'),false);
await agentApp('navigate',{sessionId,url:url+'/history-second'});assert.ok(page.getURL().endsWith('/history-second'));
await agentApp('back',{sessionId});assert.equal(new URL(page.getURL()).pathname,'/');
await agentApp('forward',{sessionId});assert.ok(page.getURL().endsWith('/history-second'));
await agentApp('reload',{sessionId});assert.ok(page.getURL().endsWith('/history-second'));
await agentApp('back',{sessionId});assert.equal(new URL(page.getURL()).pathname,'/');
log('PQ agent history back/forward and same-URL reload passed');
const appStatus=await agentApp('application:state');assert.equal(appStatus.activeTabId,sessionId);
await agentApp('settings:update',{appearance:{mode:'dark'}});assert.equal((await agentApp('settings:get')).appearance.mode,'dark');
const library=await agentApp('bookmarks:list');const bookmark={id:'agent-native-proof',title:'Public fixture bookmark',url:url+'/'};
await agentApp('bookmarks:mutate',{action:'add',bookmark,expectedRevision:library.personal.revision,policyVersion:library.policyVersion});
const updatedLibrary=await agentApp('bookmarks:list');assert.equal(updatedLibrary.personal.items.some(item=>item.id===bookmark.id),true);
await agentApp('bookmarks:mutate',{action:'delete',id:bookmark.id,expectedRevision:updatedLibrary.personal.revision,policyVersion:updatedLibrary.policyVersion});
const createdTab=await agentApp('tabs:create',{group:'Agent proof'});assert.notEqual(createdTab.sessionId,sessionId);
await agentApp('tabs:group',{sessionId:createdTab.sessionId,group:'Public work'});
await agentApp('tabs:activate',{sessionId});await agentApp('tabs:close',{sessionId:createdTab.sessionId});
assert.equal((await agentApp('application:state')).activeTabId,sessionId);
log('First-class agent settings, centrally revisioned bookmarks and native tab controls passed');
const fixtureMaster='fixture-master-password-for-smoke-only';
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.vaultCreate(${JSON.stringify(fixtureMaster)})`)).ok,true);
const generated=await win.webContents.executeJavaScript('window.safetynet.vaultGenerate()');assert.equal(generated.ok,true);assert.equal(generated.data.length,32);
const login={origin:'https://vault-login.test',label:'Fixture login',username:'fixture-user',password:generated.data};
const saved=await win.webContents.executeJavaScript(`window.safetynet.vaultSave(${JSON.stringify(login)})`);assert.equal(saved.ok,true);
const listed=await win.webContents.executeJavaScript('window.safetynet.vaultList()');assert.equal(listed.ok,true);assert.equal(listed.data[0].password,undefined);
const encryptedVault=fs.readFileSync(path.join(process.env.SAFETYNET_SMOKE_USERDATA,'password-vault.json'),'utf8');assert.equal(encryptedVault.includes(login.password),false);assert.equal(encryptedVault.includes(login.username),false);assert.equal(encryptedVault.includes(fixtureMaster),false);
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.vaultFill(${JSON.stringify(saved.data.id)})`)).ok,false,'HTTP page accepted vault fill');
// Protocol fixture exercises Chromium's actual isolated DOM fill; production TLS remains mandatory.
await page.session.protocol.handle('https',request=>{if(new URL(request.url).origin!==login.origin)throw Error('Unexpected fixture origin');return new Response('<!doctype html><title>Vault login fixture</title><form method="post" action="/signin"><label>Username<input id="login-user" name="username" autocomplete="username"></label><label>Password<input id="login-password" type="password" autocomplete="current-password"></label><button type="submit">Sign in</button></form>',{headers:{'content-type':'text/html'}});});
try{
assert.equal((await win.webContents.executeJavaScript('window.safetynet.navigate("https://vault-login.test/login")')).ok,true);
const beforeScriptedClipboard=await clipboard.readText();
try{
await clipboard.writeText(clipboardSentinel);
const scriptWrite=await Promise.race([page.executeJavaScript("navigator.clipboard.writeText('Hidden page clipboard replacement').then(()=>true).catch(()=>false)",true),wait(3000).then(()=>false)]);
assert.equal(scriptWrite,false,'Secure page acquired unguarded Clipboard API write');
assert.equal(await clipboard.readText(),clipboardSentinel,'Secure page overwrote OS clipboard through Clipboard API');
await page.executeJavaScript("(()=>{const frame=document.createElement('iframe');frame.id='clipboard-child';frame.srcdoc='<p id=selected>Secret Roadmap</p>';document.body.append(frame)})()");await wait(350);
const childCapabilities=await page.executeJavaScript("(()=>{const child=document.getElementById('clipboard-child').contentWindow;return [typeof child.require,typeof child.process,typeof child.safetynet]})()");
assert.deepEqual(childCapabilities,['undefined','undefined','undefined'],'Child frame obtained Node or browser bridge capabilities');
assert.equal(page.getLastWebPreferences().sandbox,true,'Managed renderer sandbox was disabled');
await page.executeJavaScript("(()=>{const frame=document.getElementById('clipboard-child');try{const child=frame.contentWindow,d=child.document;if(!d.getElementById('selected'))return;const r=d.createRange();r.selectNodeContents(d.getElementById('selected'));child.getSelection().removeAllRanges();child.getSelection().addRange(r);child.focus();d.execCommand('copy')}catch{}finally{frame.remove()}})()",true);await wait(200);
assert.equal(await clipboard.readText(),clipboardSentinel,'Child frame legacy copy bypassed clipboard protection');
await page.executeJavaScript("(()=>{const frame=document.createElement('iframe');document.body.append(frame);try{const child=frame.contentWindow,d=child.document;d.body.textContent='Secret Roadmap';const r=d.createRange();r.selectNodeContents(d.body);child.getSelection().removeAllRanges();child.getSelection().addRange(r);child.focus();d.execCommand('copy')}finally{frame.remove()}})()",true);await wait(200);
assert.equal(await clipboard.readText(),clipboardSentinel,'Immediate about:blank child copy bypassed clipboard protection');
const childReset=await page.executeJavaScript("(()=>{const frame=document.createElement('iframe');document.body.append(frame);try{const child=frame.contentWindow,d=child.document;d.open();d.write('<p>Secret Roadmap</p>');d.close();const r=d.createRange();r.selectNodeContents(d.body);child.getSelection().removeAllRanges();child.getSelection().addRange(r);child.focus();d.execCommand('copy');return 'reset-completed'}catch(error){return error.name}finally{frame.remove()}})()",true);await wait(200);
assert.equal(childReset,'SecurityError','Child document replacement was not blocked');
assert.equal(await clipboard.readText(),clipboardSentinel,'Document reset bypassed child clipboard protection');
const mainReset=await page.executeJavaScript("(()=>{try{document.open();document.write('<p>Secret Roadmap</p>');document.close();const r=document.createRange();r.selectNodeContents(document.body);getSelection().removeAllRanges();getSelection().addRange(r);document.execCommand('copy');return 'reset-completed'}catch(error){return error.name}})()",true);await wait(200);
assert.equal(mainReset,'SecurityError','Main document replacement was not blocked');
assert.equal(await clipboard.readText(),clipboardSentinel,'Document reset bypassed main-frame clipboard protection');
assert.equal((await win.webContents.executeJavaScript('window.safetynet.navigate("https://vault-login.test/login")')).ok,true);
}finally{await clipboard.writeText(beforeScriptedClipboard);}
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.vaultFill(${JSON.stringify(saved.data.id)})`)).ok,true,'Exact HTTPS origin fill failed');
assert.equal(await page.executeJavaScript('document.getElementById("login-user").value'),login.username);assert.equal(await page.executeJavaScript('document.getElementById("login-password").value'),login.password);
assert.equal(await page.executeJavaScript('typeof window.safetynet'),'undefined','Remote site obtained vault bridge');
await page.executeJavaScript('document.querySelector("form").action="https://different-origin.test/capture"');
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.vaultFill(${JSON.stringify(saved.data.id)})`)).ok,false,'Cross-origin form accepted password');
}finally{await page.session.protocol.unhandle('https');await win.webContents.executeJavaScript(`window.safetynet.navigate(${JSON.stringify(url)})`);}
await win.webContents.executeJavaScript('document.getElementById("passwords").click()');await wait(200);
assert.equal(await win.webContents.executeJavaScript('document.getElementById("vault").hidden'),false);
try{fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'browser-vault.png'),(await win.webContents.capturePage()).toPNG());}catch{log('Vault screenshot unavailable');}
win.emit('blur');await wait(100);const blurVaultStatus=await win.webContents.executeJavaScript('window.safetynet.vaultStatus()');if(!blurVaultStatus.ok){const failedState=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;log('Vault status denial: '+JSON.stringify({error:blurVaultStatus.error,ready:failedState.ready,message:failedState.message,policyVersion:failedState.policyVersion}));}assert.equal(blurVaultStatus.ok,true,blurVaultStatus.error);assert.equal(blurVaultStatus.data.locked,true);
assert.equal((await win.webContents.executeJavaScript('window.safetynet.vaultList()')).ok,false);
assert.equal((await win.webContents.executeJavaScript('window.safetynet.vaultUnlock("wrong-fixture-password-only")')).ok,false);
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.vaultUnlock(${JSON.stringify(fixtureMaster)})`)).ok,true);
assert.equal((await win.webContents.executeJavaScript('window.safetynet.vaultList()')).data.length,1);
await win.webContents.executeJavaScript('document.getElementById("vault-close").click()');await wait(100);
log('Real local vault: native ML-KEM, DPAPI, encrypted storage, masked metadata, isolated exact-HTTPS fill, hostile form denial, blur lock and reopen passed');
const {dialog}=require('electron'),originalSave=dialog.showSaveDialog;let saveCalls=0;
dialog.showSaveDialog=async(_win,options)=>{saveCalls++;return {canceled:false,filePath:path.join(process.env.SAFETYNET_SMOKE_USERDATA,path.basename(options.defaultPath))};};
try{
await page.executeJavaScript('document.getElementById("safe-download").click()');
const safeFile=path.join(process.env.SAFETYNET_SMOKE_USERDATA,'safe.bin');for(let n=0;n<600;n++){if(fs.existsSync(safeFile)&&fs.statSync(safeFile).size===5)break;await wait(100);}
assert.equal(fs.existsSync(safeFile),true,'Scanned benign download was not released');assert.deepEqual(fs.readFileSync(safeFile),Buffer.from([0,1,2,3,255]));assert.equal(saveCalls,1);
await clipboardWait(async()=>{const completed=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;return completed.ready&&completed.message==='Download scanned and saved.';});
await page.executeJavaScript('document.getElementById("blocked-download").click()');
for(let n=0;n<300;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(s.data.message.startsWith('Download blocked:'))break;await wait(100);}
assert.equal(fs.existsSync(path.join(process.env.SAFETYNET_SMOKE_USERDATA,'blocked.bin')),false);assert.equal(saveCalls,1,'Blocked download reached save dialog');
log('Real YARA download gate: safe binary saved; blocked file never reaches save dialog/filesystem');
const evidenceHeaders={authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`};let recorded;
await clipboardWait(async()=>{recorded=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:evidenceHeaders})).json()).events.filter(e=>e.kind==='evidence.recorded');return recorded.length>=2;});
const captured=[];for(const event of recorded){const response=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/evidence/${event.metadata.evidenceId}?reason=investigation`,{headers:evidenceHeaders});assert.equal(response.status,200);captured.push((await response.json()).payload);}
assert.ok(captured.some(p=>p.decision==='allow'&&p.name==='safe.bin'&&p.bytes===5&&p.sourceUrl===url+'/download-safe'));
assert.ok(captured.some(p=>p.decision==='block'&&p.name==='blocked.bin'&&p.sourceUrl===url+'/download-blocked'));
assert.ok(captured.every(p=>!p.content&&!p.data&&!p.filePath));
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'download-evidence-native-proof.json'),JSON.stringify({actualElectron:true,allowedDownloadCaptured:true,blockedDownloadCaptured:true,noFileContents:true,protectedAccessAudited:true,eventIds:recorded.map(e=>e.metadata.sourceEventId)},null,2));
log('Native allowed/blocked download metadata captured in encrypted evidence with audited analyst access');
}finally{dialog.showSaveDialog=originalSave;}
const sample=path.join(process.env.SAFETYNET_SMOKE_USERDATA,'secret-sample.docx');
const runtime=path.resolve('.runtime/windows/python/python.exe');
if(fs.existsSync(runtime)){
const create=require('node:child_process').spawnSync(runtime,['-c','import sys,zipfile; z=zipfile.ZipFile(sys.argv[1],"w"); z.writestr("word/document.xml",\'<document xmlns="urn:test"><t>Secret Roadmap</t></document>\'); z.close()',sample],{encoding:'utf8',windowsHide:true});assert.equal(create.status,0,create.stderr);
const {dialog}=require('electron'),originalChooser=dialog.showOpenDialog;
dialog.showOpenDialog=async()=>({canceled:false,filePaths:[sample]});
try{const inspection=await win.webContents.executeJavaScript('window.safetynet.inspectFile()');assert.equal(inspection.ok,true,inspection.error);assert.equal(inspection.data.ruleId,'secret-roadmap');assert.equal(inspection.data.contentType,'office');}finally{dialog.showOpenDialog=originalChooser;}
log('Bundled local document inspection passed');
}
await page.executeJavaScript(`fetch(${JSON.stringify(url+'/sink')},{method:'POST',body:new Uint8Array([255,254])}).catch(()=>{})`);
assert.equal((await (await fetch(url+'/count')).json()).posts,1,'Binary upload reached the destination');
const requestAuditHeaders={authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`};
const credentialBody='password=synthetic-low-entropy-only';
await page.executeJavaScript(`fetch(${JSON.stringify(url+'/sink')},{method:'POST',body:${JSON.stringify(credentialBody)}}).then(r=>r.text())`);
let requestEvents;await clipboardWait(async()=>{requestEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers:requestAuditHeaders})).json()).events;return requestEvents.some(e=>e.kind==='upload.authorized'&&e.metadata.request?.bytes===Buffer.byteLength(credentialBody));});
const credentialHash=require('node:crypto').createHash('sha256').update(credentialBody).digest('hex');
assert.equal(JSON.stringify(requestEvents).includes(credentialBody),false,'Credential request body leaked into central events');
assert.equal(JSON.stringify(requestEvents).includes(credentialHash),false,'Credential request fingerprint leaked into central events');
assert.ok(requestEvents.filter(e=>e.kind.startsWith('upload.')).every(e=>!e.metadata.file),'Upload request bodies remained classified as hash-bearing files');
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'request-privacy-native-proof.json'),JSON.stringify({actualElectron:true,credentialRequestReceived:true,bodyNotLogged:true,bodyHashNotLogged:true,safeBytesRetained:true,traceId:requestEvents.find(e=>e.kind==='upload.authorized'&&e.metadata.request?.bytes===Buffer.byteLength(credentialBody))?.metadata.traceId},null,2));
log('Real credential POST preserves byte count without body or fingerprint logging');
log('Capturing browser');
try{fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'browser.png'),(await win.webContents.capturePage()).toPNG());}catch(e){log('Screenshot unavailable: '+e.message);}
log('Loading admin console');
const admin=new BrowserWindow({show:false,width:1440,height:1100,webPreferences:{nodeIntegration:false,contextIsolation:true,sandbox:true}});
await admin.loadURL(process.env.SAFETYNET_SMOKE_SERVER);
await admin.webContents.executeJavaScript(`document.getElementById('token').value=${JSON.stringify(process.env.SAFETYNET_SMOKE_ADMIN)};document.getElementById('connect').click();`);
for(let n=0;n<30;n++){if(await admin.webContents.executeJavaScript('!document.getElementById("workspace").hidden'))break;await wait(100);}
assert.equal(await admin.webContents.executeJavaScript('document.getElementById("workspace").hidden'),false);
assert.equal(await admin.webContents.executeJavaScript('document.getElementById("evidence-policy-enabled").checked&&document.getElementById("evidence-policy-downloads").checked'),true,'Signed evidence policy missing from actual admin controls');
try{fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'admin.png'),(await admin.webContents.capturePage()).toPNG());}catch(e){log('Screenshot unavailable: '+e.message);}
const headers={authorization:`Bearer ${process.env.SAFETYNET_SMOKE_ADMIN}`,'content-type':'application/json'};
const secondary=process.env.SAFETYNET_SMOKE_SECONDARY;
assert.equal(await page.executeJavaScript(`fetch(${JSON.stringify(secondary)}).then(r=>r.text())`),'secondary');
const beforeDNS=(await (await fetch(url+'/count')).json()).secondaryRequests;
const blocklistUpdate=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/security/blocklists`,{method:'PUT',headers,body:JSON.stringify({expectedVersion:1,blockedHosts:['blocked.test'],blockedIPs:['127.0.0.2']})});assert.equal(blocklistUpdate.status,200);
for(let n=0;n<200;n++){const updated=await win.webContents.executeJavaScript('window.safetynet.state()');if(updated.data.ready&&updated.data.policyVersion===2)break;await wait(100);}
assert.equal(await page.executeJavaScript(`fetch(${JSON.stringify(secondary)}).then(()=>false).catch(()=>true)`),true);
assert.equal((await (await fetch(url+'/count')).json()).secondaryRequests,beforeDNS,'Blocked IP receiver got the request');log('Live DNS/IP blocklist prevented a previously working destination');
const overview=await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json();
const managedPolicy=overview.policy;managedPolicy.version+=1;managedPolicy.security.dns.blockedIPs=[];managedPolicy.proxy={mode:'fixed_servers',rules:`http=127.0.0.1:${new URL(url).port}`,bypass:''};
const publication=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/policy`,{method:'PUT',headers,body:JSON.stringify(managedPolicy)});assert.equal(publication.status,200);
for(let n=0;n<180;n++){const updated=await win.webContents.executeJavaScript('window.safetynet.state()');if(updated.data.ready&&updated.data.policyVersion===3)break;await wait(100);}
const navigation=await win.webContents.executeJavaScript(`window.safetynet.navigate('http://proxy-check.invalid/')`);assert.equal(navigation.ok,true,navigation.error);
for(let n=0;n<50;n++){if((await (await fetch(url+'/count')).json()).proxyRequests>0)break;await wait(100);}
assert.ok((await (await fetch(url+'/count')).json()).proxyRequests>0,'Managed proxy did not receive browser navigation');log('Managed proxy enforcement passed');
const reference='The confidential engineering roadmap contains restricted architecture budgets and unreleased customer contracts.';
const draftResponse=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/teaching`,{method:'POST',headers,body:JSON.stringify({label:'Internal engineering reference',filename:'internal.txt',data:Buffer.from(reference).toString('base64')})});assert.equal(draftResponse.status,200);
const draft=await draftResponse.json();assert.equal(draft.status,'draft');assert.ok(draft.reference.fragmentHashes.length>0);
const publicationResponse=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/teaching/${draft.id}/publish`,{method:'POST',headers,body:JSON.stringify({expectedVersion:3,approve:true})});assert.equal(publicationResponse.status,200);
for(let n=0;n<200;n++){const updated=await win.webContents.executeJavaScript('window.safetynet.state()');if(updated.data.ready&&updated.data.policyVersion===4)break;await wait(100);}
await page.executeJavaScript("fetch('/sink',{method:'POST',body:'Public text after teaching'}).then(r=>r.text())");
const beforeExcerpt=(await (await fetch(url+'/count')).json()).posts;
const excerpt='Public preface: engineering roadmap contains restricted architecture budgets and unreleased customer contracts. Public appendix.';
assert.equal(await page.executeJavaScript(`fetch('/sink',{method:'POST',body:${JSON.stringify(excerpt)}}).then(()=>false).catch(()=>true)`),true);
assert.equal((await (await fetch(url+'/count')).json()).posts,beforeExcerpt,'Registered confidential excerpt reached external receiver');
log('Governed document teaching published signed fragment rules and blocked an altered excerpt before transmission');
for(const [enabled,version] of [[false,5],[true,6]]){
const toggle=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/devices/${result.data.deviceId}/inspection`,{method:'PATCH',headers,body:JSON.stringify({expectedVersion:version-1,documentAnalysisEnabled:enabled})});assert.equal(toggle.status,200);
for(let n=0;n<200;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(s.data.ready&&s.data.policyVersion===version)break;await wait(100);}
const scanState=await win.webContents.executeJavaScript('window.safetynet.state()');assert.equal(scanState.data.documentScanEnabled,enabled);
if(!enabled){const scan=await win.webContents.executeJavaScript('window.safetynet.inspectFile()');assert.equal(scan.ok,false);assert.match(scan.error,/disabled/);assert.equal(await page.executeJavaScript(`fetch('/sink',{method:'POST',body:'Secret Roadmap'}).then(()=>false).catch(()=>true)`),true);}
}
log('Signed per-browser document-analysis switch changed manual scanning without disabling mandatory DLP');
const displayPolicy=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json()).policy;
displayPolicy.version+=1;displayPolicy.security.content.blockedPhrases=['restricted-display-marker'];
const displayPublication=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/policy`,{method:'PUT',headers,body:JSON.stringify(displayPolicy)});assert.equal(displayPublication.status,200);
for(let n=0;n<200;n++){const updated=await win.webContents.executeJavaScript('window.safetynet.state()');if(updated.data.ready&&updated.data.policyVersion===7)break;await wait(100);}
await page.executeJavaScript("document.body.append('restricted-display-marker')");
for(let n=0;n<50;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(!s.data.ready)break;await wait(100);}
const contentState=await win.webContents.executeJavaScript('window.safetynet.state()');assert.equal(contentState.data.ready,false);assert.equal(contentState.data.message,'This page contains content blocked by company policy.');
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.navigate(${JSON.stringify(page.getURL()+'#same-document')})`)).ok,false,'Hash-only navigation escaped content quarantine');
assert.equal((await win.webContents.executeJavaScript('window.safetynet.navigate("wss://example.test/")')).ok,false,'Unsupported navigation cleared quarantine');
assert.equal((await win.webContents.executeJavaScript('window.safetynet.state()')).data.ready,false);
log('Live signed content rule quarantined a changed document through isolated preload');
displayPolicy.version+=1;displayPolicy.security.content.blockedPhrases=[];
assert.equal((await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/policy`,{method:'PUT',headers,body:JSON.stringify(displayPolicy)})).status,200);
for(let n=0;n<200;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(s.data.ready&&s.data.policyVersion===8)break;await wait(100);}
assert.equal((await win.webContents.executeJavaScript('window.safetynet.state()')).data.ready,true);
const visualLogin='<!doctype html><meta charset="utf-8"><title>Visual identity fixture</title><style>body{font-family:Arial;background:#fff;color:#202124;margin:0}form{margin:60px auto;padding:32px;border:2px solid #3267cb;border-radius:12px;width:340px;height:330px;box-sizing:content-box}h1{color:#3267cb;font-size:27px}input{display:block;margin:20px 0;padding:12px;border:1px solid #aaa;width:260px}button{background:#3267cb;color:white;padding:12px}</style><form method="post" action="/sink"><h1>SafetyNet Identity Lab</h1><h2>Sign in</h2><p>Use your laboratory account</p><input name="username" type="email" autocomplete="username"><input type="password" autocomplete="current-password"><button type="submit">Continue</button></form>';
await page.session.protocol.handle('https',request=>{if(new URL(request.url).origin!=='https://identity.example.test')throw Error('Unexpected visual fixture URL');return new Response(visualLogin,{headers:{'content-type':'text/html'}});});
log('Visual fixture: navigating approved origin');
await Promise.race([win.webContents.executeJavaScript('window.safetynet.navigate("https://identity.example.test/login")'),wait(15000).then(()=>{throw Error('Visual fixture navigation timed out');})]);await wait(400);
log('Visual fixture: capturing approved form');
const formRect=await page.executeJavaScript('(()=>{const r=document.querySelector("form").getBoundingClientRect();return {x:Math.floor(r.x),y:Math.floor(r.y),width:Math.ceil(r.width),height:Math.ceil(r.height)}})()');
const referencePNG=await require('../apps/browser/visual-capture.cjs').capturePNG(page,formRect);
const referenceResponse=await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/security/visual-reference`,{method:'POST',headers,body:JSON.stringify({expectedVersion:8,brandId:'identity-lab',label:'Controlled Identity Lab',allowedOrigins:['https://identity.example.test'],data:referencePNG.toString('base64'),scope:'login-form'})});assert.equal(referenceResponse.status,200);const visualDraft=await referenceResponse.json();
const visualPolicy=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json()).policy;visualPolicy.version++;visualDraft.brand.requiredText=['SafetyNet Identity Lab'];visualPolicy.security.visualPhishing={enabled:true,failClosed:true,brands:[visualDraft.brand]};
assert.equal((await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/policy`,{method:'PUT',headers,body:JSON.stringify(visualPolicy)})).status,200);
for(let n=0;n<200;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(s.data.ready&&s.data.policyVersion===9&&!s.data.loginCheckPending)break;await wait(100);}
assert.equal((await win.webContents.executeJavaScript('window.safetynet.state()')).data.ready,true,'Approved visual origin blocked');
const postsBeforePhish=(await (await fetch(url+'/count')).json()).posts;
const phishingNavigation=await win.webContents.executeJavaScript(`window.safetynet.navigate(${JSON.stringify(url+'/visual-login')})`);
const expectedPhishingMessage='Blocked: this login resembles a protected brand on an unapproved origin.';
for(let n=0;n<120;n++){const s=await win.webContents.executeJavaScript('window.safetynet.state()');if(!s.data.ready&&s.data.message===expectedPhishingMessage)break;await wait(100);}
const phishingState=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;
const visualDiagnosticEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json()).events.filter(e=>e.kind==='phishing.block');
// Only fixed synthetic fixture state and safe identifiers enter this artifact.
const knownMessages=[expectedPhishingMessage,'Login protection could not approve this view. Credential actions are held.','Blocked: this login could not be inspected safely.'];
fs.writeFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'visual-phishing-native-diagnostic.json'),JSON.stringify({stage:'unapproved-synthetic-login',navigationOK:phishingNavigation.ok===true,navigationErrorClass:phishingNavigation.error?.includes('ERR_BLOCKED_BY_CLIENT')?'ERR_BLOCKED_BY_CLIENT':phishingNavigation.error?'other-error':null,ready:phishingState.ready,policyVersion:phishingState.policyVersion,loginCheckPending:phishingState.loginCheckPending,message:knownMessages.includes(phishingState.message)?phishingState.message:'other-status',phishingEvents:visualDiagnosticEvents.map(e=>({id:e.id,ruleId:e.metadata.ruleId,traceId:e.metadata.traceId})),destinationPostsUnchanged:(await (await fetch(url+'/count')).json()).posts===postsBeforePhish},null,2));
assert.equal(phishingState.ready,false,'Unapproved visual login did not enter quarantine; see visual-phishing-native-diagnostic.json');assert.equal(phishingState.message,expectedPhishingMessage);
assert.equal((await win.webContents.executeJavaScript(`window.safetynet.navigate(${JSON.stringify(page.getURL()+'#same-document')})`)).ok,false,'Hash-only navigation escaped visual quarantine');
let visualEvents;await clipboardWait(async()=>{visualEvents=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json()).events;return visualEvents.some(e=>e.kind==='phishing.block'&&e.metadata.ruleId==='identity-lab');});assert.ok(visualEvents.some(e=>e.kind==='phishing.block'&&e.metadata.ruleId==='identity-lab'),'Visual brand decision was not audited');
assert.equal((await (await fetch(url+'/count')).json()).posts,postsBeforePhish);
await wait(2500);assert.equal((await win.webContents.executeJavaScript('window.safetynet.state()')).data.ready,false,'Policy refresh cleared phishing quarantine');
const safeNavigation=await win.webContents.executeJavaScript(`window.safetynet.navigate(${JSON.stringify(url)})`);assert.equal(safeNavigation.ok,true,safeNavigation.error);
await page.session.protocol.unhandle('https');
log('Real screenshot-derived pHash: trusted origin allowed, identical login at unlisted origin blocked, no payload released, quarantine survived refresh and safe navigation recovered');
const managedClipboardPolicy=(await (await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/overview`,{headers})).json()).policy;
const liveClipboardOriginal=await clipboard.readText();
try{
for(const allowed of [false,true]){
// A new policy intentionally reloads the managed document. Observe that
// reload before selecting text; otherwise the guard correctly rejects a
// selection whose document is replaced during inspection.
let policyDocumentLoaded=false;const onPolicyLoad=()=>{policyDocumentLoaded=true;};
page.once('did-finish-load',onPolicyLoad);
managedClipboardPolicy.version++;managedClipboardPolicy.security.clipboard.allowCopy=allowed;
assert.equal((await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/policy`,{method:'PUT',headers,body:JSON.stringify(managedClipboardPolicy)})).status,200);
await clipboardWait(async()=>{const s=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;return s.ready&&s.policyVersion===managedClipboardPolicy.version;});
await clipboardWait(async()=>policyDocumentLoaded&&!page.isLoading());page.removeListener('did-finish-load',onPolicyLoad);
await clipboard.writeText(clipboardSentinel);await selectClipboardText('Public live-policy sample');
// Adding the synthetic selection node triggers the preload's 150 ms
// visual-mutation debounce. Let that new document revision be checked
// before starting the deliberately slower isolated YARA scan.
await page.executeJavaScript('new Promise(resolve=>setTimeout(resolve,250))');
await clipboardWait(async()=>{const s=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;return s.ready&&!s.loginCheckPending;});
await clipboardKey('C');
if(allowed&&await clipboard.readText()!=='Public live-policy sample'){const s=(await win.webContents.executeJavaScript('window.safetynet.state()')).data;log('Live copy gate state: '+JSON.stringify({ready:s.ready,policyVersion:s.policyVersion,message:s.message,clipboardPending:s.clipboardPending,loginCheckPending:s.loginCheckPending}));}
assert.equal(await clipboard.readText(),allowed?'Public live-policy sample':clipboardSentinel,'Native copy ignored centrally published permission');
await clipboard.writeText(clipboardSentinel);const share=await win.webContents.executeJavaScript('window.safetynet.shareURL()');
assert.equal(share.ok,allowed,'Share ignored centrally published copy permission');
assert.equal(await clipboard.readText(),allowed?new URL(url).toString():clipboardSentinel,'Share clipboard effect did not match signed copy policy');
}
log('Live signed clipboard permission blocked and re-enabled native Copy and Share without restart');
}finally{await clipboard.writeText(liveClipboardOriginal);await page.executeJavaScript("document.getElementById('clipboard-source')?.remove()");}
await fetch(`${process.env.SAFETYNET_SMOKE_SERVER}/api/admin/devices/${result.data.deviceId}/revoke`,{method:'POST',headers,body:'{}'});
for(let n=0;n<180;n++){const state=await win.webContents.executeJavaScript('window.safetynet.state()');if(!state.data.ready)break;await wait(100);}
assert.equal((await win.webContents.executeJavaScript('window.safetynet.state()')).data.ready,false,'Revocation did not quarantine browser');
console.log('Electron smoke passed: enrollment, clipboard DLP/ClickFix and live permissions, sandboxed frame bypass tests, agents, YARA pre-save downloads, local documents, live DNS/content, proxy, governed teaching and revocation.');
require('../apps/browser/page-clipboard-guard.cjs').disposePageClipboardGuard(page);
app.exit(0);
}catch(e){fs.appendFileSync(path.join(process.env.SAFETYNET_SMOKE_ARTIFACTS,'smoke-entry.txt'),e.stack+'\n');console.error(e.stack);app.exit(1);}
});