Zurück zum Postfach

Changelog

aktuell v3.4.0

v3.4.0

Seitenleisten per Drag in der Breite verstellbar

  • Neue Drag-Handles zwischen Sidebar/Liste und Liste/Lesebereich (nur Desktop): Spaltenbreite durch Ziehen verstellen, Doppelklick setzt auf Standard zurueck
  • Breiten werden in localStorage gespeichert und beim Laden wiederhergestellt (mail.sidebarWidth / mail.listWidth), mit Min/Max-Grenzen geclampt
  • Pointer Capture haelt den Drag auch ueber dem Mail-iframe und ausserhalb des Fensters stabil
  • Zusammenspiel mit dem Einklappen unveraendert: eingeklappte Spalte blendet ihren Handle aus

v3.3.0

Mail-Anhaenge per Drag-und-Drop in lokale Ordner ziehen

  • Anhang-Chips in der Leseansicht sind jetzt draggable: beim Ziehen aus dem Browser in den Explorer/auf den Desktop speichert Chrome die Datei direkt am Ablageort (DataTransfer "DownloadURL", Chromium-Browser)
  • Klick zum Herunterladen funktioniert unveraendert; Tooltip erklaert beide Wege

v3.2.0

IMAP-Pool wartet bei Auslastung statt Verbindungs-Burst zu erzeugen

  • Harte Obergrenze von 3 Verbindungen pro Konto: Ist der Pool belegt, warten Anfragen (max. 30 s) auf einen freien Slot, statt zusaetzliche Verbindungen zu oeffnen - Mailserver drosseln Verbindungs-Bursts pro Nutzer/IP (Dovecot-Limit, fail2ban), was nach dem 3.1.0-Deploy beim ersten Mail-Oeffnen zu haengenden Connects und nginx-504 fuehrte
  • imapflow-Timeouts gesetzt (connect 20 s, Greeting 10 s): gedrosselte Connects enden als schnelle JSON-Fehlermeldung statt im Proxy-Timeout

v3.1.0

IMAP-Verbindungspool, echte Pagination, globale Mehrwort-Suche

  • Verbindungspool: pro Konto bleiben bis zu 3 IMAP-Verbindungen warm (4 min Idle-Timeout), statt pro Klick TCP+TLS+LOGIN neu zu bezahlen - Ordnerwechsel, Mail oeffnen, Flags, Suche reagieren deutlich schneller
  • DNS ipv4first (instrumentation.ts): behebt intermittierende Haenger gegen mail.your-server.de (Container ohne IPv6-Route, AAAA-Record)
  • Echte Pagination: "Mehr laden" holt nur die naechsten 50 Mails (Cursor) statt die ganze Liste neu; Sammelansicht mit per-Konto- Cursorn (k-way merge) statt wachsendem Limit
  • Thread-Ansicht: Kandidaten-Ordner werden parallel ueber den Pool geladen statt sequenziell
  • Suche komplett neu: durchsucht alle Konten und alle Ordner (ausser Junk/Papierkorb) parallel, auch aus der Sammelansicht; mehrere Woerter werden UND-verknuepft (Betreff/Absender/Empfaenger je Wort); Inhaltssuche optional per Checkbox (auf Servern ohne Volltext-Index langsam); Treffer zeigen Konto + Ordner und oeffnen die Mail direkt
  • Alle Mail-Routen liefern bei IMAP-Fehlern jetzt JSON-Fehler mit verstaendlicher Meldung statt leerer 500er

v3.0.0

Link-Ziel beim Mouseover in der Mail anzeigen (Status-Leiste)

  • Beim Ueberfahren eines Links in der Mail erscheint unten links eine browserartige Status-Leiste mit der echten Ziel-URL - schuetzt vor Links, deren Text eine andere Adresse vortaeuscht
  • Umsetzung ohne Skripte in der Mail: die App lauscht per Event-Delegation auf dem same-origin iframe-Dokument; die Leiste liegt ausserhalb des iframes und bleibt daher auch bei gezoomten Mails lesbar

v2.9.0

Linke Spalten einklappbar, Mail-Inhalt skaliert auf Passbreite

  • Seitenleiste und Nachrichtenliste lassen sich am Desktop einzeln zu einer schmalen Leiste einklappen (Zustand wird in localStorage gemerkt)
  • Mail-HTML mit fester Ueberbreite (starre Newsletter-Tabellen) wird im Lesebereich automatisch auf die Fensterbreite gezoomt - kein horizontales Scrollen mehr, besonders auf dem Handy; bei Rotation wird neu angepasst

