Features
- Provider-agnostic OIDC login (#7, thanks @tilwegener). The frontend now delegates the whole OpenID Connect flow to
react-oidc-context/oidc-client-ts: endpoints come from discovery, PKCE (S256) and state/nonce validation are handled by the library, and there is no Keycloak-specific URL or hand-rolled token exchange left. This works with any standards-compliant provider (Keycloak, Pocket ID, …).- One shared
UserManagerserves both the UI and API calls. An expiring access token is renewed transparently (refresh token, single-flight), with no 401s and no new login. - Logout ends the session properly (RP-initiated logout with
id_token_hint, no Keycloak confirmation page). Previously the app could still look signed in after logging out. - Sessions are kept in
localStorage, so they're shared across tabs.
- One shared
Breaking / operational notes
- OIDC login requires a secure context: HTTPS or
http://localhost. Over plain HTTP on any other hostname the app shows "Login requires a secure context". Production deployments must be served over HTTPS. Running without OIDC is unaffected. - Users already signed in with the previous flow are asked to log in once more (the old token format is discarded).
- Other providers (e.g. Pocket ID): set
OIDC_ROLES_CLAIMto the claim that carries roles/groups. The default is Keycloak'srealm_access.roles.
Fixes
- The login redirect could fire twice under React StrictMode, which made the login form fail intermittently.
Development
- The dev stack runs on
http://localhostonly (52080UI,52081API,42997Keycloak);wsl.ymbihq.localis gone..env.examplefiles now match the dev ports. The dev realm requires PKCE S256.
No database migrations.