@quantabit/rbac-sdk 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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/index.cjs +686 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.esm.js +663 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +90 -0
- package/types/index.d.ts +109 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sdkConfig = require('@quantabit/sdk-config');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RBAC SDK - API 客户端
|
|
8
|
+
* 基于角色的访问控制系统后端接口封装
|
|
9
|
+
*
|
|
10
|
+
* 使用 BaseApiClient 基类简化代码
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* RBAC API 客户端
|
|
16
|
+
*/
|
|
17
|
+
class RbacApiClient extends sdkConfig.BaseApiClient {
|
|
18
|
+
constructor(config = {}) {
|
|
19
|
+
super('/rbac', config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ============ 权限检查 ============
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 检查权限
|
|
26
|
+
* @param {string} permission - 权限标识
|
|
27
|
+
* @param {Object} context - 上下文
|
|
28
|
+
*/
|
|
29
|
+
async checkPermission(permission, context = {}) {
|
|
30
|
+
return this.post('/check', {
|
|
31
|
+
permission,
|
|
32
|
+
...context
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 批量检查权限
|
|
38
|
+
* @param {string[]} permissions - 权限标识列表
|
|
39
|
+
* @param {Object} context - 上下文
|
|
40
|
+
*/
|
|
41
|
+
async batchCheckPermissions(permissions, context = {}) {
|
|
42
|
+
return this.post('/check/batch', {
|
|
43
|
+
permissions,
|
|
44
|
+
...context
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 获取我的权限
|
|
50
|
+
*/
|
|
51
|
+
async getMyPermissions() {
|
|
52
|
+
return this.get('/my/permissions');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 获取我的角色
|
|
57
|
+
*/
|
|
58
|
+
async getMyRoles() {
|
|
59
|
+
return this.get('/my/roles');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ============ 角色管理 ============
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 获取角色列表
|
|
66
|
+
* @param {Object} params - 查询参数
|
|
67
|
+
*/
|
|
68
|
+
async getRoles(params = {}) {
|
|
69
|
+
return this.get('/roles', params);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 获取角色详情
|
|
74
|
+
* @param {string} roleId - 角色 ID
|
|
75
|
+
*/
|
|
76
|
+
async getRole(roleId) {
|
|
77
|
+
return this.get(`/roles/${roleId}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 创建角色
|
|
82
|
+
* @param {Object} role - 角色数据
|
|
83
|
+
*/
|
|
84
|
+
async createRole(role) {
|
|
85
|
+
return this.post('/roles', role);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 更新角色
|
|
90
|
+
* @param {string} roleId - 角色 ID
|
|
91
|
+
* @param {Object} updates - 更新数据
|
|
92
|
+
*/
|
|
93
|
+
async updateRole(roleId, updates) {
|
|
94
|
+
return this.put(`/roles/${roleId}`, updates);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 删除角色
|
|
99
|
+
* @param {string} roleId - 角色 ID
|
|
100
|
+
*/
|
|
101
|
+
async deleteRole(roleId) {
|
|
102
|
+
return this.delete(`/roles/${roleId}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 获取角色权限
|
|
107
|
+
* @param {string} roleId - 角色 ID
|
|
108
|
+
*/
|
|
109
|
+
async getRolePermissions(roleId) {
|
|
110
|
+
return this.get(`/roles/${roleId}/permissions`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 设置角色权限
|
|
115
|
+
* @param {string} roleId - 角色 ID
|
|
116
|
+
* @param {string[]} permissions - 权限列表
|
|
117
|
+
*/
|
|
118
|
+
async setRolePermissions(roleId, permissions) {
|
|
119
|
+
return this.put(`/roles/${roleId}/permissions`, {
|
|
120
|
+
permissions
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ============ 用户角色 ============
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 获取用户角色
|
|
128
|
+
* @param {string} userId - 用户 ID
|
|
129
|
+
*/
|
|
130
|
+
async getUserRoles(userId) {
|
|
131
|
+
return this.get(`/users/${userId}/roles`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 分配用户角色
|
|
136
|
+
* @param {string} userId - 用户 ID
|
|
137
|
+
* @param {string[]} roleIds - 角色 ID 列表
|
|
138
|
+
*/
|
|
139
|
+
async assignRoles(userId, roleIds) {
|
|
140
|
+
return this.post(`/users/${userId}/roles`, {
|
|
141
|
+
role_ids: roleIds
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 分配单个用户角色(兼容快捷导出命名)
|
|
147
|
+
* @param {string} userId - 用户 ID
|
|
148
|
+
* @param {string} roleId - 角色 ID
|
|
149
|
+
*/
|
|
150
|
+
async assignRole(userId, roleId) {
|
|
151
|
+
return this.assignRoles(userId, [roleId]);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 移除用户角色
|
|
156
|
+
* @param {string} userId - 用户 ID
|
|
157
|
+
* @param {string[]} roleIds - 角色 ID 列表
|
|
158
|
+
*/
|
|
159
|
+
async removeRoles(userId, roleIds) {
|
|
160
|
+
return this.delete(`/users/${userId}/roles`, {
|
|
161
|
+
role_ids: roleIds
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 获取角色用户
|
|
167
|
+
* @param {string} roleId - 角色 ID
|
|
168
|
+
* @param {Object} params - 查询参数
|
|
169
|
+
*/
|
|
170
|
+
async getRoleUsers(roleId, params = {}) {
|
|
171
|
+
return this.get(`/roles/${roleId}/users`, params);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ============ 权限管理 ============
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 获取权限列表
|
|
178
|
+
* @param {Object} params - 查询参数
|
|
179
|
+
*/
|
|
180
|
+
async getPermissions(params = {}) {
|
|
181
|
+
return this.get('/permissions', params);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* 获取权限详情
|
|
186
|
+
* @param {string} permissionId - 权限 ID
|
|
187
|
+
*/
|
|
188
|
+
async getPermission(permissionId) {
|
|
189
|
+
return this.get(`/permissions/${permissionId}`);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* 创建权限
|
|
194
|
+
* @param {Object} permission - 权限数据
|
|
195
|
+
*/
|
|
196
|
+
async createPermission(permission) {
|
|
197
|
+
return this.post('/permissions', permission);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 更新权限
|
|
202
|
+
* @param {string} permissionId - 权限 ID
|
|
203
|
+
* @param {Object} updates - 更新数据
|
|
204
|
+
*/
|
|
205
|
+
async updatePermission(permissionId, updates) {
|
|
206
|
+
return this.put(`/permissions/${permissionId}`, updates);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 删除权限
|
|
211
|
+
* @param {string} permissionId - 权限 ID
|
|
212
|
+
*/
|
|
213
|
+
async deletePermission(permissionId) {
|
|
214
|
+
return this.delete(`/permissions/${permissionId}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ============ 资源控制 ============
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* 获取资源列表
|
|
221
|
+
*/
|
|
222
|
+
async getResources() {
|
|
223
|
+
return this.get('/resources');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* 获取资源权限
|
|
228
|
+
* @param {string} resourceType - 资源类型
|
|
229
|
+
* @param {string} resourceId - 资源 ID
|
|
230
|
+
*/
|
|
231
|
+
async getResourcePermissions(resourceType, resourceId) {
|
|
232
|
+
return this.get(`/resources/${resourceType}/${resourceId}/permissions`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 设置资源权限
|
|
237
|
+
* @param {string} resourceType - 资源类型
|
|
238
|
+
* @param {string} resourceId - 资源 ID
|
|
239
|
+
* @param {Object} permissions - 权限配置
|
|
240
|
+
*/
|
|
241
|
+
async setResourcePermissions(resourceType, resourceId, permissions) {
|
|
242
|
+
return this.put(`/resources/${resourceType}/${resourceId}/permissions`, permissions);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// 创建默认实例
|
|
247
|
+
const rbacApi = new RbacApiClient();
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* RBAC SDK - 类型定义
|
|
251
|
+
*/
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
// 资源类型
|
|
255
|
+
const ResourceType = {
|
|
256
|
+
API: 'api',
|
|
257
|
+
PAGE: 'page',
|
|
258
|
+
MENU: 'menu',
|
|
259
|
+
BUTTON: 'button',
|
|
260
|
+
DATA: 'data',
|
|
261
|
+
FILE: 'file'
|
|
262
|
+
};
|
|
263
|
+
const PermissionEffect = {};
|
|
264
|
+
const ActionType = {};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* RBAC SDK - 多语言支持
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
const messages = {
|
|
271
|
+
en: {
|
|
272
|
+
rbac: 'Access Control',
|
|
273
|
+
roles: 'Roles',
|
|
274
|
+
role: 'Role',
|
|
275
|
+
permissions: 'Permissions',
|
|
276
|
+
permission: 'Permission',
|
|
277
|
+
users: 'Users',
|
|
278
|
+
createRole: 'Create Role',
|
|
279
|
+
editRole: 'Edit Role',
|
|
280
|
+
deleteRole: 'Delete Role',
|
|
281
|
+
roleName: 'Role Name',
|
|
282
|
+
roleDescription: 'Description',
|
|
283
|
+
assignRole: 'Assign Role',
|
|
284
|
+
revokeRole: 'Revoke',
|
|
285
|
+
resource: 'Resource',
|
|
286
|
+
action: 'Action',
|
|
287
|
+
effect: 'Effect',
|
|
288
|
+
allow: 'Allow',
|
|
289
|
+
deny: 'Deny',
|
|
290
|
+
read: 'Read',
|
|
291
|
+
write: 'Write',
|
|
292
|
+
delete: 'Delete',
|
|
293
|
+
admin: 'Admin',
|
|
294
|
+
create: 'Create',
|
|
295
|
+
update: 'Update',
|
|
296
|
+
assignedUsers: 'Assigned Users',
|
|
297
|
+
permissionCount: 'Permissions',
|
|
298
|
+
loading: 'Loading...',
|
|
299
|
+
noData: 'No data',
|
|
300
|
+
save: 'Save',
|
|
301
|
+
cancel: 'Cancel'
|
|
302
|
+
},
|
|
303
|
+
zh: {
|
|
304
|
+
rbac: '访问控制',
|
|
305
|
+
roles: '角色',
|
|
306
|
+
role: '角色',
|
|
307
|
+
permissions: '权限',
|
|
308
|
+
permission: '权限',
|
|
309
|
+
users: '用户',
|
|
310
|
+
createRole: '创建角色',
|
|
311
|
+
editRole: '编辑角色',
|
|
312
|
+
deleteRole: '删除角色',
|
|
313
|
+
roleName: '角色名称',
|
|
314
|
+
roleDescription: '描述',
|
|
315
|
+
assignRole: '分配角色',
|
|
316
|
+
revokeRole: '撤销',
|
|
317
|
+
resource: '资源',
|
|
318
|
+
action: '操作',
|
|
319
|
+
effect: '效果',
|
|
320
|
+
allow: '允许',
|
|
321
|
+
deny: '拒绝',
|
|
322
|
+
read: '读取',
|
|
323
|
+
write: '写入',
|
|
324
|
+
delete: '删除',
|
|
325
|
+
admin: '管理',
|
|
326
|
+
create: '创建',
|
|
327
|
+
update: '更新',
|
|
328
|
+
assignedUsers: '已分配用户',
|
|
329
|
+
permissionCount: '权限数',
|
|
330
|
+
loading: '加载中...',
|
|
331
|
+
noData: '暂无数据',
|
|
332
|
+
save: '保存',
|
|
333
|
+
cancel: '取消'
|
|
334
|
+
},
|
|
335
|
+
ja: {
|
|
336
|
+
rbac: 'アクセス制御',
|
|
337
|
+
roles: 'ロール',
|
|
338
|
+
role: 'ロール',
|
|
339
|
+
permissions: '権限',
|
|
340
|
+
permission: '権限',
|
|
341
|
+
users: 'ユーザー',
|
|
342
|
+
createRole: 'ロールの作成',
|
|
343
|
+
editRole: 'ロールの編集',
|
|
344
|
+
deleteRole: 'ロールの削除',
|
|
345
|
+
roleName: 'ロール名',
|
|
346
|
+
roleDescription: '説明',
|
|
347
|
+
assignRole: 'ロールの割り当て',
|
|
348
|
+
revokeRole: '取り消し',
|
|
349
|
+
resource: 'リソース',
|
|
350
|
+
action: 'アクション',
|
|
351
|
+
effect: '効果',
|
|
352
|
+
allow: '許可',
|
|
353
|
+
deny: '拒否',
|
|
354
|
+
read: '読み取り',
|
|
355
|
+
write: '書き込み',
|
|
356
|
+
delete: '削除',
|
|
357
|
+
admin: '管理',
|
|
358
|
+
create: '作成',
|
|
359
|
+
update: '更新',
|
|
360
|
+
assignedUsers: '割り当て済みユーザー',
|
|
361
|
+
permissionCount: '権限数',
|
|
362
|
+
loading: '読み込み中...',
|
|
363
|
+
noData: 'データなし',
|
|
364
|
+
save: '保存',
|
|
365
|
+
cancel: 'キャンセル'
|
|
366
|
+
},
|
|
367
|
+
ko: {
|
|
368
|
+
rbac: '접근 제어',
|
|
369
|
+
roles: '역할',
|
|
370
|
+
role: '역할',
|
|
371
|
+
permissions: '권한',
|
|
372
|
+
permission: '권한',
|
|
373
|
+
users: '사용자',
|
|
374
|
+
createRole: '역할 생성',
|
|
375
|
+
editRole: '역할 편집',
|
|
376
|
+
deleteRole: '역할 삭제',
|
|
377
|
+
roleName: '역할 이름',
|
|
378
|
+
roleDescription: '설명',
|
|
379
|
+
assignRole: '역할 할당',
|
|
380
|
+
revokeRole: '철회',
|
|
381
|
+
resource: '리소스',
|
|
382
|
+
action: '작업',
|
|
383
|
+
effect: '효과',
|
|
384
|
+
allow: '허용',
|
|
385
|
+
deny: '거부',
|
|
386
|
+
read: '읽기',
|
|
387
|
+
write: '쓰기',
|
|
388
|
+
delete: '삭제',
|
|
389
|
+
admin: '관리',
|
|
390
|
+
create: '생성',
|
|
391
|
+
update: '업데이트',
|
|
392
|
+
assignedUsers: '할당된 사용자',
|
|
393
|
+
permissionCount: '권한 수',
|
|
394
|
+
loading: '로딩 중...',
|
|
395
|
+
noData: '데이터 없음',
|
|
396
|
+
save: '저장',
|
|
397
|
+
cancel: '취소'
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
const SUPPORTED_LANGUAGES = ['en', 'zh', 'ja', 'ko'];
|
|
401
|
+
let currentLanguage = 'zh';
|
|
402
|
+
function setLanguage(lang) {
|
|
403
|
+
if (SUPPORTED_LANGUAGES.includes(lang)) currentLanguage = lang;
|
|
404
|
+
}
|
|
405
|
+
function getLanguage() {
|
|
406
|
+
return currentLanguage;
|
|
407
|
+
}
|
|
408
|
+
function t(key) {
|
|
409
|
+
return (messages[currentLanguage] || messages.en)[key] || key;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* RBAC SDK - React Hooks
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
function useRoles(options = {}) {
|
|
417
|
+
const [roles, setRoles] = React.useState([]);
|
|
418
|
+
const [loading, setLoading] = React.useState(true);
|
|
419
|
+
const [error, setError] = React.useState(null);
|
|
420
|
+
const fetch = React.useCallback(async () => {
|
|
421
|
+
setLoading(true);
|
|
422
|
+
try {
|
|
423
|
+
const result = await rbacApi.getRoles(options);
|
|
424
|
+
setRoles(result.items || result);
|
|
425
|
+
setError(null);
|
|
426
|
+
} catch (err) {
|
|
427
|
+
setError(err);
|
|
428
|
+
} finally {
|
|
429
|
+
setLoading(false);
|
|
430
|
+
}
|
|
431
|
+
}, [JSON.stringify(options)]);
|
|
432
|
+
React.useEffect(() => {
|
|
433
|
+
fetch();
|
|
434
|
+
}, [fetch]);
|
|
435
|
+
return {
|
|
436
|
+
roles,
|
|
437
|
+
loading,
|
|
438
|
+
error,
|
|
439
|
+
refresh: fetch
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function usePermissions(options = {}) {
|
|
443
|
+
const [permissions, setPermissions] = React.useState([]);
|
|
444
|
+
const [loading, setLoading] = React.useState(true);
|
|
445
|
+
const [error, setError] = React.useState(null);
|
|
446
|
+
const fetch = React.useCallback(async () => {
|
|
447
|
+
setLoading(true);
|
|
448
|
+
try {
|
|
449
|
+
const result = await rbacApi.getPermissions(options);
|
|
450
|
+
setPermissions(result.items || result);
|
|
451
|
+
setError(null);
|
|
452
|
+
} catch (err) {
|
|
453
|
+
setError(err);
|
|
454
|
+
} finally {
|
|
455
|
+
setLoading(false);
|
|
456
|
+
}
|
|
457
|
+
}, [JSON.stringify(options)]);
|
|
458
|
+
React.useEffect(() => {
|
|
459
|
+
fetch();
|
|
460
|
+
}, [fetch]);
|
|
461
|
+
return {
|
|
462
|
+
permissions,
|
|
463
|
+
loading,
|
|
464
|
+
error,
|
|
465
|
+
refresh: fetch
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
function useUserRoles(userId) {
|
|
469
|
+
const [roles, setRoles] = React.useState([]);
|
|
470
|
+
const [loading, setLoading] = React.useState(true);
|
|
471
|
+
const fetch = React.useCallback(async () => {
|
|
472
|
+
if (!userId) return;
|
|
473
|
+
setLoading(true);
|
|
474
|
+
try {
|
|
475
|
+
const result = await rbacApi.getUserRoles(userId);
|
|
476
|
+
setRoles(result.items || result);
|
|
477
|
+
} catch (err) {
|
|
478
|
+
console.error(err);
|
|
479
|
+
} finally {
|
|
480
|
+
setLoading(false);
|
|
481
|
+
}
|
|
482
|
+
}, [userId]);
|
|
483
|
+
React.useEffect(() => {
|
|
484
|
+
fetch();
|
|
485
|
+
}, [fetch]);
|
|
486
|
+
return {
|
|
487
|
+
roles,
|
|
488
|
+
loading,
|
|
489
|
+
refresh: fetch
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
function useRbacActions() {
|
|
493
|
+
const [loading, setLoading] = React.useState(false);
|
|
494
|
+
const assignRole = React.useCallback(async (userId, roleId) => {
|
|
495
|
+
setLoading(true);
|
|
496
|
+
try {
|
|
497
|
+
return await rbacApi.assignRole(userId, roleId);
|
|
498
|
+
} finally {
|
|
499
|
+
setLoading(false);
|
|
500
|
+
}
|
|
501
|
+
}, []);
|
|
502
|
+
const revokeRole = React.useCallback(async (userId, roleId) => {
|
|
503
|
+
setLoading(true);
|
|
504
|
+
try {
|
|
505
|
+
await rbacApi.revokeRole(userId, roleId);
|
|
506
|
+
} finally {
|
|
507
|
+
setLoading(false);
|
|
508
|
+
}
|
|
509
|
+
}, []);
|
|
510
|
+
const checkPermission = React.useCallback(async (userId, resource, action) => {
|
|
511
|
+
try {
|
|
512
|
+
return await rbacApi.checkPermission(userId, resource, action);
|
|
513
|
+
} catch {
|
|
514
|
+
return {
|
|
515
|
+
allowed: false
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
}, []);
|
|
519
|
+
return {
|
|
520
|
+
assignRole,
|
|
521
|
+
revokeRole,
|
|
522
|
+
checkPermission,
|
|
523
|
+
loading
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* RBAC SDK - 权限组件
|
|
529
|
+
*/
|
|
530
|
+
|
|
531
|
+
const roleIcons = {
|
|
532
|
+
admin: '👑',
|
|
533
|
+
moderator: '🛡️',
|
|
534
|
+
user: '👤',
|
|
535
|
+
guest: '🚪'
|
|
536
|
+
};
|
|
537
|
+
function PermissionTag({
|
|
538
|
+
permission,
|
|
539
|
+
effect = 'allow'
|
|
540
|
+
}) {
|
|
541
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
542
|
+
className: `rbac-permission-tag ${effect}`
|
|
543
|
+
}, effect === 'allow' ? '✓' : '✗', " ", permission);
|
|
544
|
+
}
|
|
545
|
+
function RoleCard({
|
|
546
|
+
role,
|
|
547
|
+
onClick,
|
|
548
|
+
onEdit,
|
|
549
|
+
onDelete
|
|
550
|
+
}) {
|
|
551
|
+
const icon = roleIcons[role.name?.toLowerCase()] || '🔐';
|
|
552
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
553
|
+
className: "rbac-role-card",
|
|
554
|
+
onClick: () => onClick?.(role),
|
|
555
|
+
style: {
|
|
556
|
+
cursor: onClick ? 'pointer' : 'default'
|
|
557
|
+
}
|
|
558
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
559
|
+
className: "rbac-role-name"
|
|
560
|
+
}, icon, " ", role.name), /*#__PURE__*/React.createElement("div", {
|
|
561
|
+
className: "rbac-role-desc"
|
|
562
|
+
}, role.description || '-'), /*#__PURE__*/React.createElement("div", {
|
|
563
|
+
className: "rbac-role-meta"
|
|
564
|
+
}, /*#__PURE__*/React.createElement("span", null, role.permission_count || role.permissions?.length || 0, " ", t('permissionCount')), /*#__PURE__*/React.createElement("span", null, role.user_count || 0, " ", t('users'))), (onEdit || onDelete) && /*#__PURE__*/React.createElement("div", {
|
|
565
|
+
style: {
|
|
566
|
+
display: 'flex',
|
|
567
|
+
gap: '8px',
|
|
568
|
+
marginTop: '12px'
|
|
569
|
+
}
|
|
570
|
+
}, onEdit && /*#__PURE__*/React.createElement("button", {
|
|
571
|
+
className: "rbac-btn rbac-btn-outline",
|
|
572
|
+
style: {
|
|
573
|
+
padding: '4px 10px',
|
|
574
|
+
fontSize: '12px'
|
|
575
|
+
},
|
|
576
|
+
onClick: e => {
|
|
577
|
+
e.stopPropagation();
|
|
578
|
+
onEdit(role);
|
|
579
|
+
}
|
|
580
|
+
}, t('editRole')), onDelete && /*#__PURE__*/React.createElement("button", {
|
|
581
|
+
className: "rbac-btn rbac-btn-outline",
|
|
582
|
+
style: {
|
|
583
|
+
padding: '4px 10px',
|
|
584
|
+
fontSize: '12px',
|
|
585
|
+
color: '#ef4444'
|
|
586
|
+
},
|
|
587
|
+
onClick: e => {
|
|
588
|
+
e.stopPropagation();
|
|
589
|
+
onDelete(role.id);
|
|
590
|
+
}
|
|
591
|
+
}, t('deleteRole'))));
|
|
592
|
+
}
|
|
593
|
+
function RoleGrid({
|
|
594
|
+
roles = [],
|
|
595
|
+
loading = false,
|
|
596
|
+
onClick,
|
|
597
|
+
onEdit,
|
|
598
|
+
onDelete,
|
|
599
|
+
onCreate,
|
|
600
|
+
className = ''
|
|
601
|
+
}) {
|
|
602
|
+
if (loading) return /*#__PURE__*/React.createElement("div", {
|
|
603
|
+
className: `rbac-card ${className}`
|
|
604
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
605
|
+
className: "rbac-loading"
|
|
606
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
607
|
+
className: "rbac-spinner"
|
|
608
|
+
})));
|
|
609
|
+
if (roles.length === 0) return /*#__PURE__*/React.createElement("div", {
|
|
610
|
+
className: `rbac-card ${className}`
|
|
611
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
612
|
+
className: "rbac-empty"
|
|
613
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
614
|
+
style: {
|
|
615
|
+
fontSize: '48px',
|
|
616
|
+
marginBottom: '16px'
|
|
617
|
+
}
|
|
618
|
+
}, "\uD83D\uDD10"), /*#__PURE__*/React.createElement("div", null, t('noData')), onCreate && /*#__PURE__*/React.createElement("button", {
|
|
619
|
+
className: "rbac-btn rbac-btn-primary",
|
|
620
|
+
onClick: onCreate,
|
|
621
|
+
style: {
|
|
622
|
+
marginTop: '16px'
|
|
623
|
+
}
|
|
624
|
+
}, t('createRole'))));
|
|
625
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
626
|
+
className: `rbac-card ${className}`,
|
|
627
|
+
style: {
|
|
628
|
+
padding: 0
|
|
629
|
+
}
|
|
630
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
631
|
+
className: "rbac-role-grid"
|
|
632
|
+
}, roles.map(role => /*#__PURE__*/React.createElement(RoleCard, {
|
|
633
|
+
key: role.id,
|
|
634
|
+
role: role,
|
|
635
|
+
onClick: onClick,
|
|
636
|
+
onEdit: onEdit,
|
|
637
|
+
onDelete: onDelete
|
|
638
|
+
}))));
|
|
639
|
+
}
|
|
640
|
+
function PermissionList({
|
|
641
|
+
permissions = [],
|
|
642
|
+
className = ''
|
|
643
|
+
}) {
|
|
644
|
+
if (permissions.length === 0) return null;
|
|
645
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
646
|
+
className: `rbac-permission-list ${className}`
|
|
647
|
+
}, permissions.map((p, i) => /*#__PURE__*/React.createElement(PermissionTag, {
|
|
648
|
+
key: i,
|
|
649
|
+
permission: `${p.resource}:${p.action}`,
|
|
650
|
+
effect: p.effect
|
|
651
|
+
})));
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* @quantabit/rbac-sdk
|
|
656
|
+
* RBAC SDK - Full Version
|
|
657
|
+
*/
|
|
658
|
+
|
|
659
|
+
const getRoles = (...args) => rbacApi.getRoles(...args);
|
|
660
|
+
const getPermissions = (...args) => rbacApi.getPermissions(...args);
|
|
661
|
+
const assignRole = (userId, roleId) => rbacApi.assignRoles(userId, Array.isArray(roleId) ? roleId : [roleId]);
|
|
662
|
+
const checkPermission = (...args) => rbacApi.checkPermission(...args);
|
|
663
|
+
|
|
664
|
+
exports.ActionType = ActionType;
|
|
665
|
+
exports.PermissionEffect = PermissionEffect;
|
|
666
|
+
exports.PermissionList = PermissionList;
|
|
667
|
+
exports.PermissionTag = PermissionTag;
|
|
668
|
+
exports.RbacApiClient = RbacApiClient;
|
|
669
|
+
exports.ResourceType = ResourceType;
|
|
670
|
+
exports.RoleCard = RoleCard;
|
|
671
|
+
exports.RoleGrid = RoleGrid;
|
|
672
|
+
exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
|
|
673
|
+
exports.assignRole = assignRole;
|
|
674
|
+
exports.checkPermission = checkPermission;
|
|
675
|
+
exports.getLanguage = getLanguage;
|
|
676
|
+
exports.getPermissions = getPermissions;
|
|
677
|
+
exports.getRoles = getRoles;
|
|
678
|
+
exports.messages = messages;
|
|
679
|
+
exports.rbacApi = rbacApi;
|
|
680
|
+
exports.setLanguage = setLanguage;
|
|
681
|
+
exports.t = t;
|
|
682
|
+
exports.usePermissions = usePermissions;
|
|
683
|
+
exports.useRbacActions = useRbacActions;
|
|
684
|
+
exports.useRoles = useRoles;
|
|
685
|
+
exports.useUserRoles = useUserRoles;
|
|
686
|
+
//# sourceMappingURL=index.cjs.map
|