import { describe, it, expect } from 'vitest' import { AuthenticatedPrincipalSchema, StepUpPolicySchema, type AuthenticatedPrincipal, type StepUpPolicy, } from '../src/types.js' const basePrincipal = { kind: 'human' as const, accountId: 'acct-A', principalId: 'cred-1', amr: ['passkey' as const], authAt: 1_700_000_000, stepUpAt: null, } describe('StepUpPolicy.required (host-driven, fail-closed)', () => { it('parses a policy with required=true', () => { const policy: StepUpPolicy = { required: true, maxAgeSeconds: 300, requiredMethod: 'passkey' } expect(StepUpPolicySchema.parse(policy)).toEqual(policy) }) it('parses a policy with required=false', () => { const policy: StepUpPolicy = { required: false, maxAgeSeconds: 300, requiredMethod: 'passkey' } expect(StepUpPolicySchema.parse(policy)).toEqual(policy) }) it('rejects a policy missing required', () => { const bad = { maxAgeSeconds: 300, requiredMethod: 'passkey' } expect(StepUpPolicySchema.safeParse(bad).success).toBe(false) }) it('rejects a non-boolean required', () => { const bad = { required: 'yes', maxAgeSeconds: 300, requiredMethod: 'passkey' } expect(StepUpPolicySchema.safeParse(bad).success).toBe(false) }) }) describe('AuthenticatedPrincipal.stepUpMethod (F1 method-binding, optional)', () => { it('parses a principal that omits stepUpMethod (backward compatible)', () => { const parsed = AuthenticatedPrincipalSchema.parse(basePrincipal) expect(parsed.stepUpMethod).toBeUndefined() }) it('parses a principal with an explicit stepUpMethod', () => { const p: AuthenticatedPrincipal = { ...basePrincipal, stepUpAt: 1_700_000_100, stepUpMethod: 'passkey' } expect(AuthenticatedPrincipalSchema.parse(p).stepUpMethod).toBe('passkey') }) it('parses a principal with stepUpMethod=null (no step-up)', () => { const parsed = AuthenticatedPrincipalSchema.parse({ ...basePrincipal, stepUpMethod: null }) expect(parsed.stepUpMethod).toBeNull() }) it('rejects an invalid stepUpMethod value', () => { const bad = { ...basePrincipal, stepUpMethod: 'sms' } expect(AuthenticatedPrincipalSchema.safeParse(bad).success).toBe(false) }) })