Remove invitationCode from unique constraint and update invite user logic

This commit is contained in:
faris Aljohari
2025-01-11 01:39:52 -06:00
parent 35b6f9f478
commit 78617dde83
5 changed files with 83 additions and 47 deletions

View File

@ -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<InviteUserDto> {
@Column({
type: 'uuid',

View File

@ -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 },
);
}

View File

@ -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],
})

View File

@ -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,
);
}

View File

@ -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],
})