23 lines
1.7 KiB
JavaScript
23 lines
1.7 KiB
JavaScript
const {app}=require('electron');
|
|||
|
|
const fs=require('node:fs'),path=require('node:path');
|
||
|
|
function configureClient(connectionFile){
|
||
|
|
if(!connectionFile||!path.isAbsolute(connectionFile))throw Error('Absolute encrypted pairing file required');
|
||
|
|
app.setPath('userData',path.join(app.getPath('appData'),'safetynet-agent-helper'));
|
||
|
|
}
|
||
|
|
async function runClient(connectionFile,requestFile){
|
||
|
|
let stage='credential-store';try{
|
||
|
|
if(!requestFile)throw Error('Request file required');
|
||
|
|
stage='pairing';const descriptor=JSON.parse(fs.readFileSync(connectionFile,'utf8'));
|
||
|
|
if(descriptor.format!=='windows-dpapi-v1')throw Error('Pairing format rejected');
|
||
|
|
const connection=JSON.parse(await require('./dpapi.cjs').capabilityCrypto('unprotect',descriptor.protectedConnection));
|
||
|
|
const origin=new URL(connection.address);
|
||
|
|
if(origin.protocol!=='http:'||origin.hostname!=='127.0.0.1'||origin.username||origin.password||origin.pathname!=='/'||origin.search||origin.hash)throw Error('Agent endpoint rejected');
|
||
|
|
stage='request-file';const info=fs.statSync(requestFile);if(!info.isFile()||info.size>32768)throw Error('Request too large');
|
||
|
|
const body=fs.readFileSync(requestFile);if(body.length>32768)throw Error('Request too large');JSON.parse(body.toString());
|
||
|
|
stage='transport';const response=await require('./loopback-http.cjs').postLoopback({port:Number(origin.port),route:'/v1/actions',token:connection.token,body:JSON.parse(body.toString()),signal:AbortSignal.timeout(15000)});
|
||
|
|
stage='policy-response';
|
||
|
|
const result=response.body;if(response.status!==200)throw Error('Agent policy denied action');
|
||
|
|
process.stdout.write(JSON.stringify(result)+'\n');app.exit(0);
|
||
|
|
}catch(error){error.clientStage=stage;throw error;}
|
||
|
|
}
|
||
|
|
module.exports={configureClient,runClient};
|