92 lines
2.1 KiB
JavaScript
92 lines
2.1 KiB
JavaScript
// 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,
|
|
};
|