diff --git a/apps/backoffice/src/app/layouts/nav-config.ts b/apps/backoffice/src/app/layouts/nav-config.ts index ddc1fd7ec..62a358cd6 100644 --- a/apps/backoffice/src/app/layouts/nav-config.ts +++ b/apps/backoffice/src/app/layouts/nav-config.ts @@ -26,7 +26,13 @@ import { IconUserShield, } from '@tabler/icons-react'; 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 @@ -143,7 +149,12 @@ export const NAV_SECTIONS: NavSection[] = [ { label: 'nav.groupAdministration', 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; // the config-view keys are the closest published contract. diff --git a/apps/backoffice/src/app/router/index.tsx b/apps/backoffice/src/app/router/index.tsx index a5a2c5c5b..dafbda888 100644 --- a/apps/backoffice/src/app/router/index.tsx +++ b/apps/backoffice/src/app/router/index.tsx @@ -14,6 +14,7 @@ import { } from '@ema-platform/auth'; import { AuthLayout } from '../layouts/AuthLayout'; import { BackofficeLayout } from '../layouts/BackofficeLayout'; +import { UM_PERMISSIONS } from '../layouts/nav-config'; import { ProtectedRoute } from './ProtectedRoute'; import { DashboardPage } from '../features/dashboard/pages/DashboardPage'; import UserManagementPage from '../features/user-management/UserManagementPage'; @@ -60,7 +61,10 @@ const router = createBrowserRouter([ { path: '/otp-verify', element: }, ], }, - { path: '/um/*', element: }, + { + path: '/um/*', + element: guard(UM_PERMISSIONS, ), + }, { path: '/', element: }, { path: '/profile-setup', element: }, { diff --git a/libs/auth/src/index.ts b/libs/auth/src/index.ts index 886e79d3b..1b63df2cc 100644 --- a/libs/auth/src/index.ts +++ b/libs/auth/src/index.ts @@ -28,6 +28,7 @@ export { usePermissions } from "./lib/hooks/usePermissions"; export type { PermissionSet } from "./lib/hooks/usePermissions"; export { RequirePermission } from "./lib/components/RequirePermission"; export { + IAM_ADMIN_PERMISSIONS, LICENSE_PERMISSIONS, PORTAL_PERMISSIONS, } from "./lib/permissions.constants"; diff --git a/libs/auth/src/lib/permissions.constants.ts b/libs/auth/src/lib/permissions.constants.ts index e3229ae90..987c57c0d 100644 --- a/libs/auth/src/lib/permissions.constants.ts +++ b/libs/auth/src/lib/permissions.constants.ts @@ -59,6 +59,19 @@ export const LICENSE_PERMISSIONS = { DECIDE_EXAM_APPEAL: "can:decide:exam-appeal", } 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 = { VIEW_OWN_PROFILE: "can:View:own-profile", EDIT_OWN_PROFILE: "can:edit:own-profile",