2025-04-20 11:29:53 -07:00
const SERVICE_NAME = "userModule" ;
2025-07-30 10:41:53 -07:00
const DUPLICATE_KEY_CODE = 11000 ; // MongoDB error code for duplicate key
2025-04-20 11:29:53 -07:00
2025-07-30 10:41:53 -07:00
class UserModule {
constructor ({ User , Team , GenerateAvatarImage , ParseBoolean , stringService }) {
this . User = User ;
this . Team = Team ;
this . GenerateAvatarImage = GenerateAvatarImage ;
this . ParseBoolean = ParseBoolean ;
this . stringService = stringService ;
2025-07-23 11:46:59 -07:00
}
2025-07-30 10:41:53 -07:00
checkSuperadmin = async () => {
try {
const superAdmin = await this . User . findOne ({ role : "superadmin" });
if ( superAdmin !== null ) {
return true ;
}
return false ;
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "checkSuperadmin" ;
throw error ;
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
};
insertUser = async ( userData , imageFile ) => {
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 this . GenerateAvatarImage ( imageFile );
userData . avatarImage = avatar ;
}
// Handle creating team if superadmin
if ( userData . role . includes ( "superadmin" )) {
const team = new this . Team ({
email : userData . email ,
});
userData . teamId = team . _id ;
userData . checkTTL = 60 * 60 * 24 * 30 ;
await team . save ();
}
const newUser = new this . User ( userData );
await newUser . save ();
return await this . User . 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 = this . stringService . dbUserExists ;
}
error . service = SERVICE_NAME ;
error . method = "insertUser" ;
throw error ;
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
};
getUserByEmail = async ( email ) => {
try {
// Need the password to be able to compare, removed .select()
// We can strip the hash before returning the user
const user = await this . User . findOne ({ email : email }). select ( "-profileImage" );
if ( ! user ) {
throw new Error ( this . stringService . dbUserNotFound );
}
return user ;
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "getUserByEmail" ;
throw error ;
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
};
2025-04-20 11:29:53 -07:00
2025-07-30 10:41:53 -07:00
updateUser = async ({ userId , user , file }) => {
if ( ! userId ) {
throw new Error ( "No user in request" );
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
try {
const candidateUser = { ... user };
if ( this . ParseBoolean ( candidateUser . deleteProfileImage ) === true ) {
candidateUser . profileImage = null ;
candidateUser . avatarImage = null ;
} else if ( file ) {
// 1. Save the full size image
candidateUser . profileImage = {
data : file . buffer ,
contentType : file . mimetype ,
};
// 2. Get the avatar sized image
const avatar = await this . GenerateAvatarImage ( file );
candidateUser . avatarImage = avatar ;
}
const updatedUser = await this . User . findByIdAndUpdate (
userId ,
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 ;
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
};
deleteUser = async ( userId ) => {
try {
const deletedUser = await this . User . findByIdAndDelete ( userId );
if ( ! deletedUser ) {
throw new Error ( this . stringService . dbUserNotFound );
}
return deletedUser ;
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "deleteUser" ;
throw error ;
2025-04-20 11:29:53 -07:00
}
2025-07-30 10:41:53 -07:00
};
getAllUsers = async () => {
try {
const users = await this . User . find (). select ( "-password" ). select ( "-profileImage" );
return users ;
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "getAllUsers" ;
throw error ;
2025-07-22 12:27:41 -07:00
}
2025-07-30 10:41:53 -07:00
};
getUserById = async ( roles , userId ) => {
try {
if ( ! roles . includes ( "superadmin" )) {
throw new Error ( "User is not a superadmin" );
}
const user = await this . User . findById ( userId ). select ( "-password" ). select ( "-profileImage" );
if ( ! user ) {
throw new Error ( "User not found" );
}
return user ;
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "getUserById" ;
throw error ;
2025-07-22 12:27:41 -07:00
}
2025-07-30 10:41:53 -07:00
};
editUserById = async ( userId , user ) => {
try {
await this . User . findByIdAndUpdate ( userId , user , { new : true }). select ( "-password" ). select ( "-profileImage" );
} catch ( error ) {
error . service = SERVICE_NAME ;
error . method = "editUserById" ;
throw error ;
}
};
}
2025-07-22 12:27:41 -07:00
2025-07-30 10:41:53 -07:00
export default UserModule ;