# #028 Benachrichtigungen **Status:** erledigt **Meilenstein:** v0.5.0 **Labels:** backend **Geschätzt:** 2 h **Tatsächlich:** 0,5 h ## Ziel E-Mail (M365 SMTP) und Webhook bei Drift und Ablauf. ## Aufgaben - [x] Einstellungsseite `/einstellungen` statt Platzhalter: lesen alle Rollen, ändern nur `einstellungenVerwalten` (Admin). Abschnitte „Benachrichtigungen“, „Abgleich“ (Zeitpläne aus `SSHKV_SYNC_CRON`/`SSHKV_MELDUNG_CRON`, nur Anzeige) und „Instanz“ (Version, Deployment-Key-Fingerprint, OIDC-Anbieter, TOTP des Notfall-Admins). Platz für „Syslog“ markiert. - [x] Kanal E-Mail (SMTP): Vorbelegung Microsoft 365 (`smtp.office365.com:587`, STARTTLS), wahlweise TLS (465) oder unverschlüsselt (nur internes Relay, mit Warnung); Absender, Benutzer, Passwort, Empfängerliste. - [x] Kanal Webhook: JSON per POST, optional `X-Sshkv-Signatur: sha256=` über den Body; nur `https://`, `http://` nur per Häkchen mit Warnung; keine Weiterleitungen, Zeitlimit 15 s. - [x] Geheimnisse (SMTP-Passwort, Webhook-Geheimnis) mit `verschluesseln()` in `Einstellung`; die Oberfläche bekommt nur „gesetzt“, leeres Feld behält, Häkchen entfernt. - [x] „Testnachricht senden“ je Kanal als Vorgang `BENACHRICHTIGUNG_TEST` im Worker. - [x] Anlässe (je einzeln schaltbar): neue Abweichungen je Host, Ablauf in 30/14/7 Tagen, abgelaufen aber ausgerollt, Host nicht erreichbar – gesammelt in der täglichen Zusammenfassung (`SSHKV_MELDUNG_CRON`, Standard `0 7 * * *`); geänderter Host-Key sofort (Takt alle 5 Minuten). - [x] Versandprotokoll `Zustellung` (Migration `20261012161000_benachrichtigungen`) mit Anlass-Fingerabdruck, Kanal, Ergebnis, Fehler, Versuchen; Prüfung vor jedem Versand, Wiederholung nach 5/10/20/40 Minuten (höchstens 5 Versuche); „Letzte Zustellungen“ auf der Seite. - [x] Jede Zustellung in `protokollieren()` als `benachrichtigung.gesendet`/`…fehlgeschlagen` (Empfänger nur gezählt, Webhook nur Schema und Host). - [x] Zeitpläne in `src/worker/index.ts`; `.env.example` und `docker-compose.yml` ergänzt. - [x] Tests: Unit (Nachrichtenaufbau, Signatur, Stufen, Deduplizierung, Prüfungen), DB (Einstellungen, Versandprotokoll), Integration gegen Mailpit und lokalen HTTP-Empfänger, E2E `tests/e2e/einstellungen.spec.ts`; Screenshots `einstellungen-desktop/-mobil`. ## Akzeptanzkriterien - [x] Admin speichert SMTP-Einstellungen, die Testnachricht kommt in Mailpit an (E2E). - [x] Das Passwort steht nie im Klartext in Datenbank, Protokoll oder Seite; das Feld zeigt nur „gesetzt“. - [x] Leser sieht die Seite ohne Ändern- und Test-Knöpfe. - [x] Dieselbe Abweichung, dieselbe Ablaufstufe und derselbe Ausfall werden je Kanal genau einmal gemeldet. - [x] Fehlgeschlagene Zustellungen werden begrenzt wiederholt und sind in der Oberfläche sichtbar. - [x] Ein geänderter Host-Key wird innerhalb von fünf Minuten gemeldet, ohne den Abgleich-Ablauf zu ändern. ## Abhängigkeiten #021 ## Notizen / Entscheidungen - **Versand im Worker**, auch für die Testnachricht: der Webprozess braucht so keinen Weg zu Mailserver oder Webhook-Ziel, und regulärer Versand und Test laufen über denselben Code. Die Oberfläche verfolgt den Test wie andere Vorgänge über `VorgangsKnopf`. - **Anlässe aus der Datenbank**, nicht aus dem Abgleich: `src/worker/ablaeufe/abgleich.ts` bleibt unverändert; der Sammler liest offene `Abweichung`, `Host.erreichbar = false` und Ablaufdaten. Ein verpasster Lauf holt sich der nächste. - **Fingerabdrücke:** `drift:`, `hostkey:`, `ablauf:::` (mit Datum, damit ein verlängerter Schlüssel neu erinnert wird), `abgelaufen::`, `unerreichbar::` (ändert sich nur bei gelungenem Abgleich → eine Meldung je Ausfall). Statt „seit der letzten Meldung“ zählt das Versandprotokoll – wer Benachrichtigungen erstmals einschaltet, bekommt die offenen Abweichungen einmal gemeldet. - Hosts mit offenem `HOSTKEY_GEAENDERT` erscheinen nicht zusätzlich als „nicht erreichbar“. - Der Fünf-Minuten-Takt verschickt dringende Host-Key-Meldungen und fällige Wiederholungen; Neues aus (a)–(d) wartet auf die Zusammenfassung. Läufe im selben Worker laufen nacheinander. - Leser sehen statt der Webhook-Adresse nur Schema und Host (Tokens im Pfad). - Mailpit für Tests mit `MP_SMTP_DISABLE_RDNS=true` starten, sonst wartet es je Verbindung 5 s. - `nodemailer@10.0.10` wie in ProxLedger, exakt gepinnt.