Files
safetynet/apps/browser/history-snapshot.cjs
T

19 lines
1.3 KiB
JavaScript

'use strict';
const {createHash}=require('node:crypto');
// Chromium pageState can contain form values. Keep only a private comparison
// checksum; never expose serialized pageState or the checksum through the API.
function readHistorySnapshot(contents){
if(!contents||contents.isDestroyed())throw Error('Managed history unavailable');
const history=contents.navigationHistory,rows=history.getAllEntries(),activeIndex=history.getActiveIndex();
if(!Array.isArray(rows)||rows.length<1||rows.length>100||!Number.isInteger(activeIndex)||activeIndex<0||activeIndex>=rows.length)throw Error('History size limit');
const hash=createHash('sha256');let total=0;
const entries=rows.map(row=>{
if(typeof row.url!=='string'||row.url.length>4096||typeof row.title!=='string'||row.title.length>200||row.pageState!==undefined&&typeof row.pageState!=='string')throw Error('History size limit');
const state=row.pageState??null;if(state!==null){total+=state.length;if(state.length>1048576||total>8388608)throw Error('History size limit');}
const bytes=Buffer.from(JSON.stringify([row.url,row.title,state]));try{hash.update(bytes);}finally{bytes.fill(0);}
return {url:row.url,title:row.title};
});
return {activeIndex,entries,nativeBinding:hash.digest('hex')};
}
module.exports={readHistorySnapshot};