mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2025-12-31 06:39:35 -06:00
233 lines
5.6 KiB
JavaScript
Executable File
233 lines
5.6 KiB
JavaScript
Executable File
import UserModel from "../../models/User.js";
|
|
import TeamModel from "../../models/Team.js";
|
|
import { GenerateAvatarImage } from "../../../utils/imageProcessing.js";
|
|
|
|
const DUPLICATE_KEY_CODE = 11000; // MongoDB error code for duplicate key
|
|
import { ParseBoolean } from "../../../utils/utils.js";
|
|
import ServiceRegistry from "../../../service/serviceRegistry.js";
|
|
import StringService from "../../../service/stringService.js";
|
|
const SERVICE_NAME = "userModule";
|
|
|
|
/**
|
|
* Insert a User
|
|
* @async
|
|
* @param {Express.Request} req
|
|
* @param {Express.Response} res
|
|
* @returns {Promise<UserModel>}
|
|
* @throws {Error}
|
|
*/
|
|
const insertUser = async (
|
|
userData,
|
|
imageFile,
|
|
generateAvatarImage = GenerateAvatarImage
|
|
) => {
|
|
const stringService = ServiceRegistry.get(StringService.SERVICE_NAME);
|
|
try {
|
|
if (imageFile) {
|
|
// 1. Save the full size image
|
|
userData.profileImage = {
|
|
data: imageFile.buffer,
|
|
contentType: imageFile.mimetype,
|
|
};
|
|
|
|
// 2. Get the avatar sized image
|
|
const avatar = await generateAvatarImage(imageFile);
|
|
userData.avatarImage = avatar;
|
|
}
|
|
|
|
// Handle creating team if superadmin
|
|
if (userData.role.includes("superadmin")) {
|
|
const team = new TeamModel({
|
|
email: userData.email,
|
|
});
|
|
userData.teamId = team._id;
|
|
userData.checkTTL = 60 * 60 * 24 * 30;
|
|
await team.save();
|
|
}
|
|
|
|
const newUser = new UserModel(userData);
|
|
await newUser.save();
|
|
return await UserModel.findOne({ _id: newUser._id })
|
|
.select("-password")
|
|
.select("-profileImage"); // .select() doesn't work with create, need to save then find
|
|
} catch (error) {
|
|
if (error.code === DUPLICATE_KEY_CODE) {
|
|
error.message = stringService.dbUserExists;
|
|
}
|
|
error.service = SERVICE_NAME;
|
|
error.method = "insertUser";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get User by Email
|
|
* Gets a user by Email. Not sure if we'll ever need this except for login.
|
|
* If not needed except for login, we can move password comparison here
|
|
* Throws error if user not found
|
|
* @async
|
|
* @param {Express.Request} req
|
|
* @param {Express.Response} res
|
|
* @returns {Promise<UserModel>}
|
|
* @throws {Error}
|
|
*/
|
|
const getUserByEmail = async (email) => {
|
|
const stringService = ServiceRegistry.get(StringService.SERVICE_NAME);
|
|
|
|
try {
|
|
// Need the password to be able to compare, removed .select()
|
|
// We can strip the hash before returning the user
|
|
const user = await UserModel.findOne({ email: email }).select("-profileImage");
|
|
if (!user) {
|
|
throw new Error(stringService.dbUserNotFound);
|
|
}
|
|
return user;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "getUserByEmail";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Update a user by ID
|
|
* @async
|
|
* @param {Express.Request} req
|
|
* @param {Express.Response} res
|
|
* @returns {Promise<UserModel>}
|
|
* @throws {Error}
|
|
*/
|
|
|
|
const updateUser = async (
|
|
req,
|
|
res,
|
|
parseBoolean = ParseBoolean,
|
|
generateAvatarImage = GenerateAvatarImage
|
|
) => {
|
|
const candidateUserId = req.params.userId;
|
|
try {
|
|
const candidateUser = { ...req.body };
|
|
// ******************************************
|
|
// Handle profile image
|
|
// ******************************************
|
|
|
|
if (parseBoolean(candidateUser.deleteProfileImage) === true) {
|
|
candidateUser.profileImage = null;
|
|
candidateUser.avatarImage = null;
|
|
} else if (req.file) {
|
|
// 1. Save the full size image
|
|
candidateUser.profileImage = {
|
|
data: req.file.buffer,
|
|
contentType: req.file.mimetype,
|
|
};
|
|
|
|
// 2. Get the avatar sized image
|
|
const avatar = await generateAvatarImage(req.file);
|
|
candidateUser.avatarImage = avatar;
|
|
}
|
|
|
|
// ******************************************
|
|
// End handling profile image
|
|
// ******************************************
|
|
|
|
const updatedUser = await UserModel.findByIdAndUpdate(
|
|
candidateUserId,
|
|
candidateUser,
|
|
{ new: true } // Returns updated user instead of pre-update user
|
|
)
|
|
.select("-password")
|
|
.select("-profileImage");
|
|
return updatedUser;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "updateUser";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Delete a user by ID
|
|
* @async
|
|
* @param {Express.Request} req
|
|
* @param {Express.Response} res
|
|
* @returns {Promise<UserModel>}
|
|
* @throws {Error}
|
|
*/
|
|
const deleteUser = async (userId) => {
|
|
const stringService = ServiceRegistry.get(StringService.SERVICE_NAME);
|
|
|
|
try {
|
|
const deletedUser = await UserModel.findByIdAndDelete(userId);
|
|
if (!deletedUser) {
|
|
throw new Error(stringService.dbUserNotFound);
|
|
}
|
|
return deletedUser;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "deleteUser";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Delete a user by ID
|
|
* @async
|
|
* @param {string} teamId
|
|
* @returns {void}
|
|
* @throws {Error}
|
|
*/
|
|
const deleteTeam = async (teamId) => {
|
|
try {
|
|
await TeamModel.findByIdAndDelete(teamId);
|
|
return true;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "deleteTeam";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const deleteAllOtherUsers = async () => {
|
|
try {
|
|
await UserModel.deleteMany({ role: { $ne: "superadmin" } });
|
|
return true;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "deleteAllOtherUsers";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const getAllUsers = async (req, res) => {
|
|
try {
|
|
const users = await UserModel.find().select("-password").select("-profileImage");
|
|
return users;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "getAllUsers";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
const logoutUser = async (userId) => {
|
|
try {
|
|
await UserModel.updateOne({ _id: userId }, { $unset: { authToken: null } });
|
|
return true;
|
|
} catch (error) {
|
|
error.service = SERVICE_NAME;
|
|
error.method = "logoutUser";
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export {
|
|
insertUser,
|
|
getUserByEmail,
|
|
updateUser,
|
|
deleteUser,
|
|
deleteTeam,
|
|
deleteAllOtherUsers,
|
|
getAllUsers,
|
|
logoutUser,
|
|
};
|