From 9542f9334f307a858d9f0d0573a7eb67ccaf35bf Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:02:25 -0600 Subject: [PATCH] Refactor invite user service to validate spaces and improve code structure --- .../services/invite-user.service.ts | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/src/invite-user/services/invite-user.service.ts b/src/invite-user/services/invite-user.service.ts index 4a27387..df74f21 100644 --- a/src/invite-user/services/invite-user.service.ts +++ b/src/invite-user/services/invite-user.service.ts @@ -9,7 +9,7 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { UserStatusEnum } from '@app/common/constants/user-status.enum'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { generateRandomString } from '@app/common/helper/randomString'; -import { In, IsNull, Not, QueryRunner } from 'typeorm'; +import { EntityManager, In, IsNull, Not, QueryRunner } from 'typeorm'; import { DataSource } from 'typeorm'; import { UserEntity } from '@app/common/modules/user/entities'; import { RoleType } from '@app/common/constants/role.type.enum'; @@ -69,20 +69,27 @@ export class InviteUserService { const userRepo = queryRunner.manager.getRepository(UserEntity); await this.checkEmailAndProject({ email }); - const user = await userRepo.findOne({ + const existingUser = await userRepo.findOne({ where: { email, project: Not(IsNull()), }, }); - if (user) { + if (existingUser) { throw new HttpException( 'User already has a project', HttpStatus.BAD_REQUEST, ); } + // Validate spaces + const validSpaces = await this.validateSpaces( + spaceUuids, + queryRunner.manager, + ); + + // Create invitation const inviteUser = this.inviteUserRepository.create({ firstName, lastName, @@ -97,30 +104,25 @@ export class InviteUserService { }); const invitedUser = await queryRunner.manager.save(inviteUser); - const spaceRepo = queryRunner.manager.getRepository(SpaceEntity); - const spaces = await spaceRepo.find({ - where: { - uuid: In(spaceUuids), - }, - }); - const spaceNames = spaces.map((space) => space.spaceName); - - const spaceNamesString = spaceNames.join(', '); - const spacePromises = spaceUuids.map(async (spaceUuid) => { + // Link user to spaces + const spacePromises = validSpaces.map(async (space) => { const inviteUserSpace = this.inviteUserSpaceRepository.create({ inviteUser: { uuid: invitedUser.uuid }, - space: { uuid: spaceUuid }, + space: { uuid: space.uuid }, }); return queryRunner.manager.save(inviteUserSpace); }); await Promise.all(spacePromises); + + // Send invitation email + const spaceNames = validSpaces.map((space) => space.spaceName).join(', '); await this.emailService.sendEmailWithInvitationTemplate(email, { name: firstName, invitationCode, role: roleType, - spacesList: spaceNamesString, + spacesList: spaceNames, }); await queryRunner.commitTransaction(); @@ -147,6 +149,30 @@ export class InviteUserService { await queryRunner.release(); } } + private async validateSpaces( + spaceUuids: string[], + entityManager: EntityManager, + ): Promise { + const spaceRepo = entityManager.getRepository(SpaceEntity); + + const validSpaces = await spaceRepo.find({ + where: { uuid: In(spaceUuids) }, + }); + + if (validSpaces.length !== spaceUuids.length) { + const validSpaceUuids = validSpaces.map((space) => space.uuid); + const invalidSpaceUuids = spaceUuids.filter( + (uuid) => !validSpaceUuids.includes(uuid), + ); + throw new HttpException( + `Invalid space UUIDs: ${invalidSpaceUuids.join(', ')}`, + HttpStatus.BAD_REQUEST, + ); + } + + return validSpaces; + } + async checkEmailAndProject(dto: CheckEmailDto): Promise { const { email } = dto;