const express = require("express"); const bcrypt = require("bcrypt"); const { query } = require("../config/database"); const logger = require("../config/logger"); const { validators, handleValidationErrors, } = require("../middleware/validators"); const { asyncHandler } = require("../middleware/errorHandler"); const { sendSuccess, sendError, sendUnauthorized, } = require("../utils/responseHelpers"); const { HTTP_STATUS } = require("../config/constants"); const { recordFailedAttempt, resetFailedAttempts, checkBlocked, } = require("../middleware/bruteForceProtection"); const router = express.Router(); const getUserByEmail = async (email) => { const result = await query( `SELECT u.id, u.email, u.username, u.passwordhash, u.role_id, u.isactive, r.name as role_name, r.permissions FROM adminusers u LEFT JOIN roles r ON u.role_id = r.id WHERE u.email = $1`, [email] ); return result.rows[0] || null; }; const updateLastLogin = async (userId) => { await query("UPDATE adminusers SET last_login = NOW() WHERE id = $1", [ userId, ]); }; const createUserSession = (req, user) => { req.session.user = { id: user.id, email: user.email, username: user.username, role_id: user.role_id, role_name: user.role_name, permissions: user.permissions, }; }; // Login endpoint router.post( "/login", checkBlocked, validators.login, handleValidationErrors, asyncHandler(async (req, res) => { const { email, password } = req.body; const ip = req.ip || req.connection.remoteAddress; const admin = await getUserByEmail(email); if (!admin) { logger.warn("Login attempt with invalid email", { email, ip }); recordFailedAttempt(ip); return sendUnauthorized(res, "Invalid email or password"); } if (!admin.isactive) { logger.warn("Login attempt with deactivated account", { email, ip }); recordFailedAttempt(ip); return sendUnauthorized(res, "Account is deactivated"); } const validPassword = await bcrypt.compare(password, admin.passwordhash); if (!validPassword) { logger.warn("Login attempt with invalid password", { email, ip }); recordFailedAttempt(ip); return sendUnauthorized(res, "Invalid email or password"); } // Reset failed attempts on successful login resetFailedAttempts(ip); await updateLastLogin(admin.id); createUserSession(req, admin); req.session.save((err) => { if (err) { logger.error("Session save error:", err); return sendError(res, "Session error"); } logger.info("User logged in successfully", { userId: admin.id, email: admin.email, ip, }); sendSuccess(res, { user: req.session.user }); }); }) ); // Check session endpoint router.get("/session", (req, res) => { if (req.session?.user) { return sendSuccess(res, { authenticated: true, user: req.session.user }); } res.status(HTTP_STATUS.UNAUTHORIZED).json({ authenticated: false }); }); // Logout endpoint router.post("/logout", (req, res) => { const userId = req.session?.user?.id; req.session.destroy((err) => { if (err) { logger.error("Logout error:", err); return sendError(res, "Logout failed"); } logger.info("User logged out", { userId }); sendSuccess(res, { message: "Logged out successfully" }); }); }); module.exports = router;