diff --git a/src/controllers/GroupsController.ts b/src/controllers/GroupsController.ts index ddb70a0..2e11bb1 100644 --- a/src/controllers/GroupsController.ts +++ b/src/controllers/GroupsController.ts @@ -387,6 +387,43 @@ export class GroupsController { h.success("The request has been successfully cancelled!"); } + /** + * Delete a member from a group (as a moderator or an admin) + * + * @param h Request handler + */ + public static async DeleteMember(h: RequestHandler) { + const groupID = await h.postGroupIDWithAccess("groupID", GroupsAccessLevel.MODERATOR_ACCESS); + + // Get the membership of the user making the request + const currUserMembership = await GroupsHelper.GetMembershipInfo(groupID, h.getUserId()); + + // Get the ID of the member to delete + const userID = await h.postUserId("userID"); + const membership = await GroupsHelper.GetMembershipInfo(groupID, userID); + + if(membership == null) + h.error(404, "Membership not found!"); + + // If the user is an admin, he must not be the last admin of the group + if(userID == h.getUserId() && currUserMembership.level == GroupMembershipLevels.ADMINISTRATOR + && await GroupsHelper.CountMembersAtLevel(groupID, GroupMembershipLevels.ADMINISTRATOR) == 1) + h.error(401, "You are the last administrator of this group!"); + + + // TODO : validate this check + // Only administrator can delete members that are more than member (moderators & administrators) + if(membership.level < GroupMembershipLevels.MEMBER && currUserMembership.level != GroupMembershipLevels.ADMINISTRATOR) + h.error(401, "Only an administrator can delete this membership!"); + + // Delete the membership + await GroupsHelper.DeleteMember(groupID, userID); + + // TODO : delete any group membership notifications + + h.success("Membership of the user has been successfully deleted!"); + } + /** * Turn a GroupInfo object into a valid API object * diff --git a/src/controllers/Routes.ts b/src/controllers/Routes.ts index ac2e489..16cca0f 100644 --- a/src/controllers/Routes.ts +++ b/src/controllers/Routes.ts @@ -114,4 +114,6 @@ export const Routes : Route[] = [ {path: "/groups/send_request", cb: (h) => GroupsController.SendRequest(h)}, {path: "/groups/cancel_request", cb: (h) => GroupsController.CancelRequest(h)}, + + {path: "/groups/delete_member", cb: (h) => GroupsController.DeleteMember(h)}, ] \ No newline at end of file diff --git a/src/helpers/GroupsHelper.ts b/src/helpers/GroupsHelper.ts index 4dc3219..d70f0f5 100644 --- a/src/helpers/GroupsHelper.ts +++ b/src/helpers/GroupsHelper.ts @@ -405,6 +405,21 @@ export class GroupsHelper { }); } + /** + * Count the number of members of a group at a specific member + * @param groupID Target group ID + * @param level The level to check + */ + public static async CountMembersAtLevel(groupID: number, level: GroupMembershipLevels) : Promise { + return await DatabaseHelper.Count({ + table: GROUPS_MEMBERS_TABLE, + where: { + groups_id: groupID, + level: level + } + }); + } + /** * Turn a database row into a {GroupInfo} object *