/** * Session 64 — off-box backup hardening. * * Locks three properties that are easy to silently undo later: * 1. the Storage Box host key is STATICALLY PINNED (no trust-on-first-use) * 2. the remote directory is guaranteed before a push * 3. a failed REQUIRED off-box push pages and reports offbox_ok:false */ const fs = require('fs'); const path = require('path'); const { execFileSync } = require('child_process'); const ROOT = path.join(__dirname, '..', '..'); const SCRIPT = fs.readFileSync(path.join(ROOT, 'scripts', 'backup-db.sh'), 'utf8'); const KNOWN_HOSTS_PATH = path.join(ROOT, 'scripts', 'storagebox_known_hosts'); const EXPECTED_FP = 'SHA256:XqONwb1S0zuj5A1CDxpOSuD2hnAArV1A3wKY7Z3sdgM'; describe('host key is statically pinned', () => { test('the pinned known_hosts file ships in the repo', () => { expect(fs.existsSync(KNOWN_HOSTS_PATH)).toBe(true); }); test('it contains the VERIFIED Storage Box ED25519 fingerprint', () => { // ssh-keygen is the authority — parse the file the way ssh will. const out = execFileSync('ssh-keygen', ['-lf', KNOWN_HOSTS_PATH], { encoding: 'utf8' }); expect(out).toContain(EXPECTED_FP); expect(out).toContain('[u635423.your-storagebox.de]:23'); }); test('the script uses StrictHostKeyChecking=yes with the pinned file', () => { expect(SCRIPT).toMatch(/StrictHostKeyChecking=yes/); expect(SCRIPT).toMatch(/UserKnownHostsFile=\$\{KNOWN_HOSTS\}/); }); test('trust-on-first-use and disabled checking are GONE and stay gone', () => { // Assert on EXECUTABLE lines only — the comments deliberately name // accept-new to explain what was removed and why it must not come back. const code = SCRIPT.split('\n') .filter((l) => !l.trim().startsWith('#')) .join('\n'); expect(code).not.toMatch(/StrictHostKeyChecking=accept-new/); expect(code).not.toMatch(/StrictHostKeyChecking=no\b/); expect(code).not.toMatch(/UserKnownHostsFile=\/dev\/null/); }); test('a missing pin file refuses the push rather than falling back', () => { expect(SCRIPT).toMatch(/refusing to push without host-key verification/); }); }); describe('remote directory is guaranteed', () => { test('uses --mkpath when available, else an explicit remote mkdir -p', () => { expect(SCRIPT).toMatch(/--mkpath/); expect(SCRIPT).toMatch(/mkdir -p/); }); }); describe('off-box failure is loud (Phase 2b)', () => { test('a failed REQUIRED push pages at urgent, not low', () => { const failBlock = SCRIPT.slice(SCRIPT.indexOf('off-box push FAILED')); expect(failBlock).toMatch(/notify "VYNDR OFF-BOX PUSH FAILED" "urgent"/); expect(SCRIPT).not.toMatch(/notify "VYNDR off-box push deferred" "low"/); }); test('the script emits a machine-readable off-box result', () => { expect(SCRIPT).toMatch(/OFFBOX_OK=1/); expect(SCRIPT).toMatch(/OFFBOX_OK=0/); }); test('exit code still reflects ON-BOX durability (no false total-failure)', () => { // The push lives in an if/else; neither branch exits non-zero. const pushSection = SCRIPT.slice(SCRIPT.indexOf('OFF-BOX COPY')); expect(pushSection).not.toMatch(/exit 1/); }); test('the API surfaces offbox_ok distinctly from ok', () => { const route = fs.readFileSync(path.join(ROOT, 'src', 'routes', 'internal.js'), 'utf8'); expect(route).toMatch(/offbox_ok/); expect(route).toMatch(/OFFBOX_OK=1/); }); }); describe('offbox_ok parsing', () => { // Mirrors the route's parse so the three-state logic is locked. const parse = (tail) => (/OFFBOX_OK=1/.test(tail) ? true : (/OFFBOX_OK=0/.test(tail) ? false : null)); test('success → true', () => expect(parse('...\nOFFBOX_OK=1\n')).toBe(true)); test('failure → false (never null, never true)', () => expect(parse('...\nOFFBOX_OK=0\n')).toBe(false)); test('deferred/absent → null, distinct from false', () => { expect(parse('OFFBOX_OK=deferred')).toBeNull(); expect(parse('')).toBeNull(); }); });