fdi-guard.test.ts92 lines · main
1import { describe, expect, test } from 'bun:test';
2
3import { isHostedPlatformOrigin, methodFlagDenied } from './fdi-guard.js';
4
5/**
6 * FDI lock unit tests — SuperTokens-style: app proves itself with project + pk.
7 * Full requireFdiProjectKey needs HTTP Context mock; we cover pure helpers +
8 * document the live-proved codes here for CI stability.
9 */
10
11const allOn = {
12 emailPassword: true,
13 passwordlessEmail: true,
14 magicLink: true,
15 passwordlessSms: true,
16 passkeys: true,
17 mfa: true,
18 social: true,
19};
20
21describe('fdi-guard methodFlagDenied', () => {
22 test('blocks email password when disabled', () => {
23 expect(
24 methodFlagDenied({ ...allOn, emailPassword: false }, 'emailPassword'),
25 ).toMatch(/disabled/i);
26 });
27
28 test('allows email password when enabled', () => {
29 expect(methodFlagDenied(allOn, 'emailPassword')).toBeNull();
30 });
31
32 test('blocks passwordless email / magic link / sms / passkeys', () => {
33 expect(
34 methodFlagDenied({ ...allOn, passwordlessEmail: false }, 'passwordlessEmail'),
35 ).toBeTruthy();
36 expect(methodFlagDenied({ ...allOn, magicLink: false }, 'magicLink')).toBeTruthy();
37 expect(
38 methodFlagDenied({ ...allOn, passwordlessSms: false }, 'passwordlessSms'),
39 ).toBeTruthy();
40 expect(methodFlagDenied({ ...allOn, passkeys: false }, 'passkeys')).toBeTruthy();
41 });
42
43 test('mfa flag false does not block second factor (security enroll path)', () => {
44 // Product: enrolled TOTP still verifiable even if "mfa" product toggle is off.
45 expect(methodFlagDenied({ ...allOn, mfa: false }, 'mfa')).toBeNull();
46 });
47});
48
49/** Document live FDI lock response codes (AUTH-HARDEN-90 / Batch A). */
50describe('fdi lock response codes (contract)', () => {
51 test('known codes for app integration', () => {
52 const codes = [
53 'project_required',
54 'auth_key_required',
55 'invalid_auth_key',
56 'project_key_mismatch',
57 'key_scope_readonly',
58 'auth_disabled',
59 ];
60 expect(codes).toContain('project_required');
61 expect(codes).toContain('auth_key_required');
62 expect(codes.length).toBe(6);
63 });
64});
65
66describe('isHostedPlatformOrigin (IdP hosted UI)', () => {
67 test('matches Origin to web origin', () => {
68 expect(
69 isHostedPlatformOrigin('https://briven.tech', null, 'https://briven.tech'),
70 ).toBe(true);
71 });
72
73 test('matches Referer origin when Origin empty', () => {
74 expect(
75 isHostedPlatformOrigin(
76 null,
77 'https://briven.tech/auth/p_x/otp?callbackURL=%2F',
78 'https://briven.tech',
79 ),
80 ).toBe(true);
81 });
82
83 test('rejects foreign app origins (still need pk)', () => {
84 expect(
85 isHostedPlatformOrigin(
86 'https://mavi.example',
87 null,
88 'https://briven.tech',
89 ),
90 ).toBe(false);
91 });
92});