Files
RustBox/CHANGELOG.md
T
Mateusz Gruszczyński beae94e932
RustBox CI / rustbox (push) Canceled after 0s
v0.2.23
2026-11-04 20:44:31 +01:00

71 KiB
Raw Blame History

RustBox changelog

0.2.23

  • Added Style depth to Appearance (skin_depth, migration V053). Colors only applies just a predefined style's palette and keeps every layout control editable; Standard (default) is the previous behavior — palette plus the style's fixed layout profile; Immersive additionally reshapes the interface with the style's own typography, control/button/avatar shapes, floating or flush panes, app bar and search field, sidebar colors, selection markers, card-style rows, primary/compose buttons and backdrop (gradients, glass blur, bevels). Floating-pane geometry applies only to the desktop three-pane layout; phones and tablets keep the drawer layout.
  • Added a separate Style gradients switch to Appearance (skin_gradients, part of migration V053, default off). All gradients used by styles — immersive backdrops, app bars, primary buttons, the Synthwave logo and the Roundcube Classic bevelled toolbars/buttons — are applied only when it is on; otherwise each style uses flat colors. Note: Roundcube Classic is therefore flat by default until the switch is enabled.
  • Introduced a common interface-style standard. Every predefined style now ships light and dark palettes, a fixed layout profile and a structural token block (57-skin-tokens.css, consumed by 58-skin-immersive.css). All 23 existing styles were adapted to it — for example GitHub gets its dark header and green primary button, Slack its aubergine sidebar, Gmail its pill navigation and light-blue compose button, Outlook its accent app bar and selection bar, Apple Mail its filled selection.
  • Added 14 predefined styles: Dracula, Catppuccin, Solarized, Gruvbox, Tokyo Night, Rosé Pine, Everforest, Synthwave, Paper, Terminal, Aqua Glass, Linear inspired, Material You inspired and Retro 95.
  • The interface-style catalog is defined once (display_preferences::INTERFACE_SKINS) and shared by the user preference and default_interface_skin validation. The release validator now checks that every style is present in the catalog, the settings selector, the layout profiles, both palettes and the token table.
  • Consolidated migrations V051 and V052 into the fresh schemas; the compatibility baseline is now V052. Databases below V052 must be opened once with 0.2.22 before upgrading.
  • Fixed the fresh MySQL schema: mail_preferences.message_loading_mode used a literal DEFAULT on a TEXT column, which MySQL rejects; it now uses an expression default.
  • Bumped the application/source release to 0.2.23.

0.2.22

  • Added message snooze. A new snoozed_messages table (migration V052) records a wake time for a message; snoozing it (via the new "Snooze…" context-menu entry or the b shortcut while a message is open) hides it client-side from its folder's current view until that time, using GET /folders/{name}/snoozed-uids to know which UIDs are currently asleep. POST /messages/{folder}/{uid}/snooze and DELETE /messages/{folder}/{uid}/snooze set/clear a snooze; GET /messages/snoozed lists everything currently sleeping, shown in the new "View snoozed messages…" dialog (Shift+B). This is purely a local cache: it has no IMAP side effects and does not change server-side folder pagination/count queries.
  • Added an "Undo Send" window. New undo_send_window_secs config setting (default 8, max 120; 0 restores the previous immediate-send behavior). When enabled, submitting a message stages it in memory instead of sending it right away; the composer shows a toast with an "Undo" action and countdown, and the message is only dispatched to SMTP once the window elapses without being cancelled. GET /messages/send/{pending_send_id} polls status (pending/dispatching/sent/cancelled/failed); DELETE /messages/send/{pending_send_id} cancels a still-pending send. Nothing is persisted, so a server restart during the window drops the staged send the same way an in-flight SMTP connection would be lost.
  • Bumped the application/source release to 0.2.22.

0.2.21

  • Added configurable login brute-force protection under [login_rate_limit] (env: LOGIN_RATE_LIMIT__*): the per-IP token bucket on POST /api/auth/login is now driven by ip_burst/ip_replenish_secs instead of hard-coded values, plus failed-attempt lockouts per mailbox (account_max_failures, any IP) and per client IP (ip_max_failures, password spraying) with exponential back-off (lockout_secs → max_lockout_secs). Locked attempts return 429 with Retry-After before any IMAP connection is opened.
  • The public GET /api/auth/policy no longer consumes the per-IP login budget.
  • Added cookie_secure = "auto" | "always" | "never" (env: COOKIE_SECURE). The default auto sets the Secure cookie attribute only when the browser actually reached RustBox over HTTPS (trusted-proxy X-Forwarded-Proto/Forwarded/X-Forwarded-Ssl, otherwise the Origin/Referer scheme). Previously Secure depended on environment != "development", which broke logins on plain-HTTP production installs and left cookies without Secure in development behind HTTPS.
  • Added memory guards for messages with attachments. An attachment set that cannot fit max_message_size_mb once base64-encoded is now rejected with 413 from the stored sizes before any blob is read when sending, saving an IMAP draft snapshot or attaching a message, and while an upload is still streaming (previously the limit was only checked after the whole MIME message had been built in RAM). New max_concurrent_message_builds (default 4) and message_build_wait_secs (default 30) limit how many requests hold attachment data in memory at once; extra requests wait and then receive 503. Environment: MAX_CONCURRENT_MESSAGE_BUILDS, MESSAGE_BUILD_WAIT_SECS.
  • Gmail-style message row opening: outside selection mode, Ctrl/Cmd+click a message opens it in a new browser tab, and Shift+click opens it in a small popup window; both deep-link to the exact message so the new tab/window loads it directly. Plain click and existing selection-mode shift/ctrl range/toggle behavior are unchanged.
  • Bumped the application/source release to 0.2.21.

0.2.20

  • Fixed interrupted initial-backfill recovery so legacy missing-date repair does not run against an invalidated or incomplete folder cache.
  • Fixed the Forward as attachment route build failure by making AttachMessageSourceRequest visible at the same crate scope as the public route handler, so Axum can resolve the handler type from routes::mod.
  • Fixed messages without a usable RFC 5322 Date header so mailbox synchronization falls back to the IMAP INTERNALDATE; cached messages with missing/invalid dates are repaired when the folder is opened instead of remaining at the end of the list.
  • Fixed Forward as attachment so the server fetches the original RFC822 source from IMAP and stores it in the draft as a real message/rfc822 .eml attachment.
  • Bumped the application/source release to 0.2.20.

0.2.19

  • Improved vertical space management in the HTML message reader: the sandboxed message iframe now expands to the actual space remaining below the reader toolbar, message header and auxiliary bars instead of stopping at a fixed 68vh.
  • Recalculate the HTML message viewport when the reader, header, attachments, security bars, window size or fullscreen state changes, avoiding an unnecessary short inner scrollbar while preserving the existing iframe sandbox.
  • Bumped the application/source release to 0.2.19.