v2.8.0

Umschalter-Darstellung, sichtbare Empfaenger im Kopf, Farbe je Postfach

  • Umschalter (Switch) mit fester Geometrie neu gebaut; kaputte Toggles in Einstellungen (Unterhaltungen, Vorlesen) behoben
  • Empfaenger/Kopie/Blindkopie/Antwort-an werden beim Oeffnen einer Mail jetzt immer im Kopf angezeigt (nicht mehr eingeklappt)
  • Farbe je Postfach in den Einstellungen festlegbar (Sammelansichten), sonst deterministischer Standard

v2.7.0

Konversationsansicht, Sammelordner, Compose im rechten Bereich, Marken-Theme

  • Konversationsansicht (ordneruebergreifendes Threading) mit Umschalter in den Einstellungen
  • Sammelansichten fuer alle Ordner: Gesendet, Entwuerfe, Archiv, Papierkorb, Spam
  • Verschieben-Dropdown funktioniert jetzt auch im Sammelmodus (Ordner des jeweiligen Kontos)
  • Reicher, ausklappbarer Kopf: Von/An/Kopie/Blindkopie/Antwort-an
  • Neue Mail und Antworten im rechten Bereich statt als Popup (mobil Vollbild)
  • Anhaenge per Drag and Drop
  • Infinite-Scroll ohne Sprung nach oben (keepPreviousData + IntersectionObserver)
  • Marken-Theme Blau/Orange (hell und dunkel) + Akzent-Auswahl in den Einstellungen
  • mailto oeffnet neue Mail in der laufenden App (Chromium Launch Handler)
  • Groessere Aktions-Icons

v2.6.0

Android-Zurueck navigiert in der App statt die PWA zu schliessen

  • Im Standalone-PWA-Modus poppte der Zurueck-Button die Browser-History und verliess die App, weil Nachricht/Compose/Suche/Drawer nur ueber State geoeffnet werden (kein History-Eintrag). Jetzt haelt useOverlayBack pro offenem Overlay einen History-Guard: ein echter Zurueck-Druck schliesst das oberste Overlay (Prioritaet: Compose > Suche > Drawer > offene Nachricht); Schliessen per UI entfernt den passenden Guard.

v2.5.0

Mail-Ansicht auf Handy — volle Breite, kein Times, kein Querscrollen

  • E-Mail-HTML wird in ein echtes Dokument mit Viewport-Meta und Basis- Styles gehuellt: moderne Sans-Serif statt Times, Bilder/Tabellen fluid (max-width:100%), Wortumbruch — kein horizontales Scrollen mehr. Inline-Styles designter Mails gewinnen weiterhin (Spezifitaet).
  • Mail-Inhalt auf Mobile randlos und in voller Breite (Rahmen/Radius nur ab md), Klartext-Mails brechen sauber um.
  • Aktionsleiste im Mailkopf: Betreff oben, Buttons darunter in voller Breite gleichmaessig verteilt, groessere Touch-Targets, kompaktere Kopfzeile auf Mobile.

v2.4.0

Touch-/Responsive-Refactoring mit Bottom-Tab-Bar

  • Macht die App grundlegend touchfreundlich und responsive, ohne die schlanke Desktop-UI aufzublaehen (Touch-Vergroesserungen nur via pointer-coarse:-Variante).
  • Bottom-Tab-Bar als Mobile-Navigation (Posteingang/Ordner/Neue Mail/ Suche/Mehr); oberer Hamburger entfaellt
  • Primitives (Button/Input/Editor) mit 44px-Touch-Targets + :active-Feedback
  • Hover-only-Aktionen (Auswahl-Checkbox, Zeilenaktionen, Ordner-Loeschen) jetzt auf Touch dauerhaft sichtbar
  • Compose und Suche als Vollbild-Sheet auf Mobile, Karte ab sm
  • Reading-Pane-Kopf entlastet: Sekundaeraktionen im Mehr-Menue auf Mobile
  • Safe-Area-Insets fuer Bottom-Bar und Compose-Footer

v2.3.0

mailto-Protokoll-Handler — PWA oeffnet neue Mail aus mailto-Links

  • Manifest registriert die installierte PWA als mailto-Handler (protocol_handlers, /?mailto=%s)
  • parseMailto() dekodiert die mailto-URI (to/cc/bcc/subject/body), mit Vitest-Tests
  • Startseite liest den mailto-Parameter beim ersten Render, oeffnet vorausgefuelltes Compose-Fenster und raeumt die URL auf

v2.2.0

