Commit Graph
85 Commits
Author SHA1 Message Date
lobo e72222a37f feat(profile): role claim in the profile ticket
Build, Test & Push Auth Service / quality-check (push) Successful in 54s
Build, Test & Push Auth Service / docker (push) Successful in 1m29s
The public profile ticket now carries the user's role so Core can check
ownership of shop items. PLATFORM_ADMIN gets every catalog item for free.
The role comes from the users table; a ticket without the claim means USER.
2026-10-01 13:14:27 +02:00
lobo 6b6ac44551 feat(user): add welcome-seen-at timestamp for welcome page tracking
Null means the welcome page was not seen yet. Existing users are backfilled
at migration time so only newly registered users see the page.
2026-10-01 10:44:22 +02:00
lobo 2b2f45b9af feat(news): add news endpoints and admin CRUD
Build, Test & Push Auth Service / quality-check (push) Successful in 51s
Build, Test & Push Auth Service / docker (push) Successful in 1m26s
Users see new entries once in a dialog after publication.
Admins manage entries via /api/admin/news with full audit trail.
2026-10-01 10:03:07 +02:00
lobo 39a4d5ae49 feat(registration): registration waits for the admin, no invite code
Build, Test & Push Auth Service / quality-check (push) Successful in 50s
Build, Test & Push Auth Service / docker (push) Successful in 1m20s
2026-10-01 09:18:12 +02:00
lobo 1008034e82 feat(admin): accept or deny registrations 2026-10-01 09:18:12 +02:00
lobo 1cac0c6b81 feat(mail): mails at registration, block and delete
Build, Test & Push Auth Service / quality-check (push) Successful in 1m12s
Build, Test & Push Auth Service / docker (push) Successful in 1m22s
2026-10-01 08:30:24 +02:00
lobo 47a03d2e6a feat(mail): outbox, SMTP sender and config 2026-10-01 08:30:24 +02:00
lobo fd79c63441 chore(security)!: drop the userId and typ claims and tokens without aud
Build, Test & Push Auth Service / quality-check (push) Successful in 46s
Build, Test & Push Auth Service / docker (push) Successful in 1m27s
2026-09-30 15:00:47 +02:00
lobo 9f56742ff6 refactor: item 29 cleanup
A10 A11 A12 A13 A14 A15 X10 X11 X12: role check denies outside a request, no API versioning, open-in-view off, no passwords in toString, X-Forwarded-For only from private peers, CORS from APP_FRONTEND_URL, non-root image.
2026-09-30 15:00:47 +02:00
lobo 89e2fa3df2 refactor(user): check only the shape of a tile id
Core and the Frontend skip ids they do not know; Core never shares the overview or the activity.
2026-09-30 15:00:47 +02:00
lobo 06f8089f5a feat(account): tell Core about Steam ID and block changes
Sent on the task executor after the commit, and every user again in the nightly cleanup. A failed call only warns.
2026-09-30 15:00:47 +02:00
lobo 3336181cdb test: one test container and one context per test kind
Build, Test & Push Auth Service / quality-check (push) Successful in 43s
Build, Test & Push Auth Service / docker (push) Successful in 1m29s
2026-09-30 13:41:57 +02:00
lobo 1f94c87a20 fix(security): refuse the access token of a blocked or deleted user
activeUsers cache, 30 s. Core still accepts the token until it expires; X4 (batch 4) tells Core.
2026-09-30 13:41:57 +02:00
lobo 509280da14 fix(cache): one cache config that expires after the write
publicStats is evicted on registration and Steam link/unlink. The cached user no longer holds the password hash. Tests no longer run with a 1 s TTL.
2026-09-30 13:41:56 +02:00
lobo cf21f4a654 refactor(settings): one load-change-save update for all settings 2026-09-30 13:41:56 +02:00
lobo fb51f836a8 fix(settings): give every user a settings row
V20 adds the row for old users, registration inserts one. The mapper fallback (en, system) disagreed with the column defaults.
2026-09-30 13:41:56 +02:00
lobo d082f3befd refactor(users): login and registration use JdbcTemplate for users 2026-09-30 13:41:56 +02:00
lobo b6be1879f0 test(architecture): apply the layer rules to repo packages 2026-09-30 13:41:56 +02:00
lobo afcfacb68b refactor(api): one error body, token audiences, user lookup by id
Build, Test & Push Auth Service / quality-check (push) Successful in 54s
Build, Test & Push Auth Service / docker (push) Successful in 1m21s
2026-09-29 14:48:28 +02:00
lobo 68919eaab4 fix(registration): check input and store emails in lower case 2026-09-29 13:27:31 +02:00
lobo ea4ae089ff feat(settings): store a favorite platform 2026-09-29 10:20:54 +02:00
lobo 315e22c220 feat(tiles): store dashboard and profile tile layouts
Build, Test & Push Auth Service / quality-check (push) Successful in 48s
Build, Test & Push Auth Service / docker (push) Successful in 1m26s
2026-09-28 15:03:16 +02:00
lobo dd4fcd1546 feat(profile): store the public profile look 2026-09-28 14:20:14 +02:00
lobo f86f3c2e63 feat(dev): add the local profile with generated keys and a dev user
Profile "local" starts without keys: LocalKeysEnvironmentPostProcessor
makes a new signing key per start and refuses to run next to prod. A
Flyway callback in db/local adds dev@localhost as PLATFORM_ADMIN with a
linked Steam ID.
2026-09-28 13:07:40 +02:00
lobo 32d4f40eec feat(hint): add admin hints for the dashboard
Build, Test & Push Auth Service / quality-check (push) Successful in 42s
Build, Test & Push Auth Service / docker (push) Successful in 1m21s
2026-09-28 10:07:49 +02:00
lobo 5341e0b870 feat(security): check role markers on services
Build, Test & Push Auth Service / quality-check (push) Successful in 41s
Build, Test & Push Auth Service / docker (push) Successful in 1m20s
Every service method a controller calls carries @RequiresRole or @Public, checked by a method interceptor and by ArchUnit. deleteByAdmin needs PLATFORM_ADMIN; the Steam callback's linkVerifiedSteamId stays unmarked.
2026-09-28 08:50:10 +02:00
lobo ff26760d40 fix(account): require the Core internal URL
Build, Test & Push Auth Service / quality-check (push) Successful in 40s
Build, Test & Push Auth Service / docker (push) Successful in 1m20s
The localhost default pointed Auth at itself in Docker, so the nightly cleanup failed silently at 04:15. Without a default a missing APP_CORE_INTERNAL_URL stops the start.
2026-09-28 07:46:21 +02:00
lobo 2ba0d99148 feat(admin): add roles, view as and the admin users API
Build, Test & Push Auth Service / quality-check (push) Successful in 39s
Build, Test & Push Auth Service / docker (push) Successful in 1m20s
users.role (USER < AUDITOR < PLATFORM_ADMIN) goes into the access token as the active role. POST /api/auth/view-as lowers the own login and is kept per refresh token, never above the stored role. /api/admin/users lists, blocks and deletes users; every action is written to admin_audit. A blocked login answers 403 ACCOUNT_BLOCKED, only after the right password.
2026-09-27 12:18:10 +02:00
lobo 7dc2fb613e feat(account): let users delete their account
Build, Test & Push Auth Service / quality-check (push) Successful in 32s
Build, Test & Push Auth Service / docker (push) Successful in 1m23s
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.
2026-09-27 11:46:22 +02:00
lobo a1763addce feat(version): answer the build commit and time
Build, Test & Push Auth Service / quality-check (push) Successful in 31s
Build, Test & Push Auth Service / docker (push) Successful in 1m21s
GET /api/version is public. CI passes GIT_SHA and BUILD_TIME as Docker build args; a local build answers dev.
2026-09-27 10:27:01 +02:00
lobo 4ec47f1b2c feat(profile): let users share stat groups
Build, Test & Push Auth Service / quality-check (push) Successful in 30s
Build, Test & Push Auth Service / docker (push) Successful in 1m24s
Store the groups in user_settings.profile_stats and send them in the
profile ticket, so Core shows only these on the public profile.
2026-09-27 07:16:10 +02:00
lobo 4b2acef381 feat(steam): verify the Steam ID with Sign in through Steam
Build, Test & Push Auth Service / quality-check (push) Successful in 34s
Build, Test & Push Auth Service / docker (push) Successful in 1m31s
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.
2026-09-26 11:20:04 +02:00
lobo e3433799f1 docs(readme): add the architecture overview 2026-09-26 07:37:44 +02:00
lobo 930e08e6dd feat(login): cookie session with rotating refresh token
Build, Test & Push Auth Service / quality-check (push) Successful in 30s
Build, Test & Push Auth Service / docker (push) Successful in 1m23s
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.
2026-09-25 13:45:04 +02:00
lobo 600b0b143f feat(login): publish verify key as JWKS
Build, Test & Push Auth Service / quality-check (push) Successful in 26s
Build, Test & Push Auth Service / docker (push) Successful in 1m21s
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.
2026-09-25 11:01:28 +02:00
lobo 3a48ce0ff1 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.
2026-09-25 09:06:30 +02:00
lobo c63b7e6aaa test: generate the JWT test keys, drop application-dev.yml
Build, Test & Push Auth Service / quality-check (push) Successful in 28s
Build, Test & Push Auth Service / docker (push) Successful in 1m20s
The dev config held real keys. Local dev config now lives outside the repo; integration tests create a fresh Ed25519 keypair per run.
2026-09-25 08:37:55 +02:00
lobo 9df7389fab docs: rewrite the readme for the public showcase
Also ignore local secrets and stop tracking the generated effective-pom.
2026-09-25 08:22:56 +02:00
lobo 508e628d86 feat(user): pick or turn off the dashboard banner 2026-09-24 15:35:48 +02:00
lobo 1d88c30d48 feat(user): synced appearance settings 2026-09-24 15:06:16 +02:00
lobo 973b980e05 feat(profile): opt-in public profile with a ticket for Core
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.
2026-09-24 14:18:32 +02:00
lobo 07ccb489ec test: share one Postgres container across test classes
The per-class container was stopped under the Spring context that the next
integration test class reused, so health answered 503 there.
2026-09-24 14:18:32 +02:00
lobo 05e87b4396 feat(user): optional display name (player tag)
users.display_name (V6), 3-24 letters, digits, space, _ . -, unique ignoring case. Set in settings (409 DISPLAY_NAME_ALREADY_IN_USE, also for the DB constraint race) and optionally at registration. Returned by /api/users/me.
2026-09-24 10:39:04 +02:00
lobo 4ebca75be4 fix(cors): expose Retry-After so the login page can show the block time 2026-09-24 10:29:57 +02:00
lobo f3b6d67b5b fix(security): hide health details and close Prometheus to the public
/actuator/health showed database and disk details to anyone, and /actuator/prometheus was open. Only health stays public, as plain UP/DOWN for the Docker health check.
2026-09-24 10:26:53 +02:00
lobo da7c3ed069 fix(login): same error for every failed login, block disabled users, rate limit
Unknown email, wrong password and disabled account now all return 401 INVALID_CREDENTIALS; unknown emails still run bcrypt against a dummy hash so timing does not leak them. After 5 failures per email or 20 per client IP, login returns 429 with Retry-After for 15 minutes. LoginRequest is now validated.
2026-09-24 10:22:30 +02:00
lobo 3b6acb2b34 fix(db): remove the seeded test user from all environments
V1 inserted test@example.com / password123 everywhere, including prod. V5 deletes that row only when email and seed hash both match.
2026-09-24 10:14:58 +02:00
lobo 0f8c724556 chore(deps): update Spring Boot to 4.1.1 and ArchUnit to 1.5.0 2026-09-24 08:56:45 +02:00
lobo 0e830aca72 fix(user): send Steam ID as string and refresh token on settings save
JavaScript rounds 17-digit Steam IDs, so 76561198000000001 was stored as
76561198005679790. Steam IDs are now JSON strings (17 digits, numbers
rejected), and null means "no Steam ID" instead of 0 (V4 migrates old rows).

PUT /api/users/settings returns a new token, because Core reads the Steam ID
from the token. A Steam ID owned by another user returns 409.
2026-09-24 08:51:01 +02:00
Andreas Dahm faed2d3411 fix(user): null-safe steamId comparison in updateSettings 2026-05-12 10:09:33 +02:00