- postgres replaces keycloak-db and holds a keycloak and a mancala database,
each with its own user, created by apps/postgres/init
- valkey with an append-only file for live game state and caches
- backend gets DATABASE_URL and VALKEY_URL
- First visit logs in as a new guest through Keycloak without a form;
the session, including an offline refresh token, is kept in local storage
- Account menu on the home page: guests can log in or sign up, users can
log out (which starts a new guest session)
- The WebSocket client in core authenticates with the access token after
connecting, reports "connected" once the server accepts it, and re-sends
renewed tokens on the open connection
- Game page shows player names; guests appear as "Guest 4F2A"
- Auth channels, AuthUser and player names in UserConnectionInfo move to
core and the backend uses them from there
- Mobile keeps using userKey login for now
- Apps and @mancala/core depend on the packages in this repo through
link: dependencies instead of the npm releases, so changes no longer
need a publish
- Root package.json gets a build:packages script that installs and
builds both packages
- Backend and frontend Docker images are built from the repo root so
they can include the packages; compose builds them that way
- Metro watches the packages folder and resolves their imports from the
app's node_modules
- New auth module verifies Keycloak access tokens offline against the
realm's signing keys (issuer, RS256, typ=Bearer, allowed azp); guests
are recognised by the guest realm role
- Clients send an auth message after connecting and get on_auth or
on_auth_error; unauthenticated sockets are closed after 5 seconds and
their messages ignored; a socket can refresh its token but not switch user
- A user can be connected from several sockets; a late close of an old
socket no longer drops the new one
- Malformed messages are ignored instead of throwing
- Games store player names and guest flags and send them with the
connection info
- Legacy ?userKey= clients and /register stay available behind
LEGACY_USERKEY_AUTH; legacy keys must be UUIDs so they cannot take a
Keycloak user's kc: id
- TypeScript target raised to es2020 for async/await
- Custom authenticator creates and logs in a guest user when the
authorization request has guest=true; other requests get the login form
- Scheduled task removes guests with no remaining sessions
- Realm export with mancala-web PKCE client, guest role and guest-aware
browser flow (verify profile disabled so guests are not asked for details)
- Dockerfile building the extension into a Keycloak 26.7.5 image
- Keycloak and Postgres in compose; nginx proxies auth.playmancala.app
and rate limits the auth endpoint
- Integration tests run the extension and realm in a Keycloak container