/** * Copyright (c) 2026 Niolla * All rights reserved. * * This source code is proprietary and confidential. * Unauthorized copying, modification, distribution, or use * of this file, via any medium, is strictly prohibited. */ // app/utils/passwordReset.util.js const crypto = require("crypto"); const createRedisConnection = require("../config/redis.config"); const redis = createRedisConnection(); const db = require("../models"); const User = db.User; const { log } = require("./consoleLog.utill"); const { hashPassword } = require("./hashPassword.util"); const RESET_TOKEN_TTL = process.env.RESET_TOKEN_TTL || 10 * 60; // 10 minutes /** * Generate password reset token * * @param {string} userId * @returns {Promise} */ async function generateResetToken(userId) { try { const token = crypto.randomBytes(32).toString("hex"); const tokenHash = crypto .createHash("sha256") .update(token) .digest("hex"); await redis.set( `passwordReset:user:${userId}`, tokenHash, "EX", RESET_TOKEN_TTL ); log(`Generated password reset token for user ${userId} with TTL of ${RESET_TOKEN_TTL} seconds, Generated token:`, token); return token; } catch (error) { log("Password reset token generation failed", error); throw new Error("Failed to generate password reset token"); } } /** * Reset password using token * * @param {string} userId * @param {string} token * @param {string} newPassword */ async function resetPassword(userId, token, newPassword) { try { const storedHash = await redis.get( `passwordReset:user:${userId}` ); if (!storedHash) { throw new Error("Invalid or expired reset token"); } const tokenHash = crypto .createHash("sha256") .update(token) .digest("hex"); const isValid = crypto.timingSafeEqual( Buffer.from(storedHash), Buffer.from(tokenHash) ); if (!isValid) { throw new Error("Invalid or expired reset token"); } const user = await User.findByPk(userId); if (!user) { throw new Error("User not found"); } user.password = await hashPassword(newPassword); await user.save(); await redis.del(`passwordReset:user:${userId}`); log( `Password reset completed successfully for user ${userId}` ); return true; } catch (error) { log("Password reset failed", error); throw error; } } module.exports = { generateResetToken, resetPassword };