rbac-manager 0.0.0-stage → 1.0.1
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/.github/workflows/ci.yml +36 -0
- package/.github/workflows/publish.yml +60 -0
- package/README.md +317 -2
- package/package.json +49 -4
- package/scripts/postbuild.js +17 -0
- package/src/config/rbac.config.ts +206 -0
- package/src/constants/actions.constants.ts +21 -0
- package/src/constants/apiKeys.constants.ts +25 -0
- package/src/constants/auth.constants.ts +39 -0
- package/src/constants/endpoints.constants.ts +66 -0
- package/src/constants/i18n.constants.ts +82 -0
- package/src/constants/index.ts +70 -0
- package/src/constants/masters.constants.ts +68 -0
- package/src/constants/permissions/index.ts +44 -0
- package/src/constants/permissions/masterPermissions.constants.ts +44 -0
- package/src/constants/permissions/rolePermissions.constants.ts +18 -0
- package/src/constants/permissions.constants.ts +34 -0
- package/src/constants/roles.constants.ts +34 -0
- package/src/core/adapters/authAdapter.ts +89 -0
- package/src/core/adapters/index.ts +17 -0
- package/src/core/adapters/mastersAdapter.ts +132 -0
- package/src/core/adapters/permissionsAdapter.ts +90 -0
- package/src/core/adapters/rolesAdapter.ts +115 -0
- package/src/core/api/httpClient.ts +296 -0
- package/src/core/context/PermissionContext.tsx +232 -0
- package/src/core/context/RBACConfigContext.tsx +52 -0
- package/src/core/guards/Can.tsx +98 -0
- package/src/core/guards/RouteGuard.tsx +42 -0
- package/src/core/hooks/useMaster.ts +99 -0
- package/src/core/hooks/usePermissions.ts +114 -0
- package/src/core/hooks/useRoles.ts +120 -0
- package/src/core/types/adapter.types.ts +54 -0
- package/src/core/types/auth.types.ts +44 -0
- package/src/core/types/index.ts +7 -0
- package/src/core/types/masters.types.ts +63 -0
- package/src/core/types/pagination.types.ts +37 -0
- package/src/core/types/rbac.types.ts +69 -0
- package/src/core/types/router.types.ts +43 -0
- package/src/core/types/style.types.ts +53 -0
- package/src/core/utils/permissionResolver.ts +44 -0
- package/src/index.ts +44 -0
- package/src/modules/masters/DepartmentMasterView.tsx +126 -0
- package/src/modules/masters/DesignationMasterView.tsx +97 -0
- package/src/modules/masters/EmployeeMasterView.tsx +107 -0
- package/src/modules/masters/EntityMasterView.tsx +102 -0
- package/src/modules/masters/ModuleMasterView.tsx +104 -0
- package/src/modules/masters/SubModuleMasterView.tsx +106 -0
- package/src/modules/masters/components/MasterDataTable.tsx +684 -0
- package/src/modules/masters/index.ts +7 -0
- package/src/modules/roles-and-permissions/components/PermissionMatrix.tsx +289 -0
- package/src/modules/roles-and-permissions/components/PermissionRegistry.tsx +108 -0
- package/src/modules/roles-and-permissions/components/RoleListTable.tsx +568 -0
- package/src/modules/roles-and-permissions/components/RoleModal.tsx +213 -0
- package/src/modules/roles-and-permissions/index.ts +4 -0
- package/src/shared/components/Badge.tsx +24 -0
- package/src/shared/components/Button.tsx +75 -0
- package/src/shared/components/DynamicSidebar.tsx +181 -0
- package/src/shared/components/Input.tsx +48 -0
- package/src/shared/components/Modal.tsx +70 -0
- package/src/shared/components/Table.tsx +345 -0
- package/src/styles/standalone.css +51 -0
- package/src/theme/ThemeContext.tsx +74 -0
- package/src/theme/defaultTheme.ts +81 -0
- package/src/theme/index.ts +3 -0
- package/src/theme/theme.types.ts +106 -0
- package/tsconfig.cjs.json +10 -0
- package/tsconfig.esm.json +10 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action keys, IDs, and human-readable labels.
|
|
3
|
+
* Used for the Permission Matrix and Permission Gates.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_ACTION_KEYS = {
|
|
6
|
+
VIEW: 'view',
|
|
7
|
+
ADD: 'add',
|
|
8
|
+
EDIT: 'edit',
|
|
9
|
+
DELETE: 'delete',
|
|
10
|
+
ASSIGN: 'assign',
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export const DEFAULT_ACTION_CONFIGS = [
|
|
14
|
+
{ actionId: 1, action_key: DEFAULT_ACTION_KEYS.VIEW, action_name: 'View', sort_order: 1 },
|
|
15
|
+
{ actionId: 2, action_key: DEFAULT_ACTION_KEYS.ADD, action_name: 'Add (Create)', sort_order: 2 },
|
|
16
|
+
{ actionId: 3, action_key: DEFAULT_ACTION_KEYS.EDIT, action_name: 'Edit', sort_order: 3 },
|
|
17
|
+
{ actionId: 4, action_key: DEFAULT_ACTION_KEYS.DELETE, action_name: 'Delete', sort_order: 4 },
|
|
18
|
+
{ actionId: 5, action_key: DEFAULT_ACTION_KEYS.ASSIGN, action_name: 'Assign', sort_order: 5 },
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
export type ActionKey = (typeof DEFAULT_ACTION_KEYS)[keyof typeof DEFAULT_ACTION_KEYS] | string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global API response and pagination field keys.
|
|
3
|
+
* If your backend wraps responses in different keys (e.g. `items` instead of `list`),
|
|
4
|
+
* change it here or pass overrides via RBACConfig.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_API_RESPONSE_KEYS = {
|
|
7
|
+
SUCCESS: 'success',
|
|
8
|
+
STATUS_CODE: 'statusCode',
|
|
9
|
+
MESSAGE: 'message',
|
|
10
|
+
DATA: 'data',
|
|
11
|
+
ERROR: 'error',
|
|
12
|
+
ERRORS: 'errors',
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_PAGINATION_KEYS = {
|
|
16
|
+
PAGE: 'page',
|
|
17
|
+
LIMIT: 'limit',
|
|
18
|
+
TOTAL: 'total',
|
|
19
|
+
TOTAL_PAGES: 'totalPages',
|
|
20
|
+
HAS_NEXT: 'hasNext',
|
|
21
|
+
ITEMS: 'list', // container API returns `list` or direct array
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export type ApiResponseKeys = typeof DEFAULT_API_RESPONSE_KEYS;
|
|
25
|
+
export type PaginationKeys = typeof DEFAULT_PAGINATION_KEYS;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field keys for Auth, Login, and User Profile (/auth/me) responses.
|
|
3
|
+
* Never hardcode field names in components or adapters.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_AUTH_KEYS = {
|
|
6
|
+
// Login response fields
|
|
7
|
+
USER_CONTAINER: 'user',
|
|
8
|
+
TOKEN: 'token',
|
|
9
|
+
ACCESS_TOKEN: 'accessToken',
|
|
10
|
+
SESSION_ID: 'sessionId',
|
|
11
|
+
|
|
12
|
+
// User entity fields
|
|
13
|
+
USER_ID: 'id',
|
|
14
|
+
EMPLOYEE_USER_ID: 'employeeUserId',
|
|
15
|
+
EMAIL: 'email',
|
|
16
|
+
FIRST_NAME: 'firstName',
|
|
17
|
+
LAST_NAME: 'lastName',
|
|
18
|
+
FULL_NAME: 'name',
|
|
19
|
+
MOBILE_NUMBER: 'mobile_number',
|
|
20
|
+
IS_MOBILE_VERIFIED: 'is_mobile_number_verified',
|
|
21
|
+
ENTITY_ID: 'entityId',
|
|
22
|
+
DEPARTMENT_ID: 'departmentId',
|
|
23
|
+
|
|
24
|
+
// Role reference inside user
|
|
25
|
+
USER_ROLE: 'role',
|
|
26
|
+
USER_ROLE_ID: 'id',
|
|
27
|
+
USER_ROLE_NAME: 'role_name',
|
|
28
|
+
USER_ROLE_KEY: 'role_key',
|
|
29
|
+
|
|
30
|
+
// Permissions & Navigation inside /auth/me
|
|
31
|
+
PERMISSIONS_ARRAY: 'permissions',
|
|
32
|
+
PERMISSION_KEY: 'permission_key',
|
|
33
|
+
ROUTE_PATH: 'route_path',
|
|
34
|
+
|
|
35
|
+
NAVIGATION_ARRAY: 'navigation',
|
|
36
|
+
MODULES_ARRAY: 'modules',
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
39
|
+
export type AuthKeys = typeof DEFAULT_AUTH_KEYS;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default API route endpoints matching the live container API structure.
|
|
3
|
+
* Override any URL in `rbac.config.ts` without modifying component source code.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_ENDPOINTS = {
|
|
6
|
+
// Auth
|
|
7
|
+
AUTH_LOGIN: '/auth/login',
|
|
8
|
+
AUTH_LOGOUT: '/auth/logout',
|
|
9
|
+
AUTH_ME: '/auth/me',
|
|
10
|
+
|
|
11
|
+
// Roles & Permissions
|
|
12
|
+
ROLES_LIST: '/roles/list',
|
|
13
|
+
ROLES_CREATE: '/roles/create',
|
|
14
|
+
ROLES_DETAILS: '/roles/details/:id',
|
|
15
|
+
ROLES_EDIT: '/roles/edit/:id',
|
|
16
|
+
ROLES_DELETE: '/roles/delete/:id',
|
|
17
|
+
ROLES_GET_PERMISSIONS: '/roles/permissions/:id',
|
|
18
|
+
ROLES_ASSIGN_PERMISSIONS: '/roles/assign-permissions/:id',
|
|
19
|
+
|
|
20
|
+
// Alternate user-panel roles endpoints (if backend uses /user-panel/roles)
|
|
21
|
+
USER_PANEL_ROLES_LIST: '/user-panel/roles/list',
|
|
22
|
+
USER_PANEL_ROLES_CREATE: '/user-panel/roles/create',
|
|
23
|
+
USER_PANEL_ROLES_UPDATE: '/user-panel/roles/update/:id',
|
|
24
|
+
USER_PANEL_ROLES_DELETE: '/user-panel/roles/delete/:id',
|
|
25
|
+
USER_PANEL_ROLES_ASSIGN_PERMISSIONS: '/user-panel/roles/:id/assign-permissions',
|
|
26
|
+
|
|
27
|
+
// Permission Registry & Modules
|
|
28
|
+
PERMISSIONS_ACTIONS: '/permissions/actions',
|
|
29
|
+
PERMISSIONS_REGISTRY: '/permissions/registry',
|
|
30
|
+
PERMISSIONS_MODULES_PARENTS: '/permissions/modules/parents',
|
|
31
|
+
PERMISSIONS_MODULES_SUBMODULES: '/permissions/modules/submodules',
|
|
32
|
+
PERMISSIONS_MODULE_CREATE: '/permissions/modules',
|
|
33
|
+
PERMISSIONS_MODULE_EDIT: '/permissions/modules/:id',
|
|
34
|
+
PERMISSIONS_MODULE_DELETE: '/permissions/modules/:id',
|
|
35
|
+
PERMISSIONS_SETUP_MODULE: '/permissions/setup-module',
|
|
36
|
+
|
|
37
|
+
USER_PANEL_PERMISSION_KEYS: '/user-panel/permissions/keys',
|
|
38
|
+
USER_PANEL_PERMISSION_KEY_REGISTER: '/user-panel/permissions/keys/register',
|
|
39
|
+
USER_PANEL_PERMISSION_MODULES: '/user-panel/permissions/modules',
|
|
40
|
+
|
|
41
|
+
// Masters: Entity
|
|
42
|
+
ENTITY_LIST: '/entity/list',
|
|
43
|
+
ENTITY_CREATE: '/entity/create',
|
|
44
|
+
ENTITY_EDIT: '/entity/edit/:id',
|
|
45
|
+
ENTITY_DELETE: '/entity/delete/:id',
|
|
46
|
+
|
|
47
|
+
// Masters: Department
|
|
48
|
+
DEPARTMENT_LIST: '/department/list',
|
|
49
|
+
DEPARTMENT_CREATE: '/department/create',
|
|
50
|
+
DEPARTMENT_EDIT: '/department/edit/:id',
|
|
51
|
+
DEPARTMENT_DELETE: '/department/delete/:id',
|
|
52
|
+
|
|
53
|
+
// Masters: Designation
|
|
54
|
+
DESIGNATION_LIST: '/designation/list',
|
|
55
|
+
DESIGNATION_CREATE: '/designation/create',
|
|
56
|
+
DESIGNATION_EDIT: '/designation/edit/:id',
|
|
57
|
+
DESIGNATION_DELETE: '/designation/delete/:id',
|
|
58
|
+
|
|
59
|
+
// Masters: Employee
|
|
60
|
+
EMPLOYEE_LIST: '/employee/list',
|
|
61
|
+
EMPLOYEE_CREATE: '/employee/create',
|
|
62
|
+
EMPLOYEE_EDIT: '/employee/edit/:id',
|
|
63
|
+
EMPLOYEE_DELETE: '/employee/delete/:id',
|
|
64
|
+
} as const;
|
|
65
|
+
|
|
66
|
+
export type Endpoints = typeof DEFAULT_ENDPOINTS;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export interface RBACLocaleStrings {
|
|
2
|
+
// Actions
|
|
3
|
+
addNew: string;
|
|
4
|
+
create: string;
|
|
5
|
+
edit: string;
|
|
6
|
+
delete: string;
|
|
7
|
+
saveChanges: string;
|
|
8
|
+
cancel: string;
|
|
9
|
+
confirm: string;
|
|
10
|
+
confirmDelete: string;
|
|
11
|
+
confirmDeleteMessage: string;
|
|
12
|
+
deleteTitle: string;
|
|
13
|
+
permissions: string;
|
|
14
|
+
toggleAll: string;
|
|
15
|
+
actions: string;
|
|
16
|
+
search: string;
|
|
17
|
+
searchPlaceholder: string;
|
|
18
|
+
noData: string;
|
|
19
|
+
loading: string;
|
|
20
|
+
checkingPermissions: string;
|
|
21
|
+
accessDenied: string;
|
|
22
|
+
accessDeniedMessage: string;
|
|
23
|
+
|
|
24
|
+
// Feedback & Notifications
|
|
25
|
+
success: string;
|
|
26
|
+
error: string;
|
|
27
|
+
|
|
28
|
+
// Pagination
|
|
29
|
+
showingEntries: (from: number, to: number, total: number) => string;
|
|
30
|
+
pageOf: (page: number, totalPages: number) => string;
|
|
31
|
+
previous: string;
|
|
32
|
+
next: string;
|
|
33
|
+
|
|
34
|
+
// Batch actions
|
|
35
|
+
selectedCount: (count: number) => string;
|
|
36
|
+
itemsSelected: (count: number) => string;
|
|
37
|
+
selectAll: string;
|
|
38
|
+
clearSelection: string;
|
|
39
|
+
|
|
40
|
+
// Status
|
|
41
|
+
active: string;
|
|
42
|
+
inactive: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const DEFAULT_LOCALE_STRINGS: RBACLocaleStrings = {
|
|
46
|
+
addNew: '+ Add New',
|
|
47
|
+
create: 'Create',
|
|
48
|
+
edit: 'Edit',
|
|
49
|
+
delete: 'Delete',
|
|
50
|
+
saveChanges: 'Save Changes',
|
|
51
|
+
cancel: 'Cancel',
|
|
52
|
+
confirm: 'Confirm',
|
|
53
|
+
confirmDelete: 'Confirm Delete',
|
|
54
|
+
confirmDeleteMessage: 'Are you sure you want to delete this record? This action cannot be undone.',
|
|
55
|
+
deleteTitle: 'Delete Record',
|
|
56
|
+
permissions: 'Permissions',
|
|
57
|
+
toggleAll: 'Toggle All',
|
|
58
|
+
actions: 'Actions',
|
|
59
|
+
search: 'Search',
|
|
60
|
+
searchPlaceholder: 'Search...',
|
|
61
|
+
noData: 'No data available',
|
|
62
|
+
loading: 'Loading...',
|
|
63
|
+
checkingPermissions: 'Checking permissions...',
|
|
64
|
+
accessDenied: 'Access Denied',
|
|
65
|
+
accessDeniedMessage: 'You do not have permission to access this resource.',
|
|
66
|
+
|
|
67
|
+
success: 'Success',
|
|
68
|
+
error: 'Error',
|
|
69
|
+
|
|
70
|
+
showingEntries: (from, to, total) => `Showing ${from} to ${to} of ${total} entries`,
|
|
71
|
+
pageOf: (page, totalPages) => `Page ${page} of ${totalPages}`,
|
|
72
|
+
previous: 'Previous',
|
|
73
|
+
next: 'Next',
|
|
74
|
+
|
|
75
|
+
selectedCount: (count) => `${count} selected`,
|
|
76
|
+
itemsSelected: (count) => `${count} items selected`,
|
|
77
|
+
selectAll: 'Select All',
|
|
78
|
+
clearSelection: 'Clear',
|
|
79
|
+
|
|
80
|
+
active: 'Active',
|
|
81
|
+
inactive: 'Inactive',
|
|
82
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { DEFAULT_API_RESPONSE_KEYS, DEFAULT_PAGINATION_KEYS } from './apiKeys.constants';
|
|
2
|
+
import { DEFAULT_AUTH_KEYS } from './auth.constants';
|
|
3
|
+
import { DEFAULT_ACTION_KEYS, DEFAULT_ACTION_CONFIGS } from './actions.constants';
|
|
4
|
+
import { DEFAULT_ROLE_KEYS } from './roles.constants';
|
|
5
|
+
import { DEFAULT_PERMISSION_KEYS } from './permissions.constants';
|
|
6
|
+
import { DEFAULT_MASTER_KEYS } from './masters.constants';
|
|
7
|
+
import { DEFAULT_ENDPOINTS } from './endpoints.constants';
|
|
8
|
+
import { DEFAULT_LOCALE_STRINGS, RBACLocaleStrings } from './i18n.constants';
|
|
9
|
+
|
|
10
|
+
export * from './apiKeys.constants';
|
|
11
|
+
export * from './auth.constants';
|
|
12
|
+
export * from './actions.constants';
|
|
13
|
+
export * from './roles.constants';
|
|
14
|
+
export * from './permissions.constants';
|
|
15
|
+
export * from './masters.constants';
|
|
16
|
+
export * from './endpoints.constants';
|
|
17
|
+
export * from './i18n.constants';
|
|
18
|
+
|
|
19
|
+
export interface ActionConfigItem {
|
|
20
|
+
actionId: number;
|
|
21
|
+
action_key: string;
|
|
22
|
+
action_name: string;
|
|
23
|
+
sort_order: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Global Constants Container.
|
|
28
|
+
* All adapters and components reference this object instead of raw strings.
|
|
29
|
+
*/
|
|
30
|
+
export const RBAC_CONSTANTS = {
|
|
31
|
+
api: { ...DEFAULT_API_RESPONSE_KEYS },
|
|
32
|
+
pagination: { ...DEFAULT_PAGINATION_KEYS },
|
|
33
|
+
auth: { ...DEFAULT_AUTH_KEYS },
|
|
34
|
+
actions: { ...DEFAULT_ACTION_KEYS },
|
|
35
|
+
actionConfigs: [...DEFAULT_ACTION_CONFIGS] as ActionConfigItem[],
|
|
36
|
+
roles: { ...DEFAULT_ROLE_KEYS },
|
|
37
|
+
permissions: { ...DEFAULT_PERMISSION_KEYS },
|
|
38
|
+
masters: { ...DEFAULT_MASTER_KEYS },
|
|
39
|
+
endpoints: { ...DEFAULT_ENDPOINTS },
|
|
40
|
+
i18n: { ...DEFAULT_LOCALE_STRINGS },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type RBACConstantsRegistry = typeof RBAC_CONSTANTS;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Helper to override keys at runtime or during app initialization.
|
|
47
|
+
*/
|
|
48
|
+
export function configureRBACConstants(overrides: Partial<{
|
|
49
|
+
api: Partial<typeof DEFAULT_API_RESPONSE_KEYS>;
|
|
50
|
+
pagination: Partial<typeof DEFAULT_PAGINATION_KEYS>;
|
|
51
|
+
auth: Partial<typeof DEFAULT_AUTH_KEYS>;
|
|
52
|
+
actions: Partial<typeof DEFAULT_ACTION_KEYS>;
|
|
53
|
+
actionConfigs: ActionConfigItem[];
|
|
54
|
+
roles: Partial<typeof DEFAULT_ROLE_KEYS>;
|
|
55
|
+
permissions: Partial<typeof DEFAULT_PERMISSION_KEYS>;
|
|
56
|
+
masters: Partial<typeof DEFAULT_MASTER_KEYS>;
|
|
57
|
+
endpoints: Partial<typeof DEFAULT_ENDPOINTS>;
|
|
58
|
+
i18n: Partial<RBACLocaleStrings>;
|
|
59
|
+
}>): void {
|
|
60
|
+
if (overrides.api) Object.assign(RBAC_CONSTANTS.api, overrides.api);
|
|
61
|
+
if (overrides.pagination) Object.assign(RBAC_CONSTANTS.pagination, overrides.pagination);
|
|
62
|
+
if (overrides.auth) Object.assign(RBAC_CONSTANTS.auth, overrides.auth);
|
|
63
|
+
if (overrides.actions) Object.assign(RBAC_CONSTANTS.actions, overrides.actions);
|
|
64
|
+
if (overrides.actionConfigs) RBAC_CONSTANTS.actionConfigs = overrides.actionConfigs;
|
|
65
|
+
if (overrides.roles) Object.assign(RBAC_CONSTANTS.roles, overrides.roles);
|
|
66
|
+
if (overrides.permissions) Object.assign(RBAC_CONSTANTS.permissions, overrides.permissions);
|
|
67
|
+
if (overrides.masters) Object.assign(RBAC_CONSTANTS.masters, overrides.masters);
|
|
68
|
+
if (overrides.endpoints) Object.assign(RBAC_CONSTANTS.endpoints, overrides.endpoints);
|
|
69
|
+
if (overrides.i18n) Object.assign(RBAC_CONSTANTS.i18n, overrides.i18n);
|
|
70
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field keys for Masters modules: Entity, Department, Designation, Employee, Module Master, Sub-Module.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_MASTER_KEYS = {
|
|
5
|
+
// Generic master keys
|
|
6
|
+
ID: 'id',
|
|
7
|
+
NAME: 'name',
|
|
8
|
+
DESCRIPTION: 'description',
|
|
9
|
+
IS_ACTIVE: 'is_active',
|
|
10
|
+
IS_DELETED: 'is_deleted',
|
|
11
|
+
CREATED_AT: 'createdAt',
|
|
12
|
+
UPDATED_AT: 'updatedAt',
|
|
13
|
+
|
|
14
|
+
// Entity Master
|
|
15
|
+
ENTITY: {
|
|
16
|
+
ID: 'entityId',
|
|
17
|
+
NAME: 'entity_name',
|
|
18
|
+
CODE: 'entity_code',
|
|
19
|
+
STATE: 'state',
|
|
20
|
+
CITY: 'city',
|
|
21
|
+
PINCODE: 'pincode',
|
|
22
|
+
STATUS: 'status',
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Department Master
|
|
26
|
+
DEPARTMENT: {
|
|
27
|
+
ID: 'departmentId',
|
|
28
|
+
NAME: 'department_name',
|
|
29
|
+
CODE: 'department_code',
|
|
30
|
+
ENTITY_ID: 'entityId',
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// Designation Master
|
|
34
|
+
DESIGNATION: {
|
|
35
|
+
ID: 'designationId',
|
|
36
|
+
NAME: 'designation_name',
|
|
37
|
+
CODE: 'designation_code',
|
|
38
|
+
DEPARTMENT_ID: 'departmentId',
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Employee Master
|
|
42
|
+
EMPLOYEE: {
|
|
43
|
+
ID: 'employeeUserId',
|
|
44
|
+
EMPLOYEE_CODE: 'employee_code',
|
|
45
|
+
FIRST_NAME: 'firstName',
|
|
46
|
+
LAST_NAME: 'lastName',
|
|
47
|
+
EMAIL: 'email',
|
|
48
|
+
MOBILE_NUMBER: 'mobile_number',
|
|
49
|
+
ENTITY_ID: 'entityId',
|
|
50
|
+
DEPARTMENT_ID: 'departmentId',
|
|
51
|
+
DESIGNATION_ID: 'designationId',
|
|
52
|
+
REPORTING_MANAGER_ID: 'reportingManagerId',
|
|
53
|
+
ROLE_ID: 'roleId',
|
|
54
|
+
STATUS: 'status',
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
// Module & Sub-Module Master
|
|
58
|
+
MODULE: {
|
|
59
|
+
ID: 'permissionMasterId',
|
|
60
|
+
NAME: 'name',
|
|
61
|
+
SLUG_NAME: 'slug_name',
|
|
62
|
+
ROUTE_PATH: 'route_path',
|
|
63
|
+
SORT_ORDER: 'sort_order',
|
|
64
|
+
PARENT_ID: 'parentId',
|
|
65
|
+
},
|
|
66
|
+
} as const;
|
|
67
|
+
|
|
68
|
+
export type MasterKeys = typeof DEFAULT_MASTER_KEYS;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { DEFAULT_ROLE_PERMISSIONS } from './rolePermissions.constants';
|
|
2
|
+
import { DEFAULT_MASTER_PERMISSIONS } from './masterPermissions.constants';
|
|
3
|
+
|
|
4
|
+
export * from './rolePermissions.constants';
|
|
5
|
+
export * from './masterPermissions.constants';
|
|
6
|
+
|
|
7
|
+
export const PERMISSION_KEYS = {
|
|
8
|
+
roles: { ...DEFAULT_ROLE_PERMISSIONS },
|
|
9
|
+
masters: {
|
|
10
|
+
entity: { ...DEFAULT_MASTER_PERMISSIONS.entity },
|
|
11
|
+
department: { ...DEFAULT_MASTER_PERMISSIONS.department },
|
|
12
|
+
designation: { ...DEFAULT_MASTER_PERMISSIONS.designation },
|
|
13
|
+
employee: { ...DEFAULT_MASTER_PERMISSIONS.employee },
|
|
14
|
+
moduleMaster: { ...DEFAULT_MASTER_PERMISSIONS.moduleMaster },
|
|
15
|
+
subModuleMaster: { ...DEFAULT_MASTER_PERMISSIONS.subModuleMaster },
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type PermissionKeysContainer = typeof PERMISSION_KEYS;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Configure permission key overrides globally (e.g. if backend uses roles.addition)
|
|
23
|
+
*/
|
|
24
|
+
export function configurePermissionKeys(overrides: Partial<{
|
|
25
|
+
roles: Partial<typeof DEFAULT_ROLE_PERMISSIONS>;
|
|
26
|
+
masters: Partial<{
|
|
27
|
+
entity: Partial<typeof DEFAULT_MASTER_PERMISSIONS.entity>;
|
|
28
|
+
department: Partial<typeof DEFAULT_MASTER_PERMISSIONS.department>;
|
|
29
|
+
designation: Partial<typeof DEFAULT_MASTER_PERMISSIONS.designation>;
|
|
30
|
+
employee: Partial<typeof DEFAULT_MASTER_PERMISSIONS.employee>;
|
|
31
|
+
moduleMaster: Partial<typeof DEFAULT_MASTER_PERMISSIONS.moduleMaster>;
|
|
32
|
+
subModuleMaster: Partial<typeof DEFAULT_MASTER_PERMISSIONS.subModuleMaster>;
|
|
33
|
+
}>;
|
|
34
|
+
}>): void {
|
|
35
|
+
if (overrides.roles) Object.assign(PERMISSION_KEYS.roles, overrides.roles);
|
|
36
|
+
if (overrides.masters) {
|
|
37
|
+
if (overrides.masters.entity) Object.assign(PERMISSION_KEYS.masters.entity, overrides.masters.entity);
|
|
38
|
+
if (overrides.masters.department) Object.assign(PERMISSION_KEYS.masters.department, overrides.masters.department);
|
|
39
|
+
if (overrides.masters.designation) Object.assign(PERMISSION_KEYS.masters.designation, overrides.masters.designation);
|
|
40
|
+
if (overrides.masters.employee) Object.assign(PERMISSION_KEYS.masters.employee, overrides.masters.employee);
|
|
41
|
+
if (overrides.masters.moduleMaster) Object.assign(PERMISSION_KEYS.masters.moduleMaster, overrides.masters.moduleMaster);
|
|
42
|
+
if (overrides.masters.subModuleMaster) Object.assign(PERMISSION_KEYS.masters.subModuleMaster, overrides.masters.subModuleMaster);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission keys for Masters modules: Entity, Department, Designation, Employee, Module, SubModule.
|
|
3
|
+
* Override any module's permission slugs if your backend uses different formats.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_MASTER_PERMISSIONS = {
|
|
6
|
+
entity: {
|
|
7
|
+
VIEW: 'entity_master.view',
|
|
8
|
+
ADD: 'entity_master.add',
|
|
9
|
+
EDIT: 'entity_master.edit',
|
|
10
|
+
DELETE: 'entity_master.delete',
|
|
11
|
+
},
|
|
12
|
+
department: {
|
|
13
|
+
VIEW: 'department_master.view',
|
|
14
|
+
ADD: 'department_master.add',
|
|
15
|
+
EDIT: 'department_master.edit',
|
|
16
|
+
DELETE: 'department_master.delete',
|
|
17
|
+
},
|
|
18
|
+
designation: {
|
|
19
|
+
VIEW: 'designation_master.view',
|
|
20
|
+
ADD: 'designation_master.add',
|
|
21
|
+
EDIT: 'designation_master.edit',
|
|
22
|
+
DELETE: 'designation_master.delete',
|
|
23
|
+
},
|
|
24
|
+
employee: {
|
|
25
|
+
VIEW: 'employee_master.view',
|
|
26
|
+
ADD: 'employee_master.add',
|
|
27
|
+
EDIT: 'employee_master.edit',
|
|
28
|
+
DELETE: 'employee_master.delete',
|
|
29
|
+
},
|
|
30
|
+
moduleMaster: {
|
|
31
|
+
VIEW: 'module_master.view',
|
|
32
|
+
ADD: 'module_master.add',
|
|
33
|
+
EDIT: 'module_master.edit',
|
|
34
|
+
DELETE: 'module_master.delete',
|
|
35
|
+
},
|
|
36
|
+
subModuleMaster: {
|
|
37
|
+
VIEW: 'sub_module_master.view',
|
|
38
|
+
ADD: 'sub_module_master.add',
|
|
39
|
+
EDIT: 'sub_module_master.edit',
|
|
40
|
+
DELETE: 'sub_module_master.delete',
|
|
41
|
+
},
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
export type MasterPermissionKeys = typeof DEFAULT_MASTER_PERMISSIONS;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission keys for Roles & Permissions module.
|
|
3
|
+
* If your backend uses different slugs (e.g. 'roles.addition' or 'roles:create'),
|
|
4
|
+
* override them here or via configureRBACConstants({ permissions: { ... } }).
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_ROLE_PERMISSIONS = {
|
|
7
|
+
VIEW: 'roles.view',
|
|
8
|
+
ADD: 'roles.add',
|
|
9
|
+
EDIT: 'roles.edit',
|
|
10
|
+
DELETE: 'roles.delete',
|
|
11
|
+
ASSIGN: 'roles.assign',
|
|
12
|
+
REGISTRY_VIEW: 'permission.view',
|
|
13
|
+
REGISTRY_ADD: 'permission.add',
|
|
14
|
+
REGISTRY_EDIT: 'permission.edit',
|
|
15
|
+
REGISTRY_DELETE: 'permission.delete',
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
export type RolePermissionKeys = typeof DEFAULT_ROLE_PERMISSIONS;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field keys for Permission Registry, Module Hierarchy, and Permission Actions.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_PERMISSION_KEYS = {
|
|
5
|
+
// Module master
|
|
6
|
+
PERMISSION_MASTER_ID: 'permissionMasterId',
|
|
7
|
+
MODULE_ID: 'id',
|
|
8
|
+
MODULE_NAME: 'name',
|
|
9
|
+
SLUG_NAME: 'slug_name',
|
|
10
|
+
ROUTE_PATH: 'route_path',
|
|
11
|
+
SORT_ORDER: 'sort_order',
|
|
12
|
+
PARENT_ID: 'parentId',
|
|
13
|
+
IS_ACTIVE: 'is_active',
|
|
14
|
+
IS_DELETED: 'is_deleted',
|
|
15
|
+
CHILDREN_ARRAY: 'children',
|
|
16
|
+
SUBMODULES_ARRAY: 'submodules',
|
|
17
|
+
|
|
18
|
+
// Actions on a module
|
|
19
|
+
ACTIONS_ARRAY: 'actions',
|
|
20
|
+
PERMISSION_ACTION_ID: 'permissionActionId',
|
|
21
|
+
ACTION_ID: 'actionId',
|
|
22
|
+
ACTION_DETAILS: 'actionDetails',
|
|
23
|
+
PERMISSION_KEY: 'permission_key',
|
|
24
|
+
ACTION_NAME: 'action_name',
|
|
25
|
+
ACTION_KEY: 'action_key',
|
|
26
|
+
|
|
27
|
+
// Flat permission keys list
|
|
28
|
+
PERMISSION_KEY_ID: 'permissionKeyId',
|
|
29
|
+
NAME: 'name',
|
|
30
|
+
PERMISSION_TYPE: 'permission_type',
|
|
31
|
+
PRODUCT_ID: 'productId',
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
export type PermissionKeys = typeof DEFAULT_PERMISSION_KEYS;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field keys for Role entity, Role list, and Role assignment APIs.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_ROLE_KEYS = {
|
|
5
|
+
// Primary identifier (supports both 'id' and 'roleId')
|
|
6
|
+
ID: 'id',
|
|
7
|
+
ROLE_ID: 'roleId',
|
|
8
|
+
|
|
9
|
+
// Basic info
|
|
10
|
+
ROLE_NAME: 'role_name',
|
|
11
|
+
ROLE_KEY: 'role_key',
|
|
12
|
+
DESCRIPTION: 'description',
|
|
13
|
+
IS_ACTIVE: 'is_active',
|
|
14
|
+
IS_DELETED: 'is_deleted',
|
|
15
|
+
SORT_ORDER: 'sort_order',
|
|
16
|
+
CREATED_AT: 'createdAt',
|
|
17
|
+
UPDATED_AT: 'updatedAt',
|
|
18
|
+
|
|
19
|
+
// Scoping relationships
|
|
20
|
+
ENTITY_ID: 'entityId',
|
|
21
|
+
ENTITY_OBJECT: 'entity',
|
|
22
|
+
ENTITY_NAME: 'entity_name',
|
|
23
|
+
|
|
24
|
+
DEPARTMENT_ID: 'departmentId',
|
|
25
|
+
DEPARTMENT_OBJECT: 'department',
|
|
26
|
+
DEPARTMENT_NAME: 'department_name',
|
|
27
|
+
|
|
28
|
+
// Role permissions assignment
|
|
29
|
+
ASSIGNED_PERMISSIONS_ARRAY: 'permissions',
|
|
30
|
+
ASSIGNED_PERMISSION_KEYS: 'permissionKeys',
|
|
31
|
+
ASSIGNED_ACTION_IDS_PAYLOAD_KEY: 'permissionActionIds',
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
export type RoleKeys = typeof DEFAULT_ROLE_KEYS;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { RBAC_CONSTANTS } from '../../constants';
|
|
2
|
+
import { AuthAdapter, StandardAuthMeData, StandardUser, LoginCredentials } from '../types';
|
|
3
|
+
|
|
4
|
+
export const defaultAuthAdapter: AuthAdapter = {
|
|
5
|
+
transformLoginPayload: (credentials: LoginCredentials) => {
|
|
6
|
+
return {
|
|
7
|
+
[RBAC_CONSTANTS.auth.EMAIL]: credentials.email,
|
|
8
|
+
password: credentials.password,
|
|
9
|
+
...(credentials.mobileNumber ? { [RBAC_CONSTANTS.auth.MOBILE_NUMBER]: credentials.mobileNumber } : {}),
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
transformLoginResponse: (raw: any) => {
|
|
14
|
+
const dataKey = RBAC_CONSTANTS.api.DATA;
|
|
15
|
+
const successKey = RBAC_CONSTANTS.api.SUCCESS;
|
|
16
|
+
const msgKey = RBAC_CONSTANTS.api.MESSAGE;
|
|
17
|
+
const userContainerKey = RBAC_CONSTANTS.auth.USER_CONTAINER;
|
|
18
|
+
|
|
19
|
+
const dataObj = raw?.[dataKey] || raw || {};
|
|
20
|
+
const userObj = dataObj?.[userContainerKey] || dataObj;
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
success: Boolean(raw?.[successKey] ?? true),
|
|
24
|
+
message: raw?.[msgKey] || '',
|
|
25
|
+
token: raw?.token || dataObj?.token || dataObj?.accessToken,
|
|
26
|
+
user: userObj
|
|
27
|
+
? {
|
|
28
|
+
id: userObj[RBAC_CONSTANTS.auth.USER_ID] || userObj[RBAC_CONSTANTS.auth.EMPLOYEE_USER_ID],
|
|
29
|
+
email: userObj[RBAC_CONSTANTS.auth.EMAIL],
|
|
30
|
+
mobileNumber: userObj[RBAC_CONSTANTS.auth.MOBILE_NUMBER],
|
|
31
|
+
}
|
|
32
|
+
: undefined,
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
transformAuthMeResponse: (raw: any): StandardAuthMeData => {
|
|
37
|
+
const dataKey = RBAC_CONSTANTS.api.DATA;
|
|
38
|
+
const authKeys = RBAC_CONSTANTS.auth;
|
|
39
|
+
|
|
40
|
+
const root = raw?.[dataKey] || raw || {};
|
|
41
|
+
const rawUser = root[authKeys.USER_CONTAINER] || root;
|
|
42
|
+
const rawRole = rawUser[authKeys.USER_ROLE] || {};
|
|
43
|
+
|
|
44
|
+
const user: StandardUser = {
|
|
45
|
+
id: rawUser[authKeys.USER_ID] || rawUser[authKeys.EMPLOYEE_USER_ID] || '',
|
|
46
|
+
email: rawUser[authKeys.EMAIL] || '',
|
|
47
|
+
firstName: rawUser[authKeys.FIRST_NAME] || '',
|
|
48
|
+
lastName: rawUser[authKeys.LAST_NAME] || '',
|
|
49
|
+
fullName:
|
|
50
|
+
`${rawUser[authKeys.FIRST_NAME] || ''} ${rawUser[authKeys.LAST_NAME] || ''}`.trim() ||
|
|
51
|
+
rawUser[authKeys.FULL_NAME] ||
|
|
52
|
+
rawUser[authKeys.EMAIL] ||
|
|
53
|
+
'',
|
|
54
|
+
mobileNumber: rawUser[authKeys.MOBILE_NUMBER],
|
|
55
|
+
entityId: rawUser[authKeys.ENTITY_ID],
|
|
56
|
+
departmentId: rawUser[authKeys.DEPARTMENT_ID],
|
|
57
|
+
role: {
|
|
58
|
+
id: rawRole[authKeys.USER_ROLE_ID] || rawRole[RBAC_CONSTANTS.roles.ROLE_ID] || '',
|
|
59
|
+
name: rawRole[authKeys.USER_ROLE_NAME] || '',
|
|
60
|
+
key: rawRole[authKeys.USER_ROLE_KEY] || '',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const rawPermissions = root[authKeys.PERMISSIONS_ARRAY] || [];
|
|
65
|
+
const permissions = Array.isArray(rawPermissions)
|
|
66
|
+
? rawPermissions.map((p: any) => ({
|
|
67
|
+
permissionKey: p[authKeys.PERMISSION_KEY] || p.key || '',
|
|
68
|
+
routePath: p[authKeys.ROUTE_PATH] || p.route || '',
|
|
69
|
+
}))
|
|
70
|
+
: [];
|
|
71
|
+
|
|
72
|
+
const rawNav = root[authKeys.NAVIGATION_ARRAY] || root[authKeys.MODULES_ARRAY] || [];
|
|
73
|
+
const mapNav = (item: any): any => ({
|
|
74
|
+
id: item[RBAC_CONSTANTS.permissions.PERMISSION_MASTER_ID] || item.id,
|
|
75
|
+
name: item[RBAC_CONSTANTS.permissions.MODULE_NAME] || item.name,
|
|
76
|
+
slug: item[RBAC_CONSTANTS.permissions.SLUG_NAME] || item.slug,
|
|
77
|
+
routePath: item[RBAC_CONSTANTS.permissions.ROUTE_PATH],
|
|
78
|
+
sortOrder: item[RBAC_CONSTANTS.permissions.SORT_ORDER] || 0,
|
|
79
|
+
parentId: item[RBAC_CONSTANTS.permissions.PARENT_ID] || 0,
|
|
80
|
+
children: Array.isArray(item[RBAC_CONSTANTS.permissions.CHILDREN_ARRAY])
|
|
81
|
+
? item[RBAC_CONSTANTS.permissions.CHILDREN_ARRAY].map(mapNav)
|
|
82
|
+
: [],
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const navigation = Array.isArray(rawNav) ? rawNav.map(mapNav) : [];
|
|
86
|
+
|
|
87
|
+
return { user, permissions, navigation };
|
|
88
|
+
},
|
|
89
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RBACAdapters } from '../types';
|
|
2
|
+
import { defaultAuthAdapter } from './authAdapter';
|
|
3
|
+
import { defaultRolesAdapter } from './rolesAdapter';
|
|
4
|
+
import { defaultPermissionsAdapter } from './permissionsAdapter';
|
|
5
|
+
import { defaultMastersAdapter } from './mastersAdapter';
|
|
6
|
+
|
|
7
|
+
export * from './authAdapter';
|
|
8
|
+
export * from './rolesAdapter';
|
|
9
|
+
export * from './permissionsAdapter';
|
|
10
|
+
export * from './mastersAdapter';
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_ADAPTERS: RBACAdapters = {
|
|
13
|
+
auth: defaultAuthAdapter,
|
|
14
|
+
roles: defaultRolesAdapter,
|
|
15
|
+
permissions: defaultPermissionsAdapter,
|
|
16
|
+
masters: defaultMastersAdapter,
|
|
17
|
+
};
|