feat(auth): rate limit registration, atomic login limit

10 failed registrations per IP block it for 15 minutes (429 TOO_MANY_ATTEMPTS with Retry-After). Login and registration now take an attempt before the check, so a burst of parallel requests cannot pass the limit.
This commit is contained in:
lobo committed 2026-09-25 09:06:30 +02:00
1 parent c63b7e6aaa
commit 3a48ce0ff1
17 files changed
+445 -83

No files matched your search

+3 -1
View File
@@ -14,6 +14,9 @@ To Be Played is split into three repositories:
## Features
- Registration with an invitation code, login with email and password (BCrypt).
- Brute-force protection in memory: 5 failed logins per email or 20 per IP, and 10 failed registrations per IP,
block for 15 minutes with `429 TOO_MANY_ATTEMPTS` and `Retry-After`. Unknown emails cost the same BCrypt time as a
wrong password, and every failed login gets the same error.
- JWT signed with **EdDSA (Ed25519)**. Auth holds the private key, Core only the public key, so Core can verify
tokens but never create them. Tokens carry a `kid` header for key rotation.
- User settings: display name (unique, case-insensitive), Steam ID, language, dark mode.
@@ -99,7 +102,6 @@ Runs unit, WebMvc, persistence and integration tests plus the ArchUnit rules. Ne
## Roadmap
- Rate limit `/api/auth/login` and `/api/registration/**`.
- JWKS endpoint (`/.well-known/jwks.json`), so Core fetches the public key and keys rotate without a redeploy.
- Short-lived access token plus rotating refresh token in an httpOnly cookie, with CSRF protection. Today the token
lives 24 h in `localStorage` and cannot be revoked.