aere-quantum/control-plane/control-negativ-raport-conformitate.mjs

64 lines
4.8 KiB
JavaScript

// control-negativ-raport-conformitate.mjs (2026-09-29): controlul negativ al verificarilor RC1-RC3 din proba-raport-conformitate.mjs
// (revizuirea adversariala dinaintea publicarii). Trei stari pe caz: PRINS (proba a ajuns la capat si verificarea numita e rosie),
// SCAPAT, STRICAT (copia nu s-a incarcat sau proba nu a ajuns la capat).
// V0 raportul de dinainte de reparatie, din git (sarit si spus daca revizia nu e in istoricul depozitului) -> RC1, RC2, RC3 rosii
// P1 RC1 scos cu o conditie falsa la rulare -> RC1 rosie
// P2 RC2 scos -> RC2 rosie
// P3 RC3 scos (cheile luate si din prototip) -> RC3 rosie
// Copiile stau LANGA original (importurile relative trebuie sa se rezolve) si se sterg; originalul trebuie sa ramana octet cu octet.
// node control-negativ-raport-conformitate.mjs -> 0 toate prinse, 1 unul scapa, 2 STRICAT
import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
import { fileURLToPath, pathToFileURL } from 'node:url';
const AICI = path.dirname(fileURLToPath(import.meta.url));
const SRC = path.join(AICI, 'raport-conformitate.mjs');
const PROBA = path.join(AICI, 'proba-raport-conformitate.mjs');
const sha = (f) => crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex');
const inainte = sha(SRC);
const REV = process.env.AERE_RAPORT_REV_VECHE || 'a88be275';
let prinse = 0, stricate = 0, total = 0;
function caz(id, text, tinte) {
total++;
const copie = path.join(AICI, `.plantat-raport-${id}.mjs`);
try {
fs.writeFileSync(copie, text);
const r = spawnSync(process.execPath, [PROBA], { encoding: 'utf8', timeout: 280000, env: { ...process.env, AERE_RAPORT_MODUL: pathToFileURL(copie).href } });
const out = (r.stdout || '') + (r.stderr || '');
if (!/raportul de conformitate: \d+\/\d+ cum trebuia/.test(out)) { stricate++; console.log(` STRICAT ${id}: proba nu a ajuns la capat (${out.trim().split('\n').filter((l) => !/^\s+at /.test(l)).pop()?.slice(0, 120)})`); return; }
const rosii = out.split('\n').filter((l) => l.includes('[RAU ]'));
const lipsa = tinte.filter((x) => !rosii.some((l) => l.includes(x)));
if (r.status === 1 && !lipsa.length) { prinse++; console.log(` PRINS ${id}: ${rosii.length} verificari rosii, intre ele ${tinte.join(', ')}`); }
else console.log(` SCAPAT ${id}: cod ${r.status}, nerosii: ${lipsa.join(', ') || '-'}`);
} finally { fs.rmSync(copie, { force: true }); }
}
const planta = (t, a, b) => (t.split(a).length === 2 ? t.replace(a, b) : null);
const CALE = `${REV}:cloud-gateway/control-plane/raport-conformitate.mjs`;
if (spawnSync('git', ['cat-file', '-e', CALE], { cwd: AICI }).status !== 0) console.log(` SARIT V0: revizia ${REV} nu e in istoricul acestui depozit; NEMASURAT aici`);
else {
const g = spawnSync('git', ['-c', 'core.autocrlf=false', 'show', CALE], { cwd: AICI, encoding: 'utf8' });
if (g.status !== 0 || g.stdout.includes('RC1 (2026-09-29)')) { stricate++; total++; console.log(' STRICAT V0: revizia veche nu se citeste sau are deja reparatia'); }
// forma 1 a raportului (API si campuri in romana, pana la 2026-09-29) nu se poate masura cu proba formei 2: nimic comparabil
else if (g.stdout.includes('organizatie')) console.log(` SARIT V0: revizia ${REV} e forma 1 a raportului (API romanesc); proba formei 2 nu o poate masura. RC1-RC3 raman pazite de P1-P3`);
else caz('V0', g.stdout, ['RC1:', 'RC2:', 'RC3:']);
}
const nou = fs.readFileSync(SRC, 'utf8');
const P = [
['P1', 'rezumat.verdict = vulnerabile === 0 && rezumat.unclassified > 0', "rezumat.verdict = vulnerabile === 0 && rezumat.unclassified > 0 && process.env.AERE_PLANTA_NICIODATA === 'da'", ['RC1:']],
['P2', "if (Number.isNaN(zi0.getTime()) || zi0.toISOString().slice(0, 10) !== date) throw", "if (Number.isNaN(zi0.getTime()) && process.env.AERE_PLANTA_NICIODATA === 'da') throw", ['RC2:']],
['P3', "const cc = typeof cat === 'string' && Object.hasOwn(C.categories, cat) ? C.categories[cat] : null;", 'const cc = cat ? C.categories[cat] : null;', ['RC3:']],
];
for (const [id, a, b, tinte] of P) {
const t = planta(nou, a, b);
if (!t) { stricate++; total++; console.log(` STRICAT ${id}: ancora nu apare exact o data`); continue; }
caz(id, t, tinte);
}
const ramase = fs.readdirSync(AICI).filter((f) => f.startsWith('.plantat-raport-'));
if (sha(SRC) !== inainte || ramase.length) { stricate++; console.log(' STRICAT originalul s-a schimbat sau au ramas copii: ' + ramase.join(',')); }
console.log(`\ncontrolul negativ RC1-RC3: prinse ${prinse}/${total}, stricate ${stricate}`);
process.exitCode = stricate ? 2 : prinse === total ? 0 : 1;