chore: add loger

This commit is contained in:
Nathnael
2026-07-03 11:48:39 +00:00
parent 2d71f24937
commit 37ec1c40ab

View File

@@ -1,9 +1,6 @@
// otp.service.ts
import {
BadRequestException,
Injectable,
} from "@nestjs/common";
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
import { OtpRepository } from "./otp.repository";
@@ -16,20 +13,19 @@ export type OtpTarget = { phone?: string; email?: string };
@Injectable()
export class OtpService {
logger = new Logger(OtpService.name);
constructor(
private readonly otpRepository: OtpRepository,
private readonly smsClient: SmsClientService,
private readonly emailClient: EmailClientService
) {}
private readonly emailClient: EmailClientService,
) { }
// ---------------------------------------------------------------------------
// Generate OTP
// ---------------------------------------------------------------------------
generateOtp(): string {
return Math.floor(
100000 + Math.random() * 900000
).toString();
return Math.floor(100000 + Math.random() * 900000).toString();
}
// ---------------------------------------------------------------------------
@@ -44,23 +40,14 @@ export class OtpService {
const otp = this.generateOtp();
// find existing row for this channel
const existing =
await this.otpRepository.findByTarget(
target
);
const existing = await this.otpRepository.findByTarget(target);
// update existing otp
if (existing) {
await this.otpRepository.updateOtp(
existing,
otp
);
await this.otpRepository.updateOtp(existing, otp);
} else {
// create new otp
await this.otpRepository.createOtp(
target,
otp
);
await this.otpRepository.createOtp(target, otp);
}
if (target.email) {
@@ -78,18 +65,16 @@ export class OtpService {
});
}
this.logger.log(`OTP send for ${target.email ?? target.phone}: ${otp}`);
return {
success: true,
message:
"OTP sent successfully",
message: "OTP sent successfully",
};
} catch (error) {
console.log(error);
throw new BadRequestException(
"Failed to send OTP"
);
throw new BadRequestException("Failed to send OTP");
}
}
@@ -97,44 +82,31 @@ export class OtpService {
// Verify OTP
// ---------------------------------------------------------------------------
async verifyOtp(
target: OtpTarget,
otp: string
) {
async verifyOtp(target: OtpTarget, otp: string) {
// find the channel's row
const otpData =
await this.otpRepository.findByTarget(
target
);
const otpData = await this.otpRepository.findByTarget(target);
// not found
if (!otpData) {
throw new BadRequestException(
target.email
? "Email address not found"
: "Phone number not found"
target.email ? "Email address not found" : "Phone number not found",
);
}
// invalid otp
if (otpData.otp !== otp) {
throw new BadRequestException(
"Invalid OTP"
);
throw new BadRequestException("Invalid OTP");
}
// mark verified
await this.otpRepository.markVerified(
otpData
);
await this.otpRepository.markVerified(otpData);
return {
success: true,
message:
target.email
? "Email verified successfully"
: "Phone verified successfully",
message: target.email
? "Email verified successfully"
: "Phone verified successfully",
};
}
@@ -146,51 +118,34 @@ export class OtpService {
// contract signature). Unlike verifyOtp above — which marks a phone verified
// and leaves the code in place — this enforces a short TTL and consumes the
// code on success so it can never be replayed.
private readonly ACTION_OTP_TTL_MS =
5 * 60 * 1000;
private readonly ACTION_OTP_TTL_MS = 5 * 60 * 1000;
async verifyOtpForAction(
phone: string,
otp: string
) {
const otpData =
await this.otpRepository.findByPhone(
phone
);
async verifyOtpForAction(phone: string, otp: string) {
const otpData = await this.otpRepository.findByPhone(phone);
if (!otpData) {
throw new BadRequestException(
"No verification code was requested for this phone"
"No verification code was requested for this phone",
);
}
const ageMs =
Date.now() -
new Date(
otpData.updatedAt
).getTime();
const ageMs = Date.now() - new Date(otpData.updatedAt).getTime();
if (ageMs > this.ACTION_OTP_TTL_MS) {
await this.otpRepository.deleteOtp(
otpData
);
await this.otpRepository.deleteOtp(otpData);
throw new BadRequestException(
"Verification code has expired. Request a new one."
"Verification code has expired. Request a new one.",
);
}
if (otpData.otp !== otp) {
throw new BadRequestException(
"Invalid verification code"
);
throw new BadRequestException("Invalid verification code");
}
// single-use: consume on success
await this.otpRepository.deleteOtp(
otpData
);
await this.otpRepository.deleteOtp(otpData);
return { success: true };
}
}
}