import assert from 'node:assert/strict'; import test from 'node:test'; import { buildApp } from '../../src/app/build-app.js'; const userId = '464e9b49-8617-4d00-af3c-78b3294e1d70'; const methodId = '6833868a-2a1b-4d33-90d1-fc9f2b7be869'; const headers = { cookie: 'pokemon_inventory_session=session-token', 'x-csrf-token': 'csrf-token', }; function createTestApp(mfaService) { return buildApp({ authenticationService: { async authorizeUnsafeRequest(sessionToken, csrfToken) { assert.equal(sessionToken, 'session-token'); assert.equal(csrfToken, 'csrf-token'); return { userId }; }, }, loginRateLimiter: { async consume() { return { allowed: true }; } }, mfaService, }); } test('enrolls MFA only for the authenticated user and returns its provisioning URI', async (testContext) => { const app = createTestApp({ async enroll(input) { assert.deepEqual(input, { userId, name: 'Authenticator' }); return { id: methodId, provisioningUri: 'otpauth://totp/example' }; }, }); testContext.after(() => app.close()); const response = await app.inject({ method: 'POST', url: '/api/v1/auth/mfa/enroll', headers, payload: { name: 'Authenticator' }, }); assert.equal(response.statusCode, 201); assert.equal(response.json().data.provisioningUri, 'otpauth://totp/example'); }); test('verifies MFA with CSRF protection and does not expose secret material', async (testContext) => { const app = createTestApp({ async verifyEnrollment(input) { assert.deepEqual(input, { userId, methodId, code: '123456' }); return { id: methodId, name: 'Authenticator', type: 'TOTP', secretCiphertext: 'hidden' }; }, }); testContext.after(() => app.close()); const response = await app.inject({ method: 'POST', url: '/api/v1/auth/mfa/verify', headers, payload: { methodId, code: '123456' }, }); assert.equal(response.statusCode, 200); assert.equal(response.json().data.secretCiphertext, undefined); assert.equal(response.json().data.type, 'TOTP'); }); test('rejects MFA enrollment without CSRF validation', async (testContext) => { const app = buildApp({ authenticationService: { async authorizeUnsafeRequest() { const error = new Error('CSRF validation failed.'); error.code = 'FORBIDDEN'; error.statusCode = 403; throw error; }, }, loginRateLimiter: { async consume() { return { allowed: true }; } }, mfaService: { async enroll() {} }, }); testContext.after(() => app.close()); const response = await app.inject({ method: 'POST', url: '/api/v1/auth/mfa/enroll', payload: { name: 'Authenticator' }, }); assert.equal(response.statusCode, 403); assert.equal(response.json().error.code, 'FORBIDDEN'); });