Auth: Add 2FA requirement to magic link login flow
Status Closed — not planned
Maintainer reply None cached
Activity 3 comments · opened Nov 26, 2025 · closed Jan 26, 2026
Summary
Add 2FA (TOTP) verification requirement to magic link login when users have mfaPreference.twoFA enabled, matching the security of password login.
Current Behavior
- Password login (
post-login-password.ts) checksmfaPreference.twoFAand requires TOTP before issuing JWT - Magic link login (
post-verify-login.ts,post-verify-login-worker.ts) skips 2FA entirely and issues JWT immediately
Proposed Implementation
Use the Intermediate Session Token (IST) pattern (industry standard used by Stytch, Auth0):
Flow
- User clicks magic link
POST /auth/v1/login/verify { magicToken }
- If 2FA enabled: returns
{ intermediateToken, state: ONE, mfaRequired: true } - If no 2FA: returns
{ accessToken, state: TWO }(current behavior)
POST /auth/v1/login/verify { intermediateToken, token: "123456" }
- Validates IST + TOTP → returns
{ accessToken, state: TWO }
Why IST Pattern
- Magic link stays one-time use (consumed immediately)
- IST is short-lived (10 minutes) reducing attack window
- Clean separation of authentication stages
- Industry standard approach
Files to Modify
services/auth/handlers/post-verify-login.ts- Add 2FA check for integratorsservices/auth/handlers/post-verify-login-worker.ts- Add 2FA check for workerslib/schemas/models/session.ts- Add IST creation/validation functionsservices/auth/schema/request/- Update request schemas to accept intermediateToken + token
Acceptance Criteria
- [ ] Magic link login requires 2FA when
mfaPreference.twoFAis enabled - [ ] Intermediate tokens expire after 10 minutes
- [ ] Intermediate tokens are one-time use
- [ ] Existing flow unchanged when 2FA not enabled
- [ ] Works for both integrators and workers/admins
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