let db; let bcrypt; function init(database, bcryptModule) { db = database; bcrypt = bcryptModule; } function getAllUsers(req, res) { db.all(`SELECT id, login, full_name, email, role, created_at FROM users ORDER BY created_at DESC`, [], (err, rows) => { if (err) return res.status(500).json({ error: 'Database error' }); res.json(rows); }); } function createUser(req, res) { const { login, password, full_name, email, role } = req.body; if (!login || !password) return res.status(400).json({ error: 'Login and password required' }); if (!['admin', 'user'].includes(role)) return res.status(400).json({ error: 'Role must be "admin" or "user"' }); if (password.length < 4) return res.status(400).json({ error: 'Password must be at least 4 characters' }); const hash = bcrypt.hashSync(password, 10); db.run(`INSERT INTO users (login, password_hash, full_name, email, role) VALUES (?, ?, ?, ?, ?)`, [login, hash, full_name || null, email || null, role], function(err) { if (err) { if (err.message.includes('UNIQUE constraint')) return res.status(409).json({ error: 'Login already exists' }); return res.status(500).json({ error: 'Database error' }); } db.get(`SELECT id, login, full_name, email, role, created_at FROM users WHERE id = ?`, [this.lastID], (err, row) => { res.status(201).json({ message: 'User created', user: row }); }); }); } function updateUser(req, res) { const userId = parseInt(req.params.id); const { full_name, email, role, password } = req.body; if (role && !['admin', 'user'].includes(role)) return res.status(400).json({ error: 'Role must be "admin" or "user"' }); db.get(`SELECT id FROM users WHERE id = ?`, [userId], (err, row) => { if (err) return res.status(500).json({ error: 'Database error' }); if (!row) return res.status(404).json({ error: 'User not found' }); let fields = []; let values = []; if (full_name !== undefined) { fields.push('full_name = ?'); values.push(full_name || null); } if (email !== undefined) { fields.push('email = ?'); values.push(email || null); } if (role !== undefined) { fields.push('role = ?'); values.push(role); } if (password) { if (password.length < 4) return res.status(400).json({ error: 'Password must be at least 4 characters' }); fields.push('password_hash = ?'); values.push(bcrypt.hashSync(password, 10)); } if (fields.length === 0) return res.status(400).json({ error: 'No fields to update' }); values.push(userId); db.run(`UPDATE users SET ${fields.join(', ')} WHERE id = ?`, values, (err) => { if (err) return res.status(500).json({ error: 'Database error' }); db.get(`SELECT id, login, full_name, email, role, created_at FROM users WHERE id = ?`, [userId], (err, row) => { res.json({ message: 'User updated', user: row }); }); }); }); } function deleteUser(req, res) { const userId = parseInt(req.params.id); const ADMIN_LOGIN = process.env.ADMIN_LOGIN; if (userId === req.user.id) return res.status(400).json({ error: 'Cannot delete yourself' }); db.get(`SELECT login FROM users WHERE id = ?`, [userId], (err, row) => { if (err) return res.status(500).json({ error: 'Database error' }); if (!row) return res.status(404).json({ error: 'User not found' }); if (row.login === ADMIN_LOGIN) return res.status(403).json({ error: 'Cannot delete superadmin defined in .env' }); db.run(`DELETE FROM users WHERE id = ?`, [userId], (err) => { if (err) return res.status(500).json({ error: 'Database error' }); res.json({ message: 'User deleted' }); }); }); } function setupRoutes(app, authenticateToken, requireAdmin) { app.get('/api/admin/users', authenticateToken, requireAdmin, getAllUsers); app.post('/api/admin/users', authenticateToken, requireAdmin, createUser); app.put('/api/admin/users/:id', authenticateToken, requireAdmin, updateUser); app.delete('/api/admin/users/:id', authenticateToken, requireAdmin, deleteUser); } module.exports = { init, setupRoutes };