mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-26 11:49:16 +00:00
4722028904
* feat(mfa): auto-submit 6-digit TOTPs and normalize pasted backup codes Match the UX every major MFA prompt has (GitHub, GitLab, 1Password): the challenge screen and every code-entry dialog now submit automatically once the sixth TOTP digit lands, and the backup-code input accepts pastes with smart-dashes, trailing whitespace, or mixed case without silently truncating the value. Also caps the backup-code input at the correct 11 characters (10 plus a single separator) instead of 12. Shared normalization helpers live in frontend/src/lib/mfa.ts so the challenge and the three account-settings dialogs stay in lockstep. * feat(mfa): warn users when backup codes run low The Account & Security card silently showed a dim count of backup codes remaining, which meant users could drift toward zero without noticing until their phone was already lost. The card now surfaces a warning tone with an alert icon when 1 or 2 codes remain, and swaps to a dedicated destructive warning card with a "Regenerate now" action when the user has used every code. * feat(mfa): gate diagnostic logs behind developer mode Reuses the existing isDebugEnabled() gate so operators investigating a 2FA support ticket can flip Developer Mode on to get per-branch diagnostics (login path taken, replay check outcome, failure counter after a verify, replay-table purge counts), and flip it back off when they are done. Standard lifecycle logs stay on by default: enrolment completed, 2FA disabled, backup codes regenerated, admin reset, SSO bypass toggled, lockout engaged. Nothing that could reveal a TOTP code, base32 secret, backup-code cleartext, or partial-auth JWT is ever logged. * test(mfa): cover drift, invalid formats, lockout recovery, and paste normalization Backend: a TOTP generated for a window that has already slid out is rejected, malformed backup codes (too short, non-alphanumeric, 11-char alphanumeric that matches no hash) all increment failed_attempts, a successful verify clears a below-threshold failure streak, a successful verify after locked_until has passed clears the lockout, a second enroll/start overwrites the prior pending secret, and the backup-code normalizer treats en-dash/em-dash/figure-dash with stray whitespace the same as the canonical form. E2E: low-backup-codes warning renders in the warning tone and the exhausted-codes state flips to the dedicated warning card, a 6-digit TOTP auto-submits without a button click, and a backup code pasted without the separator still signs in. * docs(mfa): auto-submit, paste guidance, and expanded troubleshooting Document that the challenge screen submits automatically on the sixth digit, that backup codes accept the separator and any case, and that the Account & Security card nudges at low code counts. Expands the troubleshooting section with entries for lost or exhausted backup codes and adds a short note to the admin guide about surfacing auth diagnostics via Developer Mode.
63 lines
3.2 KiB
Plaintext
63 lines
3.2 KiB
Plaintext
---
|
|
title: Managing Two-Factor Authentication
|
|
description: Reset a user's 2FA, configure per-user SSO enforcement, and recover from lockouts.
|
|
---
|
|
|
|
This guide is for administrators. For general 2FA usage, see [Two-Factor Authentication](/features/two-factor-authentication).
|
|
|
|
## Reset a user's 2FA
|
|
|
|
A user who has lost their authenticator app and all backup codes cannot sign in on their own. Any administrator can reset the affected account from the Settings UI.
|
|
|
|
1. Open **Settings → Users**
|
|
2. Find the user in the list. Users with 2FA enabled show a shield icon in the action column
|
|
3. Click the shield icon and confirm the reset
|
|
|
|
<Frame>
|
|
<img src="/images/two-factor-auth/admin-reset.png" alt="Administrator resetting a user's 2FA from the Users settings" />
|
|
</Frame>
|
|
|
|
After the reset:
|
|
|
|
- The user can sign in with their password only, no second factor is required
|
|
- Their existing sessions are invalidated, so any stale browser tabs have to sign in again
|
|
- The action is recorded in the audit log with the administrator's username
|
|
|
|
Instruct the user to enrol again from **Settings → Account & Security** as soon as they are back in. The account is unprotected until they do.
|
|
|
|
## Emergency recovery from the command line
|
|
|
|
If every administrator has lost access to 2FA and no one can sign in through the UI, reset the admin account directly from the host running Sencho.
|
|
|
|
From a shell on that host:
|
|
|
|
```bash
|
|
docker compose exec sencho node dist/cli/resetMfa.js <username>
|
|
```
|
|
|
|
Replace `<username>` with the admin's account name. On success the command prints a confirmation line and exits 0. Sign in with the password, then re-enrol immediately.
|
|
|
|
The command respects the container's `DATA_DIR`, so it always acts on the same SQLite database the application uses. It writes an audit log entry attributed to `cli` so the action is auditable after the fact.
|
|
|
|
<Note>
|
|
Turning on **Developer Mode** in **Settings → Developer** surfaces additional authentication diagnostics in the backend logs. These are helpful when investigating a 2FA support ticket, and can be turned off again once the issue is resolved.
|
|
</Note>
|
|
|
|
## Per-user SSO enforcement
|
|
|
|
When SSO (LDAP or OIDC) is configured, users with 2FA enabled sign in through SSO without a second factor by default. SSO is already an authenticated flow, and requiring a TOTP on top is extra friction that most teams do not need.
|
|
|
|
Each user can opt into stricter behaviour by flipping **Require 2FA even when signing in via SSO** on their own Account & Security screen. There is no admin-wide override, every user decides for themselves.
|
|
|
|
If your organisation needs to force 2FA for every SSO sign-in for every user, raise this with the Sencho team, it is not exposed as a global policy today.
|
|
|
|
## What a reset changes in the database
|
|
|
|
For completeness, a reset does the following to the target user:
|
|
|
|
- Clears the stored TOTP secret and all remaining backup codes
|
|
- Rotates the user's session version, which invalidates any outstanding session cookies
|
|
- Leaves the account otherwise unchanged, the username, password hash, role, and audit history are preserved
|
|
|
|
Nothing about the user's SSO bindings changes. If the user was signing in with SSO plus 2FA, they simply resume SSO-only sign-in after the reset.
|