Skip to content

2026.5.1 — sign-in fix

Choose a tag to compare

@saschb2b saschb2b released this 02 Jun 19:17
· 51 commits to main since this release

A fix release for 2026.5.0. Headline: sign-in actually works now.

Two mismatches introduced by the Better Auth dependency bump broke OIDC sign-in on a fresh 2026.5.0 install — every attempt ended in a 500 or a Keycloak invalid_redirect_uri. If you're on 2026.5.0, upgrade.

⚠️ Upgrading from 2026.5.0

  1. Run migrations. New migration 0005 renames the Better Auth columns to camelCase. The Helm pre-upgrade Job / the compose migrate service / pnpm migrate apply it automatically; it preserves data, indexes, and foreign keys.
  2. Update your Keycloak (OIDC) client redirect URI to <BASE_URL>/api/auth/oauth2/callback/keycloak — note the new /oauth2/ segment. The old /api/auth/callback/keycloak no longer matches what StateBoard sends. (The bundled dev realm is already fixed; bring-your-own-IdP deployments must update this themselves.)

Fixed — sign-in (broken in 2026.5.0)

  • Better Auth columns match the library again. They were created snake_case while Better Auth queries camelCase (expiresAt, emailVerified, userId, …), so sign-in 500'd with column "expiresAt" of relation "verification" does not exist. Migration 0005 renames them.
  • OIDC callback path corrected to /api/auth/oauth2/callback/keycloak (Better Auth's genericOAuth path). The bundled realm and all setup docs had registered /api/auth/callback/keycloak, which Keycloak rejected.
  • pnpm migrate now loads .env, so cp .env.example .env && pnpm migrate creates the schema instead of failing with "DATABASE_URL required".

Fixed — deployment

  • Base64 DB passwords (e.g. from openssl rand -base64) no longer break DATABASE_URL parsing; the parse-error log masks the password.

Hardened

  • Free-text fields (name / description / label / notes) and JSON request bodies are length-capped on every write. The uploads route sends X-Content-Type-Options: nosniff and turns a truncated image into a clean 400 instead of a 500. The region box invariant (x+w, y+h ≤ 1) is enforced on PATCH as well as POST.

Editor & accessibility

  • Failed saves now surface an error instead of silently doing nothing.
  • The editor's "open share view" icon button has an accessible name.

Under the hood

  • A zero-dependency node:test suite now covers the coordinate/validation logic, the example board's invariants, the role-rank authorization check, and the DATABASE_URL redaction. CI runs on Node 26 to match the runtime image.

Container image

ghcr.io/saschb2b/stateboard:2026.5.1   # also :2026.5 and :latest

Full changelog: v2026.5.0...v2026.5.1