import { Prisma } from "@prisma/client"; import prisma from "../db"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import { RequestWithUser } from "../interfaces/user"; import { isSystem } from "../utils/keycloak"; export function branchRelationPermInclude(user: RequestWithUser["user"]) { return { headOffice: { include: { branch: { where: { user: { some: { userId: user.sub } } } }, user: { where: { userId: user.sub } }, }, }, branch: { where: { user: { some: { userId: user.sub } } } }, user: { where: { userId: user.sub } }, }; } export function createPermCondition(globalAllow: (user: RequestWithUser["user"]) => boolean) { return ( user: RequestWithUser["user"], opts?: { alwaysIncludeHead?: boolean; includeInActive?: boolean }, ) => isSystem(user) ? undefined : [ { user: { some: { userId: user.sub } }, }, { branch: opts?.alwaysIncludeHead || globalAllow(user) ? { some: { user: { some: { userId: user.sub } } } } : undefined, }, { headOffice: globalAllow(user) ? { branch: { some: { user: { some: { userId: user.sub } } } } } : undefined, }, { headOffice: globalAllow(user) ? { user: { some: { userId: user.sub } } } : undefined, }, ]; } export async function getBranchPermissionCheck(user: RequestWithUser["user"], branchId: string) { return await prisma.branch.findUnique({ include: branchRelationPermInclude(user), where: { id: branchId }, }); } export function createPermCheck(globalAllow: (user: RequestWithUser["user"]) => boolean) { return async ( user: RequestWithUser["user"], branch: Awaited> | string, ) => { if (typeof branch === "string") { branch = await getBranchPermissionCheck(user, branch); } if (!branch) { throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); } if (!isSystem(user)) { if (!globalAllow(user) && branch.user.length === 0) { throw new HttpError( HttpStatus.FORBIDDEN, "You do not have permission to perform this action.", "noPermission", ); } else { if ( (branch.user.length === 0 && branch.branch.length === 0 && !branch.headOffice) || (branch.headOffice && branch.headOffice.user.length === 0 && branch.headOffice.branch.length === 0) ) { throw new HttpError( HttpStatus.FORBIDDEN, "You do not have permission to perform this action.", "noPermission", ); } } } return branch; }; }