made resend otp lambda
This commit is contained in:
81
src/modules/host/handlers/resendOtp.ts
Normal file
81
src/modules/host/handlers/resendOtp.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
|
||||
import { PrismaService } from "../../../common/database/prisma.service";
|
||||
import { safeHandler } from "../../../common/utils/handlers/safeHandler";
|
||||
import ApiError from "../../../common/utils/helper/ApiError";
|
||||
import { resendOtpHelper } from "../../../common/utils/helper/resendOtpHelper";
|
||||
import { resendOtpEmail } from "../services/resendOTPEmail.service";
|
||||
|
||||
const prisma = new PrismaService();
|
||||
|
||||
// allowed purposes
|
||||
const ALLOWED_PURPOSES = ["Register", "Login", "ForgotPassword"] as const;
|
||||
type OtpPurpose = typeof ALLOWED_PURPOSES[number];
|
||||
|
||||
export const handler = safeHandler(
|
||||
async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||
// parse body safely
|
||||
let body: { email?: string; purpose?: string } = {};
|
||||
try {
|
||||
body = event.body ? JSON.parse(event.body) : {};
|
||||
} catch {
|
||||
throw new ApiError(400, "Invalid JSON in request body");
|
||||
}
|
||||
|
||||
// allow passing purpose via query string too (useful for GET requests)
|
||||
const qsPurpose = event.queryStringParameters?.purpose;
|
||||
const purposeRaw = (body.purpose || qsPurpose || "").trim();
|
||||
|
||||
if (!purposeRaw) {
|
||||
throw new ApiError(400, "purpose is required. Allowed values: Register, Login, ForgotPassword");
|
||||
}
|
||||
|
||||
if (!ALLOWED_PURPOSES.includes(purposeRaw as OtpPurpose)) {
|
||||
throw new ApiError(
|
||||
400,
|
||||
`Invalid purpose '${purposeRaw}'. Allowed values: ${ALLOWED_PURPOSES.join(", ")}`
|
||||
);
|
||||
}
|
||||
|
||||
const purpose = purposeRaw as OtpPurpose;
|
||||
|
||||
const email = (body.email || "").trim();
|
||||
if (!email) throw new ApiError(400, "Email is required");
|
||||
|
||||
// find user (you can adapt the isActive / userStatus checks per your rules)
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { emailAddress: email, isActive: true },
|
||||
select: { id: true, emailAddress: true, role: true },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new ApiError(404, "User not found");
|
||||
}
|
||||
const role = user.role.roleName
|
||||
|
||||
// call resend helper (old OTPs become inactive + verified, new OTP gets created)
|
||||
const otpResult = await resendOtpHelper(
|
||||
prisma,
|
||||
user.id,
|
||||
user.emailAddress,
|
||||
purpose,
|
||||
6, // 6-digit OTP
|
||||
5 // expires in 5 minutes
|
||||
);
|
||||
|
||||
// send email (use appropriate template based on 'purpose' inside the email service)
|
||||
await resendOtpEmail(user.emailAddress, otpResult.otp, role);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
success: true,
|
||||
message: "OTP resent successfully.",
|
||||
data: { purpose },
|
||||
}),
|
||||
};
|
||||
}
|
||||
);
|
||||
39
src/modules/host/services/resendOTPEmail.service.ts
Normal file
39
src/modules/host/services/resendOTPEmail.service.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { brevoService } from "@/common/email/brevoApi";
|
||||
import ApiError from "@/common/utils/helper/ApiError";
|
||||
|
||||
export async function resendOtpEmail(
|
||||
emailAddress: string,
|
||||
otp: string | number,
|
||||
role: string
|
||||
): Promise<{
|
||||
sent: boolean;
|
||||
// messageId: string
|
||||
}> {
|
||||
|
||||
const subject = "New OTP from Minglar Team";
|
||||
|
||||
const htmlContent = `
|
||||
<p>Dear ${role},</p>
|
||||
<p>Your new OTP is: <strong>${otp}</strong></p>
|
||||
<p>This code is valid for 5 minutes. Please do not share it with anyone.</p>
|
||||
<p>Best regards,<br/>Minglar Team</p>
|
||||
`;
|
||||
|
||||
try {
|
||||
const result = await brevoService.sendEmail({
|
||||
recipients: [{ email: emailAddress }],
|
||||
subject,
|
||||
htmlContent,
|
||||
});
|
||||
|
||||
// console.log("📧 Email sent successfully:", result);
|
||||
|
||||
return {
|
||||
sent: true,
|
||||
// messageId: result.messageId
|
||||
};
|
||||
} catch (err) {
|
||||
console.error("Brevo email send failed:", err);
|
||||
throw new ApiError(500, "Failed to send OTP to host via email.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user