Upload-Fortschritt in der Fusszeile + ehrliche 413-Meldung

  • Fortschritt jetzt ohne Scrollen sichtbar: Prozent + Spinner direkt neben dem Klammer-Symbol, duenner Balken an der Oberkante der Leiste.
  • 413 vom Proxy nennt keine App-Limits mehr (nginx kappt aktuell frueher); App-eigene Limit-Fehler nennen dafuer ihre Grenzen (10/25 MB).

v2.1.0

Anhaenge ueberleben Entwurf-Fortsetzung + echtes Upload-Feedback

  • Entwurf oeffnen laedt gespeicherte Anhaenge als Chips; beim Senden/ erneuten Speichern holt der Server sie per IMAP (keepAttachments).
  • Draft-Route gibt neue UID (APPENDUID) + Anhang-Referenzen zurueck, damit Mehrfach-Speichern im selben Fenster konsistent bleibt.
  • Compose: Upload-Fortschritt via XHR (Prozent + Balken), Groessen- validierung beim Auswaehlen (10 MB/Datei, 25 MB gesamt), Summenzeile, klare 413-Fehlermeldung statt generischem Sende-Fehler.
  • Fix: FileList-Snapshot in addFiles (Live-Liste wurde durch value-Reset geleert, Dateien gingen timing-abhaengig verloren).

v2.0.0

Absender im Compose-Fenster auswaehlbar (From-Adresse + Signatur)

  • Beim Schreiben einer neuen Mail war der Absender fest auf das beim Oeffnen aktive Konto gesetzt. Wer mehrere Konten hat, musste vorher in der Sidebar das richtige Konto waehlen.
  • ComposeDialog bekommt die Kontenliste und einen "Von"-Dropdown (nur sichtbar bei mehr als einem Konto); Auswahl steuert die gesendete accountId. Kein Backend-Change noetig — send/route.ts baut den From-Header bereits aus dem Konto.
  • Beim Absenderwechsel wird die Signatur mitgewechselt: der zuletzt eingefuegte Signaturblock wird im Editor durch den des neuen Kontos ersetzt. Nur bei neuer Mail, nicht bei Antwort/Weiterleitung/Entwurf.

v1.9.0

klare Fehlermeldungen + SMTP-Test beim Anlegen neuer Konten

  • Beim Anlegen eines Postfachs zeigte jeder Verbindungsfehler nur "Fehler: Command failed" — imapflow wirft einen generischen Error, dessen echte Ursache in err.responseText/err.code steckt.
  • neuer Helper describeMailError() uebersetzt imapflow-/nodemailer-Fehler in klare deutsche Meldungen (falsches Passwort, Host/Port, Timeout, TLS)
  • POST /api/accounts gibt detail jetzt ueber describeMailError() zurueck
  • zusaetzlich SMTP-Verbindung via verifySmtp() vor dem Speichern pruefen, damit SMTP-Fehler nicht erst beim ersten Sendeversuch auffallen

v1.8.0

Versionsschema (1 Commit = 0.1) + Changelog-Generator, Version 1.7.0

  • Generator (scripts/gen-changelog.mjs) vergibt jetzt eine Version pro Commit (+0.1, Initial = v0.1.0, Merges ausgenommen) statt nach Git-Tags zu gruppieren. pnpm changelog schreibt nun beide Quellen aus derselben Historie: CHANGELOG.md und die In-App-Liste src/lib/changelog.ts (vorher handgepflegt und veraltet), damit sie nicht mehr auseinanderdriften. package.json auf 1.7.0 gesetzt (Stand des neuesten Feature-Commits Vorlesefunktion), wird in der App-Spalte angezeigt.

v1.7.0

Vorlesefunktion (Text-to-Speech) fuer neue Mails und geoeffnete Mail

  • Liest neu eintreffende Mails automatisch vor (Absender + Betreff) und bietet im Lesebereich einen Vorlesen-Knopf fuer die geoeffnete Mail. Konfigurierbar in den Einstellungen: An/Aus, Stimmenauswahl (Deutsch bevorzugt), Test-Knopf.
  • Basiert auf der Web Speech API (window.speechSynthesis) - rein clientseitig, keine Server-/DB-Aenderung. Einstellungen liegen in localStorage (mail.readAloud.*).

v1.6.0

remember selected account/view across browser reloads

  • selectedAccountId was React-only state (initial null), so a reload always fell back to the first account — "Alle Konten" never stuck. Persist the choice in localStorage (like the theme) and restore it via a lazy useState initializer. A stored account that no longer exists is ignored once accounts load, falling back to the first account.

