const {app,BrowserWindow,session}=require('electron'); const {writeFileSync}=require('node:fs'); // This fixed helper is serialized into native Chromium Window and Worker realms. /* global WebTransport */ app.disableHardwareAcceleration();app.enableSandbox(); const mode=process.env.SAFETYNET_WT_MODE; if(mode==='disable-quic')app.commandLine.appendSwitch('disable-quic'); if(mode==='disable-blink')app.commandLine.appendSwitch('disable-blink-features','WebTransport'); async function sendWebTransport(target,hash){ const outcome={api:typeof WebTransport==='function',supportsReliableOnly:typeof WebTransport==='function'&&WebTransport.supportsReliableOnly===true,connected:false,sent:false,error:''};let transport; try{transport=new WebTransport(target,{serverCertificateHashes:[{algorithm:'sha-256',value:new Uint8Array(hash)}]});await Promise.race([transport.ready,new Promise((_,reject)=>setTimeout(()=>reject(Error('fixture-timeout')),6000))]);outcome.connected=true;const bytes=new TextEncoder().encode('SYNTHETIC_WEBTRANSPORT_DLP_MARKER');const datagram=transport.datagrams.writable.getWriter();await datagram.write(bytes);datagram.releaseLock();const stream=await transport.createUnidirectionalStream();const writer=stream.getWriter();await writer.write(bytes);await writer.close();outcome.sent=true;await new Promise(resolve=>setTimeout(resolve,300));}catch(error){outcome.error=error.name+':'+error.message;}finally{transport?.close();}return outcome; } app.on('login',(event,_contents,_details,authInfo,callback)=>{if(mode==='private-relay'&&authInfo.isProxy&&authInfo.host==='127.0.0.1'&&Number(authInfo.port)===Number(process.env.SAFETYNET_WT_PROXY.split(':').at(-1))){event.preventDefault();callback(process.env.SAFETYNET_WT_USERNAME,process.env.SAFETYNET_WT_PASSWORD);}}); app.whenReady().then(async()=>{ const target=process.env.SAFETYNET_WT_TARGET,hash=process.env.SAFETYNET_WT_HASH;let events=0; if(['forced-proxy','private-relay'].includes(mode))await session.defaultSession.setProxy({mode:'fixed_servers',proxyRules:process.env.SAFETYNET_WT_PROXY,proxyBypassRules:'<-loopback>'}); session.defaultSession.webRequest.onBeforeRequest({urls:[target+'*']},(_details,callback)=>{events++;callback({cancel:true});}); const win=new BrowserWindow({show:false,webPreferences:{sandbox:true,nodeIntegration:false,contextIsolation:true}}); await win.loadURL(process.env.SAFETYNET_WT_PAGE); const hashBytes=Array.from(Buffer.from(hash,'hex')),result=await win.webContents.executeJavaScript(`(${sendWebTransport.toString()})(${JSON.stringify(target)},${JSON.stringify(hashBytes)})`); const workerSource=`const send=${sendWebTransport.toString()};onmessage=async event=>{postMessage(await send(event.data.target,event.data.hash));close();};`; const worker=await win.webContents.executeJavaScript(`new Promise((resolve,reject)=>{const url=URL.createObjectURL(new Blob([${JSON.stringify(workerSource)}],{type:'text/javascript'}));const worker=new Worker(url);const timer=setTimeout(()=>{worker.terminate();URL.revokeObjectURL(url);reject(Error('worker-fixture-timeout'));},10000);worker.onmessage=event=>{clearTimeout(timer);worker.terminate();URL.revokeObjectURL(url);resolve(event.data);};worker.onerror=()=>{clearTimeout(timer);worker.terminate();URL.revokeObjectURL(url);reject(Error('worker-fixture-failed'));};worker.postMessage({target:${JSON.stringify(target+'/worker')},hash:${JSON.stringify(hashBytes)}});})`); const ordinaryPageLoaded=await win.webContents.executeJavaScript("document.querySelector('h1')?.textContent==='Local WebTransport receiver proof'"); writeFileSync(process.env.SAFETYNET_WT_OUTPUT,JSON.stringify({...result,worker,ordinaryPageLoaded,mode,resolvedProxy:await session.defaultSession.resolveProxy(target),webRequestEvents:events,chromium:process.versions.chrome,electron:process.versions.electron}));win.destroy();app.quit(); }).catch(error=>{console.error(error.stack);app.exit(1);});