0.2.18

  • Fixed new-message sender selection so the composer prefers the configured default identity, then the identity matching the active account address, then the first available identity; the visible From field now shows the active account address instead of an ambiguous Account default label when no identity is selected.
  • Restored visible signatures/footers for new messages when no identity was explicitly marked default by using the same preferred-identity fallback for signature insertion and sending.
  • Added explicit composer undo/redo keyboard handling: Ctrl/Cmd+Z, Ctrl/Cmd+Shift+Z and Ctrl+Y.
  • Improved adaptive HTML-mail rendering for legacy/marketing templates: preserve safe CSS from <head>, retain body presentation metadata, adapt HSL/HSLA and background shorthands with URLs, enforce readable text contrast and remove the hard-coded white iframe canvas.
  • Suppress realtime new-mail notifications caused by intentional message moves (including Spam/Junk) by tracking the destination UID while retaining normal notifications for unrelated incoming mail.
  • Fixed visible-signature image materialization so cleanup waits for the in-flight CID upload instead of deleting the signature image while the composer is opening.
  • Added a top-bar quick account switcher that appears when more than one account is signed in to the current browser session.
  • Added browser-level combined notification selection in Account settings; selected accounts keep their own notification folder, sound and DND preferences.
  • Added administrator feature gate multi_account_enabled; disabling it hides multi-account controls, rejects adding a second account and limits realtime WebSocket monitoring to the active account.
  • Made the plain-text and HTML signature editors the same visual height.
  • Added a dedicated HTML signature source modal with sanitized source import, visual preview/editing, formatting controls and image insertion.
  • Kept the global synchronization spinner active for mailbox page loads, progressive/full-folder loading and individual message/IMAP-draft retrieval.
  • Added Shift-click range selection across the currently displayed message list, using the last regular/toggle selection as the anchor.
  • Added first-page and last-page controls to mailbox pagination.
  • Hide HTML inline/CID resources, including images inserted through signature management, from the reader attachment list while continuing to resolve them inside the message body.
  • Treat MIME parts explicitly marked Content-Disposition: inline as inline content rather than message attachments, preventing signature-only messages from gaining an attachment indicator after the next IMAP metadata sync.
  • Retain signature images as multipart/related CID parts for outgoing mail; regular file attachments remain unchanged.
  • Kept the application/source release at 0.2.18.

0.2.16

  • Added opt-in adaptive HTML-mail colors that adjust neutral backgrounds and low-contrast text to the active light/dark theme while preserving layout, images and brand colors.
  • Added mailbox pagination, enabled by default at 300 messages per page, with optional smooth progressive loading or full-folder loading.
  • Added runtime schema migration V051 for SQLite, MySQL and PostgreSQL. Existing V050 databases gain display_preferences.adaptive_email_colors and mail_preferences.message_loading_mode before the new preferences are queried.
  • Kept V050 as the consolidated compatibility baseline and removed the standalone V050 migration files because those changes are already present in the complete schema.sql definitions.
  • Bumped the application/source release to 0.2.16.

0.2.15

  • Fixed HTML signature editor container semantics so clicks on whitespace/outside the editable area no longer implicitly activate the Bold toolbar button.

  • Fixed the HTML signature editor so toolbar actions preserve the active text selection and only run on an actual selection; collapsed-caret clicks no longer enable sticky bold/italic/underline typing modes.

  • Fixed visible signatures in new messages by creating an editable body entry before the signature instead of placing the signature at the top of an otherwise empty editor.

  • Refined the visible-signature separator with more breathing room and a subtler solid rule so it reads as a boundary without dominating the composer.

  • Strips the editor-only body-entry marker from outgoing HTML while retaining the visible-signature marker used for de-duplication.

  • Consolidated migrations V047-V050 into the V050 compatibility baseline and removed their standalone migration files. Databases older than V050 must be upgraded through a V050-capable release first.

  • Bumped the application/source release to 0.2.15.

0.2.14

  • Made pane resizing tolerant of frontend/backend range mismatches: pane widths are normalized server-side, and a rejected width silently disables the in-view resizer for the current session instead of showing a validation error.
  • Added a default-on compact message-list layout that consolidates sender, subject/snippet, date and status icons into one row when the message pane is wide enough; it can be disabled in Appearance settings.
  • Added per-identity signature insertion mode: silent (default) keeps the composer clean and appends the signature during send, while visible inserts an editable/removable signature in the composer.
  • Visible HTML signatures are structurally marked for de-duplication and keep inline signature images attached through the existing CID flow.
  • Added runtime schema migration V050 for SQLite, MySQL and PostgreSQL (mail_preferences.compact_wide_rows, identities.signature_insert_mode). V051 is the next migration number.
  • Bumped the application/source release to 0.2.14.

0.2.13

  • Added durable per-tenant blob deletion outbox for every configured blob backend (filesystem including shared NFS/POSIX, and S3-compatible storage). Attachment metadata deletion and cleanup enqueue now commit atomically, so a temporary storage failure cannot silently orphan blobs.
  • Blob cleanup runs immediately when possible and is also retried by a background worker with claim leases and exponential backoff; missing objects are treated as successful idempotent deletes and retries do not dead-letter permanently.
  • Deleting one attachment, deleting a whole draft, and post-send draft cleanup all use the same durable deletion path. Failed/finalized uploads and failed storage-migration destination objects are queued for cleanup as well.
  • Storage health probes reuse a fixed probe key so a failed cleanup cannot accumulate unbounded health-check objects.
  • Added runtime schema migration V049 for SQLite, MySQL and PostgreSQL (blob_delete_outbox). V050 is the next migration number.
  • Bumped the application/source release to 0.2.13.

0.2.12

  • Saving or updating a draft no longer raises a realtime “new message” toast/system notification for the Drafts folder; the folder/list still refreshes normally, and IMAP snapshots remain \Draft + \Seen.
  • Added a composer Delete draft action that permanently removes the current IMAP draft and cascades cleanup through the local autosave row, draft attachment rows and uploaded attachment blobs; IMAP deletion is verified before local state is reported as deleted.
  • IMAP-only drafts opened from other mail clients can be deleted without requiring a pre-existing RustBox draft database row, while UIDVALIDITY and \\Draft/Drafts-folder checks prevent deleting a stale or non-draft message by mistake.
  • Explicit Save draft now records the newly appended IMAP UID in the live composer even for a brand-new draft, so later Save/Delete/Send operations consistently target the current server snapshot.
  • Draft messages in the configured IMAP Drafts folder (or carrying the \\Draft flag) now open directly in the normal composer from their server-side RFC822/MIME content; opening does not depend on a RustBox draft database row or X-RustBox-Draft-ID, so drafts created by other mail clients can be edited and sent.
  • Editing an IMAP-sourced draft keeps its original server UID as the replacement source: explicit Save draft appends the new MIME snapshot first and removes the superseded IMAP draft only after the new UID is resolved; sending also removes the source draft after successful SMTP delivery.
  • Existing IMAP draft attachments stay usable directly from their MIME parts while editing, can be removed/re-embedded without first copying the whole message into the draft database, and are carried into Save/Send together with newly uploaded local attachments.
  • Inline MIME parts now preserve their original filenames through Content-Disposition: inline; filename=... when saving drafts and sending messages, improving Roundcube/Thunderbird interoperability.
  • IMAP draft reopening restores To/Cc/Bcc, Subject, plain/HTML body, reply threading headers, priority, MDN state, From identity when it matches a configured identity, inline CIDs and attachment filenames directly from the server message.
  • Fixed manual IMAP draft saving for drafts without To/Cc/Bcc recipients by using a build-only envelope while keeping recipient headers empty; Bcc is retained in saved draft snapshots.
  • IMAP draft saving now honors the per-account Special folders → Drafts mapping and default_drafts_folder, then falls back to the IMAP \Drafts attribute and common Drafts/Draft folder names.
  • Added an explicit Save draft composer action immediately before Cancel; it forces the current message and attachments to be persisted as a real IMAP \Draft snapshot while leaving background autosave behavior unchanged.
  • Manual IMAP draft saves now report a failure when RFC822 snapshot creation or IMAP APPEND fails instead of showing a misleading success state.
  • Fixed draft recovery so attachment metadata is restored from both the browser recovery snapshot and the authoritative server draft.
  • Composer attachment chips now show every uploaded file, including inline images/links, instead of hiding embedded items from the attachment list.
  • Adding another attachment now merges by unique attachment ID and refreshes the server-side draft attachment list, preventing an existing chip from appearing to be replaced.
  • Inline attachment chips expose an attachment-only action that removes the inline occurrence without deleting the uploaded file.
  • Stretched Load more and Load all across the full message-list action area with equal-width controls.
  • Added a composer Hide fields / Show fields toggle that collapses From/To/Cc/Bcc/Subject/options so the editor can use the freed vertical space; invalid recipient input automatically expands the fields again.
  • Fixed inline image insertion so adding another image or attachment appends a new element instead of replacing the current selection.
  • Replaced deprecated execCommand("insertHTML") attachment insertion with DOM Range insertion and safe caret placement.
  • Removed filename/size attachment de-duplication so separate files with identical metadata can still be attached independently.
  • Moved inline-image resize/alignment controls into a floating contextual panel so selecting an image no longer reduces the composer editing area.
  • Added mouse/touch resize handles around the selected inline image while preserving its aspect ratio.
  • Inline images can be dragged to another caret position inside the message body.
  • Pasting PNG/JPEG/GIF/WebP files with Ctrl/Cmd+V embeds them inline, and dropping files into the editor uploads them at the drop position.
  • Attachment chips explicitly identify regular/image attachments, while selected embedded images are labelled Inline image.
  • Made attachment re-embed actions compact icon buttons to keep the attachment strip readable.
  • Collapsed large To/Cc recipient lists in the message reader into a compact summary with on-demand expansion.
  • Added a Load all action beside Load more in the message list.
  • Renamed the reader toolbar action from Message details to Details.
  • Images added to HTML messages now embed inline by default; removing an inline image keeps the underlying file available as an attachment that can be embedded again.
  • Added Embed actions for attachments: images are inserted inline and other files can be inserted as CID links in the message body.
  • Added quick inline-image sizing and alignment controls, plus the existing advanced crop/resize editor and an explicit Keep as attachment action.
  • No schema migration is required; V049 remains the next migration number.

