Release Notes
✨ New Features
- Folder Exclusions Cover Their Subfolders - An excluded folder can now also exclude everything below it; controllable installation-wide via
MailSync:ExcludeSubfolders(defaultfalse) - Global Excluded Folders - Installation-wide
MailSync:GlobalExcludedFolderslist that is additive to the per-account excluded folders - Page Size & Sortable Columns on Account and User Lists - Both lists now offer a page-size selector (20/50/75/100/150) and sortable columns
- Audit Data Export Page - A dedicated admin page (reachable from the Logs page) creates tabular mass data export packages (INDEX.XML + CSV tables + DTD) from the existing archive for external audit tools
⚙️ Improvements
- FolderName Index for Archive Filtering - New index (
text_pattern_ops, migrationMigrateV2609_1_1) onArchivedEmails.FolderNameso filtering the archive by folder stops reading the whole table - Sync Slot Refill Latency - A freed sync slot wakes the scheduler immediately instead of waiting out the 60 s poll delay
- Sync Timeout & UID-based Resume Checkpoints -
MailSync:TimeoutMinutesdefault is0(no timeout). A scheduled sync that exceeds the timeout stops at the next message boundary, is reported asTimed Out, keeps its checkpoints and resumes on the next run;LastSyncis not advanced and the retention passes are skipped. Resume checkpoints now store the last archived UID per folder together with the folder's UIDVALIDITY - Email Count in Account Overview - The account overview table (desktop and mobile cards) now shows the number of archived emails per account, computed with a single grouped query instead of per-account lookups
- Dashboard Performance - Dashboard statistics are now cached in memory (
Dashboard:CacheSeconds, default 60, 0 disables), the 12 per-month counts were consolidated into a single grouped query, and the recent-emails list uses a slim projection instead of loading full email bodies/headers - Job Cancel Ownership - Background jobs can only be cancelled by their owner or an admin
- Stats API Scope - Non-admin API keys no longer receive the instance-wide PostgreSQL database size
- Offload into Disabled Accounts - Disabled IMAP accounts can now be selected as offload targets (UI and CLI)
- Deletion Jobs in the Job List - The Jobs page now also lists account deletion and email deletion jobs (running/queued first, latest 20), with links to the existing per-job status pages
🐛 Bug Fixes
- Banner Line in EML Import - EMLs whose first line is a non standard banner are now recovered and imported instead of being skipped as unrecoverable
- Failed File List in EML Import Status - The EML import status page now lists every skipped file with a categorized reason (banner line, mbox marker, split header block, unparseable headers, ...) in a collapsible panel
- IMAP Certificate Validation with Combined SSL Policy Errors - With
MailSync:IgnoreSelfSignedCert=true, connections to servers whose certificate is both self-signed and issued to a different hostname are now accepted - Folder Tree Bulk Buttons on Keyboard - Enter/Space on the desktop expand/collapse-all buttons no longer folds the whole panel away instead of running the action
- Stuck Page after Back/Forward Cache Restore - A folder click that was served from the browser's back/forward cache (Back button in Firefox/Safari) no longer leaves the result column covered by the busy overlay and the folder tree inert until a manual reload
- Edit Form Re-Render Keeps Picker State - A failed account-save re-renders the form with the same
ExcludeSubfoldersswitch and the installation-wide global exclusion list as on first load; previously the folder picker silently fell back to the default, so withExcludeSubfolders: falseit locked subfolders the sync would actually process - Acknowledged Sync Failures No Longer Claim LastSync Was Held Back - After an operator acknowledges a failed sync run (which advances
LastSync), the account page, account list and dashboard no longer show that the timestamp was held back or keep the warning marker; the issue details remain visible on the account page - Storage Refresh Timeout on Large Archives - The per-account storage calculation now uses a configurable command timeout (
AccountStorage:CommandTimeoutSeconds, default 300s) instead of the 30s Npgsql default that made the scheduled refresh fail silently on large archives, leaving the dashboard with stale storage values; refresh failures are now counted and logged as warnings - UTF-8 Sanitization Overcounting - The replacement counter in
SanitizingJsonParseNodeFactorynow tracks replacements during validation instead of counting U+FFFD characters in the decoded string, preventing overcounting when the original payload legitimately contains the Unicode replacement character - Duplicate Detection Compares Stored Format - Restore/append duplicate checks now compare Message-ID and fingerprint (From/To/Subject/SentDate) in the exact form stored at import time, fixing false negatives that let copies be re-archived when a non-UTC display timezone or multiple recipients were involved
- Recent Emails Robust Against Future Date Headers - Emails with an implausible future "Date:" header (e.g. spam claiming the year 2096) no longer stay pinned at the top of the Recent Emails dashboard for decades: any SentDate beyond the current day falls back to ReceivedDate for ordering and display, for both admin and per-user dashboards; the stored message metadata is never modified
- Folder Hierarchy in EML ZIP Import - The full directory path of each .eml file inside the ZIP (e.g.
Test Folder/Lectures/_AD 2006) is now preserved as the archive folder path with proper nesting in the folder tree, instead of collapsing every directory level into unrelated flat top-level folders; root-level files still land in INBOX