AUTH4D-21 project onboarding and application configuration screens
Console screens in apps/console/src/features/projects/ let developers create projects, register
applications and copy integration settings. They add no API routes: every call goes through the
console BFF to the AUTH4D-18 management routes, and the API remains the authority for validation
and roles. The fixed AUTH4D-20 route table mounts them through the placeholders in
features/{project-create,applications,sign-in-methods,project-settings}.
| Console route | Management calls (via /api/management/…) |
|---|---|
/projects/new |
POST /tenants (displayName, idempotencyKey) |
/projects/{id}/applications |
GET /tenants/{id}, GET /tenants/{id}/clients |
/projects/{id}/applications?new=1 |
POST /tenants/{id}/clients (with idempotencyKey) |
/projects/{id}/applications?app={clientId} |
GET, PATCH, DELETE /tenants/{id}/clients/{cid} |
/projects/{id}/sign-in-methods |
GET, PATCH /tenants/{id} (signup, guest, email, Discord) |
/projects/{id}/settings |
GET, PATCH /tenants/{id} (name, scope ceiling) |
Behavior
- Onboarding. A developer with no projects sees a short getting-started outline. After creation the console reloads the project list and opens the applications screen. Create requests carry a random idempotency key that is reused while the submitted values are unchanged, so a retried request cannot create a duplicate.
- Applications. Only
browserandnative(game, device authorization) types are offered. Browser forms edit redirect URIs and allowed origins (one per line); native forms send neither. Scopes are chosen from the project’sallowedScopes. Disabling usesDELETEwith{}after a confirmation dialog; enabling usesPATCH {"enabled":true}. Forms never send client secrets, grant types, audiences or authentication methods. - Field errors. The shared API client keeps only the error code, so writes use a per-call client
that also reads
error.messageanderror.details[].field. Errors are shown beside the matching input (redirectUris,allowedOrigins,allowedScopes,displayName,providers.discord.clientId,providers.discord.clientSecret), and any others in the form summary. A 401 is passed to the shared client, which marks the console session as expired. - Discord credentials. The client secret is a write-only password input. It starts empty, is
sent only when the developer types a value, and is cleared after a save. The screen only shows
clientSecretConfiguredandclientSecretUpdatedAt. - Roles. The role comes from
GET /tenants/{id}(owner,admin,viewer; anything else is treated asviewer). Owners edit everything. Admins edit applications. Viewers see disabled controls, no save, create or disable actions, and no secret input. The API still enforces every write, and its403 insufficient_roleis shown if a role changes while a page is open. - Integration values. Each application shows copyable issuer (
{AUTH_ORIGIN}/t/{tenantId}), client ID, audience (the client ID, which is theaudof its tokens), and either the callback URL (browser) or the device authorization endpoint (native), plus framework-neutral snippets: OIDC settings and@auth4/sdk-browserfor browser apps, device authorization and token polling requests for games, and@auth4/sdk-serververification. No client secret is shown or invented. The console derivesAUTH_ORIGINfrom its own host (app.{domain}→auth.{domain}, loopback → port 8787), or from the build-time variableVITE_AUTH4_AUTH_ORIGIN. - Nothing is written to browser storage. Copy uses the Clipboard API and falls back to selecting the text.
Tests
tests/e2e/auth4d-21.projects.spec.ts has 10 Playwright tests that run against a stateful mock of
the BFF that matches the AUTH4D-18 error format. They cover onboarding, browser and native
registration, backend redirect, origin and scope errors, editing and disabling an application,
sign-in method changes, write-only Discord credential replacement, settings that persist after
reload, copyable values, viewer and admin controls, and a role change while a page is open. They
use their own port (5186) and output directories:
pnpm exec playwright test -c tests/e2e/auth4d-21.playwright.config.ts
Source: docs/api-spec/auth4d-21.md