0.2.11

  • No schema migration is required; V049 remains the next migration number.
  • RoundCube migration script
  • Allow to edit all themes.

0.2.10

  • Message-body links without an explicit target now open in a new browser tab/window instead of navigating inside the sandboxed mail preview iframe.
  • Explicit link targets from the message are preserved; links that open a new tab/window receive rel="noopener noreferrer".
  • Authentication success toast now appears only after a real login request; restoring an existing session after page refresh stays silent.
  • Improved iPhone/Safari mail rendering by explicitly declaring UTF-8 in message preview documents and using broader RFC 2047 header decoding (including ISO-8859-2/Windows-1250) for non-ASCII subjects/sender names.
  • Changed PDF attachment preview to use the authenticated inline attachment URL instead of a blob: iframe, improving Safari/iPhone compatibility.
  • Simplified Composing size-limit information to one compact line with only the attachment and complete-message limits.
  • No schema migration is required; V049 remains the next migration number.

0.2.9

  • Made realtime new-mail notifications less aggressive: startup synchronization is silent, notifications are armed only after the application is open, and bulk move/copy/archive/junk/delete destinations suppress self-generated NewMessages toasts while the bulk summary toast remains.
  • Added a success toast after a completed authenticated startup/login.
  • Restored browser/system modifier shortcuts by limiting RustBox single-key shortcuts to unmodified keys; Ctrl/Cmd+C, Ctrl/Cmd+V, Ctrl/Cmd+X, Ctrl/Cmd+A, Ctrl/Cmd+F, Ctrl/Cmd+R and Ctrl/Cmd+N are no longer intercepted by mail actions.
  • Changed the default messages-per-page setting from 50 to 300 and raised the supported folder-page limit to 300.
  • No schema migration is required; V049 remains the next migration number.

0.2.8

  • Scoped default logging so RustBox can run at DEBUG/INFO without enabling verbose dependency logs; Tantivy merge/GC/file-watcher noise and its internal filesystem/source paths are hidden unless explicitly enabled through a custom RUST_LOG target filter. Development and deployment examples now use target-scoped filters.
  • Kept administrator diagnostics process-local and cross-platform: removed host CPU/RAM/load-average and Linux /proc sampling; runtime diagnostics now rely on portable RustBox in-memory counters plus the process PID.
  • Added a disabled-by-default administrator system-diagnostics endpoint with loopback-only CIDR allowlisting, mandatory token or Basic authentication, fail-closed trusted-proxy handling, secret redaction, live SQL/session/storage/search probes, active IMAP IDLE/session/runtime state and bounded security telemetry for failed logins, rate limiting, access denials and server errors.
  • Moved the synchronization/index activity indicator to the left of Contacts.
  • Corrected production TOML section ordering so intended top-level database/session/mail/security/special-folder settings are no longer accidentally parsed as search settings.
  • Refined folder counters so only the unread value is emphasized, hid the sync/index activity icon when idle, and made manual search-index rebuilds drive the same live activity indicator as background indexing.
  • Made folder totals/unread counts server-authoritative: IMAP STATUS MESSAGES/UNSEEN drives badges, selected-mailbox fallback counts UID SEARCH UNSEEN, periodic reconciliation repairs counters even when HIGHESTMODSEQ is unchanged, and mutation-time compare-and-set/retry prevents out-of-order STATUS responses from rolling counters backwards.
  • Decoupled counter refresh from folder-tree discovery: a forced counter refresh reuses a fresh cached folder tree and batches STATUS requests instead of forcing another IMAP LIST.
  • Changed read/unread/flag updates to patch the affected message row and folder badge live; ordinary flag changes no longer rebuild the message list, removing the reader/list jump during mark-read operations.
  • Added responsive folder counters (total / unread when unread is non-zero, total-only at zero, compact mode in narrow sidebars) and surfaced IMAP header-cache plus search-index backlog in the top-right activity indicator/tooltip.
  • Extended the opt-in security-header middleware with a private /api profile (no-store, nosniff, same-origin CORP, frame-ancestors 'none' and X-Frame-Options: DENY), while keeping Permissions-Policy/COOP and the full document CSP on HTML and HSTS at the public HTTPS edge; disabling security_headers_enabled removes the whole RustBox-added security profile.
  • Minimized unauthenticated /api/auth/policy to rememberMeEnabled; optional feature policy moved behind authenticated /api/auth/session-policy, and session/remember durations are no longer exposed by policy endpoints.
  • Added optimistic read/unread updates in the browser with guarded rollback, followed by authoritative server reconciliation; normal read/unread operations no longer replace the message list.
  • Fixed realtime WebSocket deduplication so unique server eventId values always win over payload fingerprints; rapid legitimate counter cycles such as 1 → 0 → 1 are no longer dropped as duplicates. Active-folder total text is patched live together with the sidebar counter.
  • Hardened IDLE/CONDSTORE reconciliation: counter STATUS no longer advances the flag-sync cursor, non-CONDSTORE servers fall back to a full UID FLAGS comparison, partial IMAP fetch streams are discarded instead of being treated as complete, and IDLE header/index writes participate in the same cache-generation transaction.
  • Fixed UIDVALIDITY reset writes to stay inside the same database transaction on SQLite, MySQL and PostgreSQL instead of mixing transaction/base-connection writes.
  • Tightened the HTML CSP to style-src 'self' plus the narrower style-src-attr 'unsafe-inline'; inline JavaScript remains disallowed.
  • Added regression coverage for authoritative unread refresh, API/document/static header profiles and pre-login policy minimization.
  • Added database migration V048 on SQLite, MySQL and PostgreSQL: folder counters now carry a monotonic counter_generation, so delayed STATUS responses cannot win an ABA race after newer read/unread activity. V049 is the next migration number.
  • Bumped the application/source release to 0.2.8.

0.2.7

  • Made opt-in browser security headers content-type-aware instead of attaching document-only policies to every response.
  • HTML documents keep the full CSP, clickjacking, permissions, COOP, referrer and MIME-sniffing protections.
  • CSS responses now receive only the applicable Referrer-Policy and X-Content-Type-Options; JavaScript, JSON, SVG, API and other non-document responses retain X-Content-Type-Options: nosniff without redundant document policies.
  • Added regression coverage for HTML, CSS and API header sets while preserving the disabled-by-default compatibility switch.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.

