Crash recovery for nuzlocke-tracker-f2hs: MFA feature was already implemented and merged via PR #76. Verified code, tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
66 lines
2.8 KiB
Markdown
66 lines
2.8 KiB
Markdown
---
|
|
# nuzlocke-tracker-f2hs
|
|
title: Optional TOTP MFA for email/password accounts
|
|
status: completed
|
|
type: feature
|
|
priority: normal
|
|
created_at: 2026-03-21T12:19:18Z
|
|
updated_at: 2026-03-22T09:06:25Z
|
|
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
|
|
- [x] 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)
|
|
|
|
## Summary of Changes
|
|
|
|
Implementation completed and merged to develop via PR #76:
|
|
- Settings page with MFA enrollment UI (QR code + backup secret display)
|
|
- Login flow with TOTP challenge step for enrolled users
|
|
- AAL level checking after login to require TOTP when needed
|
|
- Disable MFA option with TOTP re-verification
|
|
- OAuth user detection to hide MFA options (Google/Discord users use their provider's MFA)
|