diff --git a/src/core/api/README.md b/src/core/api/README.md index 2fb4e62..f33e17c 100644 --- a/src/core/api/README.md +++ b/src/core/api/README.md @@ -181,7 +181,7 @@ Champs optionnels : | Champ | Type | Description | |-------|------|-------------| | `skipRateLimit` | `boolean` | Exempte la route du rate limiting par IP (ex. health checks) | -| `permission` | `string` | Sur une route `auth: 'admin'`, exige en plus cette clé de permission granulaire (ex. `'users.edit'`). Retourne 403 si l'utilisateur ne la possède pas. Voir `PERMISSIONS` dans `src/core/users/constants.js` | +| `permission` | `string` | Sur une route `auth: 'admin'`, exige en plus cette clé de permission granulaire (ex. `'users.manage'`). Retourne 403 si l'utilisateur ne la possède pas. Voir `PERMISSIONS` dans `src/core/users/constants.js` | --- diff --git a/src/core/api/define.js b/src/core/api/define.js index 6aeba46..35451de 100644 --- a/src/core/api/define.js +++ b/src/core/api/define.js @@ -25,7 +25,7 @@ * (e.g. health checks from monitoring systems). * permission {string} When set on an 'admin' route, the router additionally * verifies that the authenticated user holds this granular - * permission key (e.g. 'users.edit'). If the user lacks + * permission key (e.g. 'users.manage'). If the user lacks * the permission, the request is rejected with 403 Forbidden. * * Auth levels: diff --git a/src/core/users/README.md b/src/core/users/README.md index 43cbf18..edce495 100644 --- a/src/core/users/README.md +++ b/src/core/users/README.md @@ -204,7 +204,7 @@ const role = await createRole({ name: 'Modérateur', description: 'Peut gérer l await updateRole(roleId, { name: 'Modérateur', - permissionKeys: [PERMISSIONS.USERS_VIEW, PERMISSIONS.USERS_EDIT], + permissionKeys: [PERMISSIONS.USERS_VIEW, PERMISSIONS.USERS_MANAGE], }); await deleteRole(roleId); // impossible sur les rôles système @@ -230,7 +230,7 @@ const keys = await getUserPermissions(userId); | Groupe | Clés | |--------|------| | Administration | `admin.access` | -| Utilisateurs | `users.view`, `users.edit`, `users.delete` | +| Utilisateurs | `users.view`, `users.manage` | | Rôles | `roles.view`, `roles.manage` | --- diff --git a/src/core/users/constants.js b/src/core/users/constants.js index 01c874a..94d0b85 100644 --- a/src/core/users/constants.js +++ b/src/core/users/constants.js @@ -6,19 +6,17 @@ export const PERMISSIONS = { ADMIN_ACCESS: 'admin.access', USERS_VIEW: 'users.view', - USERS_EDIT: 'users.edit', - USERS_DELETE: 'users.delete', + USERS_MANAGE: 'users.manage', ROLES_VIEW: 'roles.view', ROLES_MANAGE: 'roles.manage', }; export const PERMISSION_DEFINITIONS = [ - { key: 'admin.access', name: 'Accès au panneau admin', description: "Permet d'accéder à l'interface d'administration.", group_name: 'Administration' }, - { key: 'users.view', name: 'Voir les utilisateurs', description: 'Permet de consulter la liste des membres et leurs profils.', group_name: 'Utilisateurs' }, - { key: 'users.edit', name: 'Modifier les utilisateurs', description: 'Permet de changer les informations et les rôles des membres.', group_name: 'Utilisateurs' }, - { key: 'users.delete', name: 'Supprimer des utilisateurs', description: 'Permet de supprimer des comptes membres.', group_name: 'Utilisateurs' }, - { key: 'roles.view', name: 'Voir les rôles', description: 'Permet de consulter la liste des rôles et leurs permissions.', group_name: 'Rôles' }, - { key: 'roles.manage', name: 'Gérer les rôles', description: 'Permet de créer, modifier et supprimer des rôles.', group_name: 'Rôles' }, + { key: 'admin.access', name: 'Accès au panneau admin', description: "Permet d'accéder à l'interface d'administration.", group_name: 'Administration' }, + { key: 'users.view', name: 'Voir les utilisateurs', description: 'Permet de consulter la liste des membres et leurs profils.', group_name: 'Utilisateurs' }, + { key: 'users.manage', name: 'Gérer les utilisateurs', description: 'Permet de créer, modifier et supprimer des comptes membres.', group_name: 'Utilisateurs' }, + { key: 'roles.view', name: 'Voir les rôles', description: 'Permet de consulter la liste des rôles et leurs permissions.', group_name: 'Rôles' }, + { key: 'roles.manage', name: 'Gérer les rôles', description: 'Permet de créer, modifier et supprimer des rôles.', group_name: 'Rôles' }, ]; /** diff --git a/src/core/users/db.js b/src/core/users/db.js index 9ba8f7b..4b05f33 100644 --- a/src/core/users/db.js +++ b/src/core/users/db.js @@ -66,6 +66,20 @@ async function dropRoleCheckConstraint() { `); } +async function migratePermissions() { + // Migrate users.edit / users.delete → users.manage + await query(` + INSERT INTO zen_auth_role_permissions (role_id, permission_key) + SELECT DISTINCT role_id, 'users.manage' + FROM zen_auth_role_permissions + WHERE permission_key IN ('users.edit', 'users.delete') + AND EXISTS (SELECT 1 FROM zen_auth_permissions WHERE key = 'users.manage') + ON CONFLICT DO NOTHING + `); + await query(`DELETE FROM zen_auth_role_permissions WHERE permission_key IN ('users.edit', 'users.delete')`); + await query(`DELETE FROM zen_auth_permissions WHERE key IN ('users.edit', 'users.delete')`); +} + async function seedDefaultRolesAndPermissions() { // Permissions for (const perm of PERMISSION_DEFINITIONS) { @@ -75,6 +89,8 @@ async function seedDefaultRolesAndPermissions() { ); } + await migratePermissions(); + // Admin role const adminRoleId = generateId(); await query( diff --git a/src/features/admin/pages/UsersPage.client.js b/src/features/admin/pages/UsersPage.client.js index a583095..7a10777 100644 --- a/src/features/admin/pages/UsersPage.client.js +++ b/src/features/admin/pages/UsersPage.client.js @@ -174,7 +174,7 @@ const UsersPageClient = ({ currentUserId, refreshKey, canEdit }) => { const UsersPage = ({ user }) => { const [createModalOpen, setCreateModalOpen] = useState(false); const [refreshKey, setRefreshKey] = useState(0); - const canEdit = user?.permissions?.includes('users.edit'); + const canEdit = user?.permissions?.includes('users.manage'); return (