0.2.6

  • Fixed iPhone/iOS reader toolbar popovers (Message details and Move / copy) by rendering the open menu outside the horizontally scrolling toolbar and positioning it against the visual viewport.
  • Made folder counters and message-list refreshes more responsive: realtime sync stores the server-reported unread count, folder hierarchy refresh avoids unnecessary IMAP LIST calls, and manual refresh forces the active-folder status check in parallel with counter refresh.
  • Improved realtime mail delivery: INBOX remains on IMAP IDLE, the actively viewed folder gets its own IDLE watcher, other folders are reconciled immediately and every 30 seconds, and newly detected headers are cached before realtime events are emitted.
  • Added an in-app toast for new mail in any folder and deduplicated browser notifications per account/folder/UID to prevent repeated notifications for the same message.
  • Added an animated indexing indicator beside Contacts while deep message indexing is active, and prevented excluded Trash/Junk/Spam folders from starving the indexing batch.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.

0.2.5

  • After moving or deleting the currently opened message, RustBox now automatically opens the next message in the current list; if the removed message was last, it falls back to the previous message.
  • The behavior applies to Spam, Not spam, Archive, Move and Delete actions and keeps the reader open while advancing.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.

0.2.4

  • Fixed S3-compatible storage over explicitly allowed plain HTTP endpoints by applying storage.allow_http to the final ClientOptions object instead of setting it before with_client_options() replaces those options. This fixes Garage/MinIO/Ceph-style internal HTTP endpoints without weakening the HTTPS default.
  • Added an HTTP S3 regression test that verifies a request reaches an explicitly allowed local S3-compatible endpoint.
  • Updated the pinned Rust toolchain/MSRV to Rust 1.99.1.
  • Updated RustBox Docker build/runtime images from Debian 12 Bookworm to Debian 13 Trixie (rust:1.99.1-trixie, debian:trixie-slim) and switched the runtime OpenSSL package to Trixie's libssl3t64.
  • Updated PostgreSQL 17 Compose images from Bookworm to the supported Trixie variant.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.

