Browse Source

fix: remove existing team invitation for an invitee when adding invitee to team by admin (HBE-229) (#3157)

Ankit Sridhar 1 year ago
parent
commit
878ec833ce

+ 14 - 2
packages/hoppscotch-backend/src/admin/admin.service.ts

@@ -236,11 +236,11 @@ export class AdminService {
     const user = await this.userService.findUserByEmail(userEmail);
     if (O.isNone(user)) return E.left(USER_NOT_FOUND);
 
-    const isUserAlreadyMember = await this.teamService.getTeamMemberTE(
+    const teamMember = await this.teamService.getTeamMemberTE(
       teamID,
       user.value.uid,
     )();
-    if (E.left(isUserAlreadyMember)) {
+    if (E.isLeft(teamMember)) {
       const addedUser = await this.teamService.addMemberToTeamWithEmail(
         teamID,
         userEmail,
@@ -248,6 +248,18 @@ export class AdminService {
       );
       if (E.isLeft(addedUser)) return E.left(addedUser.left);
 
+      const userInvitation =
+        await this.teamInvitationService.getTeamInviteByEmailAndTeamID(
+          userEmail,
+          teamID,
+        );
+
+      if (E.isRight(userInvitation)) {
+        await this.teamInvitationService.revokeInvitation(
+          userInvitation.right.id,
+        )();
+      }
+
       return E.right(addedUser.right);
     }
 

+ 29 - 0
packages/hoppscotch-backend/src/team-invitation/team-invitation.service.ts

@@ -3,6 +3,7 @@ import * as T from 'fp-ts/Task';
 import * as O from 'fp-ts/Option';
 import * as TO from 'fp-ts/TaskOption';
 import * as TE from 'fp-ts/TaskEither';
+import * as E from 'fp-ts/Either';
 import { pipe, flow, constVoid } from 'fp-ts/function';
 import { PrismaService } from 'src/prisma/prisma.service';
 import { Team, TeamMemberRole } from 'src/team/team.model';
@@ -10,6 +11,7 @@ import { Email } from 'src/types/Email';
 import { User } from 'src/user/user.model';
 import { TeamService } from 'src/team/team.service';
 import {
+  INVALID_EMAIL,
   TEAM_INVITE_ALREADY_MEMBER,
   TEAM_INVITE_EMAIL_DO_NOT_MATCH,
   TEAM_INVITE_MEMBER_HAS_INVITE,
@@ -19,6 +21,7 @@ import { TeamInvitation } from './team-invitation.model';
 import { MailerService } from 'src/mailer/mailer.service';
 import { UserService } from 'src/user/user.service';
 import { PubSubService } from 'src/pubsub/pubsub.service';
+import { validateEmail } from '../utils';
 
 @Injectable()
 export class TeamInvitationService {
@@ -63,6 +66,32 @@ export class TeamInvitationService {
     );
   }
 
+  /**
+   * Get the team invite for an invitee with email and teamID.
+   * @param inviteeEmail invitee email
+   * @param teamID team id
+   * @returns an Either of team invitation for the invitee or error
+   */
+  async getTeamInviteByEmailAndTeamID(inviteeEmail: string, teamID: string) {
+    const isEmailValid = validateEmail(inviteeEmail);
+    if (!isEmailValid) return E.left(INVALID_EMAIL);
+
+    try {
+      const teamInvite = await this.prisma.teamInvitation.findUniqueOrThrow({
+        where: {
+          teamID_inviteeEmail: {
+            inviteeEmail: inviteeEmail,
+            teamID: teamID,
+          },
+        },
+      });
+
+      return E.right(teamInvite);
+    } catch (e) {
+      return E.left(TEAM_INVITE_NO_INVITE_FOUND);
+    }
+  }
+
   createInvitation(
     creator: User,
     team: Team,