Neuer CLI-Subcommand: archivmail recompress [--dry-run]
Komprimiert alle unkomprimierten Dateien im Store atomisch (temp + rename).
Überspringt bereits komprimierte Dateien (Magic-Byte 0x01).
Aktualisiert storage_objects und emails.storage_id in der DB.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sprint 1: Emails werden vor AES-256-GCM optional gzip-komprimiert (compress: true).
Magic-Byte 0x01 als Prefix ermöglicht backward-kompatibles Load() für Legacy-Dateien.
Neue DB-Tabelle storage_objects trackt Kompressions-Metadaten.
Sprint 2: Attachments werden via SHA-256 dedupliziert — gleicher Anhang in N Mails
wird nur einmal gespeichert. Neue Tabellen: attachments, email_attachments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auditoren haben keine eigenen Mails — Labels machen für sie keinen Sinn.
Die Sidebar (inkl. "+ Neues Label") wird jetzt nur noch für Rollen
mit eigenen Mails angezeigt (user, domain_admin, superadmin).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- main.go: Default-Backend von "xapian" auf "manticore" geändert
- index.go: Kommentar und Fehlermeldung aktualisiert
- update.sh: Xapian-Verzeichnis wird nach erfolgreichem Manticore-Reindex
automatisch entfernt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
auditor-Rolle hat evtl. tenant_id gesetzt (historisch), soll aber
trotzdem immer den globalen Index durchsuchen und nur No-Tenant-Mails
sehen. tenant_id auf auditor-User per DB-Migration auf NULL gesetzt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auditor-Rolle sieht jetzt Mails wo tenant_id IS NULL und kein
email_refs-Eintrag existiert (statt nur eigene Mails)
- Neues storage.IsWithoutTenant() für effizienten Direktzugriff
- Neues storage.GetAllIDsWithoutTenant() für Suche + ZIP-Export
- Konsistente Prüfung in Search, GetMail, GetAttachment, GetRaw, Export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- emailsFromHeader gibt bei Parse-Fehler nil zurück (fail-closed) statt raw-Header-String;
verhindert Authorization-Bypass via malformiertem From-Header
- mailBelongsToUser: strings.Contains-Fallback entfernt (war dead code nach dem fix-closed-Fix)
- handleSearch: domain_auditor ohne TenantID wird mit 403 abgewiesen, bevor der globale Index
abgefragt wird
- manticoreTableName: Regex-Validierung ^emails_(global|tenant_\d+)$ mit panic bei Abweichung
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- mailBelongsToUser: net/mail.ParseAddressList statt strings.Contains
verhindert False-Positives durch Display-Namen in Mail-Headern
- LDAP mail-Attribut: net/mail.ParseAddress-Validierung vor Übernahme,
Fallback auf username / username@ldap.local bei ungültiger Adresse
- handleSearch: Auditor-Rolle in userEmailFilter-Check eingeschlossen,
sodass Auditoren im Search-Pfad dieselbe Mail-Isolation erhalten wie User
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stem_de wird vom nativen MySQL-Handler in Manticore 25.0.0 nicht erkannt.
lemmatize_de_all nutzt das mitgelieferte de.pak und funktioniert korrekt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
imapclient.New gibt in beta.8 nur *Client zurueck (kein error).
Alle drei Aufrufe in Connect() korrigiert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Verhindert duplicate-key-Fehler wenn LDAP-uid (z.B. "patrick") vom
gespeicherten username ("patrick@perlbach24.de") abweicht. Erst per
Email matchen und updaten, dann neu anlegen falls nicht vorhanden.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /admin/login: neue Login-Seite nur für auditor, admin, domain_admin, superadmin
- /: blockiert Admin-Rollen mit Hinweis auf /admin
- useAuth: neuer loginPage-Parameter für flexiblen Unauthentifiziert-Redirect
- /admin: leitet bei Nicht-Auth zu /admin/login statt /
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bei doppeltem Signup wird eine "bereits registriert"-Mail gesendet,
sodass jeder Signup-Versuch eine ausgehende E-Mail erzeugt.
Side-Channel-Angriff zur Account-Enumeration nicht mehr möglich.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
storage.Save(): retention_days eines Mandanten muss explizit > 0 sein.
Globale config greift nie automatisch auf Mandanten-Mails.
Mails ohne Mandant: globale config als Fallback (unveraendert).
Frontend: Hinweis und Labels klargestellt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ersetzt nicht-existente getSession(r) durch sessionFromCtx(r.Context()) und
passt den audlog.Log-Aufruf auf die korrekte audit.Entry-Struct-Signatur an.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- version.go: AppVersion + Modules-Map (pro Modul interne Versionsnummer)
- GET /api/version: liefert App- und Modulversionen (ohne Auth)
- archivmail version: zeigt App- und Modulversionen in CLI
- version-Konstante aus cmd_import.go entfernt (war falsche Stelle)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- superadmin + domain_admin haben keinen Mail-Zugriff mehr (requireMailAccess)
- Neue Rolle domain_auditor: alle Tenant-Mails, kein Admin-Zugriff
- auditor + user: nur eigene Mails
- ZIP-Export: kein separates Attachment-Entpacken mehr, nur EML
- roleLevel() um domain_auditor (Level 3) erweitert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>