v1.5.0

Sammelposteingang (unified inbox across all accounts)

  • Adds an opt-in "Alle Konten" view that merges every account's INBOX into one date-sorted list.
  • New /api/mail/messages-unified route fetches all accounts' INBOX in parallel (Promise.allSettled), merges/sorts by date, isolates per-account failures into errors[] so one dead mailbox never blanks the view.
  • Message identity is now composite (accountId:uid) so the unified view survives IMAP uid collisions across accounts. Action handlers take a per-message accountId; single-account callers fall back to the page account (behavior unchanged). Optimistic updates patch both the per-account and unified caches (matched on accountId AND uid).
  • Bulk actions group the selection per account → one request each.
  • List shows a per-account colour dot + label badge and a banner for failed accounts. Reply/compose derive the owning account from the open message (fixes from-address in unified mode). Folder sidebar, search and move-to-folder are hidden in unified mode; SSE opens one stream per account.

v1.4.0

use next/link instead of <a> on offline page

  • Resolves the no-html-link-for-pages lint error breaking CI.

v1.3.0

open email links in a new tab instead of inside the message frame

  • Inbound email anchors had no target, so clicking a link navigated the sandboxed iframe itself and replaced the message content. Sanitizer now adds target=_blank + rel=noopener, and the iframe sandbox allows popups to escape so links open as a normal new tab.

v1.2.0

