Files
chimera-Public/test/server/command-registry.test.js

49 lines
4.0 KiB
JavaScript

'use strict';
const test = require('node:test');
const assert = require('node:assert/strict');
const { CommandRegistry, DEFAULT_BODY_LIMIT, EXPERT_MODE_CONFIRMATION, EXPERT_MODE_DURATION_MS, setSessionExpertMode } = require('../../src/core/command-registry');
test('command registry enforces authentication, validation and destructive confirmation', async () => {
const audited = [];
const registry = new CommandRegistry({ platform: 'server', audit: event => audited.push(event) });
registry.register({ name: 'item:read', classification: 'read-only', validate: value => Number(value), handler: value => value + 1 });
registry.register({ name: 'item:upload', classification: 'mutating', maxBodyBytes: 2 * 1024 * 1024, handler: value => value });
registry.register({ name: 'item:delete', classification: 'destructive', confirmation: 'VERWIJDER', validate: value => value, handler: () => true });
await assert.rejects(() => registry.invoke('item:read', 1), /Authenticatie/);
assert.equal(await registry.invoke('item:read', '2', { session: { id: 's1' } }), 3);
await assert.rejects(() => registry.invoke('item:delete', {}, { session: { id: 's1' } }), /VERWIJDER/);
assert.equal(await registry.invoke('item:delete', { confirmation: 'VERWIJDER' }, { session: { id: 's1' }, requestIp: '192.0.2.10' }), true);
assert.equal(audited.length, 1);
assert.equal(audited[0].classification, 'destructive');
assert.equal(audited[0].requestIp, '192.0.2.10');
assert.equal(audited[0].ok, true);
assert.equal(registry.requestBodyLimit('item:read'), DEFAULT_BODY_LIMIT);
assert.equal(registry.requestBodyLimit('item:upload'), 2 * 1024 * 1024);
assert.equal(registry.metrics().invocations, 2);
assert.equal(registry.metrics().failures, 0);
assert.ok(registry.metrics().sampleSize <= 256);
assert.throws(() => registry.register({ name: 'item:unsafe-limit', classification: 'mutating', maxBodyBytes: 100 * 1024 * 1024, handler() {} }), /requestlimiet/);
assert.throws(
() => registry.register({ name: 'unsafe:delete', classification: 'destructive', handler: () => true }),
/mist een exacte bevestiging/
);
});
test('expert mode requires recent admin authentication, explicit confirmation and expires', async () => {
const now = 1_800_000_000_000;
const registry = new CommandRegistry({ platform: 'server' });
registry.register({ name: 'session:expert-mode', classification: 'sensitive', permission: 'authenticated', handler: (input, context) => setSessionExpertMode(input, context, now) });
registry.register({ name: 'database:expert-action', classification: 'sensitive', permission: 'expert', handler: () => true });
const ordinary = { id: 'ordinary', role: 'user', authenticatedAt: now };
await assert.rejects(() => registry.invoke('session:expert-mode', { enabled: true, confirmation: EXPERT_MODE_CONFIRMATION }, { session: ordinary }), error => error.code === 'EXPERT_ADMIN_REQUIRED');
const stale = { id: 'stale', role: 'admin', authenticatedAt: now - (11 * 60 * 1000) };
await assert.rejects(() => registry.invoke('session:expert-mode', { enabled: true, confirmation: EXPERT_MODE_CONFIRMATION }, { session: stale }), error => error.code === 'EXPERT_REAUTH_REQUIRED');
const admin = { id: 'admin', role: 'admin', authenticatedAt: now };
await assert.rejects(() => registry.invoke('session:expert-mode', { enabled: true }, { session: admin }), error => error.code === 'EXPERT_CONFIRMATION_REQUIRED');
const enabled = await registry.invoke('session:expert-mode', { enabled: true, confirmation: EXPERT_MODE_CONFIRMATION }, { session: admin });
assert.deepEqual(enabled, { enabled: true, expiresAt: now + EXPERT_MODE_DURATION_MS, sessionId: 'admin' });
assert.equal(await registry.invoke('database:expert-action', {}, { session: admin }), true);
assert.equal((await registry.invoke('session:expert-mode', { enabled: false }, { session: admin })).enabled, false);
await assert.rejects(() => registry.invoke('database:expert-action', {}, { session: admin }), error => error.code === 'EXPERT_MODE_REQUIRED');
});