diff --git a/libs/common/src/modules/Invite-user/entities/Invite-user.entity.ts b/libs/common/src/modules/Invite-user/entities/Invite-user.entity.ts index 345c1b8..04e5119 100644 --- a/libs/common/src/modules/Invite-user/entities/Invite-user.entity.ts +++ b/libs/common/src/modules/Invite-user/entities/Invite-user.entity.ts @@ -18,7 +18,7 @@ import { InviteUserDto, InviteUserSpaceDto } from '../dtos'; import { ProjectEntity } from '../../project/entities'; @Entity({ name: 'invite-user' }) -@Unique(['email', 'invitationCode', 'project']) +@Unique(['email', 'project']) export class InviteUserEntity extends AbstractEntity { @Column({ type: 'uuid', diff --git a/src/invite-user/services/invite-user.service.ts b/src/invite-user/services/invite-user.service.ts index 8d63959..f8aa1df 100644 --- a/src/invite-user/services/invite-user.service.ts +++ b/src/invite-user/services/invite-user.service.ts @@ -287,13 +287,12 @@ export class InviteUserService { // Update invited user and associated user data await this.inviteUserRepository.update( { uuid: invitedUser.uuid }, - { status: UserStatusEnum.ACTIVE }, + { status: UserStatusEnum.ACTIVE, user: { uuid: user.uuid } }, ); await this.userRepository.update( { uuid: user.uuid }, { project: { uuid: invitedUser.project.uuid }, - inviteUser: { uuid: invitedUser.uuid }, roleType: { uuid: invitedUser.roleType.uuid }, }, ); @@ -460,12 +459,12 @@ export class InviteUserService { projectUuid, } = dto; - const user = await this.userRepository.findOne({ - where: { inviteUser: { uuid: invitedUserUuid } }, - relations: ['userSpaces.space', 'userSpaces.space.community'], + const userData = await this.inviteUserRepository.findOne({ + where: { uuid: invitedUserUuid }, + relations: ['user.userSpaces.space', 'user.userSpaces.space.community'], }); - if (!user) { + if (!userData) { throw new HttpException( `User with invitedUserUuid ${invitedUserUuid} not found`, HttpStatus.NOT_FOUND, @@ -486,12 +485,12 @@ export class InviteUserService { ); // Disassociate the user from all current spaces - const disassociatePromises = user.userSpaces.map((userSpace) => + const disassociatePromises = userData.user.userSpaces.map((userSpace) => this.spaceUserService .disassociateUserFromSpace({ communityUuid: userSpace.space.community.uuid, spaceUuid: userSpace.space.uuid, - userUuid: user.uuid, + userUuid: userData.user.uuid, projectUuid, }) .catch((error) => { @@ -517,7 +516,7 @@ export class InviteUserService { // Grant permissions to the user for all devices in the space await this.userSpaceService.addUserPermissionsToDevices( - user.uuid, + userData.user.uuid, deviceUUIDs, ); @@ -525,7 +524,7 @@ export class InviteUserService { await this.spaceUserService.associateUserToSpace({ communityUuid: spaceDetails.communityUuid, spaceUuid: spaceUuid, - userUuid: user.uuid, + userUuid: userData.user.uuid, projectUuid, }); } catch (error) { @@ -584,30 +583,36 @@ export class InviteUserService { } if (userData.status === UserStatusEnum.INVITED) { - await this.updateUserStatus(invitedUserUuid, projectUuid, disable); + await this.updateUserStatus(invitedUserUuid, projectUuid, !disable); } else if (userData.status === UserStatusEnum.ACTIVE) { - const user = await this.userRepository.findOne({ - where: { inviteUser: { uuid: invitedUserUuid } }, - relations: ['userSpaces.space', 'userSpaces.space.community'], + const invitedUserData = await this.inviteUserRepository.findOne({ + where: { uuid: invitedUserUuid }, + relations: [ + 'user.userSpaces.space', + 'user.userSpaces.space.community', + ], }); - if (!user) { + if (!invitedUserData.user) { throw new HttpException( 'User account not found', HttpStatus.NOT_FOUND, ); } - if (!disable) { - await this.disassociateUserFromSpaces(user, projectUuid); - await this.updateUserStatus(invitedUserUuid, projectUuid, disable); - } else if (disable) { + if (disable) { + await this.disassociateUserFromSpaces( + invitedUserData.user, + projectUuid, + ); + await this.updateUserStatus(invitedUserUuid, projectUuid, !disable); + } else if (!disable) { await this.associateUserToSpaces( - user, + invitedUserData.user, userData, projectUuid, invitedUserUuid, - disable, + !disable, ); } } else { @@ -640,11 +645,11 @@ export class InviteUserService { private async updateUserStatus( invitedUserUuid: string, projectUuid: string, - disable: boolean, + isEnabled: boolean, ) { await this.inviteUserRepository.update( { uuid: invitedUserUuid, project: { uuid: projectUuid } }, - { isEnabled: disable }, + { isEnabled }, ); } @@ -727,25 +732,31 @@ export class InviteUserService { { isActive: false }, ); } else if (userData.status === UserStatusEnum.ACTIVE) { - const user = await this.userRepository.findOne({ - where: { inviteUser: { uuid: invitedUserUuid } }, - relations: ['userSpaces.space', 'userSpaces.space.community'], + const invitedUserData = await this.inviteUserRepository.findOne({ + where: { uuid: invitedUserUuid }, + relations: [ + 'user.userSpaces.space', + 'user.userSpaces.space.community', + ], }); - if (!user) { + if (!invitedUserData.user) { throw new HttpException( 'User account not found', HttpStatus.NOT_FOUND, ); } - await this.disassociateUserFromSpaces(user, userData.project.uuid); + await this.disassociateUserFromSpaces( + invitedUserData.user, + userData.project.uuid, + ); await this.inviteUserRepository.update( { uuid: invitedUserUuid }, { isActive: false }, ); await this.userRepository.update( - { uuid: user.uuid }, + { uuid: invitedUserData.user.uuid }, { isActive: false }, ); } diff --git a/src/space/space.module.ts b/src/space/space.module.ts index e4bddfc..9cc0519 100644 --- a/src/space/space.module.ts +++ b/src/space/space.module.ts @@ -66,7 +66,10 @@ import { CqrsModule } from '@nestjs/cqrs'; import { DisableSpaceHandler } from './handlers'; import { RegionRepository } from '@app/common/modules/region/repositories'; import { TimeZoneRepository } from '@app/common/modules/timezone/repositories'; -import { InviteUserRepository } from '@app/common/modules/Invite-user/repositiories'; +import { + InviteUserRepository, + InviteUserSpaceRepository, +} from '@app/common/modules/Invite-user/repositiories'; export const CommandHandlers = [DisableSpaceHandler]; @@ -124,6 +127,7 @@ export const CommandHandlers = [DisableSpaceHandler]; RegionRepository, TimeZoneRepository, InviteUserRepository, + InviteUserSpaceRepository, ], exports: [SpaceService], }) diff --git a/src/users/services/user-space.service.ts b/src/users/services/user-space.service.ts index 074dcf1..b96ca87 100644 --- a/src/users/services/user-space.service.ts +++ b/src/users/services/user-space.service.ts @@ -18,7 +18,10 @@ import { PermissionType } from '@app/common/constants/permission-type.enum'; import { InviteSpaceEntity } from '@app/common/modules/space/entities/invite-space.entity'; import { UserService } from './user.service'; import { RoleType } from '@app/common/constants/role.type.enum'; -import { InviteUserRepository } from '@app/common/modules/Invite-user/repositiories'; +import { + InviteUserRepository, + InviteUserSpaceRepository, +} from '@app/common/modules/Invite-user/repositiories'; import { UserStatusEnum } from '@app/common/constants/user-status.enum'; @Injectable() @@ -29,6 +32,7 @@ export class UserSpaceService { private readonly inviteSpaceRepository: InviteSpaceRepository, private readonly userService: UserService, private readonly inviteUserRepository: InviteUserRepository, + private readonly inviteUserSpaceRepository: InviteUserSpaceRepository, private readonly userDevicePermissionService: UserDevicePermissionService, ) {} @@ -141,23 +145,36 @@ export class UserSpaceService { ) { try { const space = await this.getProjectBySpaceUuid(spaceUuid); - - const inviteUser = this.inviteUserRepository.create({ - firstName: user.firstName, - lastName: user.lastName, - email: user.email, - jobTitle: null, - phoneNumber: null, - roleType: { uuid: user.role.uuid }, - status: UserStatusEnum.ACTIVE, - invitationCode: inviteCode, - invitedBy: RoleType.SPACE_OWNER, - project: { uuid: space.community.project.uuid }, + const invitedUserData = await this.inviteUserRepository.findOne({ + where: { + email: user.email, + project: { uuid: space.community.project.uuid }, + }, }); - await this.inviteUserRepository.save(inviteUser); + if (!invitedUserData) { + const inviteUser = this.inviteUserRepository.create({ + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + jobTitle: null, + phoneNumber: null, + roleType: { uuid: user.role.uuid }, + status: UserStatusEnum.ACTIVE, + invitationCode: inviteCode, + invitedBy: RoleType.SPACE_OWNER, + project: { uuid: space.community.project.uuid }, + }); + const invitedUser = await this.inviteUserRepository.save(inviteUser); + const inviteUserSpace = this.inviteUserSpaceRepository.create({ + inviteUser: { uuid: invitedUser.uuid }, + space: { uuid: spaceUuid }, + }); + + await this.inviteUserSpaceRepository.save(inviteUserSpace); + } } catch (err) { throw new HttpException( - err.message || 'Internal Server Error', + err.message || 'Failed to add user as an active invitation.', HttpStatus.INTERNAL_SERVER_ERROR, ); } diff --git a/src/users/user.module.ts b/src/users/user.module.ts index bf5164d..004ac32 100644 --- a/src/users/user.module.ts +++ b/src/users/user.module.ts @@ -19,7 +19,10 @@ import { import { UserDevicePermissionService } from 'src/user-device-permission/services'; import { DeviceUserPermissionRepository } from '@app/common/modules/device/repositories'; import { PermissionTypeRepository } from '@app/common/modules/permission/repositories'; -import { InviteUserRepository } from '@app/common/modules/Invite-user/repositiories'; +import { + InviteUserRepository, + InviteUserSpaceRepository, +} from '@app/common/modules/Invite-user/repositiories'; @Module({ imports: [ConfigModule, CommunityModule], @@ -38,6 +41,7 @@ import { InviteUserRepository } from '@app/common/modules/Invite-user/repositior UserSpaceService, InviteSpaceRepository, InviteUserRepository, + InviteUserSpaceRepository, ], exports: [UserService], })