import { Router } from 'express'; import bcrypt from 'bcryptjs'; import { getDb } from '../config/database.js'; import { authenticateToken, requireAdmin } from '../middleware/auth.js'; const router = Router(); // POST /api/admin/users - Create user (admin) router.post('/users', authenticateToken, requireAdmin, async (req, res) => { try { const { name, email, password, role } = req.body; if (!name || !email || !password) { return res.status(400).json({ error: 'Alle Felder sind erforderlich' }); } if (password.length < 6) { return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' }); } const validRole = ['user', 'admin'].includes(role) ? role : 'user'; const db = getDb(); const existing = await db.get('SELECT id FROM users WHERE email = ?', [email.toLowerCase()]); if (existing) { return res.status(409).json({ error: 'E-Mail wird bereits verwendet' }); } const hash = bcrypt.hashSync(password, 12); const result = await db.run( 'INSERT INTO users (name, email, password_hash, role) VALUES (?, ?, ?, ?)', [name, email.toLowerCase(), hash, validRole] ); const user = await db.get('SELECT id, name, email, role, created_at FROM users WHERE id = ?', [result.lastInsertRowid]); res.status(201).json({ user }); } catch (err) { console.error('Create user error:', err); res.status(500).json({ error: 'Benutzer konnte nicht erstellt werden' }); } }); // GET /api/admin/users - List all users router.get('/users', authenticateToken, requireAdmin, async (req, res) => { try { const db = getDb(); const users = await db.all(` SELECT id, name, email, role, language, theme, avatar_color, avatar_image, created_at, (SELECT COUNT(*) FROM rooms WHERE rooms.user_id = users.id) as room_count FROM users ORDER BY created_at DESC `); res.json({ users }); } catch (err) { console.error('List users error:', err); res.status(500).json({ error: 'Benutzer konnten nicht geladen werden' }); } }); // PUT /api/admin/users/:id/role - Update user role router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res) => { try { const { role } = req.body; if (!['user', 'admin'].includes(role)) { return res.status(400).json({ error: 'Ungültige Rolle' }); } const db = getDb(); // Prevent demoting last admin if (role === 'user') { const adminCount = await db.get('SELECT COUNT(*) as count FROM users WHERE role = ?', ['admin']); const currentUser = await db.get('SELECT role FROM users WHERE id = ?', [req.params.id]); if (currentUser?.role === 'admin' && adminCount.count <= 1) { return res.status(400).json({ error: 'Der letzte Admin kann nicht herabgestuft werden' }); } } await db.run('UPDATE users SET role = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [role, req.params.id]); const updated = await db.get('SELECT id, name, email, role, created_at FROM users WHERE id = ?', [req.params.id]); res.json({ user: updated }); } catch (err) { console.error('Update role error:', err); res.status(500).json({ error: 'Rolle konnte nicht aktualisiert werden' }); } }); // DELETE /api/admin/users/:id - Delete user router.delete('/users/:id', authenticateToken, requireAdmin, async (req, res) => { try { const db = getDb(); if (parseInt(req.params.id) === req.user.id) { return res.status(400).json({ error: 'Sie können sich nicht selbst löschen' }); } const user = await db.get('SELECT id, role FROM users WHERE id = ?', [req.params.id]); if (!user) { return res.status(404).json({ error: 'Benutzer nicht gefunden' }); } // Check if it's the last admin if (user.role === 'admin') { const adminCount = await db.get('SELECT COUNT(*) as count FROM users WHERE role = ?', ['admin']); if (adminCount.count <= 1) { return res.status(400).json({ error: 'Der letzte Admin kann nicht gelöscht werden' }); } } await db.run('DELETE FROM users WHERE id = ?', [req.params.id]); res.json({ message: 'Benutzer gelöscht' }); } catch (err) { console.error('Delete user error:', err); res.status(500).json({ error: 'Benutzer konnte nicht gelöscht werden' }); } }); // PUT /api/admin/users/:id/password - Reset user password (admin) router.put('/users/:id/password', authenticateToken, requireAdmin, async (req, res) => { try { const { newPassword } = req.body; if (!newPassword || newPassword.length < 6) { return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' }); } const db = getDb(); const hash = bcrypt.hashSync(newPassword, 12); await db.run('UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [hash, req.params.id]); res.json({ message: 'Passwort zurückgesetzt' }); } catch (err) { console.error('Reset password error:', err); res.status(500).json({ error: 'Passwort konnte nicht zurückgesetzt werden' }); } }); export default router;