From 9f66b9bb4d9a9328c6fab81c474a080bac69df1a Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:08:20 +0200 Subject: [PATCH] Leave project service --- .../project-membership-service.ts | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index a6682465f..45e3f9ab5 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -36,6 +36,7 @@ import { TDeleteProjectMembershipsDTO, TGetProjectMembershipByUsernameDTO, TGetProjectMembershipDTO, + TLeaveProjectDTO, TUpdateProjectMembershipDTO } from "./project-membership-types"; import { TProjectUserMembershipRoleDALFactory } from "./project-user-membership-role-dal"; @@ -531,6 +532,53 @@ export const projectMembershipServiceFactory = ({ return memberships; }; + const leaveProject = async ({ projectId, actorId, actor }: TLeaveProjectDTO) => { + if (actor !== ActorType.USER) { + throw new BadRequestError({ message: "Only users can leave projects" }); + } + + const project = await projectDAL.findById(projectId); + if (!project) throw new BadRequestError({ message: "Project not found" }); + + if (project.version !== ProjectVersion.V2) { + throw new BadRequestError({ + message: "Please ask your project administrator to upgrade the project before leaving." + }); + } + + const projectMembers = await projectMembershipDAL.findAllProjectMembers(projectId); + + if (!projectMembers?.length) { + throw new BadRequestError({ message: "Failed to find project members" }); + } + + if (projectMembers.length < 2) { + throw new BadRequestError({ message: "You cannot leave the project as you are the only member" }); + } + + const adminMembers = projectMembers.filter( + (member) => member.roles.map((r) => r.role).includes("admin") && member.userId !== actorId + ); + if (!adminMembers.length) { + throw new BadRequestError({ + message: "You cannot leave the project as you are the only admin. Promote another user to admin before leaving." + }); + } + + const deletedMembership = ( + await projectMembershipDAL.delete({ + projectId: project.id, + userId: actorId + }) + )?.[0]; + + if (!deletedMembership) { + throw new BadRequestError({ message: "Failed to leave project" }); + } + + return deletedMembership; + }; + return { getProjectMemberships, getProjectMembershipByUsername, @@ -538,6 +586,7 @@ export const projectMembershipServiceFactory = ({ addUsersToProjectNonE2EE, deleteProjectMemberships, deleteProjectMembership, // TODO: Remove this - addUsersToProject + addUsersToProject, + leaveProject }; };