diff --git a/features/INDEX.md b/features/INDEX.md index 8b4ac1a..e433c86 100644 --- a/features/INDEX.md +++ b/features/INDEX.md @@ -39,6 +39,8 @@ | PROJ-24 | TOTP Zwei-Faktor-Authentifizierung (2FA) | Deployed | [PROJ-24](PROJ-24-totp-zwei-faktor.md) | 2026-03-18 | | PROJ-25 | User-Profil & Einstellungen | Deployed | [PROJ-25](PROJ-25-user-profil-einstellungen.md) | 2026-03-18 | +| PROJ-26 | IMAP-Server-Schnittstelle (Read-Only Archivzugriff) | Planned | [PROJ-26](PROJ-26-imap-server-schnittstelle.md) | 2026-03-18 | + -## Next Available ID: PROJ-26 +## Next Available ID: PROJ-27 diff --git a/features/PROJ-26-imap-server-schnittstelle.md b/features/PROJ-26-imap-server-schnittstelle.md new file mode 100644 index 0000000..32a692d --- /dev/null +++ b/features/PROJ-26-imap-server-schnittstelle.md @@ -0,0 +1,73 @@ +# PROJ-26: IMAP-Server-Schnittstelle (Read-Only Archivzugriff) + +## Status: Planned +**Created:** 2026-03-18 +**Last Updated:** 2026-03-18 + +## Dependencies +- Requires: PROJ-1 (Authentifizierung & Rollen) — Login via Benutzername/Passwort +- Requires: PROJ-5 (Speicherung & Indexierung) — E-Mails aus dem Archiv lesen +- Requires: PROJ-9 (Labels) — Labels als IMAP-Ordner abbilden +- Requires: PROJ-21 (Multi-Tenancy) — Nutzer sieht nur eigene Mails + +## User Stories +- Als Nutzer möchte ich mein E-Mail-Archiv mit Thunderbird, Outlook oder Apple Mail öffnen können, damit ich ohne Webinterface auf archivierte Mails zugreifen kann. +- Als Nutzer möchte ich mich mit meinem normalen Benutzername und Passwort am IMAP-Server anmelden, damit ich keine separaten Zugangsdaten brauche. +- Als Nutzer möchte ich meine Labels als IMAP-Ordner sehen, damit ich archivierte Mails thematisch organisiert abrufen kann. +- Als Admin möchte ich, dass Nutzer das Archiv nur lesen können (kein Löschen, kein Verschieben), damit die GoBD-Konformität und Archivintegrität gewahrt bleibt. +- Als Nutzer möchte ich den IMAP-Zugang von außen (Port 993, SSL) nutzen können, damit ich auch unterwegs auf das Archiv zugreifen kann. + +## Acceptance Criteria +- [ ] Eingebetteter IMAP4rev1-Server läuft als Teil des Go-Backends (Port 1143 intern) +- [ ] Externer Zugriff via IMAPS Port 993 — nginx oder stunnel terminiert TLS, leitet an 1143 weiter +- [ ] Authentifizierung mit Benutzername + Passwort (bcrypt-Vergleich, wie Webinterface) +- [ ] LDAP-Nutzer können sich ebenfalls per IMAP anmelden (LDAP-Auth-Pfad) +- [ ] Jeder Nutzer sieht ausschließlich seine eigenen archivierten E-Mails (Multi-Tenant-Isolation) +- [ ] Ordnerstruktur: `INBOX` (alle Mails) + Labels als Unterordner (z.B. `INBOX/Rechnungen`) +- [ ] Globale Labels (Admin-Labels) erscheinen ebenfalls als Ordner +- [ ] Vollständig Read-Only: keine DELETE, STORE \Deleted, COPY oder MOVE-Operationen erlaubt +- [ ] `\Seen`-Flag darf NICHT persistent gesetzt werden (Archivintegrität) +- [ ] IMAP-Kommandos implementiert: `LOGIN`, `LIST`, `SELECT`, `FETCH`, `SEARCH`, `LOGOUT`, `NOOP`, `CAPABILITY` +- [ ] `FETCH` liefert vollständige RFC-2822 E-Mail (Header + Body + Anhänge) +- [ ] `SEARCH` unterstützt mindestens: `ALL`, `FROM`, `TO`, `SUBJECT`, `SINCE`, `BEFORE` +- [ ] Verbindungen werden nach Inaktivität getrennt (Timeout 30 Min.) +- [ ] Maximale gleichzeitige Verbindungen pro Nutzer: 5 +- [ ] Audit-Log-Eintrag bei jedem Login (Erfolg + Fehlschlag) + +## Edge Cases +- Nutzer hat keine E-Mails → `INBOX` ist leer, `SELECT INBOX` antwortet mit 0 EXISTS +- Label wurde gelöscht aber IMAP-Client cached den Ordner → leerer Ordner, keine Fehlermeldung +- Falsches Passwort → nach 5 Fehlversuchen temporäre Sperre (30 Min.), Audit-Log-Eintrag +- Sehr großes Archiv (> 100.000 Mails) → `SELECT` liefert korrekte EXISTS-Zahl, `FETCH` paginiert +- IMAP-Client versucht APPEND (Mail hochladen) → `NO [CANNOT] Read-only archive` +- Gleichzeitige Verbindungen vom gleichen Client → erlaubt bis Limit (5), danach `BYE` +- LDAP-Nutzer dessen LDAP-Server nicht erreichbar ist → Login verweigert, Fehlermeldung im Audit-Log +- Nutzer wird während aktiver IMAP-Session gelöscht → Session wird beim nächsten Kommando beendet + +## Technical Requirements +- **Protokoll:** IMAP4rev1 (RFC 3501) +- **Port intern:** 1143 (plaintext, nur localhost/LAN) +- **Port extern:** 993 (IMAPS via nginx/stunnel als TLS-Terminator) +- **TLS:** Pflicht für externe Verbindungen — Zertifikat von `/etc/letsencrypt/` oder selbstsigniert +- **Authentifizierung:** LOGIN-Mechanismus (Benutzername/Passwort), PLAIN über TLS +- **Performance:** SELECT auf 10.000 Mails < 500ms, FETCH einer einzelnen Mail < 200ms +- **Bibliothek:** `github.com/emersion/go-imap` (v1 oder v2) — battle-tested IMAP-Server-Bibliothek für Go +- **Integration:** IMAP-Server startet als Goroutine im bestehenden Go-Backend (wie smtpd) +- **Konfiguration:** Neuer Abschnitt `imap_server:` in `/etc/archivmail/config.yml` + ```yaml + imap_server: + enabled: true + bind: "0.0.0.0:1143" + tls: false # TLS-Terminierung durch nginx + ``` +- **Sicherheit:** Kein STARTTLS auf 1143 (nginx übernimmt TLS) — Rate-Limiting bei Login-Fehlern + +--- +## Tech Design (Solution Architect) +_To be added by /architecture_ + +## QA Test Results +_To be added by /qa_ + +## Deployment +_To be added by /deploy_