DELETE /api/users/me with the password sets users.deleted_at, ends all logins and frees the Steam ID. A nightly job removes users flagged 30 days ago, Core first, and prunes Core orphans. Dry run by default.
The Steam ID is no longer typed in at registration or in the settings.
A logged-in user links it through Steam OpenID 2.0: Auth checks the
answer with Steam (check_authentication) and stores the ID as verified
(V11 steam_id_verified). A one-time state plus a binding cookie tie the
callback to the browser that started the link, so a foreign Steam login
link cannot move someone's Steam ID into another account.
Typed-in IDs from before stay unverified; a verified link from another
account takes them away. DELETE /api/users/steam-link unlinks.
The login token moves out of localStorage into an HttpOnly cookie
(15 min), so a script on the page can no longer read it. A random
refresh token (30 days, sliding) renews it; only its SHA-256 is
stored. Each refresh replaces the token, and a replaced token that
comes back revokes every token of that login.
Unsafe requests need an X-TBP-Client or Authorization header, and
CORS allows only the exact frontend origin. A missing or expired
token now answers 401 instead of 403, so the frontend can refresh.
Auth serves its Ed25519 public key at GET /.well-known/jwks.json, so
Core can find the key by the token kid. Startup fails on a blank
JWT_KID, because compose turns an unset value into "" and Core finds
keys only by kid.
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.
user_settings.public_profile (off by default, needs a display name).
GET /api/public/profiles/{displayName} answers only for enabled users with a
public profile and returns a 10-minute EdDSA ticket for Core. A token with a
typ claim is no login, so the ticket cannot be used as one.
Captures the Auth slices of the cross-service product roadmap:
username + public-profile opt-in, friends graph, email/notification
preferences, invitation system enhancements, and GDPR delete/export.
Cross-links to the umbrella roadmap in ToBePlayed-Deployment.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move domain packages into a new modules.* hierarchy and rename controller packages to api.* across login, registration, and user modules. Update package declarations and imports (including shared.api DTOs and JwtService -> modules login TokenGenerator), adjust tests and persistence/mapper paths accordingly, and apply minor formatting fixes (missing EOF newlines). This reorganizes the project to better separate API surface and module boundaries.