add create user and login user parts
This commit is contained in:
@@ -12,12 +12,20 @@
|
||||
const { checkPassword } = require("../utils/hashPassword.util");
|
||||
const { sendMail } = require("../utils/mail.util");
|
||||
const { generateOTP, validateOTP } = require("../utils/otp.util");
|
||||
const {getCachedUser,clearUserCache} = require("../utils/cache.util");
|
||||
const { getCachedUser, clearUserCache } = require("../utils/cache.util");
|
||||
const { generateToken } = require("../utils/jwt.util");
|
||||
const {
|
||||
createRefreshSession,
|
||||
validateRefreshSession,
|
||||
deleteRefreshSession,
|
||||
} = require("../utils/refreshSession.util");
|
||||
const db = require("../models");
|
||||
const { log } = require("../utils/consoleLog.utill");
|
||||
|
||||
const appName = process.env.APP_NAME || "Niolla";
|
||||
|
||||
const User = db.User;
|
||||
|
||||
// Login Step 1: Request OTP
|
||||
exports.loginReq = async (req, res) => {
|
||||
try {
|
||||
@@ -47,7 +55,7 @@ exports.loginReq = async (req, res) => {
|
||||
firstName: user.firstName,
|
||||
otp: otp,
|
||||
},
|
||||
text: `Hello ${user.firstName}, your otp is ${otp}`,
|
||||
text: `Hello ${user.firstName}, your otp is ${otp}`,
|
||||
});
|
||||
|
||||
log(`OTP for ${email}: ${otp}`);
|
||||
@@ -65,6 +73,12 @@ exports.login = async (req, res) => {
|
||||
try {
|
||||
const { email, otp } = req.body;
|
||||
|
||||
if (!email || !otp) {
|
||||
return res
|
||||
.status(400)
|
||||
.send({ success: false, message: "Email and OTP are required" });
|
||||
}
|
||||
|
||||
const user = await getCachedUser(email);
|
||||
|
||||
if (!user) {
|
||||
@@ -73,7 +87,14 @@ exports.login = async (req, res) => {
|
||||
.send({ success: false, message: "User Not Found" });
|
||||
}
|
||||
|
||||
const isValidOTP = validateOTP(email, otp);
|
||||
if (user.accountStatus !== "ACTIVE") {
|
||||
return res.status(403).send({
|
||||
success: false,
|
||||
message: "Account is not active",
|
||||
});
|
||||
}
|
||||
|
||||
const isValidOTP = validateOTP(email, String(otp));
|
||||
|
||||
if (!isValidOTP) {
|
||||
return res
|
||||
@@ -87,16 +108,24 @@ exports.login = async (req, res) => {
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
accountType: user.accountType,
|
||||
});
|
||||
|
||||
const { refreshToken } = createRefreshSession(user.id);
|
||||
|
||||
// 3. Set JWT as HttpOnly cookie
|
||||
res.cookie("access_token", token, {
|
||||
httpOnly: true, // JS cannot access
|
||||
secure: process.env.NODE_ENV === "production", // HTTPS only in prod
|
||||
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
|
||||
maxAge: 24 * 60 * 60 * 1000, // 1 day
|
||||
maxAge: 15 * 60 * 1000, // 1 day
|
||||
});
|
||||
|
||||
res.cookie("refresh_token", refreshToken, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
|
||||
});
|
||||
|
||||
log(`JWT issued for ${email}`);
|
||||
@@ -112,6 +141,7 @@ exports.login = async (req, res) => {
|
||||
lastName: user.lastName,
|
||||
role: user.role,
|
||||
accountType: user.accountType,
|
||||
accessToken: token,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -120,6 +150,83 @@ exports.login = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
exports.refreshToken = async (req, res) => {
|
||||
try {
|
||||
const refreshToken = req.cookies?.refresh_token;
|
||||
|
||||
if (!refreshToken) {
|
||||
return res.status(401).send({
|
||||
success: false,
|
||||
message: "Refresh token is required",
|
||||
});
|
||||
}
|
||||
|
||||
const session = validateRefreshSession(refreshToken);
|
||||
|
||||
if (!session) {
|
||||
res.clearCookie("refresh_token");
|
||||
|
||||
return res.status(401).send({
|
||||
success: false,
|
||||
message: "Invalid or expired session. Please login again.",
|
||||
});
|
||||
}
|
||||
|
||||
const user = await User.findByPk(session.userId);
|
||||
|
||||
if (!user || user.accountStatus !== "ACTIVE") {
|
||||
deleteRefreshSession(session.sessionId);
|
||||
|
||||
return res.status(401).send({
|
||||
success: false,
|
||||
message: "Session is no longer valid",
|
||||
});
|
||||
}
|
||||
|
||||
// Generate new Access Token
|
||||
const token = generateToken({
|
||||
id: user.id,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
accountType: user.accountType,
|
||||
});
|
||||
|
||||
// Generate new Refresh Token
|
||||
const { refreshToken: newRefreshToken } = createRefreshSession(user.id);
|
||||
|
||||
deleteRefreshSession(session.sessionId);
|
||||
|
||||
// Replace access cookie
|
||||
res.cookie("access_token", token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
|
||||
maxAge: 15 * 60 * 1000,
|
||||
});
|
||||
|
||||
// Replace refresh cookie
|
||||
res.cookie("refresh_token", newRefreshToken, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
|
||||
maxAge: 7 * 24 * 60 * 60 * 1000,
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
success: true,
|
||||
message: "Session refreshed successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("REFRESH ERROR:", error);
|
||||
|
||||
return res.status(401).send({
|
||||
success: false,
|
||||
message: "Invalid or expired session. Please login again.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Logout: Clear the JWT cookie
|
||||
exports.logout = (req, res) => {
|
||||
res.clearCookie("access_token", {
|
||||
|
||||
Reference in New Issue
Block a user