Files
Zumri-Backend/app/utils/passwordReset.utill.js
T
Isuru Bimsara 81d0e65686 first commit
2026-08-14 22:46:02 +05:30

114 lines
2.5 KiB
JavaScript

/**
* 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<string>}
*/
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
};