237 lines
7.5 KiB
JavaScript
237 lines
7.5 KiB
JavaScript
import express from 'express';
|
|
import bcrypt from 'bcryptjs';
|
|
import db from '../config/database.js';
|
|
import { authenticateToken, authorize } from '../middleware/auth.js';
|
|
|
|
const router = express.Router();
|
|
|
|
// Get all users (with filters)
|
|
router.get('/', authenticateToken, async (req, res) => {
|
|
try {
|
|
const { role, departmentId } = req.query;
|
|
let query = `
|
|
SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
|
u.contractor_id, u.is_active, u.created_at,
|
|
d.name as department_name,
|
|
c.name as contractor_name
|
|
FROM users u
|
|
LEFT JOIN departments d ON u.department_id = d.id
|
|
LEFT JOIN users c ON u.contractor_id = c.id
|
|
WHERE 1=1
|
|
`;
|
|
const params = [];
|
|
|
|
// Supervisors can only see users in their department
|
|
if (req.user.role === 'Supervisor') {
|
|
query += ' AND u.department_id = ?';
|
|
params.push(req.user.departmentId);
|
|
}
|
|
|
|
if (role) {
|
|
query += ' AND u.role = ?';
|
|
params.push(role);
|
|
}
|
|
|
|
if (departmentId) {
|
|
query += ' AND u.department_id = ?';
|
|
params.push(departmentId);
|
|
}
|
|
|
|
query += ' ORDER BY u.created_at DESC';
|
|
|
|
const [users] = await db.query(query, params);
|
|
res.json(users);
|
|
} catch (error) {
|
|
console.error('Get users error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Get user by ID
|
|
router.get('/:id', authenticateToken, async (req, res) => {
|
|
try {
|
|
const [users] = await db.query(
|
|
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
|
u.contractor_id, u.is_active, u.created_at,
|
|
d.name as department_name,
|
|
c.name as contractor_name
|
|
FROM users u
|
|
LEFT JOIN departments d ON u.department_id = d.id
|
|
LEFT JOIN users c ON u.contractor_id = c.id
|
|
WHERE u.id = ?`,
|
|
[req.params.id]
|
|
);
|
|
|
|
if (users.length === 0) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
|
|
// Supervisors can only view users in their department
|
|
if (req.user.role === 'Supervisor' && users[0].department_id !== req.user.departmentId) {
|
|
return res.status(403).json({ error: 'Access denied' });
|
|
}
|
|
|
|
res.json(users[0]);
|
|
} catch (error) {
|
|
console.error('Get user error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Create user
|
|
router.post('/', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => {
|
|
try {
|
|
const { username, name, email, password, role, departmentId, contractorId } = req.body;
|
|
|
|
if (!username || !name || !email || !password || !role) {
|
|
return res.status(400).json({ error: 'Missing required fields' });
|
|
}
|
|
|
|
// Supervisors can only create users in their department
|
|
if (req.user.role === 'Supervisor') {
|
|
if (departmentId !== req.user.departmentId) {
|
|
return res.status(403).json({ error: 'Can only create users in your department' });
|
|
}
|
|
if (role === 'SuperAdmin' || role === 'Supervisor') {
|
|
return res.status(403).json({ error: 'Cannot create admin or supervisor users' });
|
|
}
|
|
}
|
|
|
|
const hashedPassword = await bcrypt.hash(password, 10);
|
|
|
|
const [result] = await db.query(
|
|
'INSERT INTO users (username, name, email, password, role, department_id, contractor_id) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
|
[username, name, email, hashedPassword, role, departmentId || null, contractorId || null]
|
|
);
|
|
|
|
const [newUser] = await db.query(
|
|
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
|
u.contractor_id, u.is_active, u.created_at,
|
|
d.name as department_name,
|
|
c.name as contractor_name
|
|
FROM users u
|
|
LEFT JOIN departments d ON u.department_id = d.id
|
|
LEFT JOIN users c ON u.contractor_id = c.id
|
|
WHERE u.id = ?`,
|
|
[result.insertId]
|
|
);
|
|
|
|
res.status(201).json(newUser[0]);
|
|
} catch (error) {
|
|
if (error.code === 'ER_DUP_ENTRY') {
|
|
return res.status(400).json({ error: 'Username or email already exists' });
|
|
}
|
|
console.error('Create user error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Update user
|
|
router.put('/:id', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => {
|
|
try {
|
|
const { name, email, role, departmentId, contractorId, isActive } = req.body;
|
|
|
|
// Check if user exists
|
|
const [existingUsers] = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]);
|
|
|
|
if (existingUsers.length === 0) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
|
|
// Supervisors can only update users in their department
|
|
if (req.user.role === 'Supervisor') {
|
|
if (existingUsers[0].department_id !== req.user.departmentId) {
|
|
return res.status(403).json({ error: 'Can only update users in your department' });
|
|
}
|
|
if (role === 'SuperAdmin' || role === 'Supervisor') {
|
|
return res.status(403).json({ error: 'Cannot modify admin or supervisor roles' });
|
|
}
|
|
}
|
|
|
|
const updates = [];
|
|
const params = [];
|
|
|
|
if (name !== undefined) {
|
|
updates.push('name = ?');
|
|
params.push(name);
|
|
}
|
|
if (email !== undefined) {
|
|
updates.push('email = ?');
|
|
params.push(email);
|
|
}
|
|
if (role !== undefined) {
|
|
updates.push('role = ?');
|
|
params.push(role);
|
|
}
|
|
if (departmentId !== undefined) {
|
|
updates.push('department_id = ?');
|
|
params.push(departmentId);
|
|
}
|
|
if (contractorId !== undefined) {
|
|
updates.push('contractor_id = ?');
|
|
params.push(contractorId);
|
|
}
|
|
if (isActive !== undefined) {
|
|
updates.push('is_active = ?');
|
|
params.push(isActive);
|
|
}
|
|
|
|
if (updates.length === 0) {
|
|
return res.status(400).json({ error: 'No fields to update' });
|
|
}
|
|
|
|
params.push(req.params.id);
|
|
|
|
await db.query(
|
|
`UPDATE users SET ${updates.join(', ')} WHERE id = ?`,
|
|
params
|
|
);
|
|
|
|
const [updatedUser] = await db.query(
|
|
`SELECT u.id, u.username, u.name, u.email, u.role, u.department_id,
|
|
u.contractor_id, u.is_active, u.created_at,
|
|
d.name as department_name,
|
|
c.name as contractor_name
|
|
FROM users u
|
|
LEFT JOIN departments d ON u.department_id = d.id
|
|
LEFT JOIN users c ON u.contractor_id = c.id
|
|
WHERE u.id = ?`,
|
|
[req.params.id]
|
|
);
|
|
|
|
res.json(updatedUser[0]);
|
|
} catch (error) {
|
|
console.error('Update user error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
// Delete user
|
|
router.delete('/:id', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => {
|
|
try {
|
|
const [users] = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]);
|
|
|
|
if (users.length === 0) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
|
|
// Supervisors can only delete users in their department
|
|
if (req.user.role === 'Supervisor') {
|
|
if (users[0].department_id !== req.user.departmentId) {
|
|
return res.status(403).json({ error: 'Can only delete users in your department' });
|
|
}
|
|
if (users[0].role === 'SuperAdmin' || users[0].role === 'Supervisor') {
|
|
return res.status(403).json({ error: 'Cannot delete admin or supervisor users' });
|
|
}
|
|
}
|
|
|
|
await db.query('DELETE FROM users WHERE id = ?', [req.params.id]);
|
|
res.json({ message: 'User deleted successfully' });
|
|
} catch (error) {
|
|
console.error('Delete user error:', error);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
export default router;
|