import test from 'node:test';
import assert from 'node:assert/strict';
import { createAdminWorker, createDurableObjectStore, normalizeRecord, recordLegalRelease, createDocumentHistory } from '../dist/index.js';
import { canonicalJson, sha256 } from '../dist/history.js';
import { createSyntheticStorage } from '../examples/synthetic.mjs';
const request = (path = '', init) => new Request(`https://example.test/admin/notabenda${path}`, init);
const query = (overrides = {}) => ({ query: '', kind: '', keyPrefix: '', from: '', to: '', limit: 25, ...overrides });
const createStore = (storage, prefix = 'evidence/demo-site/', options = {}) => createDurableObjectStore(storage, { prefix, ...options });
const mount = (store, extra = {}) => createAdminWorker({ authorize: () => ({ store, scopeLabel: 'Synthetic workspace' }), ...extra });
/** @requirements REQ-PRODUCT-CF-ADMIN */
test('authorization is mandatory, fail-closed, and evaluated before any store access', async () => {
assert.throws(() => createAdminWorker({}), /authorization/);
let reads = 0;
const store = { list: async () => { reads++; throw Error('must not run'); }, get: async () => { reads++; throw Error('must not run'); } };
for (const authorize of [() => null, () => false, () => ({ store: null }), () => { throw Error('SECRET'); }]) {
const worker = createAdminWorker({ authorize });
for (const path of ['', '/record?id=private', '/diff?before=a&after=b', '/unknown']) {
const response = await worker.fetch(request(path), {});
assert.equal(response.status, 403); assert.equal(await response.text(), 'Access denied.');
assert.equal(response.headers.get('cache-control'), 'no-store, private');
}
}
let authCalls = 0;
const worker = mount(store, { authorize: () => { authCalls++; return null; } });
await worker.fetch(request(), {}); await worker.fetch(request('/record?id=a'), {});
assert.equal(authCalls, 2); assert.equal(reads, 0);
});
test('authorized UI exposes evidence search, safe detail, and restrictive headers', async () => {
const worker = mount(createStore(createSyntheticStorage()));
const response = await worker.fetch(request(), {});
assert.equal(response.status, 200);
const html = await response.text();
assert.match(html, /Refine your search/); assert.match(html, /subject-4z2/); assert.match(html, /4 records on this page/);
assert.doesNotMatch(html, /
';
const storage = createSyntheticStorage([{ id: payload, data: { kind: payload, subjectId: payload, body: payload } }]);
const worker = mount(createStore(storage), { authorize: () => ({ store: createStore(storage), scopeLabel: payload }) });
for (const path of ['', `/record?${new URLSearchParams({ id: payload })}`]) {
const response = await worker.fetch(request(path), {}); const html = await response.text();
assert.equal(response.status, 200); assert.doesNotMatch(html, /'); const third = await artifact('3', '', 'b');
for (const value of [first,second,third]) await recordLegalRelease(storage,value);
const worker = mount(createDocumentHistory(storage));
const diff = async (before, after) => worker.fetch(request(`/diff?${new URLSearchParams({ before: before.manifest.artifactId, after: after.manifest.artifactId, kind: 'privacy' })}`), {});
const changed = await diff(first,second); assert.equal(changed.status,200);
const changedText = await changed.text(); assert.match(changedText,/<script>unsafe/); assert.doesNotMatch(changedText,/';
const records = [{ id: payload, data: { kind: 'document-release', documents: { privacy: { version: payload } }, changeNote: payload } }, { id: 'other', data: { kind: 'document-release', documents: { privacy: { version: '1' } } } }];
const html = await (await mount(createStore(createSyntheticStorage(records))).fetch(request(), {})).text();
const before = html.match(/