diff --git a/apps/api-gateway/src/authz/authz.controller.ts b/apps/api-gateway/src/authz/authz.controller.ts index 9fde40303..3896b3407 100644 --- a/apps/api-gateway/src/authz/authz.controller.ts +++ b/apps/api-gateway/src/authz/authz.controller.ts @@ -55,6 +55,9 @@ import { User } from './decorators/user.decorator'; import { user } from '@prisma/client'; import * as useragent from 'express-useragent'; import { EmptyStringParamPipe, TrimStringParamPipe } from '@credebl/common/cast.helper'; +import { Roles } from './decorators/roles.decorator'; +import { OrgRoles } from 'libs/org-roles/enums'; +import { OrgRolesGuard } from './guards/org-roles.guard'; @Controller('auth') @ApiTags('auth') @@ -143,6 +146,34 @@ export class AuthzController { return res.status(HttpStatus.CREATED).json(finalResponse); } + @Post('/verify-mail-manually') + @ApiResponse({ status: HttpStatus.CREATED, description: 'Created', type: ApiResponseDto }) + @UseGuards(AuthGuard('jwt'), OrgRolesGuard) + @Roles(OrgRoles.PLATFORM_ADMIN) + @ApiBearerAuth() + @ApiQuery({ + name: 'clientAlias', + required: false, + enum: (process.env.SUPPORTED_SSO_CLIENTS || '') + .split(',') + .map((alias) => alias.trim()?.toUpperCase()) + .filter(Boolean) + }) + @ApiOperation({ summary: 'Send verification email', description: 'Send verification email to new user' }) + async verifyEmailManually( + @Query('clientAlias', ClientAliasValidationPipe) clientAlias: string, + @Body() userEmailVerification: UserEmailVerificationDto, + @Res() res: Response + ): Promise { + userEmailVerification.clientAlias = clientAlias ?? (await getDefaultClient()).alias; + await this.authzService.sendVerificationMail(userEmailVerification); + const finalResponse: IResponseType = { + statusCode: HttpStatus.CREATED, + message: ResponseMessages.user.success.verificationSuccess + }; + return res.status(HttpStatus.CREATED).json(finalResponse); + } + /** * Registers a new user on the platform. * diff --git a/apps/api-gateway/src/authz/authz.service.ts b/apps/api-gateway/src/authz/authz.service.ts index a060788a4..c4cf3aa5e 100644 --- a/apps/api-gateway/src/authz/authz.service.ts +++ b/apps/api-gateway/src/authz/authz.service.ts @@ -42,6 +42,7 @@ export class AuthzService extends BaseService { } async sendVerificationMail(userEmailVerification: UserEmailVerificationDto): Promise { + userEmailVerification.isDefaultVerified = true; const payload = { userEmailVerification }; return this.natsClient.sendNatsMessage(this.authServiceProxy, 'send-verification-mail', payload); } diff --git a/apps/api-gateway/src/user/dto/create-user.dto.ts b/apps/api-gateway/src/user/dto/create-user.dto.ts index b52f3dc71..0101431c3 100644 --- a/apps/api-gateway/src/user/dto/create-user.dto.ts +++ b/apps/api-gateway/src/user/dto/create-user.dto.ts @@ -1,5 +1,5 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength } from 'class-validator'; +import { ApiHideProperty, ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString, IsUrl, MaxLength } from 'class-validator'; import { toLowerCase, trim } from '@credebl/common/cast.helper'; import { Transform } from 'class-transformer'; @@ -38,4 +38,9 @@ export class UserEmailVerificationDto { @IsString({ message: 'clientAlias should be string' }) @Transform(({ value }) => trim(value)) clientAlias?: string; + + @ApiHideProperty() + @IsOptional() + @IsBoolean({ message: 'isDefaultVerified should be boolean' }) + isDefaultVerified: boolean = false; } diff --git a/apps/user/src/user.service.ts b/apps/user/src/user.service.ts index 474dc6752..351a08406 100644 --- a/apps/user/src/user.service.ts +++ b/apps/user/src/user.service.ts @@ -113,7 +113,7 @@ export class UserService { async sendVerificationMail(userEmailVerification: ISendVerificationEmail): Promise { try { - const { email, brandLogoUrl, platformName, clientAlias } = userEmailVerification; + const { email, brandLogoUrl, platformName, clientAlias, isDefaultVerified } = userEmailVerification; if ('PROD' === process.env.PLATFORM_PROFILE_MODE) { // eslint-disable-next-line prefer-destructuring @@ -150,27 +150,32 @@ export class UserService { if (!redirectUrl) { throw new NotFoundException(ResponseMessages.user.error.redirectUrlNotFound); } - - sendVerificationMail = await this.sendEmailForVerification({ - email, - verificationCode: verifyCode, - redirectUrl, - clientId: clientDetails.clientId, - brandLogoUrl, - platformName, - redirectTo: clientDetails.domain, - clientAlias - }); + if (!isDefaultVerified) { + sendVerificationMail = await this.sendEmailForVerification({ + email, + verificationCode: verifyCode, + redirectUrl, + clientId: clientDetails.clientId, + brandLogoUrl, + platformName, + redirectTo: clientDetails.domain, + clientAlias + }); + } } catch (error) { throw new InternalServerErrorException(ResponseMessages.user.error.emailSend); } - if (sendVerificationMail) { + if (sendVerificationMail || isDefaultVerified) { const uniqueUsername = await this.createUsername(email, verifyCode); userEmailVerification.username = uniqueUsername; userEmailVerification.clientId = clientDetails.clientId; userEmailVerification.clientSecret = clientDetails.clientSecret; const resUser = await this.userRepository.createUser(userEmailVerification, verifyCode); + if (isDefaultVerified) { + this.logger.debug('In isDefaultVerified block'); + await this.verifyEmail({ email, verificationCode: verifyCode }); + } return resUser; } } catch (error) { diff --git a/libs/common/src/interfaces/user.interface.ts b/libs/common/src/interfaces/user.interface.ts index 54ab6f7fc..323eaab05 100644 --- a/libs/common/src/interfaces/user.interface.ts +++ b/libs/common/src/interfaces/user.interface.ts @@ -20,6 +20,7 @@ export interface ISendVerificationEmail { platformName?: string; redirectTo?: string; clientAlias?: string; + isDefaultVerified?: boolean; } export interface IClientDetailsSSO { diff --git a/libs/common/src/response-messages/index.ts b/libs/common/src/response-messages/index.ts index 8be466d1c..8b131575e 100644 --- a/libs/common/src/response-messages/index.ts +++ b/libs/common/src/response-messages/index.ts @@ -15,6 +15,7 @@ export const ResponseMessages = { newUser: 'User not found', checkEmail: 'User email checked successfully.', sendVerificationCode: 'Verification link has been successfully sent on the email. Please verify', + verificationSuccess: 'Verification Successful', userActivity: 'User activities fetched successfully', platformSettings: 'Platform settings updated', fetchPlatformSettings: 'Platform settings fetched',