/** * 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/user.controller.js const db = require("../models"); const { hashPassword } = require("../utils/hashPassword.util"); const { validatePassword } = require("../utils/validation/validatePassword.util"); const { generateUserId, generateId } = require("../utils/idGen.util"); const { logActivity } = require("../services/activity.service"); const { sendMail } = require("../utils/mail.util"); const User = db.User; const Profile = db.Profile; // Create a new user exports.createNewUser = async (req, res) => { const transaction = await db.sequelize.transaction(); try { const { firstName, lastName, email, password, accountType, } = req.body; const userExists = await User.findOne({ where: { email } }); if (userExists) { await transaction.rollback(); return res.status(400).send({ success: false, message: "User with this email already exists", }); } let pass; if(accountType === "admin" || accountType === "superadmin" || accountType === "manager" || accountType === "support_agent") { pass = process.env.DEFAULT_PASSWORD; }else{ pass = password; } const validatePasswordResult = validatePassword(pass); if (!validatePasswordResult) { await transaction.rollback(); return res.status(400).send({ success: false, message: "Password does not meet the required criteria", }); } const hashedPassword = await hashPassword(pass); const userID = generateUserId(); const newUser = await User.create( { id: userID, firstName, lastName, email, password: hashedPassword, accountType, }, { transaction }, ); const newProfile = await Profile.create( { profile_id: generateId(), user_id: newUser.id, theme: "light", notificationsEnabled: true, profilePicture_id: "N/A", backgroundImage_id: "N/A", dob: null, phone_number: null, }, { transaction }, ); await sendMail({ to: email, subject: "Welcome - Ocenic Titan", templateName: "welcome", templateVars: { firstName: firstName, email: email, password: process.env.DEFAULT_PASSWORD, }, text: `Hello ${firstName}, your account has been created successfully.`, }); await transaction.commit(); await logActivity({ user: req.user, description: `Created New User with ID: ${newUser.id}`, type: "CREATE_USER", module: "User Management", }); res.status(201).send({ success: true, message: "User Created Successfully", data: { id: newUser.id, firstName: newUser.firstName, lastName: newUser.lastName, email: newUser.email, accountType: newUser.accountType, role: newUser.role, department: newUser.department, }, }); } catch (error) { await transaction.rollback(); res.status(500).send({ success: false, message: "Failed to create user", error: error.message, }); } }; // Get users with pagination (20 per page) exports.getAllUsers = async (req, res) => { try { const page = parseInt(req.query.page) || 1; // default page = 1 const limit = 20; const offset = (page - 1) * limit; const { count, rows: users } = await User.findAndCountAll({ attributes: { exclude: ["password"] }, limit, offset, order: [["createdAt", "DESC"]], // optional sorting }); res.status(200).send({ success: true, data: users, pagination: { totalUsers: count, totalPages: Math.ceil(count / limit), currentPage: page, pageSize: limit, }, }); } catch (error) { res.status(500).send({ success: false, message: "Failed to retrieve users", error: error.message, }); } }; // Get user details by ID exports.getUserById = async (req, res) => { try { const { id } = req.params; const user = await User.findOne({ where: { id }, attributes: { exclude: ["password"] }, include: [{ model: Profile, as: "profile" }], }); if (!user) { return res.status(404).send({ success: false, message: "User not found", }); } res.status(200).send({ success: true, data: user, }); } catch (error) { res.status(500).send({ success: false, message: "Failed to retrieve user", error: error.message, }); } }; // Update user details exports.updateUser = async (req, res) => { const transaction = await db.sequelize.transaction(); try { const { id } = req.params; const { firstName, lastName, email, role, roleID, accountType, department, theme, notificationsEnabled, profilePicture_id, backgroundImage_id, dob, phone_number, } = req.body; const user = await User.findOne({ where: { id }, }); const UserProfile = await Profile.findOne({ where: { user_id: id }, }); if (!user) { return res.status(404).send({ success: false, message: "User not found", }); } if (!UserProfile) { return res.status(404).send({ success: false, message: "User profile not found", }); } user.firstName = firstName || user.firstName; user.lastName = lastName || user.lastName; user.role = role || user.role; user.roleID = roleID || user.roleID || "N/A"; user.accountType = accountType || user.accountType; user.department = department || user.department; UserProfile.theme = theme || UserProfile.theme; UserProfile.notificationsEnabled = notificationsEnabled !== undefined ? notificationsEnabled : UserProfile.notificationsEnabled; UserProfile.profilePicture_id = profilePicture_id || UserProfile.profilePicture_id || "N/A"; UserProfile.backgroundImage_id = backgroundImage_id || UserProfile.backgroundImage_id || "N/A"; UserProfile.dob = dob || UserProfile.dob; UserProfile.phone_number = phone_number || UserProfile.phone_number; await UserProfile.save({ transaction }); await user.save({ transaction }); await transaction.commit(); await logActivity({ user: req.user, description: `Updated User with ID: ${user.id}`, type: "UPDATE_USER", module: "User Management", }); const data = { id: user.id, firstName: user.firstName, lastName: user.lastName, email: user.email, accountType: user.accountType, role: user.role, department: user.department, profile: { theme: UserProfile.theme, notificationsEnabled: UserProfile.notificationsEnabled, profilePicture_id: UserProfile.profilePicture_id, backgroundImage_id: UserProfile.backgroundImage_id, dob: UserProfile.dob, phone_number: UserProfile.phone_number, }, }; res.status(200).send({ success: true, message: "User updated successfully", data, }); } catch (error) { await transaction.rollback(); res.status(500).send({ success: false, message: `Error: ${error.message}`, }); } }; // Delete user exports.deleteUser = async (req, res) => { const transaction = await db.sequelize.transaction(); try { const { id } = req.params; const user = await User.findOne({ where: { id }, }); if (!user) { return res.status(404).send({ success: false, message: "User not found", }); } await user.destroy({ transaction }); await transaction.commit(); await logActivity({ user: req.user, description: `Deleted User with ID: ${user.id}`, type: "DELETE_USER", module: "User Management", }); res.status(200).send({ success: true, message: "User deleted successfully", }); } catch (error) { await transaction.rollback(); res.status(500).send({ success: false, message: `Error: ${error.message}`, }); } };