import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { ADMIN_MFA_PROOF_TTL_MS, issueAdminMfaProof, resolveAdminMfaStatus, verifyAdminMfaProof, } from "../src/lib/admin/auth-policy.ts"; const now = 1_786_000_000_000; const context = { userId: "11111111-1111-4111-8111-111111111111", sessionId: "22222222-2222-4222-8222-222222222222", origin: "https://admin.staging.jyotisha.chat", }; const sessionToken = "better-auth-session-token-held-server-side"; const proofSecret = "admin-proof-secret-held-only-by-the-server"; test("MFA proof is server-signed, short-lived, and bound to the current user, session, origin, and session token", () => { const proof = issueAdminMfaProof(context, proofSecret, sessionToken, now); assert.equal(verifyAdminMfaProof(proof, context, proofSecret, sessionToken, now + 1_000), true); assert.equal(verifyAdminMfaProof(proof, { ...context, userId: "other-user" }, proofSecret, sessionToken, now + 1_000), false); assert.equal(verifyAdminMfaProof(proof, { ...context, sessionId: "other-session" }, proofSecret, sessionToken, now + 1_000), false); assert.equal(verifyAdminMfaProof(proof, { ...context, origin: "https://evil.example" }, proofSecret, sessionToken, now + 1_000), false); assert.equal(verifyAdminMfaProof(proof, context, "wrong-server-secret-that-is-long-enough", sessionToken, now + 1_000), false); assert.equal(verifyAdminMfaProof(proof, context, proofSecret, "rotated-session-token", now + 1_000), false); assert.equal(verifyAdminMfaProof(proof, context, proofSecret, sessionToken, now + ADMIN_MFA_PROOF_TTL_MS), false); }); test("highRiskWritesEnabled means the current session has the MFA prerequisite, not email proof", () => { assert.deepEqual(resolveAdminMfaStatus(false, false, false), { required: false, enrolled: false, verified: false, highRiskWritesEnabled: true, }); assert.equal(resolveAdminMfaStatus(true, false, false).highRiskWritesEnabled, false); assert.equal(resolveAdminMfaStatus(true, true, false).highRiskWritesEnabled, false); assert.deepEqual(resolveAdminMfaStatus(true, true, true), { required: true, enrolled: true, verified: true, highRiskWritesEnabled: true, }); }); test("MFA API keeps native Better Auth enrollment, recovery, rotation, and proof boundaries", () => { const route = readFileSync(new URL("../src/app/api/admin/mfa/route.ts", import.meta.url), "utf8"); const authFactory = readFileSync(new URL("../src/modules/identity/auth-factory.ts", import.meta.url), "utf8"); const migration = readFileSync(new URL("../db/migrations/20260806070000_admin_mfa.sql", import.meta.url), "utf8"); assert.match(authFactory, /twoFactor\(/); assert.doesNotMatch(authFactory, /skipVerificationOnEnable\s*:\s*true/); assert.match(route, /enableTwoFactor/); assert.match(route, /verifyTOTP/); assert.match(route, /verifyBackupCode/); assert.match(route, /generateBackupCodes/); assert.match(route, /disableTwoFactor/); assert.match(route, /headersAfterNativeResponse/); assert.match(route, /copyNativeCookies\(nativeResponse, response\)/); assert.match(route, /requireVerifiedMfa\(request, session\)/); assert.match(route, /ADMIN_MFA_PROOF_COOKIE/); assert.match(route, /HIGH_RISK_ADMIN_PROOF_COOKIE/); assert.match(route, /adminProofSigningSecret\(\)/); assert.doesNotMatch(route, /console\.|logger|log.*(?:seed|secret|backup|totp)|(?:seed|secret|backup|totp).*log/i); assert.match(migration, /revoke all on table identity\.two_factors[\s\S]*admin_runtime/); assert.match(migration, /grant select, insert, update, delete on table identity\.two_factors[\s\S]*identity_runtime/); }); test("high-risk UI uses permission-scoped email OTP without requiring MFA", () => { const modal = readFileSync(new URL("../src/components/admin/reason-action-modal.tsx", import.meta.url), "utf8"); const reauth = readFileSync(new URL("../src/app/api/admin/reauth/route.ts", import.meta.url), "utf8"); const http = readFileSync(new URL("../src/lib/admin/http.ts", import.meta.url), "utf8"); assert.match(modal, /action: "request"/); assert.match(modal, /action: "verify"/); assert.match(modal, /邮箱验证码/); assert.doesNotMatch(modal, /\/api\/admin\/mfa|\/admin\/security|MfaStatus|mfaFactor|mfaReady/); assert.match(reauth, /requireAdminMutation\(request, parsed\.data\.permission\)[\s\S]*getIdentityEmailOtpApi/); assert.doesNotMatch(reauth, /requireAdminMfaIfRequired/); assert.match(http, /requireAdminMutation\(request, permission\)[\s\S]*verifyHighRiskAdminProof/); assert.doesNotMatch(http, /requireAdminMfaIfRequired/); });