Files
2026-11-05 21:21:59 +00:00

75 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft, wer bei einer SLA-Überschreitung eine Mail bekommt (nur Betroffene, nie die Postfach-Adresse der Abteilung) und den Schutz vor
* Mail-Schleifen (eigene Systemmails werden vom E-Mail-Abruf nicht zu Tickets).
*/
$db = sys_get_temp_dir() . '/deskhub-sla-' . bin2hex(random_bytes(4)) . '.sqlite';
putenv('DESKHUB_TESTING=1');
putenv('DESKHUB_SQLITE_PATH=' . $db);
require_once dirname(__DIR__) . '/includes/bootstrap.php';
$failures = [];
$check = function (bool $ok, string $what) use (&$failures): void { if (!$ok) $failures[] = $what; };
$pdo = get_db();
set_setting('sla_notify_mode', 'assignee'); // diese Prüfungen betreffen den Modus „Bearbeiter bzw. Abteilung“ (Standard ist „nur Administratoren“)
$now = db_now();
$pdo->prepare('INSERT INTO departments (name, email) VALUES (?,?)')->execute(['Support', 'support@firma.example']);
$dept = (int) $pdo->lastInsertId();
$pdo->prepare('INSERT INTO departments (name, email) VALUES (?,?)')->execute(['Technik', 'technik@firma.example']);
$dept2 = (int) $pdo->lastInsertId();
$person = function (string $name, string $role, ?int $d, string $email = '') use ($pdo, $now): int {
$pdo->prepare('INSERT INTO staff (name, email, password_hash, role, department_id, is_active, created_at) VALUES (?,?,?,?,?,1,?)')
->execute([$name, $email ?: strtolower($name) . '@firma.example', 'x', $role, $d, $now]);
return (int) $pdo->lastInsertId();
};
$anna = $person('Anna', 'agent', $dept);
$ben = $person('Ben', 'agent', $dept);
$cora = $person('Cora', 'agent', $dept2);
$chef = $person('Chef', 'admin', null);
// Admin, dessen Adresse zugleich die Postfach-Adresse ist (wie bei der Fehlermeldung)
$sys = $person('Postfach-Admin', 'admin', null, 'support@firma.example');
$pdo->prepare('INSERT INTO staff_department (staff_id, department_id, notify) VALUES (?,?,1)')->execute([$cora, $dept]);
set_setting('smtp_from_email', 'noreply@firma.example');
// 1) Ticket mit Bearbeiter: nur der Bearbeiter
$r = sla_overdue_recipients($pdo, ['assigned_staff_id' => $anna, 'department_id' => $dept]);
$check($r === ['anna@firma.example'], 'Mit Bearbeiter bekommt nur er die Mail: ' . json_encode($r));
// 2) Bearbeiter im Urlaub: seine Vertretung
$pdo->prepare('UPDATE staff SET is_on_vacation = 1, vacation_substitute_id = ? WHERE id = ?')->execute([$ben, $anna]);
$r = sla_overdue_recipients($pdo, ['assigned_staff_id' => $anna, 'department_id' => $dept]);
$check($r === ['ben@firma.example'], 'Ist der Bearbeiter im Urlaub, bekommt die Vertretung die Mail: ' . json_encode($r));
$pdo->prepare('UPDATE staff SET is_on_vacation = 0, vacation_substitute_id = NULL WHERE id = ?')->execute([$anna]);
// 3) Ohne Bearbeiter: Mitarbeiter der Abteilung (Haupt- und zusätzliche mit Benachrichtigung), keine Admins, nicht die Abteilungs-Adresse
$r = sla_overdue_recipients($pdo, ['assigned_staff_id' => null, 'department_id' => $dept]);
sort($r);
$check($r === ['anna@firma.example', 'ben@firma.example', 'cora@firma.example'], 'Ohne Bearbeiter: Abteilungsmitarbeiter: ' . json_encode($r));
$check(!in_array('support@firma.example', $r, true) && !in_array('technik@firma.example', $r, true), 'Die Postfach-Adresse der Abteilung ist nie Empfänger');
$check(!in_array('chef@firma.example', $r, true), 'Administratoren bekommen nicht automatisch jede SLA-Mail');
// 4) Niemand in der Abteilung: Administratoren, aber nie eine Systemadresse
$pdo->exec('UPDATE staff SET is_active = 0 WHERE id IN (' . implode(',', [$anna, $ben, $cora]) . ')');
$r = sla_overdue_recipients($pdo, ['assigned_staff_id' => null, 'department_id' => $dept]);
$check(in_array('chef@firma.example', $r, true) && !in_array('support@firma.example', $r, true) && !in_array('anna@firma.example', $r, true), 'Ohne Abteilungsmitarbeiter bekommen die Administratoren die Mail, nicht die Postfach-Adresse: ' . json_encode($r));
// 5) Schutz vor Mail-Schleifen
$check(mail_is_own_system_mail($pdo, 'kunde@irgendwo.example', "From: x\r\nX-DeskHub-Mail: 1\r\n") === true, 'Die Kopfzeile X-DeskHub-Mail wird erkannt');
$check(mail_is_own_system_mail($pdo, 'support@firma.example') === true, 'Absender = Abteilungs-Postfach wird erkannt');
$check(mail_is_own_system_mail($pdo, 'NoReply@Firma.example') === true, 'Absender = Standard-Absender wird erkannt (Groß-/Kleinschreibung egal)');
$check(mail_is_own_system_mail($pdo, 'kunde@irgendwo.example', "From: kunde@irgendwo.example\r\nSubject: Hilfe\r\n") === false, 'Normale Kundenmails bleiben Tickets');
// 6) Die Markierung steckt in den ausgehenden Mails
$src = file_get_contents(dirname(__DIR__) . '/includes/smtp_mailer.php') . file_get_contents(dirname(__DIR__) . '/includes/mailer.php');
$check(substr_count($src, 'X-DeskHub-Mail: 1') >= 2, 'SMTP- und mail()-Versand setzen die Markierung');
@unlink($db);
if ($failures) {
fwrite(STDERR, "SLA-Empfänger / Mail-Schleifen fehlgeschlagen:\n- " . implode("\n- ", $failures) . "\n");
exit(1);
}
echo "SLA-Empfänger und Schutz vor Mail-Schleifen bestanden.\n";