Built-in Users admin screen (todo §5); /admin/users list (filter/sort/paginate) + create/edit/deactivate/delete + trigger-recovery, writing only to Kratos via the admin client — gated admin-only (anon→/login, non-admin→403) and CSRF-guarded like logout. New kratosAdmin.createRecoveryCode; reserved the "admin" plugin id; views:[viewsDir] so subfolder views reuse partials/. Reviewer §5 opener: extracted shell-context.ts (buildShellContext/shellUser) shared by dashboard+admin, threading the real signed-in user (drops the hardcoded demo profile). 217→228 units + 8 visual E2E green; boot-verified full CRUD+recovery live on the Ory stack

This commit is contained in:
2026-06-18 12:26:19 +02:00
parent cb050bd4c1
commit 79cfa2ee7f
19 changed files with 837 additions and 20 deletions

View File

@@ -78,10 +78,11 @@ export function isValidPluginId(id: string): boolean {
}
// Ids the host reserves for its own first-party mount segments (the auth flows, /auth/complete,
// /logout, the dashboard's /public/ static). Plugin routes resolve before these, so a folder named
// one of them would silently shadow a built-in route — discovery refuses it, loud like any conflict.
// /logout, the /admin screens, the dashboard's /public/ static). Plugin routes resolve before
// these, so a folder named one of them would silently shadow a built-in route — discovery refuses
// it, loud like any conflict.
export const RESERVED_PLUGIN_IDS: ReadonlySet<string> = new Set([
"auth", "login", "logout", "public", "recovery", "registration", "settings", "verification",
"admin", "auth", "login", "logout", "public", "recovery", "registration", "settings", "verification",
]);
export interface Semver {