Commit Graph
86 Commits
Author SHA1 Message Date
lobo 365b69feb4 feat(admin): let admins change user roles
V32 adds role_changed_at and the role_change log. Role changes lock
the admin rows, so there is always one admin left; the last admin
cannot delete their own account. Login and refresh read the role
under the user lock. Tokens issued before a role change are refused.
2026-10-04 20:09:22 +02:00
lobo 3410cbc598 feat(settings): store chart form choice per stat group
Build, Test & Push Auth Service / quality-check (push) Successful in 1m0s
Build, Test & Push Auth Service / docker (push) Successful in 1m24s
2026-10-04 10:43:02 +02:00
lobo 19463a1a4d feat(hint): target groups and automatic hints, V30
Build, Test & Push Auth Service / quality-check (push) Successful in 59s
Build, Test & Push Auth Service / docker (push) Successful in 1m34s
Hint targets combined with AND: without Steam, role and higher, new
users by registration_date, empty library flag. Four automatic hints
(NO_STEAM, EMPTY_LIBRARY, PILE_GREW, LINK_QUEUE), on by default; the
admin turns each on or off (audited). Users snooze one for 7 days (X)
or hide it for good (tick), stored on the server. Hint text may use
**bold** and [text](url).
2026-10-02 14:36:49 +02:00
lobo 5a2552ddf6 feat(password): add reset and change password flows
Build, Test & Push Auth Service / quality-check (push) Successful in 53s
Build, Test & Push Auth Service / docker (push) Successful in 1m30s
Forgot password with a single-use reset link (1 hour, ACTIVE users
only, same answer for every address), change password (current session
stays, others end), admin reset mail with audit row, 'password
changed' mail. Login and refresh wait for a running password change.
2026-10-02 10:35:08 +02:00
lobo 6e7fb1e066 feat(account): send display name in account state to Core
Build, Test & Push Auth Service / quality-check (push) Successful in 49s
Build, Test & Push Auth Service / docker (push) Successful in 1m31s
The account state push carries displayName. It is published when the
name changes. Contract test updated.
2026-10-02 09:10:56 +02:00
lobo 1b7bafd9f0 feat(mail): send broadcasts to every active user
Remove the platform_mails opt-out. Broadcasts go to all active users.
V28 drops the column; the PUT /api/users/settings/platform-mails
endpoint and the footer line about turning mails off are gone.
2026-10-02 07:53:35 +02:00
lobo 0af76da9c7 feat(registration): add email confirmation flow
Build, Test & Push Auth Service / quality-check (push) Successful in 58s
Build, Test & Push Auth Service / docker (push) Successful in 1m21s
Registrations become two-phase: first UNCONFIRMED with a 24-hour
single-use email link, then PENDING after confirmation and password
entry. Prevents registering with someone else's address. Admins see
unconfirmed requests and can delete them; they cannot accept them.
2026-10-01 16:20:51 +02:00
lobo 878ede914b feat(settings): reduce animations appearance flag
Build, Test & Push Auth Service / quality-check (push) Successful in 53s
Build, Test & Push Auth Service / docker (push) Successful in 1m31s
2026-10-01 15:09:25 +02:00
lobo a60011ce9f feat(mail): add broadcast mail for admins
Adds endpoints for PLATFORM_ADMIN to send mail to all active users or
picked ones. Broadcasts and account mails share the same outbox;
broadcasts take the rest of the daily limit after 10 mails are kept free
for account mail. Users can opt out via settings. History is kept in
mail_broadcast with recipient, sent and failed counts. The footer says
where to opt out.
2026-10-01 14:12:34 +02:00
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
lobo 89fdc7841b Merge pull request 'Changed from JWT token to public/privat key' (#2) from feat/jwt-eddsa into main
Reviewed-on: #2
2026-05-12 08:58:57 +02:00
lobo 2dc3cda51c Support now null as not initialized for SteamId 2026-04-19 14:59:27 +02:00
lobo 2d4fb5bef7 Support now null as not initialized for SteamId 2026-04-19 14:35:02 +02:00
lobo c7ec8c2f7c Added new db migration to set default SteamId to 2026-04-19 14:17:49 +02:00
lobo 2a5839b736 Refactor package structure: domain -> modules
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.
2026-04-19 12:50:01 +02:00
lobo 3fcba271a6 Merge pull request 'feature-cleanup' (#1) from feature-cleanup into main
Reviewed-on: #1
2026-04-18 11:52:46 +02:00
lobo 37b0fcdd21 Fixed tests 2026-04-18 11:49:09 +02:00
lobo f90b674ed2 Fixed tests 2026-04-18 11:47:58 +02:00
lobo 20402eb7c4 Added new tests fixed some problem 2026-04-18 11:28:06 +02:00
lobo 14a4ccfb87 Fixed tests 2026-04-11 12:32:32 +02:00
lobo 03d5a011ae Added lots of new stuff
- extended the jwt and put userid into it
- completed update settings
- added settings also in me call
2026-04-11 12:07:27 +02:00
lobo 6e194b9c9a Added transactional 2026-04-06 09:57:39 +02:00
lobo 954669d1a4 changed default profile to prod 2026-04-06 09:35:31 +02:00
lobo afbe950ba4 Finished registration Process and added tests 2026-04-06 09:12:45 +02:00
lobo 5dcdf7bd61 Started with:
- Registration logic for new players
- Extended User table with more information
2026-04-04 17:11:13 +02:00
lobo ad30de4190 Added tests for all services and controller 2026-04-04 16:01:05 +02:00
lobo c028e8d382 Added arch unit tests 2026-04-04 11:22:26 +02:00
lobo 7ba38fbbce Fixed problem with token response 2026-04-04 10:55:39 +02:00
lobo 5dc3632687 Cleaned a little bit up 2026-04-04 10:43:18 +02:00
lobo afd71b82be Implemented user service 2026-04-04 09:58:09 +02:00
lobo 3ee636253b Disabled test for now until db config is ready for testing 2026-04-03 12:32:40 +02:00
lobo a94b2bf9e7 Added jwt token validation and api endpoint versioning 2026-04-03 12:25:03 +02:00
lobo 161381ebe5 Cleaned up the architecture 2026-04-03 11:35:53 +02:00
lobo cc24c43ab8 Updated pipeline 2026-03-31 19:54:02 +02:00
lobo 1ce56590d1 Updated pipeline 2026-03-31 19:52:09 +02:00
lobo 132bb6bb64 Login should work now, tests are missing 2026-03-31 19:48:23 +02:00
lobo eecda99d22 Setup of springboot 2026-03-31 18:57:06 +02:00
lobo a7c9364c7a First commit 2026-03-31 18:20:40 +02:00