324 lines
7.9 KiB
JavaScript
324 lines
7.9 KiB
JavaScript
/**
|
|
* 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 { 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,
|
|
role,
|
|
roleID,
|
|
accountType,
|
|
department,
|
|
} = req.body;
|
|
|
|
const hashedPassword = await hashPassword(process.env.DEFAULT_PASSWORD);
|
|
const userID = generateUserId();
|
|
|
|
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",
|
|
});
|
|
}
|
|
|
|
const newUser = await User.create(
|
|
{
|
|
id: userID,
|
|
firstName,
|
|
lastName,
|
|
email,
|
|
password: hashedPassword,
|
|
accountType,
|
|
role,
|
|
roleID: roleID || "N/A",
|
|
department: department || null,
|
|
},
|
|
{ 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}`,
|
|
});
|
|
}
|
|
};
|