feat: enterprise MFA with TOTP, email codes, backup codes, and trusted devices
Three verification methods (TOTP authenticator, email code, backup codes), trusted device management with 30-day expiry, role-based enforcement for super_admin and org_admin, admin reset capability, and full test coverage (46 tests). Modifies login flow to support MFA challenge/response with temporary session tokens stored in cache. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,41 @@ Auth: Bearer token (Sanctum) — token delivered via httpOnly cookie, never in t
|
||||
- `POST /auth/forgot-password` — request password reset (public, rate-limited). Body: `{ email, app: "app"|"portal"|"admin" }`. Always returns 200 (no email enumeration).
|
||||
- `POST /auth/reset-password` — reset password with token (public). Body: `{ token, email, password, password_confirmation }`.
|
||||
|
||||
## MFA (Multi-Factor Authentication)
|
||||
|
||||
### Login flow with MFA
|
||||
|
||||
When MFA is enabled for a user, login becomes a two-step process:
|
||||
1. `POST /auth/login` — if MFA is active, returns `{ mfa_required: true, mfa_session_token, methods, preferred_method, expires_in }` instead of the auth token
|
||||
2. `POST /auth/mfa/verify` — submit the MFA code with the session token to complete login
|
||||
|
||||
If the device is trusted (via `X-Device-Fingerprint` header), MFA is bypassed and login proceeds normally.
|
||||
|
||||
### MFA verification during login (public, rate-limited)
|
||||
|
||||
- `POST /auth/mfa/verify` — verify MFA code during login. Body: `{ mfa_session_token, code, method: "totp"|"email"|"backup_code", trust_device?: bool, device_fingerprint?: string, device_name?: string }`. Returns user data + auth cookie on success.
|
||||
- `POST /auth/mfa/email/send` — send/resend email verification code during login. Body: `{ mfa_session_token }`. Rate-limited: 1 code per 60 seconds.
|
||||
|
||||
### MFA setup and management (authenticated)
|
||||
|
||||
- `POST /auth/mfa/setup/totp` — start TOTP setup, returns `{ secret, qr_code_url, provisioning_uri }`
|
||||
- `POST /auth/mfa/setup/totp/confirm` — confirm TOTP with first code. Body: `{ code }`. Returns `{ mfa_enabled, method, backup_codes[] }`
|
||||
- `POST /auth/mfa/setup/email` — start email MFA setup (sends verification code)
|
||||
- `POST /auth/mfa/setup/email/confirm` — confirm email MFA. Body: `{ code }`. Returns `{ mfa_enabled, method, backup_codes[] }`
|
||||
- `POST /auth/mfa/disable` — disable MFA. Body: `{ code, method: "totp"|"backup_code" }`. Requires valid verification code.
|
||||
- `POST /auth/mfa/backup-codes` — regenerate backup codes. Body: `{ code }`. Requires valid TOTP code.
|
||||
- `GET /auth/mfa/status` — current MFA status: `{ mfa_enabled, method, confirmed_at, backup_codes_remaining, is_required }`
|
||||
|
||||
### Trusted devices (authenticated)
|
||||
|
||||
- `GET /auth/trusted-devices` — list active trusted devices
|
||||
- `DELETE /auth/trusted-devices/{id}` — revoke a specific device
|
||||
- `DELETE /auth/trusted-devices` — revoke all devices
|
||||
|
||||
### Admin MFA management (super_admin)
|
||||
|
||||
- `POST /admin/users/{user}/reset-mfa` — force-disable MFA for a user. Activity logged.
|
||||
|
||||
## Account Management (authenticated)
|
||||
|
||||
- `POST /me/change-password` — change own password. Body: `{ current_password, password, password_confirmation }`. Revokes other sessions.
|
||||
|
||||
Reference in New Issue
Block a user