Admin users and RBAC
Who can use the admin, and what each role may do. The admins module owns admin users, roles and menus; the admin frontend mirrors the rules client-side.
How this page was verified
Read on 2026-09-15 from the backend admins module and guards, and the admin frontend useAccess hook and /admin/roles area.
The model
Tables: admins, roles, menus, roles_menus, departments, settings. A role links to menus through roles_menus; each link carries five abilities: view, add, update, delete, export.
Admin auth
auth resolver: login, loginWithGoogle, refreshToken, logout, requestResetPassword, verifyResetPasswordToken, resetPassword. This is the admin JWT realm (jwt / jwt-refresh strategies), separate from members. Admin login supports Google OAuth as well as email/password. See API and auth.
How rights are enforced
- Backend —
@RoleCheck({ slug, action })+RoleAbilityGuard(src/admins/guards/role-check.guard.ts) check the admin'srole.menusfor a menuslugand ability. The typical admin resolver stacks@UseGuards(JwtAuthGuard, LastActivityGuard, RoleAbilityGuard)— used across ~59 resolvers.@Public()bypasses the guards.LastActivityGuardenforces idle auto-logout afterCMS_AUTO_LOGOUT_MAX_INACTIVE_SECONDS(default 1800s). - Admin frontend —
useAccess(slug, action)(src/hooks/useAccess.tsx) readssession.user.me.role.menus[]and drives both the sidebar (src/components/Sidebar/sidebar-menus.tsxfilters bycanView) and page guards (a denied page doesrouter.push("/404")). Permissions come from the backendmequery, not hard-coded.src/middleware.tsis only a coarse "logged in?" gate — it does not check roles.
Managing it in the admin
/admin/admins— admin users (list, add, edit; Excel export)./admin/roles— roles:add-role,edit-role,view-role. The per-menu ability grid issrc/modules/roles/components/FormRoleMenuAccesses.tsx.- Menu slugs are catalogued in
src/components/Sidebar/menu.tsxand URL constants insrc/constants/menus.ts.
Gotchas
- RBAC is client-enforced in the frontend and per-resolver in the backend. The middleware does not enforce per-action rights — the real gate for data is the backend guard.
- A new admin page needs a menu slug and role grant, or
useAccesshides and blocks it. - The dashboard is a stub (see Admin repo) — do not document analytics that do not exist.