63 lines
1.4 KiB
TypeScript
63 lines
1.4 KiB
TypeScript
|
|
import * as bcrypt from "bcryptjs";
|
|||
|
|
import { OtpGenerator, OtpGeneratorSixDigit } from "./OtpGenerator";
|
|||
|
|
import { encryptUserId } from "./CodeGenerator";
|
|||
|
|
|
|||
|
|
export interface OtpResult {
|
|||
|
|
otp: string;
|
|||
|
|
hashedOtp: string;
|
|||
|
|
expiry: Date;
|
|||
|
|
encryptedId: string;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export async function resendOtpHelper(
|
|||
|
|
prisma: any,
|
|||
|
|
userId: number,
|
|||
|
|
emailPurpose: "Register" | "Login" | "ForgotPassword",
|
|||
|
|
otpLength: 4 | 6 = 4,
|
|||
|
|
expiryMinutes: number = 5
|
|||
|
|
): Promise<OtpResult> {
|
|||
|
|
|
|||
|
|
// 1️⃣ Deactivate previous OTPs
|
|||
|
|
await prisma.userOtp.updateMany({
|
|||
|
|
where: {
|
|||
|
|
userXid: userId,
|
|||
|
|
otpType: emailPurpose,
|
|||
|
|
isActive: true,
|
|||
|
|
},
|
|||
|
|
data: {
|
|||
|
|
isActive: false,
|
|||
|
|
isVerified: true,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 2️⃣ Generate new OTP
|
|||
|
|
const otp =
|
|||
|
|
otpLength === 6
|
|||
|
|
? OtpGeneratorSixDigit.generateOtp()
|
|||
|
|
: OtpGenerator.generateOtp();
|
|||
|
|
|
|||
|
|
const hashedOtp = await bcrypt.hash(otp, 10);
|
|||
|
|
const expiry = new Date(Date.now() + expiryMinutes * 60000);
|
|||
|
|
const encryptedId = encryptUserId(userId.toString());
|
|||
|
|
|
|||
|
|
// 3️⃣ Insert new OTP into table
|
|||
|
|
await prisma.userOtp.create({
|
|||
|
|
data: {
|
|||
|
|
userXid: userId,
|
|||
|
|
otpType: emailPurpose,
|
|||
|
|
otpCode: hashedOtp,
|
|||
|
|
expiresOn: expiry,
|
|||
|
|
isVerified: false,
|
|||
|
|
isActive: true,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 4️⃣ Return new OTP (email will use this)
|
|||
|
|
return {
|
|||
|
|
otp,
|
|||
|
|
hashedOtp,
|
|||
|
|
expiry,
|
|||
|
|
encryptedId,
|
|||
|
|
};
|
|||
|
|
}
|