diff --git a/src/controllers/01-branch-controller.ts b/src/controllers/01-branch-controller.ts index 44bd0d9..9e7775e 100644 --- a/src/controllers/01-branch-controller.ts +++ b/src/controllers/01-branch-controller.ts @@ -101,6 +101,49 @@ type BranchUpdate = { }[]; }; +async function permissionCheck(user: RequestWithUser["user"], branchId: string) { + const record = await prisma.branch.findUnique({ + include: { + headOffice: { + include: { + branch: { where: { user: { some: { userId: user.sub } } } }, + user: { where: { userId: user.sub } }, + }, + }, + user: { where: { userId: user.sub } }, + }, + where: { id: branchId }, + }); + + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); + } + + if (!isSystem(user)) { + if (!globalAllow(user) && record.user.length === 0) { + throw new HttpError( + HttpStatus.FORBIDDEN, + "You do not have permission to perform this action.", + "noPermission", + ); + } else { + if ( + (record.user.length === 0 && !record.headOffice) || + (record.headOffice && + record.headOffice.user.length === 0 && + record.headOffice.branch.length === 0) + ) { + throw new HttpError( + HttpStatus.FORBIDDEN, + "You do not have permission to perform this action.", + "noPermission", + ); + } + } + } + return record; +} + @Route("api/v1/branch") @Tags("Branch") export class BranchController extends Controller { @@ -119,6 +162,16 @@ export class BranchController extends Controller { ? { some: { user: { some: { userId: req.user.sub } } } } : undefined, }, + { + headOffice: globalAllow(req.user) + ? { branch: { some: { user: { some: { userId: req.user.sub } } } } } + : undefined, + }, + { + headOffice: globalAllow(req.user) + ? { user: { some: { userId: req.user.sub } } } + : undefined, + }, ], }; @@ -226,6 +279,16 @@ export class BranchController extends Controller { ? { some: { user: { some: { userId: req.user.sub } } } } : undefined, }, + { + headOffice: globalAllow(req.user) + ? { branch: { some: { user: { some: { userId: req.user.sub } } } } } + : undefined, + }, + { + headOffice: globalAllow(req.user) + ? { user: { some: { userId: req.user.sub } } } + : undefined, + }, ], }, OR: [ @@ -485,27 +548,7 @@ export class BranchController extends Controller { const { provinceId, districtId, subDistrictId, headOfficeId, bank, contact, ...rest } = body; - const branch = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { id: branchId }, - }); - - if (!branch) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if ( - !MANAGE_ROLES.some((v) => req.user.roles?.includes(v)) && - !branch?.user.find((v) => v.userId === req.user.sub) - ) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } + await permissionCheck(req.user, branchId); return await prisma.$transaction(async (tx) => { const listDeleted = bank @@ -578,28 +621,43 @@ export class BranchController extends Controller { @Delete("{branchId}") @Security("keycloak", MANAGE_ROLES) async deleteBranch(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findFirst({ + const record = await prisma.branch.findUnique({ include: { - province: true, - district: true, - subDistrict: true, - createdBy: true, - updatedBy: true, + headOffice: { + include: { + branch: { where: { user: { some: { userId: req.user.sub } } } }, + user: { where: { userId: req.user.sub } }, + }, + }, user: { where: { userId: req.user.sub } }, }, where: { id: branchId }, }); - if (!MANAGE_ROLES.some((v) => req.user.roles?.includes(v))) { - if ( - record?.createdByUserId !== req.user.sub && - !record?.user.find((v) => v.userId === req.user.sub) - ) { + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); + } + + if (!isSystem(req.user)) { + if (!globalAllow(req.user) && record.user.length === 0) { throw new HttpError( HttpStatus.FORBIDDEN, "You do not have permission to perform this action.", "noPermission", ); + } else { + if ( + (record.user.length === 0 && !record.headOffice) || + (record.headOffice && + record.headOffice.user.length === 0 && + record.headOffice.branch.length === 0) + ) { + throw new HttpError( + HttpStatus.FORBIDDEN, + "You do not have permission to perform this action.", + "noPermission", + ); + } } } @@ -656,45 +714,22 @@ export class BranchController extends Controller { @Get("{branchId}/line-image") async getLineImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const url = await presignedGetObjectIfExist( + const url = await minio.presignedGetObject( MINIO_BUCKET, fileLocation.branch.line(branchId), 60 * 60, ); - - if (!url) { - throw new HttpError(HttpStatus.NOT_FOUND, "Image cannot be found", "imageNotFound"); - } - return req.res?.redirect(url); } @Put("{branchId}/line-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async setLineImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { id: branchId }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); return req.res?.redirect( await minio.presignedPutObject( MINIO_BUCKET, - fileLocation.branch.line(record.id), + fileLocation.branch.line(branchId), 12 * 60 * 60, ), ); @@ -703,71 +738,29 @@ export class BranchController extends Controller { @Delete("{branchId}/line-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async deleteLineImage(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { - id: branchId, - }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } + await permissionCheck(req.user, branchId); await deleteFile(fileLocation.branch.line(branchId)); } @Get("{branchId}/branch-image") async getBranchImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const url = await presignedGetObjectIfExist( + const url = await minio.presignedGetObject( MINIO_BUCKET, fileLocation.branch.image(branchId), 60 * 60, ); - - if (!url) { - throw new HttpError(HttpStatus.NOT_FOUND, "Image cannot be found", "imageNotFound"); - } - return req.res?.redirect(url); } @Put("{branchId}/branch-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async setBranchImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { id: branchId }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); return req.res?.redirect( await minio.presignedPutObject( MINIO_BUCKET, - fileLocation.branch.image(record.id), + fileLocation.branch.image(branchId), 12 * 60 * 60, ), ); @@ -776,100 +769,34 @@ export class BranchController extends Controller { @Delete("{branchId}/branch-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async deleteBranchImage(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { - id: branchId, - }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); await deleteFile(fileLocation.branch.image(branchId)); } @Get("{branchId}/map-image") async getMapImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const url = await presignedGetObjectIfExist( + const url = await minio.presignedGetObject( MINIO_BUCKET, fileLocation.branch.image(branchId), 60 * 60, ); - - if (!url) { - throw new HttpError(HttpStatus.NOT_FOUND, "Image cannot be found", "imageNotFound"); - } - return req.res?.redirect(url); } @Put("{branchId}/map-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async setMapImageByBranchId(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { id: branchId }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } + await permissionCheck(req.user, branchId); return req.res?.redirect( - await minio.presignedPutObject( - MINIO_BUCKET, - fileLocation.branch.map(record.id), - 12 * 60 * 60, - ), + await minio.presignedPutObject(MINIO_BUCKET, fileLocation.branch.map(branchId), 12 * 60 * 60), ); } @Delete("{branchId}/map-image") @Security("keycloak", MANAGE_ROLES.concat("admin", "branch_manager")) async deleteMapImage(@Request() req: RequestWithUser, @Path() branchId: string) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { - id: branchId, - }, - }); - - if (!record) { - throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found.", "branchNotFound"); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); await deleteFile(fileLocation.branch.map(branchId)); } @@ -879,16 +806,11 @@ export class BranchController extends Controller { @Path() branchId: string, @Path() bankId: string, ) { - const url = await presignedGetObjectIfExist( + const url = await minio.presignedGetObject( MINIO_BUCKET, fileLocation.branch.bank(branchId, bankId), 60 * 60, ); - - if (!url) { - throw new HttpError(HttpStatus.NOT_FOUND, "Image cannot be found", "imageNotFound"); - } - return req.res?.redirect(url); } @@ -899,32 +821,7 @@ export class BranchController extends Controller { @Path() branchId: string, @Path() bankId: string, ) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { - id: branchId, - bank: { some: { id: bankId } }, - }, - }); - - if (!record) { - throw new HttpError( - HttpStatus.NOT_FOUND, - "Branch Bank cannot be found.", - "branchBankNotFound", - ); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); return req.res?.redirect( await minio.presignedPutObject( MINIO_BUCKET, @@ -941,32 +838,7 @@ export class BranchController extends Controller { @Path() branchId: string, @Path() bankId: string, ) { - const record = await prisma.branch.findUnique({ - include: { - user: { where: { userId: req.user.sub } }, - }, - where: { - id: branchId, - bank: { some: { id: bankId } }, - }, - }); - - if (!record) { - throw new HttpError( - HttpStatus.NOT_FOUND, - "Branch Bank cannot be found.", - "branchBankNotFound", - ); - } - - if (!globalAllow(req.user) && !record?.user.find((v) => v.userId === req.user.sub)) { - throw new HttpError( - HttpStatus.FORBIDDEN, - "You do not have permission to perform this action.", - "noPermission", - ); - } - + await permissionCheck(req.user, branchId); await deleteFile(fileLocation.branch.bank(branchId, bankId)); } }