31 lines
1.7 KiB
JavaScript
31 lines
1.7 KiB
JavaScript
// Owned disposable fixture ONLY. Never use against installed application data.
|
|
import assert from 'node:assert/strict';
|
|
import { createHash } from 'node:crypto';
|
|
import { existsSync, readFileSync, writeFileSync, renameSync, statSync, unlinkSync } from 'node:fs';
|
|
const key = '/data/config/server-nostr-key';
|
|
const held = '/data/config/fixture-held-server-key';
|
|
const receipt = '/data/fixture-key-loss.json';
|
|
const database = '/data/podsteadr.sqlite3';
|
|
const hash = path => createHash('sha256').update(readFileSync(path)).digest('hex');
|
|
if (process.argv[2] === 'hold') {
|
|
assert.equal(existsSync(held), false);
|
|
assert.equal(existsSync(receipt), false);
|
|
const state = { keyHash: hash(key), keyInode: statSync(key).ino, databaseHash: hash(database) };
|
|
writeFileSync(receipt, JSON.stringify(state), { flag: 'wx', mode: 0o600 });
|
|
renameSync(key, held);
|
|
console.log('Prepared synthetic missing-key preservation negative; key retained inside owned volume');
|
|
} else if (process.argv[2] === 'verify-restore') {
|
|
const state = JSON.parse(readFileSync(receipt, 'utf8'));
|
|
assert.equal(existsSync(key), false, 'startup must not regenerate a lost identity');
|
|
assert.equal(hash(database), state.databaseHash, 'startup must not migrate/mutate data without identity');
|
|
assert.equal(hash(held), state.keyHash);
|
|
assert.equal(statSync(held).ino, state.keyInode);
|
|
renameSync(held, key);
|
|
assert.equal(hash(key), state.keyHash);
|
|
assert.equal(statSync(key).ino, state.keyInode);
|
|
unlinkSync(receipt);
|
|
console.log('PASS missing-key startup preserved database and original identity; fixture restored exact inode/bytes');
|
|
} else {
|
|
throw new Error('Explicit fixture phase required');
|
|
}
|