@mostajs/rbac 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +694 -0
- package/dist/api/categories-id.d.ts +21 -0
- package/dist/api/categories-id.d.ts.map +1 -0
- package/dist/api/categories-id.js +66 -0
- package/dist/api/categories-id.js.map +1 -0
- package/dist/api/categories.d.ts +15 -0
- package/dist/api/categories.d.ts.map +1 -0
- package/dist/api/categories.js +65 -0
- package/dist/api/categories.js.map +1 -0
- package/dist/api/matrix.d.ts +15 -0
- package/dist/api/matrix.d.ts.map +1 -0
- package/dist/api/matrix.js +104 -0
- package/dist/api/matrix.js.map +1 -0
- package/dist/api/permissions-id.d.ts +21 -0
- package/dist/api/permissions-id.d.ts.map +1 -0
- package/dist/api/permissions-id.js +48 -0
- package/dist/api/permissions-id.js.map +1 -0
- package/dist/api/permissions.d.ts +16 -0
- package/dist/api/permissions.d.ts.map +1 -0
- package/dist/api/permissions.js +102 -0
- package/dist/api/permissions.js.map +1 -0
- package/dist/api/roles-id.d.ts +27 -0
- package/dist/api/roles-id.d.ts.map +1 -0
- package/dist/api/roles-id.js +89 -0
- package/dist/api/roles-id.js.map +1 -0
- package/dist/api/roles.d.ts +15 -0
- package/dist/api/roles.d.ts.map +1 -0
- package/dist/api/roles.js +65 -0
- package/dist/api/roles.js.map +1 -0
- package/dist/api/seed.d.ts +16 -0
- package/dist/api/seed.d.ts.map +1 -0
- package/dist/api/seed.js +49 -0
- package/dist/api/seed.js.map +1 -0
- package/dist/api/users-id.d.ts +28 -0
- package/dist/api/users-id.d.ts.map +1 -0
- package/dist/api/users-id.js +94 -0
- package/dist/api/users-id.js.map +1 -0
- package/dist/api/users.d.ts +17 -0
- package/dist/api/users.d.ts.map +1 -0
- package/dist/api/users.js +80 -0
- package/dist/api/users.js.map +1 -0
- package/dist/components/CategoriesManager.d.ts +5 -0
- package/dist/components/CategoriesManager.d.ts.map +1 -0
- package/dist/components/CategoriesManager.js +115 -0
- package/dist/components/CategoriesManager.js.map +1 -0
- package/dist/components/PermissionMatrix.d.ts +5 -0
- package/dist/components/PermissionMatrix.d.ts.map +1 -0
- package/dist/components/PermissionMatrix.js +82 -0
- package/dist/components/PermissionMatrix.js.map +1 -0
- package/dist/components/PermissionsManager.d.ts +5 -0
- package/dist/components/PermissionsManager.d.ts.map +1 -0
- package/dist/components/PermissionsManager.js +89 -0
- package/dist/components/PermissionsManager.js.map +1 -0
- package/dist/components/RBACManager.d.ts +5 -0
- package/dist/components/RBACManager.d.ts.map +1 -0
- package/dist/components/RBACManager.js +16 -0
- package/dist/components/RBACManager.js.map +1 -0
- package/dist/components/RolesManager.d.ts +5 -0
- package/dist/components/RolesManager.d.ts.map +1 -0
- package/dist/components/RolesManager.js +97 -0
- package/dist/components/RolesManager.js.map +1 -0
- package/dist/components/UsersManager.d.ts +10 -0
- package/dist/components/UsersManager.d.ts.map +1 -0
- package/dist/components/UsersManager.js +111 -0
- package/dist/components/UsersManager.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +19 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +67 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +37 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +48 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/card.d.ts +10 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +43 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +23 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +18 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +60 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +19 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +22 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/select.d.ts +16 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +61 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/table.d.ts +11 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +49 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +12 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +46 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/rbac-api.d.ts +66 -0
- package/dist/lib/rbac-api.d.ts.map +1 -0
- package/dist/lib/rbac-api.js +158 -0
- package/dist/lib/rbac-api.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +7 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +14 -0
- package/dist/server.js.map +1 -0
- package/dist/types/index.d.ts +88 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +126 -0
package/README.md
ADDED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
# @mostajs/rbac
|
|
2
|
+
|
|
3
|
+
> Reusable RBAC management UI — Users, Roles, Permissions, Categories, Matrix.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@mostajs/rbac)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
Part of the [@mosta suite](https://mostajs.dev). Fournit des composants React complets et des factories API pour gerer les utilisateurs, roles, permissions et matrice RBAC.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Table des matieres
|
|
13
|
+
|
|
14
|
+
1. [Installation](#installation)
|
|
15
|
+
2. [Quick Start](#quick-start)
|
|
16
|
+
3. [Integration complete dans une nouvelle app](#integration-complete)
|
|
17
|
+
4. [Composants React](#composants-react)
|
|
18
|
+
5. [API Route Factories (serveur)](#api-route-factories)
|
|
19
|
+
6. [Definitions RBAC (seed)](#definitions-rbac)
|
|
20
|
+
7. [Internationalisation (i18n)](#internationalisation)
|
|
21
|
+
8. [API Reference](#api-reference)
|
|
22
|
+
9. [Architecture](#architecture)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @mostajs/rbac @mostajs/auth @mostajs/orm
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Peer dependencies a installer :
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @tanstack/react-query lucide-react sonner
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> `@mostajs/audit` est optionnel — si installe, les actions CRUD seront journalisees automatiquement.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### 1. Page d'administration RBAC (frontend)
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// src/app/dashboard/roles/page.tsx
|
|
48
|
+
'use client'
|
|
49
|
+
import { RBACManager } from '@mostajs/rbac'
|
|
50
|
+
|
|
51
|
+
export default function RolesPage() {
|
|
52
|
+
return <RBACManager apiBasePath="/api" />
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
C'est tout. Le composant `RBACManager` affiche 4 onglets : Matrice, Roles, Permissions, Categories.
|
|
57
|
+
|
|
58
|
+
### 2. Routes API (backend)
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// src/app/api/admin/roles/route.ts
|
|
62
|
+
import { createRolesHandler } from '@mostajs/rbac/server'
|
|
63
|
+
import { checkPermission } from '@/lib/auth'
|
|
64
|
+
|
|
65
|
+
export const { GET, POST } = createRolesHandler({
|
|
66
|
+
checkPermission,
|
|
67
|
+
adminPermission: 'roles:manage',
|
|
68
|
+
})
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Integration complete
|
|
74
|
+
|
|
75
|
+
Guide pas-a-pas pour integrer `@mostajs/rbac` dans une nouvelle application Next.js.
|
|
76
|
+
|
|
77
|
+
### Etape 1 — Installer les packages
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm install @mostajs/rbac @mostajs/auth @mostajs/orm
|
|
81
|
+
npm install @tanstack/react-query lucide-react sonner
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Etape 2 — Definir vos permissions et roles
|
|
85
|
+
|
|
86
|
+
Creez un fichier de definitions RBAC propre a votre app :
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// src/lib/rbac-definitions.ts
|
|
90
|
+
import type { PermissionDefinition, RoleDefinition, CategoryDefinition } from '@mostajs/rbac'
|
|
91
|
+
|
|
92
|
+
// Categories de permissions
|
|
93
|
+
export const CATEGORIES: CategoryDefinition[] = [
|
|
94
|
+
{ name: 'users', label: 'Utilisateurs', description: 'Gestion des utilisateurs', icon: 'Users', order: 1, system: true },
|
|
95
|
+
{ name: 'products', label: 'Produits', description: 'Gestion des produits', icon: 'Package', order: 2, system: false },
|
|
96
|
+
{ name: 'orders', label: 'Commandes', description: 'Gestion des commandes', icon: 'Receipt', order: 3, system: false },
|
|
97
|
+
{ name: 'reports', label: 'Rapports', description: 'Consultation des rapports', icon: 'BarChart', order: 4, system: false },
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
// Permissions
|
|
101
|
+
export const PERMISSIONS_DEFS: PermissionDefinition[] = [
|
|
102
|
+
{ code: 'users:view', name: 'users:view', description: 'Voir les utilisateurs', category: 'users' },
|
|
103
|
+
{ code: 'users:create', name: 'users:create', description: 'Creer un utilisateur', category: 'users' },
|
|
104
|
+
{ code: 'users:edit', name: 'users:edit', description: 'Modifier un utilisateur', category: 'users' },
|
|
105
|
+
{ code: 'users:delete', name: 'users:delete', description: 'Supprimer un utilisateur', category: 'users' },
|
|
106
|
+
{ code: 'products:view', name: 'products:view', description: 'Voir les produits', category: 'products' },
|
|
107
|
+
{ code: 'products:edit', name: 'products:edit', description: 'Modifier les produits', category: 'products' },
|
|
108
|
+
{ code: 'orders:view', name: 'orders:view', description: 'Voir les commandes', category: 'orders' },
|
|
109
|
+
{ code: 'orders:manage', name: 'orders:manage', description: 'Gerer les commandes', category: 'orders' },
|
|
110
|
+
{ code: 'reports:view', name: 'reports:view', description: 'Consulter les rapports', category: 'reports' },
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
// Roles par defaut
|
|
114
|
+
export const DEFAULT_ROLES: Record<string, RoleDefinition> = {
|
|
115
|
+
admin: {
|
|
116
|
+
name: 'admin',
|
|
117
|
+
description: 'Administrateur — acces complet',
|
|
118
|
+
system: true,
|
|
119
|
+
permissions: PERMISSIONS_DEFS.map(p => p.code),
|
|
120
|
+
},
|
|
121
|
+
manager: {
|
|
122
|
+
name: 'manager',
|
|
123
|
+
description: 'Manager — gestion produits et commandes',
|
|
124
|
+
system: false,
|
|
125
|
+
permissions: ['users:view', 'products:view', 'products:edit', 'orders:view', 'orders:manage', 'reports:view'],
|
|
126
|
+
},
|
|
127
|
+
viewer: {
|
|
128
|
+
name: 'viewer',
|
|
129
|
+
description: 'Consultation seule',
|
|
130
|
+
system: false,
|
|
131
|
+
permissions: ['products:view', 'orders:view', 'reports:view'],
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Constantes de permissions pour les guards
|
|
136
|
+
export const PERMISSIONS = Object.fromEntries(
|
|
137
|
+
PERMISSIONS_DEFS.map(p => [p.code.replace(':', '_').toUpperCase(), p.code])
|
|
138
|
+
) as Record<string, string>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Etape 3 — Creer les routes API
|
|
142
|
+
|
|
143
|
+
Chaque entite RBAC a besoin de deux routes : collection et item par ID.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// src/app/api/admin/roles/route.ts
|
|
147
|
+
import { createRolesHandler } from '@mostajs/rbac/server'
|
|
148
|
+
import { checkPermission } from '@/lib/auth'
|
|
149
|
+
import { logAudit, getAuditUser } from '@mostajs/audit/lib/audit' // optionnel
|
|
150
|
+
|
|
151
|
+
export const { GET, POST } = createRolesHandler({
|
|
152
|
+
checkPermission,
|
|
153
|
+
adminPermission: 'roles:manage',
|
|
154
|
+
logAudit, // optionnel
|
|
155
|
+
getAuditUser, // optionnel
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// src/app/api/admin/roles/[id]/route.ts
|
|
161
|
+
import { createRolesIdHandler } from '@mostajs/rbac/server'
|
|
162
|
+
import { checkPermission } from '@/lib/auth'
|
|
163
|
+
|
|
164
|
+
export const { GET, PUT, DELETE } = createRolesIdHandler({
|
|
165
|
+
checkPermission,
|
|
166
|
+
adminPermission: 'roles:manage',
|
|
167
|
+
})
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// src/app/api/admin/permissions/route.ts
|
|
172
|
+
import { createPermissionsHandler } from '@mostajs/rbac/server'
|
|
173
|
+
import { checkPermission } from '@/lib/auth'
|
|
174
|
+
import { PERMISSIONS_DEFS } from '@/lib/rbac-definitions'
|
|
175
|
+
|
|
176
|
+
export const { GET, POST } = createPermissionsHandler({
|
|
177
|
+
checkPermission,
|
|
178
|
+
adminPermission: 'permissions:manage',
|
|
179
|
+
permissionDefinitions: PERMISSIONS_DEFS,
|
|
180
|
+
})
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// src/app/api/admin/permissions/[id]/route.ts
|
|
185
|
+
import { createPermissionsIdHandler } from '@mostajs/rbac/server'
|
|
186
|
+
import { checkPermission } from '@/lib/auth'
|
|
187
|
+
|
|
188
|
+
export const { PUT, DELETE } = createPermissionsIdHandler({
|
|
189
|
+
checkPermission,
|
|
190
|
+
adminPermission: 'permissions:manage',
|
|
191
|
+
})
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// src/app/api/admin/permissions/matrix/route.ts
|
|
196
|
+
import { createMatrixHandler } from '@mostajs/rbac/server'
|
|
197
|
+
import { checkPermission } from '@/lib/auth'
|
|
198
|
+
|
|
199
|
+
export const { GET, POST } = createMatrixHandler({
|
|
200
|
+
checkPermission,
|
|
201
|
+
adminPermission: 'permissions:manage',
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// src/app/api/admin/categories/route.ts
|
|
207
|
+
import { createCategoriesHandler } from '@mostajs/rbac/server'
|
|
208
|
+
import { checkPermission } from '@/lib/auth'
|
|
209
|
+
import { CATEGORIES } from '@/lib/rbac-definitions'
|
|
210
|
+
|
|
211
|
+
export const { GET, POST } = createCategoriesHandler({
|
|
212
|
+
checkPermission,
|
|
213
|
+
adminPermission: 'categories:manage',
|
|
214
|
+
categoryDefinitions: CATEGORIES,
|
|
215
|
+
})
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// src/app/api/admin/categories/[id]/route.ts
|
|
220
|
+
import { createCategoriesIdHandler } from '@mostajs/rbac/server'
|
|
221
|
+
import { checkPermission } from '@/lib/auth'
|
|
222
|
+
|
|
223
|
+
export const { PUT, DELETE } = createCategoriesIdHandler({
|
|
224
|
+
checkPermission,
|
|
225
|
+
adminPermission: 'categories:manage',
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
// src/app/api/admin/permissions/seed/route.ts
|
|
231
|
+
import { createSeedHandler } from '@mostajs/rbac/server'
|
|
232
|
+
import { checkPermission } from '@/lib/auth'
|
|
233
|
+
import { PERMISSIONS_DEFS, DEFAULT_ROLES, CATEGORIES } from '@/lib/rbac-definitions'
|
|
234
|
+
|
|
235
|
+
export const { POST } = createSeedHandler({
|
|
236
|
+
checkPermission,
|
|
237
|
+
adminPermission: 'admin',
|
|
238
|
+
permissionDefinitions: PERMISSIONS_DEFS,
|
|
239
|
+
defaultRoles: DEFAULT_ROLES,
|
|
240
|
+
categoryDefinitions: CATEGORIES,
|
|
241
|
+
})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// src/app/api/users/route.ts
|
|
246
|
+
import { createUsersHandler } from '@mostajs/rbac/server'
|
|
247
|
+
import { checkPermission } from '@/lib/auth'
|
|
248
|
+
|
|
249
|
+
export const { GET, POST } = createUsersHandler({
|
|
250
|
+
checkPermission,
|
|
251
|
+
adminPermission: 'users:manage',
|
|
252
|
+
knownRoles: ['admin', 'manager', 'viewer'],
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// src/app/api/users/[id]/route.ts
|
|
258
|
+
import { createUsersIdHandler } from '@mostajs/rbac/server'
|
|
259
|
+
import { checkPermission } from '@/lib/auth'
|
|
260
|
+
|
|
261
|
+
export const { GET, PUT, DELETE } = createUsersIdHandler({
|
|
262
|
+
checkPermission,
|
|
263
|
+
adminPermission: 'users:manage',
|
|
264
|
+
})
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Etape 4 — Provider TanStack Query
|
|
268
|
+
|
|
269
|
+
Les composants RBAC utilisent `@tanstack/react-query`. Ajoutez le provider :
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
// src/app/providers.tsx
|
|
273
|
+
'use client'
|
|
274
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
275
|
+
import { useState } from 'react'
|
|
276
|
+
|
|
277
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
278
|
+
const [queryClient] = useState(() => new QueryClient())
|
|
279
|
+
return (
|
|
280
|
+
<QueryClientProvider client={queryClient}>
|
|
281
|
+
{children}
|
|
282
|
+
</QueryClientProvider>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
// src/app/layout.tsx
|
|
289
|
+
import { Providers } from './providers'
|
|
290
|
+
|
|
291
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
292
|
+
return (
|
|
293
|
+
<html>
|
|
294
|
+
<body>
|
|
295
|
+
<Providers>{children}</Providers>
|
|
296
|
+
</body>
|
|
297
|
+
</html>
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Etape 5 — Pages d'administration
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
// src/app/dashboard/roles/page.tsx
|
|
306
|
+
'use client'
|
|
307
|
+
import { RBACManager } from '@mostajs/rbac'
|
|
308
|
+
|
|
309
|
+
export default function RolesPage() {
|
|
310
|
+
return (
|
|
311
|
+
<RBACManager
|
|
312
|
+
apiBasePath="/api"
|
|
313
|
+
systemRoles={['admin']}
|
|
314
|
+
roleColors={{ admin: 'bg-red-100 text-red-800', manager: 'bg-blue-100 text-blue-800' }}
|
|
315
|
+
/>
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
// src/app/dashboard/users/page.tsx
|
|
322
|
+
'use client'
|
|
323
|
+
import { UsersManager } from '@mostajs/rbac'
|
|
324
|
+
|
|
325
|
+
export default function UsersPage() {
|
|
326
|
+
return (
|
|
327
|
+
<UsersManager
|
|
328
|
+
apiBasePath="/api"
|
|
329
|
+
roleColors={{ admin: 'bg-red-100 text-red-800', manager: 'bg-blue-100 text-blue-800' }}
|
|
330
|
+
statusColors={{ active: 'bg-green-100 text-green-800', inactive: 'bg-gray-100 text-gray-800' }}
|
|
331
|
+
/>
|
|
332
|
+
)
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Etape 6 — Initialiser les donnees (seed)
|
|
337
|
+
|
|
338
|
+
Au premier lancement, initialisez les permissions, roles et categories :
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Via l'UI : cliquer "Initialiser" dans l'onglet Matrice
|
|
342
|
+
|
|
343
|
+
# Ou via curl :
|
|
344
|
+
curl -X POST http://localhost:3000/api/admin/permissions/seed \
|
|
345
|
+
-H 'Cookie: next-auth.session-token=...'
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Reponse :
|
|
349
|
+
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"data": {
|
|
353
|
+
"categories": 4,
|
|
354
|
+
"permissions": 9,
|
|
355
|
+
"roles": 3,
|
|
356
|
+
"message": "4 categories, 9 permissions et 3 roles initialises"
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Etape 7 — Verification
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
npm run dev
|
|
365
|
+
|
|
366
|
+
# Ouvrir http://localhost:3000/dashboard/roles
|
|
367
|
+
# → 4 onglets : Matrice, Roles, Permissions, Categories
|
|
368
|
+
# → Cliquer "Initialiser" pour seed
|
|
369
|
+
|
|
370
|
+
# Ouvrir http://localhost:3000/dashboard/users
|
|
371
|
+
# → Liste des utilisateurs avec CRUD
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Composants React
|
|
377
|
+
|
|
378
|
+
Tous les composants sont `'use client'` et s'importent depuis `@mostajs/rbac`.
|
|
379
|
+
|
|
380
|
+
### RBACManager
|
|
381
|
+
|
|
382
|
+
Orchestrateur principal avec 4 onglets (Matrice, Roles, Permissions, Categories).
|
|
383
|
+
|
|
384
|
+
```tsx
|
|
385
|
+
import { RBACManager } from '@mostajs/rbac'
|
|
386
|
+
|
|
387
|
+
<RBACManager
|
|
388
|
+
apiBasePath="/api" // Prefixe des routes API (defaut: '/api')
|
|
389
|
+
t={traductionFunction} // Fonction i18n (optionnel)
|
|
390
|
+
systemRoles={['admin']} // Roles proteges (lecture seule)
|
|
391
|
+
roleColors={{ // Couleurs badges roles (optionnel)
|
|
392
|
+
admin: 'bg-red-100 text-red-800',
|
|
393
|
+
manager: 'bg-blue-100 text-blue-800',
|
|
394
|
+
}}
|
|
395
|
+
/>
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### UsersManager
|
|
399
|
+
|
|
400
|
+
Gestion des utilisateurs : liste, creation, edition, suppression.
|
|
401
|
+
|
|
402
|
+
```tsx
|
|
403
|
+
import { UsersManager } from '@mostajs/rbac'
|
|
404
|
+
|
|
405
|
+
<UsersManager
|
|
406
|
+
apiBasePath="/api"
|
|
407
|
+
roleColors={{ admin: 'bg-red-100 text-red-800' }}
|
|
408
|
+
statusColors={{ active: 'bg-green-100 text-green-800' }}
|
|
409
|
+
/>
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### RolesManager
|
|
413
|
+
|
|
414
|
+
CRUD roles avec protection des roles systeme.
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
import { RolesManager } from '@mostajs/rbac'
|
|
418
|
+
|
|
419
|
+
<RolesManager apiBasePath="/api" systemRoles={['admin']} />
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### PermissionsManager
|
|
423
|
+
|
|
424
|
+
CRUD permissions groupees par categorie.
|
|
425
|
+
|
|
426
|
+
```tsx
|
|
427
|
+
import { PermissionsManager } from '@mostajs/rbac'
|
|
428
|
+
|
|
429
|
+
<PermissionsManager apiBasePath="/api" />
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### CategoriesManager
|
|
433
|
+
|
|
434
|
+
CRUD categories avec ordonnancement et protection systeme.
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
import { CategoriesManager } from '@mostajs/rbac'
|
|
438
|
+
|
|
439
|
+
<CategoriesManager apiBasePath="/api" />
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### PermissionMatrix
|
|
443
|
+
|
|
444
|
+
Matrice roles/permissions avec checkboxes, groupement par categorie, et boutons Sauvegarder/Initialiser.
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
import { PermissionMatrix } from '@mostajs/rbac'
|
|
448
|
+
|
|
449
|
+
<PermissionMatrix apiBasePath="/api" />
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## API Route Factories
|
|
455
|
+
|
|
456
|
+
Toutes les factories s'importent depuis `@mostajs/rbac/server`. Chaque factory retourne des handlers HTTP (GET, POST, PUT, DELETE).
|
|
457
|
+
|
|
458
|
+
### Pattern commun
|
|
459
|
+
|
|
460
|
+
Toutes les factories prennent un `checkPermission` injectable :
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
interface Config {
|
|
464
|
+
checkPermission: (perm: string) => Promise<{
|
|
465
|
+
error: NextResponse | null // null = autorise
|
|
466
|
+
session: any // session utilisateur
|
|
467
|
+
}>
|
|
468
|
+
adminPermission: string // permission requise (ex: 'roles:manage')
|
|
469
|
+
logAudit?: (entry) => void // optionnel, journalisation
|
|
470
|
+
getAuditUser?: (session) => {} // optionnel, extraction user
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Factories disponibles
|
|
475
|
+
|
|
476
|
+
| Factory | Import | Routes | Methodes |
|
|
477
|
+
|---------|--------|--------|----------|
|
|
478
|
+
| `createUsersHandler` | `@mostajs/rbac/server` | `/api/users` | GET, POST |
|
|
479
|
+
| `createUsersIdHandler` | `@mostajs/rbac/server` | `/api/users/[id]` | GET, PUT, DELETE |
|
|
480
|
+
| `createRolesHandler` | `@mostajs/rbac/server` | `/api/admin/roles` | GET, POST |
|
|
481
|
+
| `createRolesIdHandler` | `@mostajs/rbac/server` | `/api/admin/roles/[id]` | GET, PUT, DELETE |
|
|
482
|
+
| `createPermissionsHandler` | `@mostajs/rbac/server` | `/api/admin/permissions` | GET, POST |
|
|
483
|
+
| `createPermissionsIdHandler` | `@mostajs/rbac/server` | `/api/admin/permissions/[id]` | PUT, DELETE |
|
|
484
|
+
| `createMatrixHandler` | `@mostajs/rbac/server` | `/api/admin/permissions/matrix` | GET, POST |
|
|
485
|
+
| `createCategoriesHandler` | `@mostajs/rbac/server` | `/api/admin/categories` | GET, POST |
|
|
486
|
+
| `createCategoriesIdHandler` | `@mostajs/rbac/server` | `/api/admin/categories/[id]` | PUT, DELETE |
|
|
487
|
+
| `createSeedHandler` | `@mostajs/rbac/server` | `/api/admin/permissions/seed` | POST |
|
|
488
|
+
|
|
489
|
+
### Client-side API helpers
|
|
490
|
+
|
|
491
|
+
Pour appeler les routes depuis le frontend (utilises en interne par les composants) :
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
import { createUsersApi, createRolesApi, createPermissionsApi, createMatrixApi, createCategoriesApi } from '@mostajs/rbac'
|
|
495
|
+
|
|
496
|
+
const usersApi = createUsersApi('/api')
|
|
497
|
+
const users = await usersApi.fetchUsers()
|
|
498
|
+
await usersApi.createUser({ email: 'a@b.com', password: '123456', firstName: 'A', lastName: 'B', role: 'viewer' })
|
|
499
|
+
|
|
500
|
+
const rolesApi = createRolesApi('/api')
|
|
501
|
+
const roles = await rolesApi.fetchRoles()
|
|
502
|
+
|
|
503
|
+
const matrixApi = createMatrixApi('/api')
|
|
504
|
+
const matrix = await matrixApi.fetchMatrix()
|
|
505
|
+
await matrixApi.seedRbac()
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Definitions RBAC
|
|
511
|
+
|
|
512
|
+
Le systeme de seed permet d'initialiser les categories, permissions et roles depuis des definitions TypeScript.
|
|
513
|
+
|
|
514
|
+
### PermissionDefinition
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
interface PermissionDefinition {
|
|
518
|
+
code: string // Identifiant unique (ex: 'users:view')
|
|
519
|
+
name: string // Nom en DB (generalement = code)
|
|
520
|
+
description: string
|
|
521
|
+
category: string // Nom de la categorie parente
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### RoleDefinition
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
interface RoleDefinition {
|
|
529
|
+
name: string
|
|
530
|
+
description: string
|
|
531
|
+
system: boolean // true = protege (ne peut pas etre supprime)
|
|
532
|
+
permissions: string[] // Liste des codes permission
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### CategoryDefinition
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
interface CategoryDefinition {
|
|
540
|
+
name: string // Identifiant unique
|
|
541
|
+
label: string // Label affiche
|
|
542
|
+
description: string
|
|
543
|
+
icon: string // Nom d'icone Lucide
|
|
544
|
+
order: number // Ordre d'affichage
|
|
545
|
+
system: boolean // true = ne peut pas etre supprime
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## Internationalisation
|
|
552
|
+
|
|
553
|
+
Tous les composants acceptent une fonction `t(key)` pour l'i18n :
|
|
554
|
+
|
|
555
|
+
```tsx
|
|
556
|
+
const t = (key: string) => translations[key] || key
|
|
557
|
+
|
|
558
|
+
<RBACManager apiBasePath="/api" t={t} />
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
Cles utilisees :
|
|
562
|
+
|
|
563
|
+
| Cle | Defaut |
|
|
564
|
+
|-----|--------|
|
|
565
|
+
| `roles.title` | Titre de la page |
|
|
566
|
+
| `roles.tabs.matrix` | Onglet Matrice |
|
|
567
|
+
| `roles.tabs.roles` | Onglet Roles |
|
|
568
|
+
| `roles.tabs.permissions` | Onglet Permissions |
|
|
569
|
+
| `roles.tabs.categories` | Onglet Categories |
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## API Reference
|
|
574
|
+
|
|
575
|
+
### Exports client (`@mostajs/rbac`)
|
|
576
|
+
|
|
577
|
+
| Export | Type | Description |
|
|
578
|
+
|--------|------|-------------|
|
|
579
|
+
| `RBACManager` | Component | Orchestrateur 4 onglets |
|
|
580
|
+
| `UsersManager` | Component | CRUD utilisateurs |
|
|
581
|
+
| `RolesManager` | Component | CRUD roles |
|
|
582
|
+
| `PermissionsManager` | Component | CRUD permissions |
|
|
583
|
+
| `CategoriesManager` | Component | CRUD categories |
|
|
584
|
+
| `PermissionMatrix` | Component | Matrice roles/permissions |
|
|
585
|
+
| `createUsersApi(basePath)` | Function | Helpers fetch users |
|
|
586
|
+
| `createRolesApi(basePath)` | Function | Helpers fetch roles |
|
|
587
|
+
| `createPermissionsApi(basePath)` | Function | Helpers fetch permissions |
|
|
588
|
+
| `createMatrixApi(basePath)` | Function | Helpers fetch matrix + seed |
|
|
589
|
+
| `createCategoriesApi(basePath)` | Function | Helpers fetch categories |
|
|
590
|
+
|
|
591
|
+
### Exports serveur (`@mostajs/rbac/server`)
|
|
592
|
+
|
|
593
|
+
| Export | Type | Description |
|
|
594
|
+
|--------|------|-------------|
|
|
595
|
+
| `createUsersHandler(config)` | Factory | GET/POST users |
|
|
596
|
+
| `createUsersIdHandler(config)` | Factory | GET/PUT/DELETE user by ID |
|
|
597
|
+
| `createRolesHandler(config)` | Factory | GET/POST roles |
|
|
598
|
+
| `createRolesIdHandler(config)` | Factory | GET/PUT/DELETE role by ID |
|
|
599
|
+
| `createPermissionsHandler(config)` | Factory | GET/POST permissions |
|
|
600
|
+
| `createPermissionsIdHandler(config)` | Factory | PUT/DELETE permission by ID |
|
|
601
|
+
| `createMatrixHandler(config)` | Factory | GET/POST matrice |
|
|
602
|
+
| `createCategoriesHandler(config)` | Factory | GET/POST categories |
|
|
603
|
+
| `createCategoriesIdHandler(config)` | Factory | PUT/DELETE category by ID |
|
|
604
|
+
| `createSeedHandler(config)` | Factory | POST seed RBAC |
|
|
605
|
+
|
|
606
|
+
### Types
|
|
607
|
+
|
|
608
|
+
| Type | Description |
|
|
609
|
+
|------|-------------|
|
|
610
|
+
| `User` | Utilisateur (id, email, firstName, lastName, role, status) |
|
|
611
|
+
| `RoleData` | Role (id, name, description, permissions[], userCount) |
|
|
612
|
+
| `PermissionData` | Permission (id, name, description, category, roleCount) |
|
|
613
|
+
| `CategoryData` | Categorie (id, name, label, icon, order, system) |
|
|
614
|
+
| `MatrixData` | Matrice (roles, categories, categoryLabels, matrix) |
|
|
615
|
+
| `RBACConfig` | Config composants (apiBasePath, t, systemRoles, colors) |
|
|
616
|
+
| `PermissionDefinition` | Definition permission pour seed |
|
|
617
|
+
| `RoleDefinition` | Definition role pour seed |
|
|
618
|
+
| `CategoryDefinition` | Definition categorie pour seed |
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## Architecture
|
|
623
|
+
|
|
624
|
+
```
|
|
625
|
+
@mostajs/rbac
|
|
626
|
+
├── components/ # React 'use client'
|
|
627
|
+
│ ├── RBACManager.tsx # Orchestrateur 4 onglets
|
|
628
|
+
│ ├── UsersManager.tsx # CRUD utilisateurs
|
|
629
|
+
│ ├── RolesManager.tsx # CRUD roles
|
|
630
|
+
│ ├── PermissionsManager.tsx # CRUD permissions
|
|
631
|
+
│ ├── CategoriesManager.tsx # CRUD categories
|
|
632
|
+
│ ├── PermissionMatrix.tsx # Matrice interactive
|
|
633
|
+
│ └── ui/ # Shadcn/ui embarques
|
|
634
|
+
├── api/ # Factories serveur
|
|
635
|
+
│ ├── users.ts # createUsersHandler
|
|
636
|
+
│ ├── users-id.ts # createUsersIdHandler
|
|
637
|
+
│ ├── roles.ts # createRolesHandler
|
|
638
|
+
│ ├── roles-id.ts # createRolesIdHandler
|
|
639
|
+
│ ├── permissions.ts # createPermissionsHandler
|
|
640
|
+
│ ├── permissions-id.ts # createPermissionsIdHandler
|
|
641
|
+
│ ├── matrix.ts # createMatrixHandler
|
|
642
|
+
│ ├── categories.ts # createCategoriesHandler
|
|
643
|
+
│ ├── categories-id.ts # createCategoriesIdHandler
|
|
644
|
+
│ └── seed.ts # createSeedHandler
|
|
645
|
+
├── lib/
|
|
646
|
+
│ ├── rbac-api.ts # Helpers fetch client
|
|
647
|
+
│ └── utils.ts # cn() (Tailwind merge)
|
|
648
|
+
├── types/
|
|
649
|
+
│ └── index.ts # Toutes les interfaces
|
|
650
|
+
├── index.ts # Exports client
|
|
651
|
+
└── server.ts # Exports serveur
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Dependances
|
|
655
|
+
|
|
656
|
+
```
|
|
657
|
+
@mostajs/rbac
|
|
658
|
+
├── @mostajs/auth (required) # UserRepository, RoleRepository, hashPassword
|
|
659
|
+
├── @mostajs/orm (required) # getDialect(), abstraction DB
|
|
660
|
+
├── @mostajs/audit (optional) # logAudit() pour journalisation
|
|
661
|
+
├── zod # Validation schemas
|
|
662
|
+
├── @tanstack/react-query # Cache & mutations
|
|
663
|
+
├── lucide-react # Icones
|
|
664
|
+
├── sonner # Toasts
|
|
665
|
+
└── radix-ui # Primitives UI (Dialog, Tabs, etc.)
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### Pattern d'injection
|
|
669
|
+
|
|
670
|
+
```
|
|
671
|
+
┌─────────────────────┐ inject config ┌──────────────────────┐
|
|
672
|
+
│ @mostajs/rbac │ ◄───────────────────────── │ Votre app │
|
|
673
|
+
│ │ │ │
|
|
674
|
+
│ createRolesHandler({│ │ checkPermission, │
|
|
675
|
+
│ checkPermission, │ │ 'roles:manage', │
|
|
676
|
+
│ adminPermission, │ │ logAudit, │
|
|
677
|
+
│ logAudit?, │ │ getAuditUser │
|
|
678
|
+
│ }) │ │ │
|
|
679
|
+
└─────────────────────┘ └──────────────────────┘
|
|
680
|
+
|
|
681
|
+
┌─────────────────────┐ props ┌──────────────────────┐
|
|
682
|
+
│ <RBACManager │ ◄───────────────────────── │ Votre page │
|
|
683
|
+
│ apiBasePath="/api"│ │ │
|
|
684
|
+
│ t={i18nFunction} │ │ dashboard/roles/ │
|
|
685
|
+
│ systemRoles={[..]}│ │ page.tsx │
|
|
686
|
+
│ /> │ │ │
|
|
687
|
+
└─────────────────────┘ └──────────────────────┘
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
## License
|
|
693
|
+
|
|
694
|
+
MIT — Dr Hamid MADANI <drmdh@msn.com>
|