Files
zod-backend/src/common/modules/otp/services/otp.service.ts
2025-08-23 21:52:59 +03:00

56 lines
2.3 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { NotificationsService } from '../../notification/services/notifications.service';
import { DEFAULT_OTP_DIGIT, DEFAULT_OTP_LENGTH } from '../constants';
import { OtpType } from '../enums';
import { ISendOtp, IVerifyOtp } from '../interfaces';
import { OtpRepository } from '../repositories';
import { generateRandomOtp } from '../utils';
@Injectable()
export class OtpService {
private readonly logger = new Logger(OtpService.name);
constructor(
private readonly configService: ConfigService,
private readonly otpRepository: OtpRepository,
private readonly notificationService: NotificationsService,
) {}
private useMock = [true, 'true'].includes(this.configService.get<boolean>('USE_MOCK', false));
async generateAndSendOtp(sendOtpRequest: ISendOtp): Promise<string> {
this.logger.log(`invalidate OTP for ${sendOtpRequest.recipient} and ${sendOtpRequest.otpType}`);
await this.otpRepository.invalidateOtp(sendOtpRequest);
this.logger.log(`Generating OTP for ${sendOtpRequest.recipient}`);
const otp = this.useMock ? DEFAULT_OTP_DIGIT.repeat(DEFAULT_OTP_LENGTH) : generateRandomOtp(DEFAULT_OTP_LENGTH);
await this.otpRepository.createOtp({ ...sendOtpRequest, value: otp });
await this.sendOtp(sendOtpRequest, otp);
this.logger.log(`OTP generated and sent successfully to ${sendOtpRequest.recipient}`);
return sendOtpRequest.otpType == OtpType.EMAIL
? sendOtpRequest.recipient
: sendOtpRequest.recipient?.replace(/.(?=.{4})/g, '*');
}
async verifyOtp(verifyOtpRequest: IVerifyOtp) {
this.logger.log(`Verifying OTP for ${verifyOtpRequest.userId}`);
const otp = await this.otpRepository.findOtp(verifyOtpRequest);
if (!otp) {
this.logger.error(
`OTP value ${verifyOtpRequest.value} not found for ${verifyOtpRequest.userId} and ${verifyOtpRequest.otpType} or used`,
);
return false;
}
await this.otpRepository.updateOtp(otp.id, { isUsed: true });
this.logger.log(`OTP verified successfully for ${verifyOtpRequest.userId}`);
return !!otp;
}
private sendOtp(sendOtpRequest: ISendOtp, otp: string) {
return this.notificationService.sendOtpNotification(sendOtpRequest, otp);
}
}