feat: add optional TOTP MFA for email/password accounts
- Add MFA enrollment UI in new Settings page with QR code and backup secret - Add TOTP challenge step to login flow for enrolled users - Check AAL after login and show TOTP input when aal2 required - Add disable MFA option with TOTP re-verification - Only show MFA options for email/password users (not OAuth) - Add Settings link to user dropdown menu Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
---
|
||||
# nuzlocke-tracker-f2hs
|
||||
title: Optional TOTP MFA for email/password accounts
|
||||
status: in-progress
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-03-21T12:19:18Z
|
||||
updated_at: 2026-03-21T12:56:34Z
|
||||
parent: nuzlocke-tracker-wwnu
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Users who sign up with email/password have no MFA option. Google/Discord OAuth users get their provider's MFA, but email-only users have a weaker security posture.
|
||||
|
||||
## Approach
|
||||
|
||||
Supabase has built-in TOTP MFA support via the `supabase.auth.mfa` API. This should be optional — users can enable it from their profile/settings page.
|
||||
|
||||
### Backend
|
||||
- No backend changes needed — Supabase handles MFA enrollment and verification at the auth layer
|
||||
- JWT tokens from MFA-enrolled users include an `aal` (authenticator assurance level) claim; optionally validate `aal2` for sensitive operations in the future
|
||||
|
||||
### Frontend
|
||||
1. Add MFA setup flow to user profile/settings page:
|
||||
- "Enable MFA" button → calls `supabase.auth.mfa.enroll({ factorType: 'totp' })`
|
||||
- Show QR code from enrollment response
|
||||
- Verify with TOTP code → `supabase.auth.mfa.challengeAndVerify()`
|
||||
2. Add MFA challenge during login:
|
||||
- After email/password sign-in, check `supabase.auth.mfa.getAuthenticatorAssuranceLevel()`
|
||||
- If `currentLevel === 'aal1'` and `nextLevel === 'aal2'`, show TOTP input
|
||||
- Verify → `supabase.auth.mfa.challengeAndVerify()`
|
||||
3. Add "Disable MFA" option with re-verification
|
||||
4. Only show MFA options for email/password users (not OAuth)
|
||||
|
||||
### UX
|
||||
- Settings page: toggle to enable/disable MFA
|
||||
- Login flow: TOTP input step after password for enrolled users
|
||||
- Recovery: Supabase provides recovery codes during enrollment — display them
|
||||
|
||||
## Files to modify
|
||||
|
||||
- `frontend/src/pages/` — new MFA settings component or add to existing profile page
|
||||
- `frontend/src/pages/Login.tsx` — add MFA challenge step
|
||||
- `frontend/src/contexts/AuthContext.tsx` — handle AAL levels
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Add MFA enrollment UI (QR code, verification) to profile/settings
|
||||
- [x] Display backup secret code after enrollment (Supabase TOTP doesn't provide recovery codes)
|
||||
- [x] Add TOTP challenge step to login flow
|
||||
- [x] Check AAL after login and redirect to TOTP if needed
|
||||
- [x] Add "Disable MFA" with re-verification
|
||||
- [x] Only show MFA options for email/password users
|
||||
- [ ] Test: full enrollment → login → TOTP flow
|
||||
- [N/A] Test: recovery code works when TOTP unavailable (Supabase doesn't provide recovery codes; users save their secret key instead)
|
||||
Reference in New Issue
Block a user