Repository navigation
feat(frontend): wire router meta.minRole into a real guard, ranked against the backend's role order (#16244) - #16489
Conversation
…ainst the backend's role order (#16244) types/router.d.ts declared meta.minRole but no route set it and no guard read it -- it looked like working access control but wasn't. The only real role gate was meta.admin + userStore.isAdmin. Adds ROLE_RANK + meetsMinRole to constants/roles.ts, mirroring autobot_shared/auth/permissions.py's _ROLE_META priority order exactly (superadmin 110, admin 100, operator 80, analyst 60, editor 55, user 50, readonly 10) rather than a second hand-written ordering. Wires a new resolveMinRoleRedirect() into router.ts's navigation guard, alongside the existing admin check -- same pattern (redirect to /home), same caveat: this is UI routing only, and the backend's own permission gates remain the actual authority. It changes no route today (nothing sets minRole yet); it establishes the enforcement mechanism so a route safely can. resolveMinRoleRedirect is a small pure function (to, userRole) -> redirect | null, kept separate from the inline guard callback specifically so it's unit-testable without mocking the whole router/user-store stack. Tests cover: below minRole redirects, at/above minRole is allowed, no minRole set allows any authenticated user, no role at all is redirected, and the strictest minRole among nested matched records wins. Closes #16244
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ SSOT Configuration Compliance: Passing🎉 No new hardcoded values of either class — Known backlog in |
|
Independent review: approved. |
Single-issue rationale: #16244 covers wiring the router's
meta.minRoleinto a real navigation guard, ranked by the backend's role order. No other open issue shares that scope. The nearest neighbour, #16243, is aboutusePermissions' permission-string vocabulary, which is a different file and a different mechanism.Thinking Path
types/router.d.tsdeclaredmeta.minRole("Minimum role required"), but nothing used it: no route set it, no guard read it. The only real role gate wasmeta.admin+userStore.isAdmin, sominRolelooked like working access control but wasn't (found while fixing #14937, which retyped this field to the canonicalRole).Wired it in rather than removing it, per the issue's own ask: a route guard comparing the user's role to
minRoleby rank, sourced from the backend's actual ranking (autobot_shared/auth/permissions.py::_ROLE_META) rather than a second hand-written order.This is UI routing only. Same as the existing
meta.admincheck it sits beside: it never grants access the backend refuses, and the backend's own permission gates remain the actual authority. It changes no route today — nothing setsminRoleyet — it just makes the mechanism real so a route safely can.What Changed
constants/roles.ts:ROLE_RANK(mirrors_ROLE_META's priority order exactly: superadmin 110, admin 100, operator 80, analyst 60, editor 55, user 50, readonly 10) andmeetsMinRole(role, minRole).router/index.ts: new exported pure functionresolveMinRoleRedirect(to, userRole)— the strictest (highest-ranked)minRoleamong a route's matched records, checked against the caller's role, returning a redirect ornull. Wired into the existing navigation guard right after the admin check, same style (redirect to/home, same debug-log pattern). Kept as a standalone function specifically so it's unit-testable without mocking the whole router/user-store stack (there was no existing router test file to extend).Verification
constants/__tests__/roles.test.ts(+6: rank ordering including the superadmin-above-admin case,meetsMinRoleabove/at/below the floor, fails safe on missing/unknown role) and a newrouter/__tests__/resolveMinRoleRedirect.test.ts(6 cases: below minRole redirects, at/above minRole allowed, no minRole set allows any authenticated user, no role at all redirects, strictest minRole among nested matched records wins).node_modules) — CI is authoritative for frontend type-checking and tests.Closes #16244
Model Used
Claude Sonnet 5