Files
SGF/scripts/finance-bundle-check.mjs
T
2026-11-04 09:37:20 +02:00

11 lines
2.3 KiB
JavaScript

import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import {spawnSync} from 'node:child_process';
const read=p=>JSON.parse(fs.readFileSync(p,'utf8')),state=read('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'),artifact=read(path.join(state.root,'finance-bundle-latest.json')),root=path.join(state.root,'private/finance-bundle-check-'+crypto.randomBytes(6).toString('hex'));fs.mkdirSync(root);let checks=0;
const manifest=read(path.join(artifact.root,'manifest.json')),run=(dir,pin)=>spawnSync('C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe',['-r','require $argv[1]; try { Tempo\\Finance\\Composition\\Bundle::verify($argv[2],$argv[3]); echo "accepted"; } catch(Throwable $e) { echo "refused"; exit(2); }',path.resolve('packages/finance-bundle/Bundle.php'),dir,pin],{encoding:'utf8',windowsHide:true});
if(run(artifact.root,artifact.manifest_sha256).status!==0)throw Error('Valid artifact refused');checks++;
for(const kind of ['modified','missing','extra','traversal','pin']){
const dir=path.join(root,kind);fs.mkdirSync(dir);for(const f of [...manifest.files.map(f=>f.file),'manifest.json']){if(kind==='missing'&&f==='payables/bootstrap.php')continue;const target=path.join(dir,f);fs.mkdirSync(path.dirname(target),{recursive:true});fs.copyFileSync(path.join(artifact.root,f),target);}
let pin=artifact.manifest_sha256;if(kind==='modified')fs.appendFileSync(path.join(dir,'payables/bootstrap.php'),'\n// QA altered file\n');if(kind==='extra')fs.writeFileSync(path.join(dir,'unexpected.txt'),'QA');if(kind==='traversal'){const m=read(path.join(dir,'manifest.json'));m.files[0].file='../outside.php';fs.writeFileSync(path.join(dir,'manifest.json'),JSON.stringify(m));pin=crypto.createHash('sha256').update(fs.readFileSync(path.join(dir,'manifest.json'))).digest('hex');}if(kind==='pin')pin='0'.repeat(64);
if(run(dir,pin).status!==2)throw Error('Invalid artifact not refused: '+kind);checks++;
}
const output={passed:true,checks,artifact_files:manifest.files.length,manifest_sha256:artifact.manifest_sha256,refused:['modified','missing','extra','traversal','wrong_pin'],private_diagnostics_preserved:true};fs.writeFileSync(path.join(root,'proof.json'),JSON.stringify(output,null,2)+'\n');fs.writeFileSync(path.join(state.root,'finance-bundle-check-latest.json'),JSON.stringify({root,...output},null,2)+'\n');console.log(JSON.stringify(output));