Files
geograsim/App/php/api/admin-accounts.php
T

124 lines
4.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Admin API: Verwaltung der Super-Admin-Accounts (inkl. 2FA-Mailadresse)
* POST /api/admin-accounts {action}
* - list → alle Admins (ohne Passwort-Hash)
* - create {username, email_2fa, password} → neuen Admin anlegen
* - update {id, email_2fa?, password?} → 2FA-Mail und/oder Passwort ändern
* - delete {id} → Admin löschen (nicht sich selbst, nicht den letzten)
*
* Auth: eingeloggter Super-Admin ($_SESSION['admin_id']). Nur Admins verwalten Admins.
*/
if (session_status() === PHP_SESSION_NONE) session_start();
if (empty($_SESSION['admin_id'])) {
http_response_code(401);
echo json_encode(['error' => 'Nicht eingeloggt']);
exit;
}
$meId = (int)$_SESSION['admin_id'];
$db = Database::get();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
Response::error('Nur POST erlaubt', 405);
}
$body = json_decode(file_get_contents('php://input'), true) ?: [];
$action = $body['action'] ?? '';
// === LISTE ===
if ($action === 'list') {
$rows = $db->fetchAll('SELECT id, username, email_2fa, created_at FROM admin_users ORDER BY id');
foreach ($rows as &$r) {
$r['id'] = (int)$r['id'];
$r['is_self'] = ($r['id'] === $meId);
}
unset($r);
Response::ok(['admins' => $rows]);
}
// === ANLEGEN ===
if ($action === 'create') {
$username = trim($body['username'] ?? '');
$email = trim($body['email_2fa'] ?? '');
$password = (string)($body['password'] ?? '');
if ($username === '' || $email === '' || $password === '') {
Response::error('Benutzername, 2FA-E-Mail und Passwort sind erforderlich.');
}
if (!preg_match('/^[A-Za-z0-9._\-]{3,64}$/', $username)) {
Response::error('Benutzername: 364 Zeichen, nur Buchstaben, Ziffern, Punkt, Unterstrich, Bindestrich.');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
Response::error('Ungültige 2FA-E-Mail-Adresse.');
}
if (strlen($password) < 10) {
Response::error('Passwort muss mindestens 10 Zeichen haben.');
}
if ($db->fetchOne('SELECT id FROM admin_users WHERE username = ?', [$username])) {
Response::error('Dieser Benutzername ist bereits vergeben.');
}
$hash = password_hash($password, PASSWORD_DEFAULT);
$db->execute(
'INSERT INTO admin_users (username, password, email_2fa) VALUES (?, ?, ?)',
[$username, $hash, $email]
);
Response::ok(['message' => 'Admin-Account angelegt.']);
}
// === AKTUALISIEREN (2FA-Mail und/oder Passwort) ===
if ($action === 'update') {
$id = (int)($body['id'] ?? 0);
if (!$id) Response::error('ID fehlt.');
if (!$db->fetchOne('SELECT id FROM admin_users WHERE id = ?', [$id])) {
Response::error('Admin nicht gefunden.', 404);
}
$didSomething = false;
if (array_key_exists('email_2fa', $body)) {
$email = trim((string)$body['email_2fa']);
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
Response::error('Ungültige 2FA-E-Mail-Adresse.');
}
$db->execute('UPDATE admin_users SET email_2fa = ? WHERE id = ?', [$email, $id]);
$didSomething = true;
}
if (array_key_exists('password', $body) && (string)$body['password'] !== '') {
$password = (string)$body['password'];
if (strlen($password) < 10) {
Response::error('Passwort muss mindestens 10 Zeichen haben.');
}
$db->execute(
'UPDATE admin_users SET password = ? WHERE id = ?',
[password_hash($password, PASSWORD_DEFAULT), $id]
);
$didSomething = true;
}
if (!$didSomething) Response::error('Nichts zu ändern.');
Response::ok(['message' => 'Admin-Account aktualisiert.']);
}
// === LÖSCHEN ===
if ($action === 'delete') {
$id = (int)($body['id'] ?? 0);
if (!$id) Response::error('ID fehlt.');
if ($id === $meId) Response::error('Du kannst deinen eigenen Account nicht löschen.');
$row = $db->fetchOne('SELECT COUNT(*) AS c FROM admin_users');
if ((int)($row['c'] ?? 0) <= 1) {
Response::error('Der letzte Admin-Account kann nicht gelöscht werden.');
}
$db->execute('DELETE FROM admin_users WHERE id = ?', [$id]);
$db->execute('DELETE FROM admin_pins WHERE admin_id = ?', [$id]); // verwaiste PINs aufräumen
Response::ok(['message' => 'Admin-Account gelöscht.']);
}
Response::error('Unbekannte Aktion.');