security(rbac): enforce tenant workspace lock on role creation and update in role.service.js

This commit is contained in:
Inamul-hasan-tec
2026-08-11 18:36:33 +05:30
parent b2b126590f
commit 6cdef6da32
@@ -33,6 +33,15 @@ export class RoleService {
async create(data, context = {}) {
const { role_name, description, permissions, tenant_id } = data;
const isPlatformUser = context.userType === 'platform' || context.roles?.some(r => r.role_code === 'SUPER_ADMIN');
// Non-platform users are strictly locked to their own tenant workspace
const finalTenantId = isPlatformUser ? (tenant_id || null) : (context.tenantId || null);
if (!isPlatformUser && !context.tenantId) {
throw new ApiError(403, 'Forbidden: Tenant workspace context required to create roles');
}
// Generate role code from name: Admin Editor -> ADMIN_EDITOR
const role_code = role_name.toUpperCase().replace(/[^A-Z0-9]/g, '_');
@@ -40,14 +49,28 @@ export class RoleService {
role_name,
role_code,
description,
tenant_id: tenant_id || null,
role_type: tenant_id ? 'tenant' : 'platform',
tenant_id: finalTenantId,
role_type: finalTenantId ? 'tenant' : 'platform',
is_system_role: false,
status: true
}, permissions, context);
}
async update(id, data, context = {}) {
const isPlatformUser = context.userType === 'platform' || context.roles?.some(r => r.role_code === 'SUPER_ADMIN');
const role = await repository.findById(id, {}, context);
if (!role) {
throw new ApiError(404, 'Role not found');
}
if (role.is_system_role) {
throw new ApiError(403, 'Forbidden: Baseline system roles cannot be modified');
}
if (!isPlatformUser && role.tenant_id !== context.tenantId) {
throw new ApiError(403, 'Forbidden: Cannot modify roles outside your tenant workspace');
}
const { role_name, description, permissions, status } = data;
const roleData = {};
if (role_name) {
@@ -65,6 +88,7 @@ export class RoleService {
}
async delete(id, context = {}) {
const isPlatformUser = context.userType === 'platform' || context.roles?.some(r => r.role_code === 'SUPER_ADMIN');
const role = await repository.findById(id, {}, context);
if (!role) {
throw new ApiError(404, 'Role not found');
@@ -74,6 +98,10 @@ export class RoleService {
throw new ApiError(403, 'Forbidden: Super Admin and System roles cannot be deleted');
}
if (!isPlatformUser && role.tenant_id !== context.tenantId) {
throw new ApiError(403, 'Forbidden: Cannot delete roles outside your tenant workspace');
}
const deleted = await repository.delete(id, context);
if (!deleted) {
throw new ApiError(404, 'Role not found');