// app/utils/emailVerification.util.js const crypto = require("crypto"); const { sendMail } = require("../utils/mail.util"); const redis = require("../config/redisClient"); const EMAIL_VERIFICATION_TTL = Number(process.env.EMAIL_VERIFICATION_TTL_SECONDS) || 1800; const generateEmailVerificationToken = () => { return crypto.randomBytes(32).toString("hex"); }; const hashEmailVerificationToken = (token) => { return crypto.createHash("sha256").update(token).digest("hex"); }; const createEmailVerification = async (userId) => { // 1. Generate raw token const token = generateEmailVerificationToken(); // 2. Hash token const tokenHash = hashEmailVerificationToken(token); // 3. Create Redis key const redisKey = `email-verification:${tokenHash}`; await redis.set(redisKey, userId, "EX", EMAIL_VERIFICATION_TTL); return token; }; /** * Check a verification token. */ const verifyEmailVerificationToken = async (token) => { if (!token || typeof token !== "string") { return null; } // 1. Hash token received from user const tokenHash = hashEmailVerificationToken(token); // 2. Build same Redis key const redisKey = `email-verification:${tokenHash}`; // 3. Search Redis const userId = await redis.get(redisKey); if (!userId) { return null; } return { userId, redisKey, }; }; //send verification email to user const sendVerificationEmail = async (email, firstName, verificationToken) => { const confirmationLink = `${process.env.FRONTEND_URL}/verify-email?token=${verificationToken}`; // Send email await sendMail({ to: email, subject: "Confirm Your ZUMRI Account", templateName: "emailVerification", templateVars: { customer_name: firstName, confirmation_link: confirmationLink, }, text: `Hello ${firstName}, please verify your ZUMRI account using this link: ${confirmationLink}`, }); }; const deleteEmailVerification = async (redisKey) => { await redis.del(redisKey); }; module.exports = { createEmailVerification, verifyEmailVerificationToken, sendVerificationEmail, deleteEmailVerification, hashEmailVerificationToken, };