import { createHmac, randomUUID } from "node:crypto"; import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { RegistrationError, RegistrationService } from "../../apps/api/src/registration.js"; import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js"; const roots: string[] = []; const services: RegistrationService[] = []; const now = Date.parse("2026-07-28T10:00:00.000Z"); const adminPepper = Buffer.alloc(32, 0x91); function allowlistHash(email: string) { return createHmac("sha256", adminPepper).update(email.trim().toLowerCase(), "utf8").digest("hex").toUpperCase(); } function createHarness() { const root = mkdtempSync(join(tmpdir(), "dada-wp1-04-admin-")); roots.push(root); const resend = new MockResendAdapter(); const service = new RegistrationService({ adminAllowlistPepper: adminPepper, challengePepper: Buffer.alloc(32, 0x92), clock: () => now, codeGenerator: () => "418205", currentPrivacyNoticeVersion: "p0a-registration-notice-v1", databasePath: join(root, "dada.sqlite3"), invitePepper: Buffer.alloc(32, 0x93), resend, sessionPepper: Buffer.alloc(32, 0x94), }); services.push(service); return { resend, service }; } function writeEvidence(file: string, value: unknown) { const directory = process.env.DADA_EVIDENCE_DIR_ADMIN; if (!directory) return; mkdirSync(directory, { recursive: true }); writeFileSync(resolve(directory, file), `${JSON.stringify(value, null, 2)}\n`); } afterEach(() => { for (const service of services.splice(0)) service.close(); for (const root of roots.splice(0)) rmSync(root, { force: true, recursive: true }); }); describe("TDD-WP1-ADM-001-admin-auth-boundary", () => { it("keeps admin authentication allowlisted, multi-admin, isolated, and recoverable only by secure config", async () => { const { resend, service } = createHarness(); const adminEmails = ["admin-one@example.invalid", "admin-two@example.invalid"]; const hashes = adminEmails.map(allowlistHash); service.applySecureConfig({ adminAllowlistHashes: hashes, adminRecoveryHashes: [], secureConfigRevision: 1, }); await expect(service.sendAdminLoginCode({ clientKey: "blocked-client", email: "blocked@example.invalid" })) .rejects.toMatchObject({ reason: "admin_not_allowed" }); expect(resend.calls).toHaveLength(0); const admins = []; for (const [index, email] of adminEmails.entries()) { const sent = await service.sendAdminLoginCode({ clientKey: `admin-client-${index}`, email }); const completed = service.completeAdminLogin({ clientKey: `admin-client-${index}`, code: resend.readLatestCode(email), idempotencyKey: `wp1-04-admin-login-${index}`.padEnd(40, "0"), registrationId: sent.registrationId, }); expect(completed).toMatchObject({ audience: "admin", status: "authenticated", admin: { role: "super_admin" } }); admins.push(completed); } const ordinaryUserId = randomUUID(); service.database.prepare(` INSERT INTO users ( user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at ) VALUES (?, 'ordinary@example.invalid', 'user', 'active', 1, ?, ?) `).run(ordinaryUserId, randomUUID(), now); const ordinarySession = service.issueAuthenticatedSession(ordinaryUserId, "user"); expect(service.readAdminSession(ordinarySession.sessionToken)).toBeUndefined(); expect(service.readUserSession(admins[0].sessionToken)).toBeUndefined(); for (const admin of admins) service.revokeAdminSessions(admin.admin.userId, "disabled"); await expect(service.sendAdminLoginCode({ clientKey: "disabled-client", email: adminEmails[0] })) .rejects.toMatchObject({ reason: "account_suspended" }); service.applySecureConfig({ adminAllowlistHashes: hashes, adminRecoveryHashes: hashes, secureConfigRevision: 2, }); await expect(service.sendAdminLoginCode({ clientKey: "recovered-client", email: adminEmails[0] })) .resolves.toMatchObject({ status: "verification_sent" }); const counts = { adminAccess: service.database.prepare("SELECT COUNT(*) AS count FROM admin_access WHERE allowed = 1").get().count, adminCredits: service.database.prepare(` SELECT COUNT(*) AS count FROM credit_accounts c JOIN users u ON u.user_id = c.user_id WHERE u.role = 'super_admin' `).get().count, admins: service.database.prepare("SELECT COUNT(*) AS count FROM users WHERE role = 'super_admin'").get().count, ordinaryUsers: service.database.prepare("SELECT COUNT(*) AS count FROM users WHERE role = 'user'").get().count, }; expect(counts).toEqual({ adminAccess: 2, adminCredits: 0, admins: 2, ordinaryUsers: 1 }); const audits = service.database.prepare("SELECT actor_type, actor_ref, result FROM admin_operation_logs ORDER BY occurred_at").all(); expect(audits.length).toBeGreaterThanOrEqual(4); expect(audits.every((entry: any) => ["system", "super_admin"].includes(entry.actor_type))).toBe(true); expect(JSON.stringify(audits)).not.toContain("@example.invalid"); writeEvidence("response.json", { admin_count: counts.admins, audiences_isolated: true, non_allowlisted_status: "rejected_before_send", recovery_source: "secure_config_revision_2", status: "passed", }); writeEvidence("db-diff.json", { after: counts, admin_sessions_revoked_before_recovery: true, status: "passed" }); writeEvidence("external-calls.json", { calls: resend.calls.map((call) => ({ purpose: call.purpose, recipient_kind: "synthetic_admin" })), non_allowlisted_calls: 0, status: "passed", }); }); });