opencrm/backend/dist/services/user.service.js

447 lines
15 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAllUsers = getAllUsers;
exports.getUserById = getUserById;
exports.createUser = createUser;
exports.updateUser = updateUser;
exports.deleteUser = deleteUser;
exports.getAllRoles = getAllRoles;
exports.getRoleById = getRoleById;
exports.createRole = createRole;
exports.updateRole = updateRole;
exports.deleteRole = deleteRole;
exports.getAllPermissions = getAllPermissions;
const client_1 = require("@prisma/client");
const bcryptjs_1 = __importDefault(require("bcryptjs"));
const helpers_js_1 = require("../utils/helpers.js");
const prisma = new client_1.PrismaClient();
async function getAllUsers(filters) {
const { search, isActive, roleId, page = 1, limit = 20 } = filters;
const { skip, take } = (0, helpers_js_1.paginate)(page, limit);
const where = {};
if (isActive !== undefined) {
where.isActive = isActive;
}
if (roleId) {
where.roles = { some: { roleId } };
}
if (search) {
where.OR = [
{ email: { contains: search } },
{ firstName: { contains: search } },
{ lastName: { contains: search } },
];
}
const [users, total] = await Promise.all([
prisma.user.findMany({
where,
skip,
take,
orderBy: { createdAt: 'desc' },
select: {
id: true,
email: true,
firstName: true,
lastName: true,
isActive: true,
customerId: true,
createdAt: true,
roles: {
include: {
role: {
include: {
permissions: true,
},
},
},
},
},
}),
prisma.user.count({ where }),
]);
// Get Developer role ID
const developerRole = await prisma.role.findFirst({
where: { name: 'Developer' },
});
return {
users: users.map((u) => {
// Check if user has developer role assigned
const hasDeveloperAccess = developerRole
? u.roles.some((ur) => ur.roleId === developerRole.id)
: false;
return {
...u,
roles: u.roles.map((r) => r.role),
hasDeveloperAccess,
};
}),
pagination: (0, helpers_js_1.buildPaginationResponse)(page, limit, total),
};
}
async function getUserById(id) {
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
email: true,
firstName: true,
lastName: true,
isActive: true,
customerId: true,
createdAt: true,
updatedAt: true,
roles: {
include: {
role: {
include: {
permissions: {
include: { permission: true },
},
},
},
},
},
},
});
if (!user)
return null;
const permissions = new Set();
for (const userRole of user.roles) {
for (const rolePerm of userRole.role.permissions) {
permissions.add(`${rolePerm.permission.resource}:${rolePerm.permission.action}`);
}
}
return {
...user,
roles: user.roles.map((r) => r.role),
permissions: Array.from(permissions),
};
}
async function createUser(data) {
const hashedPassword = await bcryptjs_1.default.hash(data.password, 10);
const user = await prisma.user.create({
data: {
email: data.email,
password: hashedPassword,
firstName: data.firstName,
lastName: data.lastName,
customerId: data.customerId,
roles: {
create: data.roleIds.map((roleId) => ({ roleId })),
},
},
select: {
id: true,
email: true,
firstName: true,
lastName: true,
isActive: true,
customerId: true,
roles: {
include: { role: true },
},
},
});
// Entwicklerzugriff setzen falls aktiviert
if (data.hasDeveloperAccess) {
await setUserDeveloperAccess(user.id, true);
}
return user;
}
async function updateUser(id, data) {
const { roleIds, password, hasDeveloperAccess, ...userData } = data;
// Check if this would remove the last admin
const isBeingDeactivated = userData.isActive === false;
const rolesAreBeingChanged = roleIds !== undefined;
if (isBeingDeactivated || rolesAreBeingChanged) {
// Check if user currently has admin permissions
const currentUser = await prisma.user.findUnique({
where: { id },
include: {
roles: {
include: {
role: {
include: {
permissions: {
include: { permission: true },
},
},
},
},
},
},
});
const isCurrentlyAdmin = currentUser?.roles.some((ur) => ur.role.permissions.some((rp) => rp.permission.resource === 'users' && rp.permission.action === 'delete'));
if (isCurrentlyAdmin) {
// Check if user will still be admin after role change
let willStillBeAdmin = false;
if (rolesAreBeingChanged) {
const newRoles = await prisma.role.findMany({
where: { id: { in: roleIds } },
include: {
permissions: {
include: { permission: true },
},
},
});
willStillBeAdmin = newRoles.some((role) => role.permissions.some((rp) => rp.permission.resource === 'users' && rp.permission.action === 'delete'));
}
else {
willStillBeAdmin = true; // Roles not being changed
}
// If user is losing admin status or being deactivated, check for other admins
if (!willStillBeAdmin || isBeingDeactivated) {
const otherAdminCount = await prisma.user.count({
where: {
id: { not: id },
isActive: true,
roles: {
some: {
role: {
permissions: {
some: {
permission: {
resource: 'users',
action: 'delete',
},
},
},
},
},
},
},
});
if (otherAdminCount === 0) {
if (isBeingDeactivated) {
throw new Error('Dieser Benutzer ist der letzte Administrator und kann nicht deaktiviert werden');
}
else {
throw new Error('Die Admin-Rolle kann nicht entfernt werden, da dies der letzte Administrator ist');
}
}
}
}
}
// Hash password if provided
if (password) {
userData.password = await bcryptjs_1.default.hash(password, 10);
}
// Prüfen ob Rollen geändert werden (für Zwangslogout)
let rolesChanged = false;
if (roleIds !== undefined) {
const currentRoles = await prisma.userRole.findMany({
where: { userId: id },
select: { roleId: true },
});
const currentRoleIds = currentRoles.map((r) => r.roleId).sort();
const newRoleIds = [...roleIds].sort();
rolesChanged =
currentRoleIds.length !== newRoleIds.length ||
!currentRoleIds.every((id, i) => id === newRoleIds[i]);
}
// Update user - bei Rollenänderung Token invalidieren
await prisma.user.update({
where: { id },
data: {
...userData,
// Token invalidieren wenn Rollen geändert werden
...(rolesChanged && { tokenInvalidatedAt: new Date() }),
},
});
// Update roles if provided
if (roleIds) {
await prisma.userRole.deleteMany({ where: { userId: id } });
await prisma.userRole.createMany({
data: roleIds.map((roleId) => ({ userId: id, roleId })),
});
}
// Handle developer access
console.log('updateUser - hasDeveloperAccess:', hasDeveloperAccess);
if (hasDeveloperAccess !== undefined) {
await setUserDeveloperAccess(id, hasDeveloperAccess);
}
return getUserById(id);
}
// Helper to set developer access for a user
async function setUserDeveloperAccess(userId, enabled) {
console.log('setUserDeveloperAccess called - userId:', userId, 'enabled:', enabled);
// Get or create developer:access permission
let developerPerm = await prisma.permission.findFirst({
where: { resource: 'developer', action: 'access' },
});
if (!developerPerm) {
developerPerm = await prisma.permission.create({
data: { resource: 'developer', action: 'access' },
});
}
// Get or create Developer role
let developerRole = await prisma.role.findFirst({
where: { name: 'Developer' },
});
if (!developerRole) {
developerRole = await prisma.role.create({
data: {
name: 'Developer',
description: 'Entwicklerzugriff auf Datenbanktools',
permissions: {
create: [{ permissionId: developerPerm.id }],
},
},
});
}
// Check if user already has Developer role
const hasRole = await prisma.userRole.findFirst({
where: { userId, roleId: developerRole.id },
});
console.log('setUserDeveloperAccess - developerRole.id:', developerRole.id, 'hasRole:', hasRole);
if (enabled && !hasRole) {
// Add Developer role
console.log('Adding Developer role');
await prisma.userRole.create({
data: { userId, roleId: developerRole.id },
});
// Token invalidieren bei Rechteänderung
await prisma.user.update({
where: { id: userId },
data: { tokenInvalidatedAt: new Date() },
});
}
else if (!enabled && hasRole) {
// Remove Developer role
console.log('Removing Developer role');
await prisma.userRole.delete({
where: { userId_roleId: { userId, roleId: developerRole.id } },
});
// Token invalidieren bei Rechteänderung
await prisma.user.update({
where: { id: userId },
data: { tokenInvalidatedAt: new Date() },
});
}
else {
console.log('No action needed - enabled:', enabled, 'hasRole:', !!hasRole);
}
}
async function deleteUser(id) {
// Check if user is an admin
const user = await prisma.user.findUnique({
where: { id },
include: {
roles: {
include: {
role: {
include: {
permissions: {
include: { permission: true },
},
},
},
},
},
},
});
if (!user) {
throw new Error('Benutzer nicht gefunden');
}
// Check if user has admin permissions (users:delete means admin)
const isAdmin = user.roles.some((ur) => ur.role.permissions.some((rp) => rp.permission.resource === 'users' && rp.permission.action === 'delete'));
if (isAdmin) {
// Count other admins (users with users:delete permission)
const adminCount = await prisma.user.count({
where: {
id: { not: id },
isActive: true,
roles: {
some: {
role: {
permissions: {
some: {
permission: {
resource: 'users',
action: 'delete',
},
},
},
},
},
},
},
});
if (adminCount === 0) {
throw new Error('Dieser Benutzer ist der letzte Administrator und kann nicht gelöscht werden');
}
}
return prisma.user.delete({ where: { id } });
}
// Role operations
async function getAllRoles() {
return prisma.role.findMany({
include: {
permissions: {
include: { permission: true },
},
_count: {
select: { users: true },
},
},
orderBy: { name: 'asc' },
});
}
async function getRoleById(id) {
return prisma.role.findUnique({
where: { id },
include: {
permissions: {
include: { permission: true },
},
},
});
}
async function createRole(data) {
return prisma.role.create({
data: {
name: data.name,
description: data.description,
permissions: {
create: data.permissionIds.map((permissionId) => ({ permissionId })),
},
},
include: {
permissions: {
include: { permission: true },
},
},
});
}
async function updateRole(id, data) {
const { permissionIds, ...roleData } = data;
await prisma.role.update({
where: { id },
data: roleData,
});
if (permissionIds) {
await prisma.rolePermission.deleteMany({ where: { roleId: id } });
await prisma.rolePermission.createMany({
data: permissionIds.map((permissionId) => ({ roleId: id, permissionId })),
});
}
return getRoleById(id);
}
async function deleteRole(id) {
// Check if role is assigned to any users
const count = await prisma.userRole.count({ where: { roleId: id } });
if (count > 0) {
throw new Error(`Rolle kann nicht gelöscht werden, da sie ${count} Benutzern zugewiesen ist`);
}
return prisma.role.delete({ where: { id } });
}
// Permission operations
async function getAllPermissions() {
return prisma.permission.findMany({
orderBy: [{ resource: 'asc' }, { action: 'asc' }],
});
}
//# sourceMappingURL=user.service.js.map