const userModel = require("../models/user.model") const bcrypt = require("bcryptjs") const jwt = require("jsonwebtoken") const tokenBlacklistModel = require("../models/blacklist.model") /** * @name registerUserController * @description register a new user, expects username, email and password in the request body * @access Public */ async function registerUserController(req, res) { try { const { username, email, password } = req.body if (!username || !email || !password) { return res.status(400).json({ message: "Please provide username, email and password" }) } const isUserAlreadyExists = await userModel.findOne({ $or: [ { username }, { email } ] }) if (isUserAlreadyExists) { if (isUserAlreadyExists.email === email) { return res.status(400).json({ message: "Account already exists with this email address" }) } if (isUserAlreadyExists.username === username) { return res.status(400).json({ message: "Account already exists with this username" }) } } const hash = await bcrypt.hash(password, 10) const user = await userModel.create({ username, email, password: hash }) res.status(201).json({ message: "User registered successfully", user: { id: user._id, username: user.username, email: user.email } }) } catch (err) { console.error("registerUserController error:", err) res.status(500).json({ message: "Registration failed. Please try again." }) } } /** * @name loginUserController * @description login a user, expects email and password in the request body * @access Public */ async function loginUserController(req, res) { try { const { email, password } = req.body const user = await userModel.findOne({ email }) if (!user) { return res.status(400).json({ message: "Invalid email or password" }) } const isPasswordValid = await bcrypt.compare(password, user.password) if (!isPasswordValid) { return res.status(400).json({ message: "Invalid email or password" }) } const token = jwt.sign( { id: user._id, username: user.username }, process.env.JWT_SECRET, { expiresIn: "1d" } ) res.cookie("token", token, { httpOnly: true, sameSite: "none", secure: true }) res.status(200).json({ message: "User loggedIn successfully.", user: { id: user._id, username: user.username, email: user.email } }) } catch (err) { console.error("loginUserController error:", err) res.status(500).json({ message: "Login failed. Please try again." }) } } /** * @name logoutUserController * @description clear token from user cookie and add the token in blacklist * @access public */ async function logoutUserController(req, res) { const token = req.cookies.token if (token) { await tokenBlacklistModel.create({ token }) } res.clearCookie("token", { httpOnly: true, sameSite: "none", secure: true }) res.status(200).json({ message: "User logged out successfully" }) } /** * @name getMeController * @description get the current logged in user details. * @access private */ async function getMeController(req, res) { const user = await userModel.findById(req.user.id) res.status(200).json({ message: "User details fetched successfully", user: { id: user._id, username: user.username, email: user.email } }) } module.exports = { registerUserController, loginUserController, logoutUserController, getMeController }