Files

11 lines
2.9 KiB
JavaScript
Raw Permalink Normal View History

import test from 'node:test';
import assert from 'node:assert/strict';
import vm from 'node:vm';
import {readFileSync} from 'node:fs';
import {createRequire} from 'node:module';
const require=createRequire(import.meta.url),source=readFileSync(new URL('../apps/browser/main.cjs',import.meta.url),'utf8');
const delivery=require('../apps/browser/evidence-delivery.cjs');
function fixture(){const writes=[],aborts=[];const policy={version:1,expiresAt:new Date(Date.now()+60000).toISOString(),evidence:{enabled:true,captureDownloads:true,captureInteractions:true}};const c=vm.createContext({policy,ready:true,device:{id:'device-a'},auditQueue:[],evidenceRequestTypes:new Map(),require:id=>id.startsWith('node:')?require(id):id.includes('evidence-delivery')?delivery:require('../packages/core/'+id.split('/').at(-1)),persistAudit:()=>writes.push('persist'),flushAudit(){},diagnostics:{event(){}},diagnosticContext:x=>x,diagnosticCorrelation:()=>({}),quarantine:()=>{throw Error('Unexpected quarantine');}});vm.runInContext(source.slice(source.indexOf('function enforceEvidencePolicy(){'),source.indexOf('async function flushAudit()')),c);vm.runInContext(source.slice(source.indexOf('async function audit(kind'),source.indexOf('function auditAgent(event)')),c);return {c,writes,aborts};}
const sessionId='00000000-0000-4000-8000-000000000001';
test('browser persists source completion and protected typed evidence in one audit tuple',async()=>{const f=fixture(),payload={pageUrl:'https://example.test/',action:'copy',sessionId,outcome:'completed',captureSource:'guarded-clipboard',sensitiveField:false,target:{tag:'INPUT'},bytes:8};await f.c.audit('clipboard.copy',undefined,undefined,undefined,undefined,payload,undefined,{action:'copy',sessionId,outcome:'completed'});assert.equal(f.writes.length,1);const record=f.c.auditQueue[0];assert.equal(record.interaction.outcome,'completed');assert.equal(record.protectedEvidence.type,'interaction');assert.equal(record.protectedEvidence.payload.target.tag,'INPUT');assert.equal(record.pageUrl,undefined);assert.equal(record.target,undefined);assert.equal(record.eventId.length,36);});
test('type-specific policy disable aborts only matching sends and strips only matching pending evidence',()=>{const f=fixture(),ordinary={eventId:'ordinary'},download={eventId:'download',protectedEvidence:{type:'download'}},interaction={eventId:'interaction',protectedEvidence:{type:'interaction'}};f.c.auditQueue=[ordinary,download,interaction];for(const type of ['download','interaction'])f.c.evidenceRequestTypes.set({abort:()=>f.aborts.push(type)},type);f.c.policy.evidence.captureInteractions=false;f.c.enforceEvidencePolicy();assert.deepEqual(f.aborts,['interaction']);assert.equal(f.c.auditQueue[0],ordinary);assert.equal(f.c.auditQueue[1],download);assert.equal(f.c.auditQueue[2].protectedEvidence,undefined);assert.equal(f.c.auditQueue[2].eventId,'interaction');assert.equal(f.writes.length,1);f.c.enforceEvidencePolicy();assert.equal(f.writes.length,1);});