/** * 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/controllers/auth.controller.js 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 { generateToken } = require("../utils/jwt.util"); const { log } = require("../utils/consoleLog.utill"); const appName = process.env.APP_NAME || "Niolla"; // Login Step 1: Request OTP exports.loginReq = async (req, res) => { try { const { email, password } = req.body; const user = await getCachedUser(email); if (!user) { return res .status(404) .send({ success: false, message: "User Not Found" }); } const passwordIsValid = await checkPassword(password, user.password); if (!passwordIsValid) { return res .status(401) .send({ success: false, message: "Invalid Password" }); } const otp = generateOTP(email); await sendMail({ to: email, subject: `OTP for Your ${appName} Account`, templateName: "otp", templateVars: { firstName: user.firstName, otp: otp, }, text: `Hello ${user.firstName}, your otp is ${otp}`, }); log(`OTP for ${email}: ${otp}`); log(`OTP sent to ${email} successfully.`); res.status(201).send({ success: true, message: "OTP Sent Successfully" }); } catch (error) { log("Error occurred while sending OTP:", error); res.status(500).send({ success: false, message: error.message }); } }; // Login Step 2: Verify OTP and issue JWT exports.login = async (req, res) => { try { const { email, otp } = req.body; const user = await getCachedUser(email); if (!user) { return res .status(404) .send({ success: false, message: "User Not Found" }); } const isValidOTP = validateOTP(email, otp); if (!isValidOTP) { return res .status(401) .send({ success: false, message: "Invalid or Expired OTP" }); } // Generate JWT token const token = generateToken({ id: user.id, firstName: user.firstName, lastName: user.lastName, email: user.email, role: user.role, accountType: user.accountType, }); // 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 }); log(`JWT issued for ${email}`); clearUserCache(email); res.status(200).send({ success: true, message: "Login Successful", data: { id: user.id, email: user.email, firstName: user.firstName, lastName: user.lastName, role: user.role, accountType: user.accountType, }, }); } catch (error) { log("Error occurred during login:", error); res.status(500).send({ success: false, message: error.message }); } }; // Logout: Clear the JWT cookie exports.logout = (req, res) => { res.clearCookie("access_token", { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax", }); res.json({ success: true, message: "Logged out successfully" }); };