add OTP email sending functionality and integrate with user authentication flow

This commit is contained in:
faris Aljohari
2025-04-20 22:19:08 +03:00
parent 1e6503c072
commit 2b449e61ea
3 changed files with 134 additions and 70 deletions

View File

@ -19,5 +19,7 @@ export default registerAs(
process.env.MAILTRAP_DELETE_USER_TEMPLATE_UUID,
MAILTRAP_EDIT_USER_TEMPLATE_UUID:
process.env.MAILTRAP_EDIT_USER_TEMPLATE_UUID,
MAILTRAP_SEND_OTP_TEMPLATE_UUID:
process.env.MAILTRAP_SEND_OTP_TEMPLATE_UUID,
}),
);

View File

@ -181,6 +181,49 @@ export class EmailService {
);
}
}
async sendOtpEmailWithTemplate(
email: string,
emailEditData: any,
): Promise<void> {
const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN',
);
const API_URL = isProduction
? SEND_EMAIL_API_URL_PROD
: SEND_EMAIL_API_URL_DEV;
const TEMPLATE_UUID = this.configService.get<string>(
'email-config.MAILTRAP_SEND_OTP_TEMPLATE_UUID',
);
const emailData = {
from: {
email: this.smtpConfig.sender,
},
to: [
{
email: email,
},
],
template_uuid: TEMPLATE_UUID,
template_variables: emailEditData,
};
try {
await axios.post(API_URL, emailData, {
headers: {
Authorization: `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
},
});
} catch (error) {
throw new HttpException(
error.response?.data?.message ||
'Error sending email using Mailtrap template',
error.response?.status || HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
generateUserChangesEmailBody(
addedSpaceNames: string[],
removedSpaceNames: string[],

View File

@ -181,25 +181,25 @@ export class UserAuthService {
otpCode: string;
cooldown: number;
}> {
try {
const otpLimiter = new Date();
otpLimiter.setDate(
otpLimiter.getDate() - this.configService.get<number>('OTP_LIMITER'),
);
const userExists = await this.userRepository.exists({
const user = await this.userRepository.findOne({
where: {
region: data.regionUuid
? {
uuid: data.regionUuid,
}
: undefined,
region: data.regionUuid ? { uuid: data.regionUuid } : undefined,
email: data.email,
isUserVerified: data.type === OtpType.PASSWORD ? true : undefined,
},
});
if (!userExists) {
if (!user) {
throw new BadRequestException('User not found');
}
await this.otpRepository.softDelete({ email: data.email, type: data.type });
await this.otpRepository.softDelete({
email: data.email,
type: data.type,
});
await this.otpRepository.delete({
email: data.email,
type: data.type,
@ -250,10 +250,29 @@ export class UserAuthService {
},
});
cooldown = 30 * Math.pow(2, countOfOtpToReturn - 1);
const subject = 'OTP send successfully';
const message = `Your OTP code is ${otpCode}`;
this.emailService.sendEmail(data.email, subject, message);
const [otp1, otp2, otp3, otp4, otp5, otp6] = otpCode.split('');
await this.emailService.sendOtpEmailWithTemplate(data.email, {
name: user.firstName,
otp1,
otp2,
otp3,
otp4,
otp5,
otp6,
});
return { otpCode, cooldown };
} catch (error) {
if (error instanceof BadRequestException) {
throw error;
}
console.error('OTP generation error:', error);
throw new BadRequestException(
'An unexpected error occurred while generating the OTP.',
);
}
}
async verifyOTP(