0.2.3

  • Fixed API fallback routing so administratively disabled or otherwise unknown /api/* endpoints return HTTP 404 instead of being caught by the SPA fallback and returning the UI with HTTP 200.
  • Added administrator feature switches for ManageSieve, diagnostics and About; disabled Sieve/diagnostics routes are not registered, and the matching settings UI is removed while keyboard shortcuts remain available.
  • Added a protected “Reset all settings” action that restores display, mailbox, notification, folder, special-folder, calendar and OpenPGP preferences without deleting mail, identities, keys, templates or trusted-sender data.
  • Added opt-in browser security response headers (CSP, frame, referrer, permissions and cross-origin opener policies); the feature is disabled by default for compatibility.
  • Added a Docker HA example with two RustBox application nodes behind Envoy round-robin load balancing, Valkey-backed sessions, PostgreSQL, OpenSearch and Garage S3 object storage. Envoy adds X-RustBox-Backend to responses.
  • Added current pinned Garage, Valkey and Envoy images to the HA example and an idempotent Garage bucket/key initialization helper.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.

0.2.2

  • Fixed the SQLite isolation regression test to initialize AppConfig with a struct literal plus ..Default::default(), satisfying cargo clippy --all-targets -- -D warnings without suppressing field_reassign_with_default.
  • Fixed Rust test isolation for SQLite: test-only db::pool::configure() still initializes the requested database schema but no longer pins the first temporary SQLite path in the process-wide OnceLock, preventing later tests from reusing a deleted TempDir and collapsing into HTTP 500/database-open failures.
  • Added a regression test that configures SQLite in one temporary directory, removes it, then opens an account database in a second temporary directory.
  • Strengthened the offline release contract to assert that scripts/build-release.sh requires the full locked test suite, warning-free Clippy, and a locked release build before a release is accepted.
  • Fixed the PostgreSQL startup schema compile failure (implementation of sqlx::Executor is not general enough) by executing the multi-statement DDL batch through sqlx::Executor::execute() on the transaction connection instead of sqlx::raw_sql(...).execute(&mut PgConnection).
  • Preserved transactional startup schema initialization and the local client_min_messages=WARNING scope used to suppress expected idempotent PostgreSQL NOTICE output.
  • Added a static regression gate that forbids the lifetime-problematic raw_sql(&schema).execute(&mut *tx) PostgreSQL startup path.
  • No schema migration is required; runtime schema remains V047 and V048 remains the next migration number.
  • Fixed PostgreSQL header-sync invalidation used by message mutations (including marking/moving messages as spam): the UPSERT now qualifies the existing tenant user_meta.value, avoiding column reference "value" is ambiguous and HTTP 500 responses.
  • Added a regression check for tenant SQL rewriting of the qualified user_meta.value reference and a static audit covering all PostgreSQL ON CONFLICT ... DO UPDATE target-column reads.
  • Confirmed the equivalent SQLite UPSERT is not ambiguous and MySQL uses ON DUPLICATE KEY UPDATE, so no matching backend fix is required.
  • No schema migration is required; the runtime schema remains V047 and V048 remains the next migration number.
  • Centralized SQL schema initialization in db::pool::configure() so the database session store no longer executes the global schema a second time.
  • Fixed the duplicate startup DDL for all SQL backends: PostgreSQL no longer repeats relation ... already exists, skipping notices, while MySQL and SQLite also avoid the redundant second schema pass.
  • Scoped PostgreSQL startup schema initialization to a transaction with client_min_messages=WARNING, suppressing expected idempotent CREATE ... IF NOT EXISTS notices without hiding application/database warnings globally.
  • Removed the Docker-specific SQLx PostgreSQL notice filter workaround; normal RUST_LOG=info is sufficient.
  • No schema migration is required; the runtime schema remains V047 and V048 remains the next migration number.

0.2.1

  • Fixed Docker development authentication by documenting and defaulting Compose to ENVIRONMENT=development, so session cookies work over direct HTTP while production keeps Secure cookies behind HTTPS.
  • Exposed pgp_enabled through the auth policy and hid OpenPGP settings, identity controls, composer controls and reader UI when OpenPGP is disabled by administrator policy.
  • Prevented disabled OpenPGP from producing repeated UI error toasts or unnecessary API requests.
  • Added OpenSearch outbox worker backoff for HTTP 429/flood-stage/read-only conditions and stopped the current batch after the first backpressure failure, preventing log storms while preserving durable retries without consuming dead-letter attempts.
  • Kept OpenSearch disk safety thresholds intact; Docker documentation explains that named volumes consume the Docker host filesystem and how to diagnose/recover flood-stage blocks.
  • Added a stable rustbox Compose project name, documented Docker environment variables, and made application port mapping configurable through PORT.
  • Reduced PostgreSQL startup log noise in the Docker example by suppressing repeated SQLx NOTICE messages at the default log filter.

0.2.0

  • Fixed nested database transactions during message move by reusing the caller-owned transaction for cache removal, header-sync invalidation, folder invalidation, and search outbox writes.
  • Kept search_outbox in sync between tenant and legacy-import table sets so schema/import parity tests pass.
  • Decoupled SQL, blob storage and search: PostgreSQL/MySQL may still use local data_dir backends in single-node mode, while cluster mode no longer requires persistent data_dir when cluster-safe backends are configured.
  • Added BlobStorage with filesystem/shared-POSIX and S3-compatible backends, streaming attachment I/O, SHA-256 metadata, S3 retry/timeouts/checksums/SSE options and storage readiness probes.
  • Added idempotent attachment migration from legacy filesystem paths to logical object keys (rustbox storage migrate).
  • Added OpenSearch as the external full-text backend with an async HTTP client, per-tenant filtering/routing, deterministic document IDs, health checks and rebuild support.
  • Added a durable SQL search outbox with caller-transaction participation, claim/lease concurrency, retry/backoff, dead-letter state and lag/dead-letter diagnostics.
  • Hardened clustered indexing against re-enqueue/lease races, sized worker leases from the OpenSearch timeout/failover budget, and made IMAP IDLE deletions enqueue index removals in the same SQL transaction.
  • Added runtime schema migration V047 for attachment checksums and the search outbox across SQLite, MySQL and PostgreSQL.
  • Added Docker variants for standalone SQLite, PostgreSQL + SILO (S3-compatible) + OpenSearch, and MySQL + NFS + OpenSearch.
  • Added tests for cluster capability validation, filesystem blob streaming, OpenSearch tenant scoping and search-outbox transaction rollback/claim/idempotency behavior.

0.1.2

  • Added log_level to TOML configuration (trace, debug, info, warn, error, off); RUST_LOG remains an explicit runtime override.
  • Audited the MySQL and PostgreSQL query catalogs, schema baselines and backend-specific server SQL without adding application tests.
  • Fixed a MySQL DDL incompatibility by changing indexed pgp_keys.email from TEXT to VARCHAR(320); MySQL requires a prefix length when indexing TEXT/BLOB columns.
  • Fixed destructive MySQL cache upserts: folder refresh and message-header refresh now use INSERT ... ON DUPLICATE KEY UPDATE instead of REPLACE INTO, preserving child rows, message tags, cached bodies and other columns not part of the refresh.
  • Documented and enforced cluster storage behavior: mailbox metadata/body cache remains in shared SQL, while draft attachments use either S3-compatible storage or an explicitly shared POSIX filesystem.
  • Replaced the pre-0.2 storage/search compatibility switches with the final [storage] and [search] configuration model; cluster mode validates backend capabilities directly and rejects local Tantivy.
  • Added pgp_enabled; cluster mode requires OpenPGP disabled because private-key material is filesystem-backed.
  • Avoided provisioning per-user Tantivy directories when the search index backend is disabled and made diagnostics/deep indexing honor that setting.
  • Added a release audit document with SQL compatibility and distributed-storage findings.

0.1.1

  • Fixed the multi-backend compatibility layer compile blockers reported by the Rust compiler: empty [] parameter inference no longer overlaps the generic array implementation, legacy SQLite probing imports rusqlite::OptionalExtension without colliding with RustBox's own OptionalExtension, and MySQL/PostgreSQL transaction batch execution now uses the typed SQLx transaction helpers instead of the lifetime-problematic raw_sql executor path.
  • Unified the storage model: database_backend = sqlite | mysql | pgsql now selects the database engine for the whole application instead of only the SQL session store; session_backend = database | redis either keeps sessions in that same database or moves them to Redis/Redis Sentinel.
  • Added complete SQLite, MySQL and PostgreSQL baselines under migrations/{sqlite,mysql,pgsql}/schema.sql. Each schema contains global sessions plus the full account-data schema at baseline version 46; the historical SQLite V001-V046 files are squashed out of the release tree and V047 is reserved for the next schema change across all engines.
  • Preserved per-account data isolation in a shared physical database with deterministic collision-checked table prefixes, while keeping the session table global.
  • Added automatic first-use import of legacy 0.1.0 data_dir/<user_hash>/db.sqlite databases at PRAGMA user_version = 46 into the configured backend. The source database is renamed to db.sqlite.pre-0.1.1.bak only after a successful import; older schemas are rejected with an explicit upgrade requirement.
  • Added a backend-neutral database compatibility layer used by the existing Rust data modules and switched application query selection to the SQLite/MySQL/PostgreSQL catalog matching the configured backend.
  • Corrected MySQL/PostgreSQL query dialects and parameter handling, including numbered/reused parameters, upsert syntax, timestamp expressions, JSON address lookup and generated-ID handling.
  • Fixed transaction scope for server databases so cache/message synchronization, header invalidation and other grouped writes execute on the actual MySQL/PostgreSQL transaction connection rather than accidentally falling back to the pool.
  • Removed separate session.sql files: sessions are part of each engine's complete schema.sql; Redis remains schema-less.
  • Removed stale Python release-contract tests and the unused HTML fixture; retained the runtime JSON fixture used by Rust tests and added native tests for tenant scoping, placeholder adaptation and legacy SQLite import.
  • Made Oxi synchronization treat upstream backend/migrations/ and backend/tests/ as RustBox-owned review-only areas so schemas and native tests are never overwritten automatically.
  • Removed the accidental runtime log qar.txt from the source tree and refreshed release metadata for 0.1.1.

0.1.0

  • Cleaned the final release gate for Rust 1.99 Clippy with -D warnings: refactored persistent session creation into a typed input struct and fixed all reported collapsible conditionals, redundant closures, needless borrows/question marks, test layout and collection checks without disabling Clippy globally.
  • Fixed fresh user-database provisioning so only SQLite user migrations V001-V046 are applied; session migration V047 is now exclusively owned by the configured session-store backend and MySQL SQL can no longer be executed against a user SQLite database.
  • Removed the obsolete Refinery migration path/dependency and its refinery_schema_history bridge; RustBox now has one canonical user-database migration runner.
  • Removed unused test-only session removal helpers that emitted dead_code warnings during cargo test.
  • Strengthened scripts/build-release.sh to require formatting, locked tests, Clippy with -D warnings, and a locked release build before producing a release binary.
  • Removed production-build warning noise from the multi-dialect query catalogs without disabling warnings crate-wide; test-only session/SMTP helpers are now compiled only under cfg(test).
  • Fixed cached-message row decoding after the query-catalog refactor: message list queries now project the exact CachedMessage column order (flags, size, has_attachments, snippet, reaction) across SQLite/MySQL/PostgreSQL.
  • Fixed Rust macro_rules! query hygiene errors by passing dynamic SQL fragments and parameter indexes explicitly into SQLite query macros instead of capturing caller-local variables.
  • Fixed the libsqlite3-sys Cargo links conflict by using rusqlite for SQLite session persistence and limiting sqlx to MySQL/PostgreSQL drivers.
  • Refactored all executable Rust SQL into a centralized dialect tree at src/queries/{sqlite,mysql,pgsql}/queries.rs; application modules no longer embed SQL statements.
  • Added persistent sessions that survive process restarts; SQLite under data_dir/rustbox.sqlite is the default with no extra configuration.
  • Added MySQL and PostgreSQL session-database backends plus independently configurable Redis sessions with direct or Sentinel master discovery.
  • Added cluster mode validation and shared-session reads so authenticated traffic can move between nodes when a shared SQL/Redis backend is used.
  • Encrypts persisted IMAP/SMTP session credentials with AES-256-GCM; single-node SQLite auto-creates data_dir/session.key, while shared/cluster stores require an explicit common key.
  • Centralized the complete SQL query catalog by dialect under src/queries/{sqlite,mysql,pgsql}/queries.rs; session queries use the same tree. Flattened migrations directly under migrations/{sqlite,mysql,pgsql}/; SQLite user migrations remain V001-V046 and sessions use V047__sessions.sql across SQL dialects.

0.0.7

  • Added allow-downloads to the sandboxed HTML message reader so user-initiated downloads are no longer blocked by Chromium sandbox policy.
  • Added GitHub-, GitLab-, Discord-, Slack-, Reddit- and Notion-inspired predefined interface styles with light/dark palettes.
  • Added a release contract that verifies every predefined interface style is visible in the application selector, has a JavaScript profile and CSS palette, and is accepted by backend/config validation.

0.0.6

  • Allowed links in rendered HTML messages to open in a new tab from the sandboxed reader while keeping the opened page outside the message sandbox.
  • Added eight predefined color presets: Emerald, Lime, Sky, Navy, Plum, Magenta, Copper, and Sand.

0.0.5

  • Added native file logging through log_dir; the packaged Linux profile writes JSON logs to /var/log/rustbox/rustbox.log and ships 7-day logrotate policy.
  • Updated the packaged systemd profile for /var/lib/rustbox, /var/log/rustbox, hardened service settings, and user-owned configuration.
  • Fixed the mobile reader toolbar regression so compact controls keep their original height and Message details / Move-copy menus open next to the triggering control instead of at the bottom of the viewport.
  • Full-screen message reading now overrides the normal reader width limit so the message workspace uses the available screen width.
  • Fixed mobile reader actions, attachment layout, long subjects, and touch targets.
  • Added WebSocket application heartbeat, dead-connection detection, exponential reconnect, reconnect resync, event deduplication, and fallback polling.
  • Fixed live message refresh coalescing so folder updates cannot suppress a pending new-message refresh.
  • Improved new-mail notifications and made notification clicks open the target message when its UID is available.
  • Added message full-screen mode from the reader button and context menu with Escape, browser history, deep links, and scroll restoration.
  • Kept attachment upload progress only in the composer progress bar and added duplicate/cancellation safeguards.
  • Removed source-code comments and added 0.0.5 regression contracts.

0.0.4

  • Changed attachment left-click behavior to prefer in-app preview for supported files while keeping direct download for non-previewable formats.
  • Added attachment right-click actions for explicit Preview and Download.
  • When an attachment exceeds the preview limit, RustBox now offers to download it instead of stopping at a warning; known oversized files are detected before their contents are fetched for preview.

0.0.3

  • Fixed reader toolbar dropdowns for Message details and Move/copy by moving popovers out of the horizontally clipped toolbar layer.

  • Added Fastmail-, Apple Mail-, Yahoo Mail- and HEY-inspired styles plus Nord, and an optional per-account unlock for UI scaling on predefined styles.

  • Added separate mail-size controls: max_attachment_size_mb = 10 per uploaded file and max_message_size_mb = 50 for the complete final RFC822/MIME message. The final MIME bytes are checked before SMTP submission, including base64, multipart and OpenPGP overhead; the composer shows an estimated running total.

  • Moved the Diagnostics → IMAP reconnect action below capability details so it no longer collides with the status label.

  • Added the RustBox repository link to Settings → About.

  • Defaulted omitted mail endpoints to localhost:993 (IMAP) and localhost:587 (SMTP); TLS verification is skipped automatically only for loopback endpoints unless tls_verify is explicitly configured.

  • Swapped the compact composer footer groups so the HTML/Text/Markdown selector is on the left and Cancel/Send on the right.

  • Grouped message details and move/copy actions into compact reader-toolbar menus.

  • Improved Polish translations for composer, message toolbar and per-message context menu.

  • Moved composer format selection to the opposite side of Send/Cancel in the compact composer footer.

  • Added server-wide default_interface_skin (rustbox, gmail, proton, zoho, outlook, etc.) for login and accounts using Global default.

  • Fixed mobile modal/settings overflow, transparent dialog strips, calendar toolbar wrapping and narrow-layout sizing.

  • Fixed visual Sieve rule checkbox alignment and stacked its rule controls safely on small screens.

  • Added tap/keyboard expansion for full recipient addresses in the message reader.

  • Added persistent IMAP quota progress above the sidebar IMAP/version footer.

  • Added administrator-configurable default_theme = "system" | "dark" | "light" for the pre-login/login UI.

  • Added Gmail-, Proton-, Zoho- and Outlook-inspired interface profiles plus a Minimal profile.

  • Expanded Polish translations across settings, dialogs, calendar, contacts, filters and common accessibility/title attributes.

  • Bumped the application/source release to 0.0.3.

0.0.2

  • Split the monolithic browser application JavaScript into functional modules under src/web/js/; build.rs now assembles the JavaScript manifest into the embedded fingerprinted bundle alongside the existing CSS build.
  • Removed the duplicate ui/ snapshot; src/web/ is the only browser UI source and Cargo assembles embedded CSS/JS bundles in OUT_DIR.
  • Removed the top-level Compact/Balanced/Comfortable/Reading appearance preset cards.
  • Expanded Interface style with RustBox (custom), Roundcube Classic, Roundcube Larry, Roundcube Elastic, Clean, Graphite and High contrast.
  • Fixed styles no longer overwrite the user's RustBox custom colors/layout values; switching back to RustBox restores the saved manual configuration.
  • Fixed interface styles lock palette/geometry controls while leaving Theme, language, date/time formatting and accessibility/user visibility toggles available.
  • Added dedicated light/dark palettes for Larry, Clean, Graphite and High contrast while retaining the existing Classic/Elastic compatibility skins.
  • Updated UI/build contract tests for the modular JavaScript build and expanded interface-style validation.
  • Fixed the 0.0.2 release build regression by centralizing AppConfig::default() and updating stale AccountSession test fixtures for the new session metadata fields.
  • Updated UI contract tests and visual fixtures after removal of the legacy ui/ directory.
  • Fixed release-test regressions in OpenPGP fingerprint validation, protected system-folder recognition, nested base_path UI routing, and missing SMTP endpoint handling.

0.0.1

  • Reworked Roundcube appearance compatibility: dedicated Classic and Elastic interface skins now use upstream-aligned light palettes, dedicated dark variants, exact Classic red/gray selection accents, Elastic cyan/dark tokens, and palette locking so generic RustBox colors cannot bleed into the selected skin.
  • Replaced the mobile folder-drawer close affordance with a left-facing SVG back arrow in a dedicated mobile drawer header.
  • Added persisted interface_skin display preferences and two schema migrations for skin selection and saved-response format.
  • Added Roundcube-style saved/canned responses with text/HTML formats, settings CRUD UI and composer insertion; HTML is sanitized before insertion.
  • Added static theme-contract tests and browser-rendered visual fixtures for Classic/Elastic light/dark and mobile drawer validation.
  • Moved Sieve rule creation/editing into a dedicated wide modal with the existing live “what will happen” preview; Settings now shows the rule list and launches the editor instead of squeezing the full builder into the settings pane.
  • Moved identity/signature editing into a separate viewport-safe modal and eliminated the horizontal overflow caused by the two-column Settings layout.
  • Added a persistent full-screen composer toggle.
  • Collapsed the OpenPGP composer controls into a compact summary row with expandable details, while keeping PGP options hidden when no OpenPGP keyring is configured.
  • Kept the signature image/CID flow from the previous UI patch in the packaged sources and synchronized standalone ui/ assets with embedded src/web/.
  • Moved bulk message actions into a floating overlay so selection mode no longer consumes the message-list grid row or creates horizontal layout spill.
  • Hardened narrow reader/message toolbars and composer layout against controls colliding at split-pane widths.
  • Reworked composer address/options rows into distinct fields and allowed the formatting toolbar to wrap cleanly.
  • Expanded identity signatures/footers with text + HTML editing and image import/paste; imported images are materialized as inline CID draft attachments when composing.
  • Completed the OpenPGP roadmap lifecycle with private-key passphrase change. The existing rPGP implementation remains responsible for key parsing, signing, encryption, verification and decryption; GnuPG is used only to re-wrap an existing secret key when changing its passphrase. Passphrases are exchanged over stdin/status-fd and are never stored in the database or command line.
  • Added POST /pgp/keys/{fingerprint}/change-passphrase and a keyring UI action, including an explicit warning before removing passphrase protection.
  • Added optional RUSTBOX_PGP_GPG_BINARY override for deployments where the GnuPG binary is not named gpg.
  • Expanded the visual Sieve builder with dynamically addable conditions and actions. Additional conditions can be chained with nested AND/OR and capability checks now include dynamically added actions.
  • Replaced the stale roadmap gap list with a counted functional checklist: 45 functional items remain after this snapshot, with security/integration/acceptance gates tracked separately.
  • Fork base: Oxi 7f1507c486b78cf33e54beb701dd460d3bd2bd5d.
  • Flattened the Rust application to the repository root: Cargo.toml, src/, migrations/, tests/ and examples/.
  • Removed the separate Oxi frontend source and all TypeScript/React/Next.js/Node/Bun build requirements.
  • Added a RustBox-owned embedded HTML/CSS/vanilla-JavaScript interface with dark/light/system themes.
  • Added dev.sh; ordinary cargo run, cargo test and cargo build --release now work from repository root.
  • Added mail reader/list/compose/search UI and About/Credits with the consumed Oxi revision embedded from UPSTREAM_BASE.
  • Added ManageSieve API/editor with STARTTLS, implicit TLS and explicit plaintext opt-in.
  • Added native systemd packaging and Cargo-only CI/release build.
  • Added Oxi tracking tools that map upstream backend/... changes into the flat RustBox tree without importing Oxi frontend sources.
  • Added full-baseline sync review plus selective single-commit backend porting from Oxi.
  • Build fix: corrected the embedded SVG raw-string delimiter, imported Figment's Format trait for Toml::file, and removed an unused SieveCapabilities re-export.
  • Mail server endpoints are now configuration-owned; the login form only accepts email, password and remember-session preference.
  • Fixed Inbox/folder/quota/draft operations to use the connection profile stored in the authenticated session instead of re-reading an optional global IMAP host.
  • Added startup validation for imap_host to prevent successful Sieve/login state with a non-functional Inbox.
  • Rebuilt the interface as a compact three-pane webmail layout with embedded SVG icons, HTML compose formatting, threads, folder actions, Sieve filters and appearance preferences.
  • Moved browser sources to src/web/; Cargo build.rs bundles modular CSS and the executable embeds all UI assets.
  • Removed gradients and Unicode pseudo-icons from the application interface.
  • Added nested-folder indentation, Reply all, accurate IMAP connection state, and RustBox-branded HttpOnly session/browser cookies.
  • Added persistent per-user appearance personalization stored in SQLite.
  • Added EN/PL language assets embedded in the Rust binary.
  • Added theme palette presets (sage/blue/slate/amber/violet/rose/custom) and custom accent color.
  • Added font family/size, message row height, pane widths, border radius, contrast and reduced-motion controls.
  • Added toggles for avatars, attachment indicators and flags.
  • Added message and folder context menus for common webmail actions.
  • Added raw-header viewer and clipboard copy.
  • Added folder subscribe/unsubscribe UI and context actions for creating subfolders.
  • Added identities/signatures settings UI and composer From identity selection.
  • Signatures from the selected identity are inserted into the composer.
  • Replaced the internal roadmap with the user-approved 0.0.1 plan.
  • Added per-account special IMAP folders for Sent/Drafts/Trash/Junk/Archive and wired them into send/delete/archive/junk flows.
  • Added IMAP copy, mark-all-read, empty-folder, multi-select and bulk operations.
  • Added drag-and-drop message-to-folder moves and previous/next reader navigation with keyboard shortcuts.
  • Added advanced and saved search, read/flag operators, user labels/tags and mailbox quota display.
  • Expanded composer to HTML/plain/Markdown modes, inline CID images, attachment reminder and a larger formatting toolbar.
  • Expanded identities with Reply-To, automatic Bcc, Organization metadata and text/HTML signature behavior.
  • Added contact groups and vCard import/export UI.
  • Added a capability-aware visual Sieve rule builder plus vacation/autoresponder generation and server validation.
  • Added ICS calendar import UI.
  • Connected the browser to the existing IMAP IDLE/WebSocket event stream for realtime refresh and desktop notifications.
  • Added notification Do Not Disturb hours and persisted per-folder notification preferences.
  • Expanded personalization presets and added custom background, panel and text colors in addition to the accent color.
  • Added persisted mailbox preferences for page size, date sort, delayed mark-read, threaded/flat reader mode, HTML/plain preference, quote limiting, snippet visibility and remote-image policy.
  • Added remote-image prompting with sandboxed message rendering and no-referrer loading.
  • Added IMAP capability diagnostics and a settings diagnostics panel for IMAP, ManageSieve and realtime WebSocket state.
  • Added multi-account UI for adding, switching and removing accounts in the current browser session.
  • Added user-selectable date and 12/24-hour time formats.
  • Added server-side validation for message-list page size/sort and mailbox preference values.
  • Added .eml import into any selected IMAP folder using APPEND, followed by cache invalidation and realtime folder refresh.
  • Added List-Unsubscribe handling for safe HTTPS/mailto targets from message headers.
  • Added in-app full RFC822 source viewer, Message-ID/sender copy actions and folder-properties inspection.
  • Raised extractor body limits only on upload endpoints so the documented attachment/vCard/ICS/.eml limits are actually reachable.
  • Expanded contacts with phone, job title, address, website and birthday fields.
  • Added contact photo upload/remove/display for PNG/JPEG/WebP with byte-signature validation and a 2 MB limit.
  • Extended vCard import/export with TEL, TITLE, ADR, URL and BDAY.
  • Changed contact persistence from SQLite INSERT OR REPLACE to conflict-update semantics so editing a contact does not destroy group/photo relations through a row replacement.
  • Fixed the calendar delete-handler syntax regression found during pre-release static review.
  • Added Tantivy index diagnostics and an in-app rebuild from the per-user SQLite cache.
  • Added IMAP request-pool reconnect/verification from Diagnostics.
  • Added active-session inventory across browsers while the process is running, User-Agent display, individual revoke and revoke-all-others.
  • Expanded calendar events with all-day, recurrence RRULE, attendees, organizer, status, reminder, meeting URL and color fields in the UI; added full local ICS export.
  • Added direct ICS/vCard import actions for message attachments.
  • Expanded contacts to multiple e-mail addresses, phone numbers and postal addresses.
  • Added duplicate-contact detection and transactional merge preserving groups, alternate values and contact photos.
  • Validated all 28 SQLite migrations from an empty database plus browser JS/JSON/TOML/shell assets.
  • Added Month, Week, Day and Agenda calendar views with persistent view selection and event-color markers.
  • Hardened contact/calendar/header/source dialogs against viewport overflow and UI scaling.
  • Fixed UI scaling so it also changes icon sizing and field/button spacing, and added persistent draggable pane splitters.
  • Added reusable action toasts to additional folder, search, calendar and ManageSieve operations.
  • Added Spam / Not spam actions in the primary and bulk message toolbars.
  • Added safe attachment Open/Download context actions and browser-side Download all as ZIP with UTF-8 filenames.
  • Added To/Cc/Bcc autocomplete using contacts and known addresses, including keyboard navigation.
  • Added message-list quick actions for read/unread and flag/unflag.
  • Hardened message rendering against RustBox-owned icon sprite markup leaking from malformed MIME content.
  • Kept the UI free of gradients, TypeScript, React/Next and Node/Bun runtime dependencies.
  • Added collapsible hierarchical IMAP folder branches with per-account remembered expansion state and leaf-name rendering.
  • Added a keyboard-shortcuts reference dialog and ! shortcut for Spam / Not spam.
  • Added direct sender actions from the reader header: compose, add contact, copy address, search and create filter.
  • Expanded message sorting to date, sender, subject and size in ascending/descending order, available directly from the message-list toolbar and persisted per account.
  • Added the Contacts only remote-image policy, which verifies the current sender against the saved address book before allowing external images.
  • Expanded the visual Sieve builder with a second condition, AND/OR combination and per-condition negation while retaining server-side CHECKSCRIPT validation.
  • Added automatic identity selection on reply/forward using To/Cc and Delivered-To/Envelope-To headers before signature insertion.
  • Added mailbox quota warning/danger states at 80%/95% usage.
  • Added collapsible thread navigation with remembered expansion state.
  • Added safe Undo for MOVE-backed message actions when the destination UID can be resolved unambiguously, including reverse-order bulk Undo.
  • Added “Select all results” for search bulk actions by materializing the full cached match set on explicit request.
  • Hardened thread matching so References uses complete Message-ID tokens instead of accepting substring collisions.
  • Moved safe attachment previews into an in-app modal for images, PDFs and text attachments.
  • Added composer upload progress and clipboard image paste as CID inline attachments.
  • Added draft recovery from both server-side local drafts and an emergency browser snapshot; SMTP failures force a recoverable draft save.
  • Changed autosave so it no longer appends a fresh IMAP Drafts message every 1.2 seconds; IMAP snapshots are reserved for deliberate close/failure points until remote draft UID replacement is implemented.
  • Expanded keyboard shortcuts with C compose, V selection mode and X select/unselect current message.
  • Replaced runtime browser confirm()/prompt() flows in the main RustBox UI with reusable application dialogs, including folder/label choices used by message context actions and quick-filter creation.
  • Added an explicit message selection mode; row checkboxes are hidden/disabled outside that mode and bulk controls remain available while selecting.
  • Fixed compact/comfortable density so it changes control, toolbar and dialog sizing independently from UI scale and the user-defined message-row height.
  • Added visible toast auto-dismiss countdowns with pause-on-hover/focus behavior.
  • Added Compact, Balanced, Comfortable and Reading interface presets that persist through the existing display-preferences API.
  • Reworked message printing to use a sandboxed in-page print frame instead of a popup, while preserving sanitized HTML/plain-text message rendering and message metadata.
  • Added persisted composer priority and MDN/read-receipt options; outgoing optional headers are shared by SMTP delivery, draft snapshots and the IMAP Sent copy, with mailbox validation before SMTP.
  • Added RFC 8058 one-click unsubscribe through a backend HTTPS POST path with no redirects, DNS/IP public-address checks and direct-address TLS connection to reduce SSRF/DNS-rebinding risk.
  • Fixed migration registration so the existing V028 contact migration and new V029 draft-send-options migration are both executed; the migration set is now V001–V029.
  • Expanded the visual Sieve builder to three conditions with nested AND/OR grouping, two actions, capability-driven action disabling, managed visual-rule ordering, JSON backup/restore and active-script overwrite confirmation.
  • Added optional scheduled vacation start/end dates using Sieve currentdate with date + relational requirements when the server advertises those extensions.
  • Added a browser-wide default Spam/Junk destination with a per-account special-folder override; mail actions fall back to IMAP \Junk/Spam auto-detection when neither resolves.
  • Added persistent mailbox-level “flagged on top” and per-folder inherit/on/off overrides. Flagged-first ordering is performed in SQLite before pagination.
  • Added a subtle red lower-edge marker to flagged message rows without changing the existing star action.
  • Replaced the quick-filter folder prompt/raw-editor handoff with a dedicated ManageSieve filter wizard that previews the rule, respects advertised extensions, validates with CHECKSCRIPT, saves directly to the selected script and can activate it.
  • Kept an Advanced editor handoff that preloads the visual Sieve builder for users who want to refine the generated rule.
  • Added SQLite migration V030 and a folder-preferences API for per-folder list behavior.
  • Added aggregate unread counts to the browser title and supported application badges.
  • Added /api/ready alongside liveness /api/health; readiness checks that the local RustBox data directory is accessible without coupling process readiness to account-specific IMAP/SMTP availability.
  • Made generic application dialogs scroll as a fallback when their content exceeds the browser workspace, while retaining independent scroll regions for structured composer/settings/contact/calendar/source dialogs.
  • Fixed inline-image compose preview: uploaded CID images render from the authenticated draft-attachment endpoint while editing, then serialize back to cid: references for draft persistence and SMTP/IMAP MIME generation.
  • Removing an inline-image attachment now also removes its matching image node from the composer instead of leaving a broken placeholder.
  • Replaced the About-page Runtime row with Author: @linuxiarz.pl.
  • Extended the quick-filter wizard with an optional capability-aware “also mark as read” action and an explicit notice that Sieve rules apply to new incoming mail rather than retroactively changing existing messages.
  • Changed the About author label to @linuxiarz.pl.
  • Fixed action-toast controls so Undo and the close button share one compact control group; clicks no longer propagate between the two actions.
  • Preserved the active folder, loaded-page depth, message-list scroll position and active search context across normal refresh/reconnect flows within the browser session.
  • Added an explicit offline/reconnecting state and bounded automatic retry for idempotent GET/HEAD requests only; mutating operations are never automatically replayed.
  • Added authenticated SMTP connection diagnostics, IMAP custom-keyword capability detection and local synchronization-cache diagnostics with last folder/message sync timestamps.
  • Added friendly active-session client names such as Firefox · Linux while keeping the full User-Agent available as hover detail.
  • Added client-side highlighting of active search terms in sender, subject and snippet without injecting result text as HTML.
  • Fixed the Settings modal grid so the header occupies only its natural height and the sidebar/content area fills the remaining workspace instead of being pushed toward the bottom for short panels such as About.
  • Made Settings navigation/content independently scrollable and mobile tabs horizontally scrollable.
  • Added inline-image selection/editing in the composer: display width, inline/left/center/right placement and in-app crop/cut with a live preview. Cropping creates a replacement CID attachment; GIF cropping stays disabled to preserve animation.
  • Dragged image files now insert as inline CID images in HTML mode instead of silently becoming ordinary attachments.
  • Added cleanup of CID attachments whose inline image was removed from the editor, including a final cleanup before send/close.
  • Added a warning before switching away from HTML when rich formatting may be lost.
  • Added persisted Composing settings for default format, draft autosave interval, default priority, default MDN/read-receipt request and attachment-reminder behavior.
  • Added SQLite migration V031 for the new composing preferences.
  • Added SQLite migrations V032–V036 for advanced appearance preferences, draft compose-format persistence, optional IMAP-keyword synchronization, composer behavior preferences and remote IMAP-draft tracking.
  • Expanded Appearance with icon size, toolbar/sidebar density, reader/composer widths, selection color, unread styling, compact headers, border/scrollbar controls, monochrome mode and per-pane background overrides.
  • Completed the safe Markdown compose pipeline: Markdown source remains the plain alternative while preview/delivery uses escaped generated HTML rather than raw Markdown HTML.
  • Added persisted composer defaults for font, reply-above/below-quote, quote style, forward inline/as-attachment and browser spellcheck.
  • Added administrator-configurable outgoing headers with header-name validation, structural/MIME-header denylisting and CR/LF-injection rejection.
  • Added opt-in native IMAP keyword synchronization for RustBox labels. Stable RustBox keywords are written only where persistent custom keywords are supported and observed RustBox keywords are imported back into local labels; full remote-removal reconciliation remains partial.
  • Reworked deliberate IMAP Drafts snapshots so RustBox resolves the newly appended draft UID from UIDNEXT plus an exact X-RustBox-Draft-ID search, stores UID/UIDVALIDITY and removes the prior snapshot only after an unambiguous safe match.
  • Added strict draft-ID validation before attachment-path use, closing traversal through draft identifiers and making the draft marker safe for IMAP headers.
  • Changed attachment uploads to stream multipart chunks into bounded .part files with atomic rename, stale-part cleanup and cleanup on interruption/error instead of buffering the entire upload in memory.
  • Fixed the duplicated draft-route Extension(config) extractor and kept standalone ui/ assets synchronized with embedded src/web/ sources.
  • Fixed the Axum 0.8 E0277 Handler failure in tag/bulk-tag routes by separating synchronous SQLite work from awaited IMAP work; no rusqlite connection/transaction is retained across network awaits.
  • Applied the same DB/network phase separation to single-tag, untag and tag-delete handlers so the compile failure does not simply move to the next route.
  • Added authoritative IMAP-label reconciliation for folders that explicitly support persistent custom keywords. Remote RustBox keyword additions and removals can now be reconciled into local labels from Mailbox settings.
  • Fixed Keep me signed in so the server-side session timeout is extended together with the cookie instead of still expiring at the normal default timeout.
  • Active-session diagnostics now expose effective expiry and whether the session uses the remembered timeout.
  • Added graceful SIGTERM/Ctrl+C shutdown and explicit cancellation of dedicated IMAP IDLE tasks before process exit.
  • Extended synchronization diagnostics with active IMAP IDLE task/subscriber counts to make reconnect storms and leaked subscriptions visible from the UI.