UNPKG

skailan-core

Version:

Servicio de autenticación y multitenancy para Skailan.

349 lines 11.3 kB
export class PermissionService { prisma; constructor(prisma) { this.prisma = prisma; } /** * Crear un nuevo permiso */ async createPermission(data, organizationId) { try { const permission = await this.prisma.permission.create({ data: { resource: data.resource, action: data.action, description: data.description, organizationId, }, }); return this.mapToPermissionResponse(permission); } catch (error) { if (error instanceof Error && error.message.includes("Unique constraint")) { throw new Error(`El permiso ${data.resource}:${data.action} ya existe para esta organización`); } throw error; } } /** * Obtener todos los permisos de una organización */ async getPermissions(organizationId) { const permissions = await this.prisma.permission.findMany({ where: { OR: [ { organizationId }, { organizationId: null }, // Permisos globales ], }, orderBy: [{ resource: "asc" }, { action: "asc" }], }); return permissions.map(this.mapToPermissionResponse); } /** * Obtener un permiso por ID */ async getPermissionById(id) { const permission = await this.prisma.permission.findUnique({ where: { id }, }); return permission ? this.mapToPermissionResponse(permission) : null; } /** * Actualizar un permiso */ async updatePermission(id, data) { const permission = await this.prisma.permission.update({ where: { id }, data: { resource: data.resource, action: data.action, description: data.description, }, }); return this.mapToPermissionResponse(permission); } /** * Eliminar un permiso */ async deletePermission(id) { // Primero eliminar todas las asignaciones de roles await this.prisma.rolePermission.deleteMany({ where: { permissionId: id }, }); // Luego eliminar el permiso await this.prisma.permission.delete({ where: { id }, }); } /** * Asignar un permiso a un rol */ async assignPermissionToRole(data, organizationId) { try { const rolePermission = await this.prisma.rolePermission.create({ data: { role: data.role, permissionId: data.permissionId, organizationId, }, include: { permission: true, }, }); return this.mapToRolePermissionResponse(rolePermission); } catch (error) { if (error instanceof Error && error.message.includes("Unique constraint")) { throw new Error(`El permiso ya está asignado al rol ${data.role}`); } throw error; } } /** * Revocar un permiso de un rol */ async revokePermissionFromRole(role, permissionId, organizationId) { await this.prisma.rolePermission.deleteMany({ where: { role: role, permissionId, organizationId, }, }); } /** * Obtener permisos de un rol */ async getRolePermissions(role, organizationId) { const rolePermissions = await this.prisma.rolePermission.findMany({ where: { role: role, OR: [{ organizationId }, { organizationId: null }], }, include: { permission: true, }, }); return rolePermissions.map((rp) => this.mapToPermissionResponse(rp.permission)); } /** * Obtener roles que tienen un permiso específico */ async getRolesWithPermission(permissionId, organizationId) { const rolePermissions = await this.prisma.rolePermission.findMany({ where: { permissionId, OR: [{ organizationId }, { organizationId: null }], }, select: { role: true, }, }); return rolePermissions.map((rp) => rp.role); } /** * Asignar múltiples permisos a un rol */ async bulkAssignPermissions(data, organizationId) { const { role, permissions } = data; const result = { success: [], failed: [], }; for (const permissionId of permissions) { try { await this.assignPermissionToRole({ role, permissionId }, organizationId); result.success.push(permissionId); } catch (error) { result.failed.push({ permissionId, error: error instanceof Error ? error.message : "Error desconocido", }); } } return result; } /** * Verificar si un usuario tiene un permiso específico */ async checkUserPermission(userId, organizationId, requiredPermission) { // Obtener la membresía del usuario const membership = await this.prisma.membership.findFirst({ where: { userId, organizationId, status: "ACTIVE", }, }); if (!membership) { return { hasPermission: false, requiredPermission, userPermissions: [], role: "MEMBER", }; } // Obtener permisos del rol const userPermissions = await this.getRolePermissions(membership.role, organizationId); // Verificar si tiene el permiso requerido const [resource, action] = requiredPermission.split(":"); const hasPermission = userPermissions.some((p) => p.resource === resource && p.action === action); return { hasPermission, requiredPermission, userPermissions, role: membership.role, }; } /** * Obtener todos los permisos de un usuario en una organización */ async getUserPermissions(userId, organizationId) { const membership = await this.prisma.membership.findFirst({ where: { userId, organizationId, status: "ACTIVE", }, }); if (!membership) { return []; } return this.getRolePermissions(membership.role, organizationId); } /** * Crear permisos por defecto para una organización */ async createDefaultPermissions(organizationId) { const defaultPermissions = [ // Usuarios { resource: "users", action: "read", description: "Ver usuarios" }, { resource: "users", action: "update", description: "Actualizar usuarios", }, // Organizaciones { resource: "organizations", action: "read", description: "Ver organización", }, { resource: "organizations", action: "update", description: "Actualizar organización", }, // Membresías { resource: "memberships", action: "read", description: "Ver membresías", }, { resource: "memberships", action: "create", description: "Crear membresías", }, { resource: "memberships", action: "update", description: "Actualizar membresías", }, { resource: "memberships", action: "delete", description: "Eliminar membresías", }, // Pagos { resource: "payments", action: "read", description: "Ver pagos" }, { resource: "payments", action: "create", description: "Crear pagos" }, // Invitaciones { resource: "invitations", action: "read", description: "Ver invitaciones", }, { resource: "invitations", action: "create", description: "Crear invitaciones", }, { resource: "invitations", action: "delete", description: "Eliminar invitaciones", }, // Permisos { resource: "permissions", action: "read", description: "Ver permisos" }, { resource: "permissions", action: "manage", description: "Gestionar permisos", }, // Configuración { resource: "settings", action: "read", description: "Ver configuración", }, { resource: "settings", action: "update", description: "Actualizar configuración", }, // Reportes { resource: "reports", action: "read", description: "Ver reportes" }, { resource: "reports", action: "export", description: "Exportar reportes", }, // Analytics { resource: "analytics", action: "read", description: "Ver analytics" }, { resource: "analytics", action: "export", description: "Exportar analytics", }, ]; for (const permissionData of defaultPermissions) { try { await this.createPermission(permissionData, organizationId); } catch (error) { // Ignorar errores de permisos duplicados console.log(`Permiso ${permissionData.resource}:${permissionData.action} ya existe`); } } } /** * Mapear PrismaPermission a PermissionResponse */ mapToPermissionResponse(permission) { return { id: permission.id, resource: permission.resource, action: permission.action, description: permission.description || undefined, createdAt: permission.createdAt, updatedAt: permission.updatedAt, }; } /** * Mapear PrismaRolePermission a RolePermissionResponse */ mapToRolePermissionResponse(rolePermission) { return { id: rolePermission.id, role: rolePermission.role, permission: this.mapToPermissionResponse(rolePermission.permission), createdAt: rolePermission.createdAt, }; } } //# sourceMappingURL=PermissionService.js.map