add rate limiting and 2fa hardening

This commit is contained in:
2026-06-10 01:35:36 +02:00
parent ae41b96fa4
commit 58f098d4ca
11 changed files with 410 additions and 59 deletions

View File

@@ -31,7 +31,7 @@ Stores account credentials, roles, and 2FA state.
| `password` | `TEXT` | Not null | bcrypt password hash. |
| `role` | `TEXT` | Not null | User role, for example `user` or `admin`. |
| `two_factor_enabled` | `INTEGER` | Not null, default `0` | Boolean flag for TOTP 2FA state. |
| `two_factor_secret` | `TEXT` | Not null, default `''` | TOTP secret used to validate authenticator codes. Empty when 2FA is disabled. |
| `two_factor_secret` | `TEXT` | Not null, default `''` | TOTP secret used to validate authenticator codes. Empty when 2FA is disabled. During setup the secret is held in a short-lived signed setup token and is only stored after the first valid TOTP code. |
Migration note: existing databases are migrated with `ALTER TABLE` statements for `two_factor_enabled` and `two_factor_secret` if those columns do not exist yet.
@@ -166,11 +166,12 @@ When the password is updated:
When 2FA is enabled:
1. The TOTP secret must already exist from `/api/2fa/setup`.
2. The supplied TOTP code is validated.
1. The temporary setup token is validated.
2. The supplied TOTP code is validated against the setup secret.
3. Existing recovery codes are deleted.
4. New recovery-code hashes are inserted.
5. `users.two_factor_enabled` is set to `1`.
5. `users.two_factor_enabled` is set to `1` and `users.two_factor_secret` is set to the confirmed secret.
6. Existing refresh tokens are revoked and a new session is issued for the current browser.
### 2FA disable