Add delete user invitation functionality

This commit is contained in:
faris Aljohari
2025-01-04 20:10:37 -06:00
parent 97da38e31d
commit 81ec60d947
6 changed files with 103 additions and 10 deletions

View File

@ -62,6 +62,8 @@ MAILTRAP_DISABLE_TEMPLATE_UUID=
MAILTRAP_ENABLE_TEMPLATE_UUID= MAILTRAP_ENABLE_TEMPLATE_UUID=
MAILTRAP_DELETE_USER_TEMPLATE_UUID=
WEBSITES_ENABLE_APP_SERVICE_STORAGE= WEBSITES_ENABLE_APP_SERVICE_STORAGE=
PORT= PORT=

View File

@ -15,5 +15,7 @@ export default registerAs(
process.env.MAILTRAP_INVITATION_TEMPLATE_UUID, process.env.MAILTRAP_INVITATION_TEMPLATE_UUID,
MAILTRAP_DISABLE_TEMPLATE_UUID: process.env.MAILTRAP_DISABLE_TEMPLATE_UUID, MAILTRAP_DISABLE_TEMPLATE_UUID: process.env.MAILTRAP_DISABLE_TEMPLATE_UUID,
MAILTRAP_ENABLE_TEMPLATE_UUID: process.env.MAILTRAP_ENABLE_TEMPLATE_UUID, MAILTRAP_ENABLE_TEMPLATE_UUID: process.env.MAILTRAP_ENABLE_TEMPLATE_UUID,
MAILTRAP_DELETE_USER_TEMPLATE_UUID:
process.env.MAILTRAP_DELETE_USER_TEMPLATE_UUID,
}), }),
); );

View File

@ -772,6 +772,12 @@ export class ControllerRoute {
public static readonly DISABLE_USER_INVITATION_DESCRIPTION = public static readonly DISABLE_USER_INVITATION_DESCRIPTION =
'This endpoint disables an invitation for a user to assign to role and spaces.'; 'This endpoint disables an invitation for a user to assign to role and spaces.';
public static readonly DELETE_USER_INVITATION_SUMMARY =
'Delete user invitation';
public static readonly DELETE_USER_INVITATION_DESCRIPTION =
'This endpoint deletes an invitation for a user to assign to role and spaces.';
public static readonly ACTIVATION_CODE_SUMMARY = public static readonly ACTIVATION_CODE_SUMMARY =
'Activate Invitation Code'; 'Activate Invitation Code';

View File

@ -83,13 +83,12 @@ export class EmailService {
); );
} }
} }
async sendEmailWithDisableOrEnableTemplate( async sendEmailWithTemplate(
email: string, email: string,
name: string, name: string,
isEnable: boolean, isEnable: boolean,
isDelete: boolean,
): Promise<void> { ): Promise<void> {
console.log(isEnable);
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>( const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN', 'email-config.MAILTRAP_API_TOKEN',
@ -97,12 +96,16 @@ export class EmailService {
const API_URL = isProduction const API_URL = isProduction
? SEND_EMAIL_API_URL_PROD ? SEND_EMAIL_API_URL_PROD
: SEND_EMAIL_API_URL_DEV; : SEND_EMAIL_API_URL_DEV;
const TEMPLATE_UUID = isEnable
// Determine the template UUID based on the arguments
const templateUuid = isDelete
? this.configService.get<string>( ? this.configService.get<string>(
'email-config.MAILTRAP_ENABLE_TEMPLATE_UUID', 'email-config.MAILTRAP_DELETE_USER_TEMPLATE_UUID',
) )
: this.configService.get<string>( : this.configService.get<string>(
'email-config.MAILTRAP_DISABLE_TEMPLATE_UUID', isEnable
? 'email-config.MAILTRAP_ENABLE_TEMPLATE_UUID'
: 'email-config.MAILTRAP_DISABLE_TEMPLATE_UUID',
); );
const emailData = { const emailData = {
@ -111,12 +114,12 @@ export class EmailService {
}, },
to: [ to: [
{ {
email: email, email,
}, },
], ],
template_uuid: TEMPLATE_UUID, template_uuid: templateUuid,
template_variables: { template_variables: {
name: name, name,
}, },
}; };

View File

@ -2,6 +2,7 @@ import { InviteUserService } from '../services/invite-user.service';
import { import {
Body, Body,
Controller, Controller,
Delete,
Param, Param,
Post, Post,
Put, Put,
@ -114,4 +115,17 @@ export class InviteUserController {
invitedUserUuid, invitedUserUuid,
); );
} }
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Delete(':invitedUserUuid')
@ApiOperation({
summary: ControllerRoute.INVITE_USER.ACTIONS.DELETE_USER_INVITATION_SUMMARY,
description:
ControllerRoute.INVITE_USER.ACTIONS.DELETE_USER_INVITATION_DESCRIPTION,
})
async deleteUserInvitation(
@Param('invitedUserUuid') invitedUserUuid: string,
): Promise<BaseResponseDto> {
return await this.inviteUserService.deleteUserInvitation(invitedUserUuid);
}
} }

View File

@ -524,10 +524,11 @@ export class InviteUserService {
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
); );
} }
await this.emailService.sendEmailWithDisableOrEnableTemplate( await this.emailService.sendEmailWithTemplate(
userData.email, userData.email,
userData.firstName, userData.firstName,
disable, disable,
false,
); );
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
@ -611,4 +612,69 @@ export class InviteUserService {
await Promise.allSettled(associatePromises); await Promise.allSettled(associatePromises);
} }
async deleteUserInvitation(
invitedUserUuid: string,
): Promise<BaseResponseDto> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.startTransaction();
try {
const userData = await this.inviteUserRepository.findOne({
where: { uuid: invitedUserUuid },
relations: ['roleType', 'spaces.space', 'project'],
});
if (!userData) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);
}
if (userData.status === UserStatusEnum.INVITED) {
await this.inviteUserRepository.update(
{ uuid: invitedUserUuid },
{ isActive: false },
);
} else if (userData.status === UserStatusEnum.ACTIVE) {
const user = await this.userRepository.findOne({
where: { inviteUser: { uuid: invitedUserUuid } },
relations: ['userSpaces.space', 'userSpaces.space.community'],
});
if (!user) {
throw new HttpException(
'User account not found',
HttpStatus.NOT_FOUND,
);
}
await this.disassociateUserFromSpaces(user, userData.project.uuid);
await this.inviteUserRepository.update(
{ uuid: invitedUserUuid },
{ isActive: false },
);
await this.userRepository.update(
{ uuid: user.uuid },
{ isActive: false },
);
}
await this.emailService.sendEmailWithTemplate(
userData.email,
userData.firstName,
false,
true,
);
await queryRunner.commitTransaction();
return new SuccessResponseDto({
statusCode: HttpStatus.OK,
success: true,
message: 'User invitation deleted successfully',
});
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
} }