104 lines
6.6 KiB
Markdown
104 lines
6.6 KiB
Markdown
# Erweiterungsplan: mehrere Ein- und Ausgänge
|
|
|
|
Stand: 2026-09-15 · 0.1.0-alpha.5
|
|
|
|
## Update: Ausbau umgesetzt
|
|
|
|
SQLite-Outbox, Retry/Deduplizierung, SMTP-Ausgang, IMAP-Eingang, ntfy-/Gotify-Ausgänge,
|
|
Discord-Slash-Commands, Zustellhistorie, Readiness und Prometheus-Zustandsmetriken
|
|
sind implementiert. Hinzu kommen bcrypt, CSRF-/Origin-Prüfung, CSP, Login-Limits,
|
|
Body-Limits und Secret-Referenzen über Umgebungsvariablen. Die API antwortet jetzt
|
|
nach Speicherung mit HTTP 202. Einrichtung und Grenzen: [OPERATIONS.md](OPERATIONS.md).
|
|
|
|
Prüfungen umfassen SQLite-Neustart/Leases/Parallelannahme, selektive Wiederholung,
|
|
lokale SMTP-/IMAP-Server mit TLS, Discord-Signaturen und einen echten Browser-Test.
|
|
OAuth2, HTML-Mail-Konvertierung, Aufbewahrungsregeln, Verschlüsselung at rest und
|
|
CI/Lasttests bleiben Folgearbeiten.
|
|
|
|
## Bewertung des Projekts
|
|
|
|
Das Go-Projekt besitzt bereits brauchbare Bausteine: authentifizierte ntfy-,
|
|
Gotify- und Webhook-Eingänge, ein gemeinsames Nachrichtenmodell, Regeln mit
|
|
Templates, einen Divera247-Client und eine formularbasierte Administration.
|
|
Der wichtigste architektonische Engpass war die feste Kopplung des Dispatchers
|
|
an Divera247. Weitere Eingänge allein hätten die möglichen Empfänger nicht erweitert.
|
|
|
|
Die JSON-Konfiguration bleibt bestehen; SQLite speichert jetzt Zustellaufträge,
|
|
Checkpoints und Historie. Ein vollständiger
|
|
Ausbau aller Divera247-Endpunkte hat gegenüber Provider-Auswahl und
|
|
Zustellzuverlässigkeit zunächst geringere Priorität.
|
|
|
|
## Prioritäten und Abnahmekriterien
|
|
|
|
| Schritt | Umfang | Abnahme / Status |
|
|
|---|---|---|
|
|
| 1: Ausgangsmodell | Benannte Ziele, Zuordnung pro Regel, Dry-Run pro Ausgang, Vorschau | **Umgesetzt**; vorhandene Divera247-Regeln behalten ihr Schema |
|
|
| 2: HTTP-Ausgänge | Discord-Webhooks und generische JSON-Webhooks, Token, Timeout, einzelne Ergebnisse | **Umgesetzt**; lokale HTTP-Tests, keine echten Nachrichten |
|
|
| 3: Zuverlässigkeit | SQLite-Outbox, Delivery-ID, Idempotenz pro Ziel, Retry/Backoff, `Retry-After`, Dead-Letter und Audit | Neustart verliert keine angenommene Nachricht; bereits erfolgreiche Ziele werden bei Wiederholung nicht erneut versendet |
|
|
| 4: Mail-Ausgang | SMTP, verpflichtendes TLS/STARTTLS, Secret-Referenzen, Absender und Empfänger, MIME/UTF-8 | Tests gegen lokalen SMTP-Server; Header-Injection, TLS-Fehler und Timeouts abgedeckt |
|
|
| 5: Mail-Eingang | IMAP über TLS, Ordner, UID/UIDVALIDITY-Checkpoint, MIME-Text, Absender-/Empfängerfilter | Wiederanlauf ohne Verlust/Doppelverarbeitung; Nachricht erst nach persistenter Annahme quittieren; Limits für MIME/Anhänge |
|
|
| 6: Weitere Push-Ausgänge | ntfy und Gotify; danach Slack/Teams nach Bedarf | Dokumentierte Provider-Payloads, Fehlerfälle und Admin-Vorschau |
|
|
| 7: Discord-Eingang | Slash-Command/Interaction mit Signaturprüfung; Bot-Gateway nur für benötigtes Kanal-Monitoring | Signaturen, Zeitfenster, Channel-/Guild-Allowlist, schnelle Quittierung und Schleifenschutz |
|
|
| 8: Betrieb | Delivery-Historie mit Wiederholen, Readiness, Metriken, Secret-Referenzen, CSRF/Passwort-Härtung, CI | Betriebsfehler diagnostizierbar; keine Secrets in Logs; reproduzierbare automatisierte Prüfungen |
|
|
|
|
Schritt 3 geht Live-Retries und Mail-Polling voraus: Bei mehreren Empfängern
|
|
darf eine erneute Eingangsanfrage nicht alle schon erfolgreichen Zustellungen
|
|
wiederholen. Netzwerkzustellung kann trotz Timeout erfolgt sein; „exactly once“
|
|
ist ohne Unterstützung des Zielsystems nicht garantiert.
|
|
|
|
## Datenfluss und Erweiterungspunkte
|
|
|
|
`Eingangsadapter → Authentifizierung → InboundMessage → Regeln/Templates → Ausgang → DeliveryResult`
|
|
|
|
- `internal/config/outbound.go`: benannte Ausgangskonfiguration und Validierung.
|
|
- `internal/gateway`: Auswahl der Regeln, providerabhängige Payloads, Vorschau,
|
|
Weiterleitung an alle passenden Regeln und Sammlung von Fehlern.
|
|
- `internal/outbound`: HTTP-Transport für Discord und JSON-Webhooks.
|
|
- `internal/divera`: bestehender spezialisierter Divera247-Client.
|
|
- `internal/httpserver`: Admin-Formulare, bestehende Eingänge und APIs.
|
|
|
|
Ein Ausgang ist eine Verbindung, eine Regel bestimmt Inhalt und Ziel.
|
|
Mehrere Regeln können denselben Eingang an unterschiedliche Ausgänge verteilen.
|
|
SMTP hat einen eigenen Transport; ein dynamisches Pluginsystem ist für die
|
|
wenigen eingebauten Adapter derzeit nicht nötig.
|
|
|
|
## Umfang des ersten Implementierungsschritts
|
|
|
|
- [x] `outbounds[]` mit ID, Name, Provider, URL, optionalem Bearer-Token,
|
|
Timeout und explizitem `live`-Schalter (Standard: false).
|
|
- [x] `target: discord|webhook` und `outbound_id` in Zuordnungen.
|
|
- [x] CRUD-Formulare im Bereich **Ausgänge**, Zielauswahl und Payload-Vorschau.
|
|
- [x] Discord: `wait=true`, keine automatischen Mentions, leere oder zu lange
|
|
Texte werden zurückgewiesen; keine stille Kürzung/Mehrfachnachrichten.
|
|
- [x] HTTP-Webhooks: POST JSON mit gemapptem Titel/Text/Adresse und Metadaten;
|
|
Raw-Eingaben und Divera247-Extras werden nicht automatisch weitergegeben.
|
|
- [x] URLs, Referenzen, Provider, Timeout und Template-Syntax validieren.
|
|
- [x] HTTP-Redirects blockieren; URLs/Tokens und Remote-Antwortinhalte nicht in
|
|
Ergebnisse/Fehler der neuen Ausgänge übernehmen.
|
|
- [x] Bei Fehlern weitere passende Regeln versuchen und Einzelergebnisse liefern.
|
|
- [x] Regression: identische Regex in mehreren Bedingungen separat prüfen.
|
|
|
|
### Bewusste Grenzen
|
|
|
|
Ein Worker verarbeitet die persistente Queue sequenziell. Historie und
|
|
Deduplizierungsbelege werden noch unbegrenzt aufbewahrt. Ohne expliziten
|
|
HTTP-Idempotency-Key wird jede Anfrage neu angenommen. Ein unklarer Netzwerkausgang
|
|
kann trotz stabiler Delivery-ID eine Doppelzustellung beim Ziel verursachen.
|
|
|
|
IMAP unterstützt Plain-Text-MIME bis 1 MiB; problematische Nachrichten blockieren
|
|
ihren Checkpoint bis zur Korrektur. Discord-Ingress verarbeitet Slash-Commands,
|
|
kein allgemeines Channel-Monitoring. Discord-Ausgänge
|
|
unterstützen Text in normalen Kanälen bzw. bestehende Threads via `thread_id`
|
|
in der URL; keine Dateien, Embeds oder automatische Forum-Thread-Erstellung.
|
|
Webhook-URLs und Tokens liegen wie bisherige Provider-Secrets in der
|
|
Admin-Konfiguration. Die neuen Transport-Schutzmaßnahmen ersetzen keine
|
|
projektweite Überarbeitung des bestehenden Divera247-Fehlerhandlings.
|
|
|
|
## Protokollquellen
|
|
|
|
- [Discord Execute Webhook](https://docs.discord.com/developers/resources/webhook#execute-webhook): Content-Limit, `wait`, `allowed_mentions`.
|
|
- [Discord Interactions](https://docs.discord.com/developers/interactions/receiving-and-responding): Signaturprüfung und Antwortzeitfenster für den geplanten Eingang.
|
|
|
|
SMTP nutzt Go net/smtp; IMAP und MIME verwenden die emersion-Bibliotheken.
|
|
Passwort-/App-Passwort-Anmeldung ist implementiert; OAuth2 bleibt ein eigener Umfang.
|