255 lines
6.1 KiB
TypeScript
255 lines
6.1 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { ROLE } from '../../../common/utils/constants/common.constant';
|
|
|
|
import ApiError from '../../../common/utils/helper/ApiError';
|
|
|
|
function normalizeIdArray(values: unknown): number[] {
|
|
if (!Array.isArray(values)) {
|
|
return [];
|
|
}
|
|
|
|
return Array.from(
|
|
new Set(
|
|
values
|
|
.map((item) => Number(item))
|
|
.filter((item) => Number.isInteger(item) && item > 0),
|
|
),
|
|
);
|
|
}
|
|
|
|
@Injectable()
|
|
export class HostRolePermissionService {
|
|
constructor(private prisma: PrismaClient) {}
|
|
|
|
async saveRolePermissions(input: {
|
|
hostUserXid: number;
|
|
roleXid: number;
|
|
permissionMasterXids: unknown;
|
|
}) {
|
|
const permissionMasterXids = normalizeIdArray(input.permissionMasterXids);
|
|
|
|
if (!permissionMasterXids.length) {
|
|
throw new ApiError(400, 'permissionMasterXids is required.');
|
|
}
|
|
|
|
return this.prisma.$transaction(async (tx) => {
|
|
const host = await tx.hostHeader.findFirst({
|
|
where: {
|
|
userXid: input.hostUserXid,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
companyName: true,
|
|
userXid: true,
|
|
},
|
|
});
|
|
|
|
if (!host) {
|
|
throw new ApiError(404, 'Host company not found for the logged-in user.');
|
|
}
|
|
|
|
const role = await tx.roles.findFirst({
|
|
where: {
|
|
id: input.roleXid,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
roleName: true,
|
|
},
|
|
});
|
|
|
|
if (!role) {
|
|
throw new ApiError(400, 'Invalid roleXid.');
|
|
}
|
|
|
|
const selectedPermissions = await tx.hostPermissionMasters.findMany({
|
|
where: {
|
|
id: { in: permissionMasterXids },
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
permissionKey: true,
|
|
permissionGroup: true,
|
|
permissionSection: true,
|
|
permissionAction: true,
|
|
displayLabel: true,
|
|
displayOrder: true,
|
|
},
|
|
orderBy: {
|
|
displayOrder: 'asc',
|
|
},
|
|
});
|
|
|
|
if (selectedPermissions.length !== permissionMasterXids.length) {
|
|
throw new ApiError(400, 'One or more permissionMasterXids are invalid.');
|
|
}
|
|
|
|
const saved = await tx.hostRolePermissionMasters.upsert({
|
|
where: {
|
|
hostXid_roleXid: {
|
|
hostXid: host.id,
|
|
roleXid: role.id,
|
|
},
|
|
},
|
|
create: {
|
|
hostXid: host.id,
|
|
roleXid: role.id,
|
|
permissionMasterXids,
|
|
isActive: true,
|
|
},
|
|
update: {
|
|
permissionMasterXids,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
hostXid: true,
|
|
roleXid: true,
|
|
permissionMasterXids: true,
|
|
createdAt: true,
|
|
updatedAt: true,
|
|
},
|
|
});
|
|
|
|
return {
|
|
host,
|
|
role,
|
|
saved,
|
|
selectedPermissions,
|
|
};
|
|
});
|
|
}
|
|
|
|
async getMemberPermissions(input: {
|
|
hostUserXid: number;
|
|
memberUserXid: number;
|
|
}) {
|
|
return this.prisma.$transaction(async (tx) => {
|
|
// Find the host
|
|
const host = await tx.hostHeader.findFirst({
|
|
where: {
|
|
userXid: input.hostUserXid,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
companyName: true,
|
|
userXid: true,
|
|
},
|
|
});
|
|
|
|
if (!host) {
|
|
throw new ApiError(404, 'Host company not found for the logged-in user.');
|
|
}
|
|
|
|
// Find the host member
|
|
const hostMember = await tx.hostMembers.findFirst({
|
|
where: {
|
|
hostXid: host.id,
|
|
userXid: input.memberUserXid,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
memberStatus: 'accepted',
|
|
},
|
|
select: {
|
|
id: true,
|
|
userXid: true,
|
|
roleXid: true,
|
|
role: {
|
|
select: {
|
|
id: true,
|
|
roleName: true,
|
|
},
|
|
},
|
|
hostRolePermissionMasterXid: true,
|
|
},
|
|
});
|
|
|
|
if (!hostMember) {
|
|
throw new ApiError(404, 'Host member not found or not active.');
|
|
}
|
|
|
|
// Check if role is operator or co-admin
|
|
if (hostMember.roleXid !== ROLE.CO_ADMIN && hostMember.roleXid !== ROLE.OPERATOR) {
|
|
throw new ApiError(400, 'Member is not an operator or co-admin.');
|
|
}
|
|
|
|
if (!hostMember.hostRolePermissionMasterXid) {
|
|
// Return empty permissions if no role permissions assigned
|
|
return {
|
|
host,
|
|
member: {
|
|
userXid: hostMember.userXid,
|
|
role: hostMember.role,
|
|
},
|
|
permissions: [],
|
|
};
|
|
}
|
|
|
|
// Get the role permissions
|
|
const rolePermissions = await tx.hostRolePermissionMasters.findFirst({
|
|
where: {
|
|
id: hostMember.hostRolePermissionMasterXid,
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
permissionMasterXids: true,
|
|
},
|
|
});
|
|
|
|
if (!rolePermissions) {
|
|
return {
|
|
host,
|
|
member: {
|
|
userXid: hostMember.userXid,
|
|
role: hostMember.role,
|
|
},
|
|
permissions: [],
|
|
};
|
|
}
|
|
|
|
// Get the actual permissions
|
|
const permissionIds = rolePermissions.permissionMasterXids as number[];
|
|
const permissions = await tx.hostPermissionMasters.findMany({
|
|
where: {
|
|
id: { in: permissionIds },
|
|
isActive: true,
|
|
deletedAt: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
permissionKey: true,
|
|
permissionGroup: true,
|
|
permissionSection: true,
|
|
permissionAction: true,
|
|
displayLabel: true,
|
|
displayOrder: true,
|
|
},
|
|
orderBy: {
|
|
displayOrder: 'asc',
|
|
},
|
|
});
|
|
|
|
return {
|
|
host,
|
|
member: {
|
|
userXid: hostMember.userXid,
|
|
role: hostMember.role,
|
|
},
|
|
permissions,
|
|
};
|
|
});
|
|
}
|
|
}
|