feat: add IAM_ADMIN_PERMISSIONS for user management access control

This commit is contained in:
Nati
2026-08-13 14:01:57 +00:00
parent 6852fc86c6
commit a148c00792
4 changed files with 32 additions and 3 deletions

View File

@@ -26,7 +26,13 @@ import {
IconUserShield, IconUserShield,
} from '@tabler/icons-react'; } from '@tabler/icons-react';
import type { NavSection } from '@ema-platform/ui'; import type { NavSection } from '@ema-platform/ui';
import { LICENSE_PERMISSIONS as P } from '@ema-platform/auth'; import {
IAM_ADMIN_PERMISSIONS,
LICENSE_PERMISSIONS as P,
} from '@ema-platform/auth';
/** Any user-administration duty opens the embedded User Management module. */
export const UM_PERMISSIONS = Object.values(IAM_ADMIN_PERMISSIONS);
/** /**
* Every licence-type queue and its review workspace share one gate: the * Every licence-type queue and its review workspace share one gate: the
@@ -143,7 +149,12 @@ export const NAV_SECTIONS: NavSection[] = [
{ {
label: 'nav.groupAdministration', label: 'nav.groupAdministration',
items: [ items: [
{ to: '/um/user-management/dashboard', label: 'nav.userManagement', icon: IconUserShield }, {
to: '/um/user-management/dashboard',
label: 'nav.userManagement',
icon: IconUserShield,
permissions: UM_PERMISSIONS,
},
{ {
// Professions, locations and certifications have no dedicated keys; // Professions, locations and certifications have no dedicated keys;
// the config-view keys are the closest published contract. // the config-view keys are the closest published contract.

View File

@@ -14,6 +14,7 @@ import {
} from '@ema-platform/auth'; } from '@ema-platform/auth';
import { AuthLayout } from '../layouts/AuthLayout'; import { AuthLayout } from '../layouts/AuthLayout';
import { BackofficeLayout } from '../layouts/BackofficeLayout'; import { BackofficeLayout } from '../layouts/BackofficeLayout';
import { UM_PERMISSIONS } from '../layouts/nav-config';
import { ProtectedRoute } from './ProtectedRoute'; import { ProtectedRoute } from './ProtectedRoute';
import { DashboardPage } from '../features/dashboard/pages/DashboardPage'; import { DashboardPage } from '../features/dashboard/pages/DashboardPage';
import UserManagementPage from '../features/user-management/UserManagementPage'; import UserManagementPage from '../features/user-management/UserManagementPage';
@@ -60,7 +61,10 @@ const router = createBrowserRouter([
{ path: '/otp-verify', element: <OTPVerificationPage /> }, { path: '/otp-verify', element: <OTPVerificationPage /> },
], ],
}, },
{ path: '/um/*', element: <UserManagementPage /> }, {
path: '/um/*',
element: guard(UM_PERMISSIONS, <UserManagementPage />),
},
{ path: '/', element: <Navigate to="/dashboard" replace /> }, { path: '/', element: <Navigate to="/dashboard" replace /> },
{ path: '/profile-setup', element: <Navigate to="/dashboard" replace /> }, { path: '/profile-setup', element: <Navigate to="/dashboard" replace /> },
{ {

View File

@@ -28,6 +28,7 @@ export { usePermissions } from "./lib/hooks/usePermissions";
export type { PermissionSet } from "./lib/hooks/usePermissions"; export type { PermissionSet } from "./lib/hooks/usePermissions";
export { RequirePermission } from "./lib/components/RequirePermission"; export { RequirePermission } from "./lib/components/RequirePermission";
export { export {
IAM_ADMIN_PERMISSIONS,
LICENSE_PERMISSIONS, LICENSE_PERMISSIONS,
PORTAL_PERMISSIONS, PORTAL_PERMISSIONS,
} from "./lib/permissions.constants"; } from "./lib/permissions.constants";

View File

@@ -59,6 +59,19 @@ export const LICENSE_PERMISSIONS = {
DECIDE_EXAM_APPEAL: "can:decide:exam-appeal", DECIDE_EXAM_APPEAL: "can:decide:exam-appeal",
} as const; } as const;
/**
* IAM baseline keys (iamapi-common seed, granted to the admin roles) used to
* decide who sees the embedded User Management module. Any one of these marks
* a user-administration duty: super_admin carries the role keys, organization
* and unit admins carry the employee keys.
*/
export const IAM_ADMIN_PERMISSIONS = {
VIEW_ALL_USERS: "can:viewAllUsers",
CREATE_EMPLOYEE: "can:createEmployee",
CREATE_USER_ROLE: "can:create:user_role",
CREATE_ROLE: "can:create:role",
} as const;
export const PORTAL_PERMISSIONS = { export const PORTAL_PERMISSIONS = {
VIEW_OWN_PROFILE: "can:View:own-profile", VIEW_OWN_PROFILE: "can:View:own-profile",
EDIT_OWN_PROFILE: "can:edit:own-profile", EDIT_OWN_PROFILE: "can:edit:own-profile",