Update language, add LICENSE and README
All checks were successful
Build & Push Docker Image / build (push) Successful in 1m9s

This commit is contained in:
2026-02-24 21:04:19 +01:00
parent 2ef6a9f30b
commit 7426ae8088
8 changed files with 668 additions and 106 deletions

View File

@@ -11,11 +11,11 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
const { name, email, password, role } = req.body;
if (!name || !email || !password) {
return res.status(400).json({ error: 'Alle Felder sind erforderlich' });
return res.status(400).json({ error: 'All fields are required' });
}
if (password.length < 6) {
return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' });
return res.status(400).json({ error: 'Password must be at least 6 characters long' });
}
const validRole = ['user', 'admin'].includes(role) ? role : 'user';
@@ -23,7 +23,7 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
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' });
return res.status(409).json({ error: 'Email is already in use' });
}
const hash = bcrypt.hashSync(password, 12);
@@ -36,7 +36,7 @@ router.post('/users', authenticateToken, requireAdmin, async (req, res) => {
res.status(201).json({ user });
} catch (err) {
console.error('Create user error:', err);
res.status(500).json({ error: 'Benutzer konnte nicht erstellt werden' });
res.status(500).json({ error: 'User could not be created' });
}
});
@@ -54,7 +54,7 @@ router.get('/users', authenticateToken, requireAdmin, async (req, res) => {
res.json({ users });
} catch (err) {
console.error('List users error:', err);
res.status(500).json({ error: 'Benutzer konnten nicht geladen werden' });
res.status(500).json({ error: 'Users could not be loaded' });
}
});
@@ -63,7 +63,7 @@ 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' });
return res.status(400).json({ error: 'Invalid role' });
}
const db = getDb();
@@ -73,7 +73,7 @@ router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res)
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' });
return res.status(400).json({ error: 'The last admin cannot be demoted' });
}
}
@@ -83,7 +83,7 @@ router.put('/users/:id/role', authenticateToken, requireAdmin, async (req, res)
res.json({ user: updated });
} catch (err) {
console.error('Update role error:', err);
res.status(500).json({ error: 'Rolle konnte nicht aktualisiert werden' });
res.status(500).json({ error: 'Role could not be updated' });
}
});
@@ -93,27 +93,27 @@ router.delete('/users/:id', authenticateToken, requireAdmin, async (req, res) =>
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' });
return res.status(400).json({ error: 'You cannot delete yourself' });
}
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' });
return res.status(404).json({ error: 'User not found' });
}
// 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' });
return res.status(400).json({ error: 'The last admin cannot be deleted' });
}
}
await db.run('DELETE FROM users WHERE id = ?', [req.params.id]);
res.json({ message: 'Benutzer gelöscht' });
res.json({ message: 'User deleted' });
} catch (err) {
console.error('Delete user error:', err);
res.status(500).json({ error: 'Benutzer konnte nicht gelöscht werden' });
res.status(500).json({ error: 'User could not be deleted' });
}
});
@@ -122,17 +122,17 @@ router.put('/users/:id/password', authenticateToken, requireAdmin, async (req, r
try {
const { newPassword } = req.body;
if (!newPassword || newPassword.length < 6) {
return res.status(400).json({ error: 'Passwort muss mindestens 6 Zeichen lang sein' });
return res.status(400).json({ error: 'Password must be at least 6 characters long' });
}
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' });
res.json({ message: 'Password reset' });
} catch (err) {
console.error('Reset password error:', err);
res.status(500).json({ error: 'Passwort konnte nicht zurückgesetzt werden' });
res.status(500).json({ error: 'Password could not be reset' });
}
});