105 lines
4.4 KiB
PHP
105 lines
4.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/common.php';
|
|
|
|
api_require_method('GET', 'POST');
|
|
$staff = api_require_staff();
|
|
api_require_admin_or_permission($staff, 'manage_banlist');
|
|
$pdo = get_db();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
$entries = $pdo->query(
|
|
'SELECT b.*, s.name AS added_by_name FROM banlist b LEFT JOIN staff s ON s.id = b.created_by ORDER BY b.created_at DESC'
|
|
)->fetchAll();
|
|
|
|
api_json([
|
|
'items' => array_map(fn(array $b) => [
|
|
'id' => (int) $b['id'],
|
|
'matchType' => $b['match_type'],
|
|
'value' => $b['value'],
|
|
'reason' => $b['reason'],
|
|
'addedByName' => $b['added_by_name'],
|
|
'createdAt' => $b['created_at'],
|
|
], $entries),
|
|
]);
|
|
}
|
|
|
|
$body = api_request_body();
|
|
$action = $body['action'] ?? '';
|
|
|
|
/** Schließt alle offenen Tickets, die zur gerade gesperrten E-Mail/Domain passen. */
|
|
function api_close_banned_tickets(PDO $pdo, string $matchType, string $value): void
|
|
{
|
|
$col = $matchType === 'email' ? 'requester_email' : sql_email_domain('requester_email');
|
|
$before = $pdo->prepare("SELECT id,status FROM tickets WHERE $col=? AND status NOT IN ('closed')");
|
|
$before->execute([$value]);
|
|
$rows = $before->fetchAll();
|
|
$pdo->prepare("UPDATE tickets SET status='closed',resolution_code='spam',resolution_note='Im Rahmen einer Sperre geschlossen',closed_at=?,updated_at=? WHERE $col=? AND status NOT IN ('closed')")
|
|
->execute([db_now(), db_now(), $value]);
|
|
ticket_sla_transition_rows($pdo, $rows, 'closed', (int) ($GLOBALS['__api_staff']['id'] ?? 0) ?: null);
|
|
}
|
|
|
|
if ($action === 'create') {
|
|
$matchType = ($body['matchType'] ?? 'email') === 'domain' ? 'domain' : 'email';
|
|
$value = trim(strtolower((string) ($body['value'] ?? '')));
|
|
$reason = trim((string) ($body['reason'] ?? ''));
|
|
|
|
if ($value === '') {
|
|
api_error(422, 'VALUE_REQUIRED', 'Bitte einen Wert angeben.');
|
|
}
|
|
if ($matchType === 'email' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
|
api_error(422, 'INVALID_EMAIL', 'Ungültige E-Mail-Adresse.');
|
|
}
|
|
if ($matchType === 'domain' && (!str_contains($value, '.') || str_contains($value, '@'))) {
|
|
api_error(422, 'INVALID_DOMAIN', 'Nur Domain angeben, z.B. spam.de (ohne @).');
|
|
}
|
|
|
|
$chk = $pdo->prepare('SELECT id FROM banlist WHERE value=?');
|
|
$chk->execute([$value]);
|
|
if (!$chk->fetchColumn()) {
|
|
$pdo->prepare('INSERT INTO banlist (match_type,value,reason,created_by,created_at) VALUES (?,?,?,?,?)')
|
|
->execute([$matchType, $value, $reason ?: null, $staff['id'], db_now()]);
|
|
api_close_banned_tickets($pdo, $matchType, $value);
|
|
audit_log($staff['id'], "Sperrliste: {$value} hinzugefügt ({$matchType}, Mobile App)");
|
|
}
|
|
api_json(['ok' => true]);
|
|
}
|
|
|
|
if ($action === 'bulk_add') {
|
|
$raw = trim((string) ($body['values'] ?? ''));
|
|
$reason = trim((string) ($body['reason'] ?? ''));
|
|
$lines = array_filter(array_map('trim', preg_split('/[\r\n,;]+/', $raw)));
|
|
$added = 0;
|
|
$skipped = 0;
|
|
foreach ($lines as $val) {
|
|
$val = strtolower($val);
|
|
$type = str_contains($val, '@') ? 'email' : 'domain';
|
|
if ($type === 'email' && !filter_var($val, FILTER_VALIDATE_EMAIL)) { $skipped++; continue; }
|
|
if ($type === 'domain' && !str_contains($val, '.')) { $skipped++; continue; }
|
|
$chk = $pdo->prepare('SELECT id FROM banlist WHERE value=?');
|
|
$chk->execute([$val]);
|
|
if ($chk->fetchColumn()) { $skipped++; continue; }
|
|
$pdo->prepare('INSERT INTO banlist (match_type,value,reason,created_by,created_at) VALUES (?,?,?,?,?)')
|
|
->execute([$type, $val, $reason ?: null, $staff['id'], db_now()]);
|
|
api_close_banned_tickets($pdo, $type, $val);
|
|
$added++;
|
|
}
|
|
audit_log($staff['id'], "Sperrliste Massen-Import: {$added} hinzugefügt, {$skipped} übersprungen (Mobile App)");
|
|
api_json(['added' => $added, 'skipped' => $skipped]);
|
|
}
|
|
|
|
if ($action === 'delete') {
|
|
$id = (int) ($body['id'] ?? 0);
|
|
$val = $pdo->prepare('SELECT value FROM banlist WHERE id=?');
|
|
$val->execute([$id]);
|
|
$v = $val->fetchColumn();
|
|
if ($v === false) {
|
|
api_error(404, 'ENTRY_NOT_FOUND', 'Der Eintrag wurde nicht gefunden.');
|
|
}
|
|
$pdo->prepare('DELETE FROM banlist WHERE id=?')->execute([$id]);
|
|
audit_log($staff['id'], "Sperrliste: {$v} entfernt (Mobile App)");
|
|
api_json(['ok' => true]);
|
|
}
|
|
|
|
api_error(422, 'INVALID_ACTION', 'Unbekannte Aktion.');
|