Built-in Roles & permissions admin screen (todo §5); /admin/roles list (search/sort/paginate) + create/delete + assign-to-users/groups + "effective access" (Keto expand → transitive members), writing only to Keto — gated admin-only + CSRF-guarded like Users/Groups (Kratos read only to label members). A role = Keto subject set Role:<name>#members; reuses the Groups membership helpers (now-exported pagedTuples/memberCandidates/safeDecode); added a Roles nav entry (i-shield) + a .plain-list CSS rule. Stability-reviewer run as a local PR: APPROVE, no Critical/High; addressed its explicit-expand-depth nit. Live boot-verify caught a real bug the tests missed — Keto v26.2.0 nests the expand subject under tuple (not node top-level as the §4 ExpandTree type guessed), so expandToEffectiveUsers returned []; fixed type+walker+fixtures, re-verified a group-only member surfaces in effective access. 237→243 units + typecheck green; expand chain boot-verified live then torn down.
This commit is contained in:
@@ -9,8 +9,9 @@ import { composeNav, type NavNode } from "./nav.ts";
|
||||
export const ADMIN_PERMISSION = "admin"; // role token gating every admin screen
|
||||
export const ADMIN_USERS_BASE = "/admin/users";
|
||||
export const ADMIN_GROUPS_BASE = "/admin/groups";
|
||||
export const ADMIN_ROLES_BASE = "/admin/roles";
|
||||
|
||||
type AdminScreen = "dashboard" | "groups" | "users";
|
||||
type AdminScreen = "dashboard" | "groups" | "roles" | "users";
|
||||
|
||||
export function adminNav(roles: string[], menu: MenuConfig, current: AdminScreen): NavNode[] {
|
||||
const gated = (id: AdminScreen, href: string, icon: string, label: string): NavNode =>
|
||||
@@ -19,5 +20,6 @@ export function adminNav(roles: string[], menu: MenuConfig, current: AdminScreen
|
||||
{ href: "/", icon: "i-grid", id: "dashboard", label: "Dashboard" },
|
||||
gated("users", ADMIN_USERS_BASE, "i-users", "Users"),
|
||||
gated("groups", ADMIN_GROUPS_BASE, "i-layers", "Groups"),
|
||||
gated("roles", ADMIN_ROLES_BASE, "i-shield", "Roles"),
|
||||
]], menu.override, roles);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user