Initial project setup
This commit is contained in:
commit
69588c1889
@ -363,12 +363,10 @@ components:
|
|||||||
module_id: { type: integer, example: 1 }
|
module_id: { type: integer, example: 1 }
|
||||||
actions:
|
actions:
|
||||||
type: object
|
type: object
|
||||||
required: [view, create, edit, delete, approve, export]
|
required: [view, edit, approve, export]
|
||||||
properties:
|
properties:
|
||||||
view: { type: boolean, example: true }
|
view: { type: boolean, example: true }
|
||||||
create: { type: boolean, example: true }
|
edit: { type: boolean, example: true, description: 'Add & edit (grants create + edit)' }
|
||||||
edit: { type: boolean, example: true }
|
|
||||||
delete: { type: boolean, example: false }
|
|
||||||
approve: { type: boolean, example: false }
|
approve: { type: boolean, example: false }
|
||||||
export: { type: boolean, example: true }
|
export: { type: boolean, example: true }
|
||||||
|
|
||||||
@ -1619,7 +1617,7 @@ paths:
|
|||||||
schema: { type: string }
|
schema: { type: string }
|
||||||
get:
|
get:
|
||||||
tags: [Roles]
|
tags: [Roles]
|
||||||
summary: Permission matrix for role (modules x actions checkboxes)
|
summary: Permission matrix for role (modules x view/edit/approve/export; edit = add + edit)
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Matrix fetched
|
description: Matrix fetched
|
||||||
|
|||||||
@ -23,7 +23,7 @@ router.get(
|
|||||||
controller.list
|
controller.list
|
||||||
);
|
);
|
||||||
router.get('/:id', authorize('ROLES', 'view'), controller.getOne);
|
router.get('/:id', authorize('ROLES', 'view'), controller.getOne);
|
||||||
router.post('/', authorize('ROLES', 'create'), validate(createRoleSchema), controller.create);
|
router.post('/', authorize('ROLES', 'edit'), validate(createRoleSchema), controller.create);
|
||||||
router.put('/:id', authorize('ROLES', 'edit'), validate(updateRoleSchema), controller.update);
|
router.put('/:id', authorize('ROLES', 'edit'), validate(updateRoleSchema), controller.update);
|
||||||
router.put(
|
router.put(
|
||||||
'/:id/permissions',
|
'/:id/permissions',
|
||||||
@ -38,6 +38,6 @@ router.put(
|
|||||||
validate(permissionMatrixSchema),
|
validate(permissionMatrixSchema),
|
||||||
controller.savePermissionMatrix
|
controller.savePermissionMatrix
|
||||||
);
|
);
|
||||||
router.delete('/:id', authorize('ROLES', 'delete'), controller.remove);
|
router.delete('/:id', authorize('ROLES', 'edit'), controller.remove);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@ -3,7 +3,8 @@ const ApiError = require('../../utils/ApiError');
|
|||||||
const auditLog = require('../../utils/auditLog');
|
const auditLog = require('../../utils/auditLog');
|
||||||
const { getPagination } = require('../../utils/pagination');
|
const { getPagination } = require('../../utils/pagination');
|
||||||
|
|
||||||
const PERMISSION_ACTIONS = ['view', 'create', 'edit', 'delete', 'approve', 'export'];
|
const MATRIX_ACTIONS = ['view', 'edit', 'approve', 'export'];
|
||||||
|
const MERGED_EDIT_ACTIONS = ['create', 'edit'];
|
||||||
|
|
||||||
const permissionSelect = {
|
const permissionSelect = {
|
||||||
permissions: {
|
permissions: {
|
||||||
@ -293,7 +294,19 @@ const getPermissionMatrix = async (id) => {
|
|||||||
|
|
||||||
const matrix = modules.map((mod) => {
|
const matrix = modules.map((mod) => {
|
||||||
const permissions = {};
|
const permissions = {};
|
||||||
for (const action of PERMISSION_ACTIONS) {
|
for (const action of MATRIX_ACTIONS) {
|
||||||
|
if (action === 'edit') {
|
||||||
|
const createPerm = mod.permissions.find((p) => p.action === 'create');
|
||||||
|
const editPerm = mod.permissions.find((p) => p.action === 'edit');
|
||||||
|
const merged = [createPerm, editPerm].filter(Boolean);
|
||||||
|
permissions.edit = {
|
||||||
|
permission_id: editPerm?.id ?? createPerm?.id ?? null,
|
||||||
|
permission_ids: merged.map((p) => p.id),
|
||||||
|
granted: merged.some((p) => granted.has(p.id.toString())),
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const perm = mod.permissions.find((p) => p.action === action);
|
const perm = mod.permissions.find((p) => p.action === action);
|
||||||
permissions[action] = {
|
permissions[action] = {
|
||||||
permission_id: perm?.id ?? null,
|
permission_id: perm?.id ?? null,
|
||||||
@ -310,7 +323,7 @@ const getPermissionMatrix = async (id) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
role: { id: role.id, name: role.name },
|
role: { id: role.id, name: role.name },
|
||||||
actions: PERMISSION_ACTIONS,
|
actions: MATRIX_ACTIONS,
|
||||||
modules: matrix,
|
modules: matrix,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -327,8 +340,22 @@ const savePermissionMatrix = async (id, matrix, userId, requestId) => {
|
|||||||
|
|
||||||
const permissionIds = [];
|
const permissionIds = [];
|
||||||
for (const row of matrix) {
|
for (const row of matrix) {
|
||||||
for (const action of PERMISSION_ACTIONS) {
|
for (const action of MATRIX_ACTIONS) {
|
||||||
if (!row.actions?.[action]) continue;
|
if (!row.actions?.[action]) continue;
|
||||||
|
|
||||||
|
if (action === 'edit') {
|
||||||
|
for (const dbAction of MERGED_EDIT_ACTIONS) {
|
||||||
|
const perm = catalog.find(
|
||||||
|
(p) => p.module_id.toString() === String(row.module_id) && p.action === dbAction
|
||||||
|
);
|
||||||
|
if (!perm) {
|
||||||
|
throw new ApiError(422, `Permission not found for module ${row.module_id}:${dbAction}`);
|
||||||
|
}
|
||||||
|
permissionIds.push(perm.id);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const perm = catalog.find(
|
const perm = catalog.find(
|
||||||
(p) => p.module_id.toString() === String(row.module_id) && p.action === action
|
(p) => p.module_id.toString() === String(row.module_id) && p.action === action
|
||||||
);
|
);
|
||||||
|
|||||||
@ -23,9 +23,7 @@ const permissionMatrixSchema = Joi.object({
|
|||||||
module_id: Joi.number().integer().positive().required(),
|
module_id: Joi.number().integer().positive().required(),
|
||||||
actions: Joi.object({
|
actions: Joi.object({
|
||||||
view: Joi.boolean().required(),
|
view: Joi.boolean().required(),
|
||||||
create: Joi.boolean().required(),
|
|
||||||
edit: Joi.boolean().required(),
|
edit: Joi.boolean().required(),
|
||||||
delete: Joi.boolean().required(),
|
|
||||||
approve: Joi.boolean().required(),
|
approve: Joi.boolean().required(),
|
||||||
export: Joi.boolean().required(),
|
export: Joi.boolean().required(),
|
||||||
}).required(),
|
}).required(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user