103 lines
4.0 KiB
Markdown
103 lines
4.0 KiB
Markdown
# Console Security Settings Page Specification
|
|
|
|
## Purpose
|
|
|
|
A dedicated settings page at `/app/platform/security` for managing 2FA enrollment, disabling, and recovery code regeneration for platform console users.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Security Settings Route
|
|
|
|
The application MUST register the route `/app/platform/security` accessible to authenticated users with a `platform_*` role. The route MUST be reachable from the sidebar navigation or the user menu.
|
|
|
|
The page MUST display the user's current 2FA state: enabled or disabled.
|
|
|
|
#### Scenario: Authenticated platform user visits security page
|
|
|
|
- GIVEN an authenticated user with a `platform_*` role
|
|
- WHEN they navigate to `/app/platform/security`
|
|
- THEN the page renders without error
|
|
- AND the current 2FA state (enabled/disabled) is displayed
|
|
|
|
#### Scenario: Unauthenticated user redirected
|
|
|
|
- GIVEN no active session
|
|
- WHEN `/app/platform/security` is accessed directly
|
|
- THEN the user is redirected to `/login`
|
|
|
|
---
|
|
|
|
### Requirement: TOTP Enable Flow (Enrollment UI)
|
|
|
|
When 2FA is disabled, the page MUST offer an "Enable 2FA" action that initiates the enrollment flow:
|
|
|
|
1. Call `setup-start` → display QR code image (PNG rendered from `qr_code_png_base64`) AND the `secret_base32` in a copyable text field.
|
|
2. Present a 6-digit input for the first confirmation code.
|
|
3. On submit, call `setup-verify`. On success, display the 8 recovery codes.
|
|
4. The recovery codes screen MUST require an explicit "I have saved my recovery codes" confirmation before the user can dismiss it.
|
|
5. After confirmation, return to the security settings page (2FA now shown as enabled).
|
|
|
|
#### Scenario: QR and manual secret displayed after setup-start
|
|
|
|
- GIVEN the user clicks "Enable 2FA"
|
|
- WHEN `setup-start` responds with `{ secret_base32, qr_code_png_base64, otpauth_uri }`
|
|
- THEN an `<img>` rendered from the base64 PNG is shown
|
|
- AND the `secret_base32` is shown in a copyable field
|
|
|
|
#### Scenario: Valid 6-digit code confirms enrollment
|
|
|
|
- GIVEN the QR step is displayed and the user enters the correct code
|
|
- WHEN the code is submitted
|
|
- THEN `setup-verify` is called
|
|
- AND on success the recovery codes screen is shown with 8 codes
|
|
|
|
#### Scenario: Recovery codes require save confirmation
|
|
|
|
- GIVEN the recovery codes screen is displayed
|
|
- WHEN the user has NOT checked the confirmation checkbox
|
|
- THEN the dismiss/continue button is disabled
|
|
|
|
#### Scenario: After confirmation, page shows 2FA enabled
|
|
|
|
- GIVEN the user confirmed they saved the recovery codes
|
|
- WHEN they dismiss the screen
|
|
- THEN the security page shows 2FA state as "enabled"
|
|
|
|
---
|
|
|
|
### Requirement: TOTP Disable Flow
|
|
|
|
When 2FA is enabled, the page MUST offer a "Disable 2FA" action that renders a form requiring both the current password and a current valid TOTP code. On successful submission, the page returns to the security settings view with 2FA shown as disabled.
|
|
|
|
#### Scenario: Correct password + TOTP disables 2FA
|
|
|
|
- GIVEN the user enters their correct password and a valid TOTP code
|
|
- WHEN the disable form is submitted
|
|
- THEN `POST /api/auth/2fa/disable` is called
|
|
- AND on HTTP 200 the page shows 2FA state as "disabled"
|
|
|
|
#### Scenario: Incorrect inputs show error
|
|
|
|
- GIVEN the user submits wrong credentials on the disable form
|
|
- WHEN the server returns HTTP 401
|
|
- THEN an inline error is shown
|
|
- AND 2FA state remains "enabled"
|
|
|
|
---
|
|
|
|
### Requirement: Recovery Code Regeneration Flow
|
|
|
|
When 2FA is enabled, the page MUST offer a "Regenerate recovery codes" action. The action renders a form requiring a current valid TOTP code. On success, the new 8 codes are displayed once with the same save-confirmation gate as during enrollment.
|
|
|
|
#### Scenario: Valid TOTP → new codes displayed once
|
|
|
|
- GIVEN the user enters a valid TOTP code in the regenerate form
|
|
- WHEN `POST /api/auth/2fa/regenerate-recovery-codes` returns 200
|
|
- THEN the page displays the 8 new recovery codes with save-confirmation gate
|
|
|
|
#### Scenario: Invalid TOTP → error shown, codes unchanged
|
|
|
|
- GIVEN the user enters an invalid TOTP code
|
|
- WHEN the server returns HTTP 401
|
|
- THEN an inline error is shown and no new codes are displayed
|