Auto-Deploy zu Dokku aktualisieren

    v1.1.0

    PWA (installable + offline shell) + responsive mobile layout

    • PWA: web manifest (src/app/manifest.ts), icons (src/app/icon.svg + public/icons/*.png generated from the logo SVG), viewport/theme-color + apple-web-app metadata. Privacy-safe service worker (public/sw.js): caches only the static app shell, NEVER /api/* or mail (keeps the live-only model); navigations network-first with an /offline fallback. SW registered in production only; new src/app/offline/page.tsx.
    • Responsive: sidebar becomes a slide-in drawer on mobile (hamburger + backdrop), static on desktop; message list and reading pane become a master-detail below md (list → full-screen message with a back button) and stay side-by-side on desktop. (app)/layout.tsx uses h-dvh; reading-pane toolbar wraps.

    v1.0.0

    Outlook-style features — signatures, account editing, M365 OAuth, rich-text compose, organization, theme & shortcuts

    • AI/Ollama: per-request timeout + per-chunk inactivity guard, friendly German error mapping (no more raw "fetch failed"), GET /api/ollama/health, shared model allowlist module.
    • Accounts: edit/delete via /api/accounts/[id]; per-account HTML+text signatures (sanitized at write time), inserted client-side in the composer.
    • Microsoft 365: OAuth2/XOAUTH2 (Authorization Code + PKCE) for Exchange Online IMAP/SMTP; connectImap + SMTP sender branch on authType (basic | oauth_ms).
    • Compose: rich-text HTML editor, signature insertion, BCC, attachment upload (multipart), drafts save/resume (IMAP APPEND to Drafts); HTML reply quoting.
    • Organization: multi-select bulk actions, mark-all-read, folder create/delete, move-to-folder; flags/move routes accept uid or uids[].
    • UX: settings index, light/dark toggle (FOUC-free inline script), keyboard shortcuts + help overlay, Ollama connection test + model pull in settings.
    • DB: migration 0001 (signature + oauth columns; password columns nullable).

    v0.9.0

    app versioning + in-app changelog from git history

    • Version is sourced from package.json (now 0.2.0) and inlined into the bundle via next.config (NEXT_PUBLIC_APP_VERSION); exposed as APP_VERSION in src/lib/version.ts.
    • CHANGELOG.md is generated from the commit descriptions, grouped by git tag, via scripts/gen-changelog.mjs (`pnpm changelog`). Tagged v0.1.0 at the pre-rework commit so the 0.1.0 / 0.2.0 split is accurate.
    • New public /changelog page renders the curated release history (src/lib/changelog.ts) and links to the full CHANGELOG.md on GitHub.
    • The version number is shown as a link to /changelog in the mail sidebar footer and on the login screen.
    • typecheck/lint/test/build all green; /changelog prerenders with the version.

    v0.8.0

    stop tracking local .claude harness artifacts

      v0.7.0

      align documentation with the live-only rework

      • Findings from a multi-agent doc audit (README/.env/comments vs. code):
      • README: DB service is `maildb` (not `postgres`) in the stack line and architecture diagram; add the rationale note.
      • README: add a compact internal API route table (maps features to method+path), documenting the messages pagination params (limit max 200, before = count of newest messages to skip) and the attachment dl=1 flag.
      • README: clarify the remote-image toggle (client-side, per message), the AI-output cache semantics, the /api/ollama/pull endpoint, the /api/health endpoint, and the db:generate script.
      • .env.example: document the bundled-Postgres POSTGRES_* vars.
      • Dockerfile: drop stale comments referencing a removed `worker` service.
      • drizzle.config.ts: drop stale pgvector comment.
      • ollama/pull allowlist: drop the removed embedding model (nomic-embed-text), add the default chat model (llama3.1) — chat-only, matches the feature set.
      • No behavior change beyond the pull allowlist; typecheck/lint/test/build green.

      v0.6.0

      Rework to live-only IMAP client (no mail persistence)

      • Per the owner's requirement, emails must never be downloaded or stored locally - they stay on the IMAP server. This inverts the previous DB-first architecture.
      • Removed:
      • Mail persistence layer (sync, persist, messages/folders/threads/attachments tables) and the pg-boss worker + job queue
      • Index-based AI: embeddings (pgvector), semantic search, RAG categorization
      • Postgres now stores only Better Auth tables + encrypted mail_accounts credentials (plus an optional ai_outputs cache, off by default).
      • Added / reworked (all live IMAP/SMTP, nothing persisted):
      • Read/unread, star, archive, trash/delete (flags + move routes)
      • Reply / reply-all / forward with quoting (isomorphic buildReplyDraft)
      • Sent-folder APPEND of outgoing mail (fixed Message-ID)
      • On-demand attachment download + inline cid image resolution
      • Remote-image blocking with a client-side load-images toggle
      • Live AI (Ollama): summarize + reply draft; optional output cache (PERSIST_AI_OUTPUTS, never raw mail)
      • Server-side IMAP keyword search
      • Near-real-time new mail via SSE (IMAP IDLE held in the web process)
      • Pagination, /api/health, single-image docker-compose (web + postgres)
      • Tooling: Vitest unit tests (reply, sanitize, crypto), GitHub Actions CI. All green: typecheck, lint, test, build.

      v0.5.0

      Add auth-gated endpoint to pull small Ollama models

      • POST /api/ollama/pull streams progress while pulling an allowlisted model (llama3.2:1b/3b, qwen2.5:1.5b/3b, nomic-embed-text) onto the Ollama server. Lets the app provision a CPU-friendly model without server CLI access.

      v0.4.0

      Make AI lightweight for CPU-only hosts (Hetzner CAX21)

      • Disable background AI jobs by default (ENABLE_AI_BACKGROUND, default false): the worker no longer runs an LLM inference per synced message, which was saturating the 4-core ARM CPU (categorize on qwen3 also looped via retries).
      • Disable model "thinking" (think:false) for chat/summarize: qwen3 reasoning multiplies CPU latency and breaks format:json.
      • Lower job retryLimit 5->1 and concurrency 2->1 so a failing job can't loop. Summarize and search remain available on-demand.

      v0.3.0

      Rename DB service postgres -> maildb to avoid network name collision

      • With Coolify's predefined-network connection (required to reach Ollama), a generic "postgres" service name collides with other stacks' postgres on the shared coolify network; DNS resolved ambiguously, causing intermittent "password authentication failed". A unique service name fixes it.

      v0.2.0

      Fix Docker build for Coolify deploy

      • Pin pnpm@9.15.9 (packageManager + corepack prepare): corepack otherwise pulls pnpm v11 which needs Node >=22.13 and fails on node:20-alpine.
      • Add placeholder env in the build stage so `next build` can import env-validating modules (Better Auth, db); real values come at runtime.

      v0.1.0

      Initial commit: AI mail client (Phases 1-4)

      • Modern self-hosted webmail for Coolify with local Ollama:
      • Phase 1: IMAP/SMTP accounts (AES-256-GCM creds), read/render (sanitized iframe), compose+send, AI summarize (streamed) — Next.js 16 + Better Auth.
      • Phase 2: Postgres persistence + worker with supervised IMAP IDLE sync, pg-boss job queue, DB-first message routes with live-IMAP fallback.
      • Phase 3: pgvector embeddings + semantic search (/api/search).
      • Phase 4: AI categorize/prioritize + natural-language "ask" search (RAG).
      • Command-palette search UI (Cmd/Ctrl+K).
      • Deploy via docker-compose (web + worker + pgvector postgres) on Coolify.
      Vollständige Commit-Historie (CHANGELOG.md)