mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-27 12:18:59 +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.
149 lines
7.9 KiB
Plaintext
149 lines
7.9 KiB
Plaintext
---
|
||
title: Two-Factor Authentication
|
||
description: Protect your Sencho account with a time-based one-time password (TOTP) and single-use backup codes.
|
||
---
|
||
|
||
Two-factor authentication (2FA) adds a second step to sign-in. After your password is accepted, Sencho asks for a six-digit code from your authenticator app. Someone who steals your password still cannot sign in without that code.
|
||
|
||
2FA is available on all Sencho tiers, including Community.
|
||
|
||
## How it works
|
||
|
||
1. You enrol once by scanning a QR code with an authenticator app (or typing a secret by hand)
|
||
2. The app generates a fresh six-digit code every 30 seconds
|
||
3. On every sign-in, Sencho asks for the current code after your password passes
|
||
4. You also save ten single-use backup codes for the days when your phone is not available
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/challenge.png" alt="Sign-in challenge screen asking for the six-digit code" />
|
||
</Frame>
|
||
|
||
## Enrol
|
||
|
||
Open **Settings → Account & Security** and click **Set up 2FA**. Sencho walks you through three steps.
|
||
|
||
### Step 1 – Scan the QR code
|
||
|
||
Scan the QR code with an authenticator app such as **1Password**, **Bitwarden**, **Google Authenticator**, **Authy**, or **Microsoft Authenticator**.
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/enroll-qr.png" alt="Enrolment dialog showing the QR code" />
|
||
</Frame>
|
||
|
||
If your app cannot scan or you would rather type the secret into a password manager, click **Can't scan? Show secret key** and copy the base32 string. Paste it into the app's manual-entry field.
|
||
|
||
### Step 2 – Confirm
|
||
|
||
Enter the six-digit code your app is currently showing. This proves the app is paired correctly before Sencho turns 2FA on.
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/enroll-confirm.png" alt="Enrolment confirmation step asking for the six-digit code" />
|
||
</Frame>
|
||
|
||
### Step 3 – Save your backup codes
|
||
|
||
Sencho shows ten single-use backup codes. Each code can sign you in once without the authenticator app. **Save them somewhere safe before closing this dialog**, they are not shown again.
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/enroll-backup-codes.png" alt="Ten backup codes shown after enrolment" />
|
||
</Frame>
|
||
|
||
Copy them to a password manager or download them as a text file. Common places users store them:
|
||
|
||
- Their primary password manager as a secure note on the Sencho entry
|
||
- An encrypted document on a separate device
|
||
- Printed and stored with other emergency recovery material
|
||
|
||
## Sign in with 2FA
|
||
|
||
After entering your password, Sencho shows the 2FA challenge screen.
|
||
|
||
1. Open your authenticator app, find the Sencho entry, read the six-digit code
|
||
2. Type it into the **Verification code** field
|
||
3. Sencho submits automatically once you enter the sixth digit. No click required.
|
||
|
||
<Note>
|
||
If you prefer the explicit route, the **Verify and sign in** button still works. The auto-submit only applies to the six-digit TOTP field; backup codes always require a click to confirm.
|
||
</Note>
|
||
|
||
If your phone is unavailable, click **Use a backup code instead**, enter one of the codes you saved during enrolment, and click **Verify and sign in**. That code is now used up.
|
||
|
||
### Backup code entry tips
|
||
|
||
Backup codes are shown grouped as `ABCDE-FGHIJ` to make them easier to read. When signing in, you can enter them any of these ways:
|
||
|
||
- Paste the code exactly as shown: `ABCDE-FGHIJ`
|
||
- Paste without the dash: `ABCDEFGHIJ`
|
||
- Paste with extra whitespace or lowercase letters; Sencho normalises the input before sending it to the server
|
||
|
||
Only letters and digits are significant; dashes, spaces, and case are ignored.
|
||
|
||
## Regenerate backup codes
|
||
|
||
If you think your backup codes have been exposed, or you have used most of them, regenerate them from **Settings → Account & Security → Regenerate backup codes**. Sencho asks for a current code, then issues a fresh set of ten and invalidates the old set immediately.
|
||
|
||
The Account & Security card nudges you about low code counts so you notice before you are locked out:
|
||
|
||
- **3 or more codes remaining:** a muted count under the status message.
|
||
- **1 or 2 codes remaining:** the count turns warning-coloured with an alert icon, inviting you to regenerate a fresh set.
|
||
- **0 codes remaining:** a dedicated warning card appears with a **Regenerate now** button. At this point, losing your authenticator app means recovery needs an administrator, so regenerate before that happens.
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/account-card-enabled.png" alt="Account card showing 2FA enabled with regenerate and disable actions" />
|
||
</Frame>
|
||
|
||
## Disable 2FA
|
||
|
||
From the same Account & Security section, click **Disable 2FA**. Sencho asks you to confirm with a current authenticator code (or a backup code) so that no one else can disable protection without your phone. Once disabled, only your password protects the account.
|
||
|
||
## Signing in with SSO
|
||
|
||
If Sencho is configured with LDAP or an OIDC provider (Google, GitHub, Okta), the SSO flow signs you in without the second factor by default. Your identity provider has already authenticated you.
|
||
|
||
If you want Sencho to ask for a TOTP code even after a successful SSO sign-in, flip the **Require 2FA even when signing in via SSO** switch on the Account & Security card. The switch only appears when at least one SSO provider is enabled.
|
||
|
||
<Frame>
|
||
<img src="/images/two-factor-auth/sso-enforce.png" alt="Toggle that requires 2FA even when signing in via SSO" />
|
||
</Frame>
|
||
|
||
## Troubleshooting
|
||
|
||
### "Code invalid" even though the code is current
|
||
|
||
The most common cause is clock drift between your phone and the Sencho server. Authenticator apps compute codes from the current Unix time, and even a 30 second skew breaks verification.
|
||
|
||
- On iOS, open **Settings → General → Date & Time** and enable **Set Automatically**
|
||
- On Android, open **Settings → System → Date & time** and enable **Automatic date & time**
|
||
- In Google Authenticator, open the menu → **Settings → Time correction for codes → Sync now**
|
||
- In Authy, open **Settings → My account → Sync device time**
|
||
|
||
If your server runs in a container, make sure its host clock is synced with NTP.
|
||
|
||
### Wrong account selected in the authenticator
|
||
|
||
Authenticator apps let you store many accounts. If you have more than one Sencho instance, or a Sencho entry and a different service that looks similar, pick the correct one. The issuer label Sencho uses is simply `Sencho`.
|
||
|
||
### The QR code will not scan
|
||
|
||
Click **Can't scan? Show secret key** during enrolment, copy the base32 string, and paste it into the authenticator app's manual-entry screen. The secret is identical, the QR code is just a convenience.
|
||
|
||
### Lost phone and no backup codes left
|
||
|
||
Contact an administrator. An admin can reset your 2FA from the Users section in **Settings → Users**. See the [admin guide](/operations/two-factor-admin) for the steps. If you are the only admin and have lost access, the administrator can also reset 2FA from the command line on the host running Sencho.
|
||
|
||
### Lost your backup codes
|
||
|
||
If you still have your authenticator app, sign in as normal and regenerate the codes from **Settings → Account & Security → Regenerate backup codes**. The previous set stops working immediately. If you no longer have the authenticator app either, follow the "Lost phone and no backup codes left" entry above and ask an administrator to reset 2FA.
|
||
|
||
### Ran out of backup codes
|
||
|
||
Each backup code can be used once. As soon as you sign back in with an authenticator code, regenerate a new set from **Settings → Account & Security**. Without codes, losing your phone means recovery requires an administrator.
|
||
|
||
### SSO sign-in is unexpectedly asking for a code
|
||
|
||
The **Require 2FA even when signing in via SSO** toggle is on for your account. Open **Settings → Account & Security** and flip it off if SSO alone is enough for your threat model.
|
||
|
||
### Enrolment did not activate after confirmation
|
||
|
||
The browser may have dropped the JSON response. Retry the confirmation step and watch for an error toast. If confirmation continues to fail, cancel the dialog, ensure your clock is synced, and start enrolment again.
|