55 lines
4.6 KiB
JavaScript
55 lines
4.6 KiB
JavaScript
// Controlul negativ al probei remedierii: fiecare paznic din remediere.mjs e stricat intr-o COPIE a arborelui, si proba trebuie sa
|
|
// iasa ROSIE pe copia stricata (cu probele chiar rulate: se cere cel putin un rand RAU, nu doar codul de iesire), iar pe copia
|
|
// neatinsa VERDE. O plantare care nu se potriveste cu sursa (tiparul nu mai exista) e un ESEC al controlului, nu o linie informativa.
|
|
// node control-negativ-remediere.mjs iesire 0 = copia neatinsa verde si toate plantarile rosii
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const AICI = path.dirname(fileURLToPath(import.meta.url));
|
|
// dosarul scanerului: readiness/ intr-o copie publica, cloud-gateway/ in depozitul de dezvoltare (aceeasi regula ca in control-plane.mjs)
|
|
const { caleaScanerului } = await import('./control-plane.mjs');
|
|
const CG = path.dirname(caleaScanerului());
|
|
const PLANTARI = [
|
|
{ nume: 'judecata fara proprietatea pozitiva ("defect absent" = rezolvat)', din: 'if (inca || poz === false)', in: 'if (inca)' },
|
|
{ nume: 'reteta node fara grupul hibrid', din: 'if (s.groups) opt.ecdhCurve = grup(s.groups);', in: 'if (false) opt.ecdhCurve = grup(s.groups);' },
|
|
{ nume: 'scanarea de dinainte de aplicare acceptata', din: 'else if (!(Date.parse(scan.measuredAt) > Date.parse(limita)))', in: 'else if (false)' },
|
|
// 2026-09-29, R1 si R2 (revizuirea adversariala inainte de publicare); R2 pune inapoi FORMA VECHE intreaga (fara margine = se judeca)
|
|
{ nume: 'R1: domeniul din ref folosit fara verificare in comenzi', din: 'if (d && Object.hasOwn(REMEDIERI, d.id) && !domeniuValid(d.domain))', in: 'if (d && Object.hasOwn(REMEDIERI, d.id) && !domeniuValid(d.domain) && process.env.AERE_PLANTA_NICIODATA)' },
|
|
{ nume: 'R2: fara margine de timp se judeca pe orice scanare', perechi: [
|
|
['const limita = o.appliedAt || plan.generatedAt || null;', 'const limita = o.appliedAt || null;'],
|
|
["else if (!limita || !Number.isFinite(Date.parse(limita)))", 'else if (false)'],
|
|
['else if (!(Date.parse(scan.measuredAt) > Date.parse(limita)))', 'else if (limita && !(Date.parse(scan.measuredAt) > Date.parse(limita)))'] ] },
|
|
{ nume: 'alta gazda acceptata', din: 'else if (scan.domain !== d.domain)', in: 'else if (false)' },
|
|
{ nume: 'versiunea minima scapata din unire', din: "if (x.tlsMin) s.tlsMin = s.tlsMin === '1.3' || x.tlsMin === '1.3' ? '1.3' : '1.2';", in: "if (x.tlsMin) s.tlsMin = '1.2';" },
|
|
];
|
|
function copie() {
|
|
const t = fs.mkdtempSync(path.join(os.tmpdir(), 'aere-b1-rem-cn-'));
|
|
fs.mkdirSync(path.join(t, 'control-plane'));
|
|
for (const f of ['readiness-service.mjs', 'adrese-private.mjs']) fs.copyFileSync(path.join(CG, f), path.join(t, f));
|
|
for (const f of ['remediere.mjs', 'proba-remediere.mjs', 'plan-migrare.mjs', 'executa-migrare.mjs', 'control-plane.mjs']) fs.copyFileSync(path.join(AICI, f), path.join(t, 'control-plane', f));
|
|
return t;
|
|
}
|
|
function ruleaza(t) {
|
|
const r = spawnSync(process.execPath, [path.join(t, 'control-plane', 'proba-remediere.mjs')], { encoding: 'utf8', timeout: 240000 });
|
|
const out = (r.stdout || '') + (r.stderr || '');
|
|
return { cod: r.status, rele: (out.match(/^\s+RAU\s/gm) || []).length, bune: (out.match(/^\s+OK\s/gm) || []).length, out };
|
|
}
|
|
let esecuri = 0;
|
|
const t0 = copie(); const r0 = ruleaza(t0); fs.rmSync(t0, { recursive: true, force: true });
|
|
if (r0.cod === 0 && r0.rele === 0 && r0.bune > 0) console.log(` OK copia neatinsa: verde (${r0.bune} treceri)`);
|
|
else { esecuri++; console.log(` RAU copia neatinsa nu e verde (cod ${r0.cod}, ${r0.rele} RAU)`); }
|
|
for (const p of PLANTARI) {
|
|
const t = copie(); const f = path.join(t, 'control-plane', 'remediere.mjs'); const src = fs.readFileSync(f, 'utf8');
|
|
const perechi = p.perechi || [[p.din, p.in]];
|
|
if (perechi.some(([a]) => src.split(a).length !== 2)) { esecuri++; console.log(` RAU ${p.nume}: tiparul nu apare exact o data in sursa (plantarea nu s-a putut pune)`); fs.rmSync(t, { recursive: true, force: true }); continue; }
|
|
fs.writeFileSync(f, perechi.reduce((s, [a, b]) => s.replace(a, b), src));
|
|
const r = ruleaza(t); fs.rmSync(t, { recursive: true, force: true });
|
|
if (r.cod !== 0 && r.rele > 0 && r.bune > 0) console.log(` OK ${p.nume}: proba ROSIE (${r.rele} RAU)`);
|
|
else { esecuri++; console.log(` RAU ${p.nume}: proba nu a iesit rosie din motivul plantat (cod ${r.cod}, ${r.rele} RAU, ${r.bune} OK)`); }
|
|
}
|
|
console.log(esecuri ? `RAU: ${esecuri} esecuri ale controlului` : `DOVEDIT: copia neatinsa verde, ${PLANTARI.length} din ${PLANTARI.length} plantari rosii`);
|
|
process.exitCode = esecuri ? 1 : 0;
|