(Feat): Initial Commit
This commit is contained in:
236
backend/routes/users.js
Normal file
236
backend/routes/users.js
Normal file
@@ -0,0 +1,236 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user