- Updated all package.json name fields and dependency references - Updated all TypeScript/JavaScript imports - Updated .woodpecker/publish.yml filters and registry paths - Updated tools/install.sh scope default - Updated .npmrc registry paths (worktree + host) - Enhanced update-checker.ts with checkForAllUpdates() multi-package support - Updated CLI update command to show table of all packages - Added KNOWN_PACKAGES, formatAllPackagesTable, getInstallAllCommand - Marked checkForUpdate() with @deprecated JSDoc Closes #391
66 lines
3.4 KiB
Markdown
66 lines
3.4 KiB
Markdown
# P8-001 — WorkOS + Keycloak SSO Providers
|
|
|
|
**Branch:** feat/p8-001-sso-providers
|
|
**Started:** 2026-03-18
|
|
**Mode:** Delivery
|
|
|
|
## Objective
|
|
|
|
Add WorkOS and Keycloak as optional SSO providers to the BetterAuth configuration, following the existing Authentik pattern.
|
|
|
|
## Scope
|
|
|
|
| Surface | Change |
|
|
| ---------------------------------------- | ----------------------------------------------------------------------- |
|
|
| `packages/auth/src/auth.ts` | Refactor provider array, add WorkOS + Keycloak conditional registration |
|
|
| `apps/web/src/lib/auth-client.ts` | Add `genericOAuthClient()` plugin |
|
|
| `apps/web/src/app/(auth)/login/page.tsx` | WorkOS + Keycloak SSO buttons gated by `NEXT_PUBLIC_*` env vars |
|
|
| `.env.example` | Document WorkOS + Keycloak env vars |
|
|
| `packages/auth/src/auth.test.ts` | Unit tests verifying env-var gating |
|
|
|
|
## Plan
|
|
|
|
1. ✅ Refactor `createAuth` to build `oauthProviders[]` conditionally
|
|
2. ✅ Add WorkOS provider (explicit URLs, no discovery)
|
|
3. ✅ Add Keycloak provider (discoveryUrl pattern)
|
|
4. ✅ Add `genericOAuthClient()` to auth-client.ts
|
|
5. ✅ Add SSO buttons to login page gated by `NEXT_PUBLIC_WORKOS_ENABLED` / `NEXT_PUBLIC_KEYCLOAK_ENABLED`
|
|
6. ✅ Update `.env.example`
|
|
7. ⏳ Write `auth.test.ts` with env-var gating tests
|
|
8. ⏳ Quality gates: typecheck + lint + format:check + test
|
|
9. ⏳ Commit + push + PR
|
|
|
|
## Decisions
|
|
|
|
- **WorkOS**: Uses explicit `authorizationUrl`, `tokenUrl`, `userInfoUrl` (no discovery endpoint available)
|
|
- **Keycloak**: Uses `discoveryUrl` pattern (`{URL}/realms/{REALM}/.well-known/openid-configuration`)
|
|
- **UI gating**: Login page uses `NEXT_PUBLIC_WORKOS_ENABLED` / `NEXT_PUBLIC_KEYCLOAK_ENABLED` feature flags (safer than exposing secret env var names client-side)
|
|
- **Refactor**: Authentik moved into same `oauthProviders[]` array pattern — cleaner, more extensible
|
|
- **Feature flag design**: `NEXT_PUBLIC_*` flags are opt-in alongside credentials (prevents accidental button render when creds not set)
|
|
|
|
## Assumptions
|
|
|
|
- `ASSUMPTION:` WorkOS OIDC discovery URL is not publicly documented; using direct URL pattern from WorkOS SSO docs.
|
|
- `ASSUMPTION:` `NEXT_PUBLIC_WORKOS_ENABLED=true` must be explicitly set — this is intentional (credential presence alone doesn't enable the button since NEXT_PUBLIC vars are baked at build time).
|
|
|
|
## Tests
|
|
|
|
- `auth.test.ts`: Mocks betterAuth stack, verifies WorkOS included/excluded based on env var
|
|
- `auth.test.ts`: Verifies Keycloak discoveryUrl constructed correctly
|
|
|
|
## Quality Gate Results
|
|
|
|
| Gate | Status |
|
|
| ------------------------ | -------------------------------------------- |
|
|
| typecheck | ✅ 32/32 cached green |
|
|
| lint | ✅ 18/18 cached green |
|
|
| format:check | ✅ All matched files use Prettier code style |
|
|
| test (@mosaicstack/auth) | ✅ 8/8 tests passed |
|
|
|
|
## Verification Evidence
|
|
|
|
- `pnpm typecheck` — FULL TURBO, 32 tasks successful
|
|
- `pnpm lint` — FULL TURBO, 18 tasks successful
|
|
- `pnpm format:check` — All matched files use Prettier code style!
|
|
- `pnpm --filter=@mosaicstack/auth test` — 8 tests passed, 0 failed
|