Files
safetynet/apps/browser/evidence-delivery.cjs
T

17 lines
1.8 KiB
JavaScript

'use strict';
const {validateDownloadEvidence}=require('./evidence-capture.cjs');
function collectionAllowed(context){return !!context?.ready&&context.policy?.evidence?.enabled===true&&context.policy.evidence.captureDownloads===true&&Date.parse(context.policy.expiresAt)>Date.now();}
function validatedEvidence(payload){if(!validateDownloadEvidence(payload))throw Error('Invalid protected download evidence');return structuredClone(payload);}
function stripPendingEvidence(queue){return queue.map(({protectedEvidence,...event})=>event);}
async function deliverAuditRecord({record,send,getContext}){
const {protectedEvidence,...event}=record;await send('/api/device/events',event);
if(!protectedEvidence)return {eventDelivered:true,evidenceDelivered:false};
const context=getContext();
if(protectedEvidence.deviceId!==context?.deviceId||context?.policy&&(context.policy.evidence?.enabled!==true||context.policy.evidence.captureDownloads!==true||!(Date.parse(context.policy.expiresAt)>Date.now())))return {eventDelivered:true,evidenceDiscarded:true};
if(!context?.ready||!context.policy)throw Error('Evidence delivery paused until managed context is ready');
const payload=validatedEvidence(protectedEvidence.payload);
try{const result=await send('/api/device/evidence',{eventId:event.eventId,type:'download',payload});if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(result?.id||'')||!Number.isSafeInteger(result.sourceEventId)||result.sourceEventId<1)throw Error('Evidence acknowledgement invalid');return {eventDelivered:true,evidenceDelivered:true};}
catch(error){if(error.status===403)return {eventDelivered:true,evidenceDiscarded:true};throw error;}
}
module.exports={validatedEvidence,collectionAllowed,stripPendingEvidence,deliverAuditRecord};