ininventer/backend/controllers/userController.js

281 lines
7.6 KiB
JavaScript

const User = require('../models/User');
const { validationResult } = require('express-validator');
// @desc Get all users
// @route GET /api/users
// @access Private (superadmin: all users, companyadmin: only users from their company)
exports.getUsers = async (req, res, next) => {
try {
let query = {};
// If user is companyadmin, only get users from their company
if (req.user.role === 'companyadmin') {
query = { companyId: req.user.companyId };
}
const users = await User.find(query).select('-password');
res.status(200).json({
success: true,
count: users.length,
data: users
});
} catch (error) {
next(error);
}
};
// @desc Get single user
// @route GET /api/users/:id
// @access Private (superadmin: any user, companyadmin: only users from their company)
exports.getUser = async (req, res, next) => {
try {
const user = await User.findById(req.params.id).select('-password');
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if companyadmin is trying to access user from another company
if (req.user.role === 'companyadmin' &&
user.companyId.toString() !== req.user.companyId.toString()) {
return res.status(403).json({
success: false,
message: 'Not authorized to access this user'
});
}
res.status(200).json({
success: true,
data: user
});
} catch (error) {
next(error);
}
};
// @desc Create user
// @route POST /api/users
// @access Private (superadmin: can create any user, companyadmin: can only create employers in their company)
exports.createUser = async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
const { email, password, role, companyId } = req.body;
// Check if user is trying to create a role they're not allowed to
if (req.user.role === 'companyadmin' && role !== 'employer') {
return res.status(403).json({
success: false,
message: 'Company admin can only create employer users'
});
}
// Check if companyadmin is trying to create user for another company
if (req.user.role === 'companyadmin' &&
companyId.toString() !== req.user.companyId.toString()) {
return res.status(403).json({
success: false,
message: 'Not authorized to create user for another company'
});
}
// Create user
const user = await User.create({
email,
password,
role,
companyId: role === 'superadmin' ? null : companyId,
createdBy: req.user._id
});
res.status(201).json({
success: true,
data: {
_id: user._id,
email: user.email,
role: user.role,
companyId: user.companyId,
createdAt: user.createdAt
}
});
} catch (error) {
// Check for duplicate email
if (error.code === 11000) {
return res.status(400).json({
success: false,
message: 'Email already exists'
});
}
next(error);
}
};
// @desc Update user
// @route PUT /api/users/:id
// @access Private (superadmin: any user, companyadmin: only employers in their company)
exports.updateUser = async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
let user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if companyadmin is trying to update user from another company
if (req.user.role === 'companyadmin' &&
user.companyId.toString() !== req.user.companyId.toString()) {
return res.status(403).json({
success: false,
message: 'Not authorized to update this user'
});
}
// Check if companyadmin is trying to update a companyadmin
if (req.user.role === 'companyadmin' && user.role === 'companyadmin') {
return res.status(403).json({
success: false,
message: 'Company admin cannot update other company admins'
});
}
// Check if trying to change role to something not allowed
if (req.body.role && req.user.role === 'companyadmin' && req.body.role !== 'employer') {
return res.status(403).json({
success: false,
message: 'Company admin can only update to employer role'
});
}
// Update user
user = await User.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true, runValidators: true }
).select('-password');
res.status(200).json({
success: true,
data: user
});
} catch (error) {
next(error);
}
};
// @desc Delete user
// @route DELETE /api/users/:id
// @access Private (superadmin: any user, companyadmin: only employers in their company)
exports.deleteUser = async (req, res, next) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if companyadmin is trying to delete user from another company
if (req.user.role === 'companyadmin' &&
user.companyId.toString() !== req.user.companyId.toString()) {
return res.status(403).json({
success: false,
message: 'Not authorized to delete this user'
});
}
// Check if companyadmin is trying to delete a companyadmin
if (req.user.role === 'companyadmin' && user.role === 'companyadmin') {
return res.status(403).json({
success: false,
message: 'Company admin cannot delete other company admins'
});
}
await user.deleteOne();
res.status(200).json({
success: true,
data: {}
});
} catch (error) {
next(error);
}
};
// @desc Reset user password
// @route PUT /api/users/:id/reset-password
// @access Private (superadmin: any user, companyadmin: only employers in their company)
exports.resetPassword = async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
const { newPassword } = req.body;
let user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if companyadmin is trying to reset password for user from another company
if (req.user.role === 'companyadmin' &&
user.companyId.toString() !== req.user.companyId.toString()) {
return res.status(403).json({
success: false,
message: 'Not authorized to reset password for this user'
});
}
// Check if companyadmin is trying to reset password for a companyadmin
if (req.user.role === 'companyadmin' && user.role === 'companyadmin') {
return res.status(403).json({
success: false,
message: 'Company admin cannot reset password for other company admins'
});
}
// Update password
user.password = newPassword;
await user.save();
res.status(200).json({
success: true,
message: 'Password reset successful'
});
} catch (error) {
next(error);
}
};