61 KiB
RustBox changelog
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.
-
Added an opt-in Appearance setting that adapts neutral HTML-mail backgrounds and low-contrast text to the active light/dark theme while preserving layout, images and brand colors.
-
Consolidated migrations V047-V049 into the V049 compatibility baseline and removed their standalone migration files. V050 remains the single runtime migration for the unreleased 0.2.15 schema changes. Databases older than V049 must be upgraded to that baseline first.
-
Added mailbox pagination, enabled by default at 300 messages per page, with optional smooth progressive loading or full-folder loading.
-
Folded
display_preferences.adaptive_email_colorsandmail_preferences.message_loading_modeinto the unreleased V050 runtime migration; V051 remains the next migration number. -
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, whilevisibleinserts 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 (
filesystemincluding 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 draftaction 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 draftnow 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
\\Draftflag) now open directly in the normal composer from their server-side RFC822/MIME content; opening does not depend on a RustBox draft database row orX-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\Draftsattribute and commonDrafts/Draftfolder names. - Added an explicit
Save draftcomposer action immediately beforeCancel; it forces the current message and attachments to be persisted as a real IMAP\Draftsnapshot 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 moreandLoad allacross the full message-list action area with equal-width controls. - Added a composer
Hide fields/Show fieldstoggle 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 allaction besideLoad morein the message list. - Renamed the reader toolbar action from
Message detailstoDetails. - 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
Embedactions 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 attachmentaction. - 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
targetnow 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
NewMessagestoasts 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+RandCtrl/Cmd+Nare 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_LOGtarget 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
/procsampling; 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/UNSEENdrives badges, selected-mailbox fallback countsUID SEARCH UNSEEN, periodic reconciliation repairs counters even whenHIGHESTMODSEQis 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 / unreadwhen 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
/apiprofile (no-store,nosniff, same-origin CORP,frame-ancestors 'none'andX-Frame-Options: DENY), while keeping Permissions-Policy/COOP and the full document CSP on HTML and HSTS at the public HTTPS edge; disablingsecurity_headers_enabledremoves the whole RustBox-added security profile. - Minimized unauthenticated
/api/auth/policytorememberMeEnabled; 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
eventIdvalues always win over payload fingerprints; rapid legitimate counter cycles such as1 → 0 → 1are 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 FLAGScomparison, 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 narrowerstyle-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-PolicyandX-Content-Type-Options; JavaScript, JSON, SVG, API and other non-document responses retainX-Content-Type-Options: nosniffwithout 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 detailsandMove / 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_httpto the finalClientOptionsobject instead of setting it beforewith_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'slibssl3t64. - 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-Backendto 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
AppConfigwith a struct literal plus..Default::default(), satisfyingcargo clippy --all-targets -- -D warningswithout suppressingfield_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-wideOnceLock, preventing later tests from reusing a deletedTempDirand 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.shrequires 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 throughsqlx::Executor::execute()on the transaction connection instead ofsqlx::raw_sql(...).execute(&mut PgConnection). - Preserved transactional startup schema initialization and the local
client_min_messages=WARNINGscope 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, avoidingcolumn reference "value" is ambiguousand HTTP 500 responses. - Added a regression check for tenant SQL rewriting of the qualified
user_meta.valuereference and a static audit covering all PostgreSQLON CONFLICT ... DO UPDATEtarget-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, skippingnotices, 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 idempotentCREATE ... IF NOT EXISTSnotices without hiding application/database warnings globally. - Removed the Docker-specific SQLx PostgreSQL notice filter workaround; normal
RUST_LOG=infois 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 keepsSecurecookies behind HTTPS. - Exposed
pgp_enabledthrough 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
rustboxCompose project name, documented Docker environment variables, and made application port mapping configurable throughPORT. - Reduced PostgreSQL startup log noise in the Docker example by suppressing repeated SQLx
NOTICEmessages 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_outboxin 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_dirbackends in single-node mode, while cluster mode no longer requires persistentdata_dirwhen cluster-safe backends are configured. - Added
BlobStoragewith 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_levelto TOML configuration (trace,debug,info,warn,error,off);RUST_LOGremains 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.emailfromTEXTtoVARCHAR(320); MySQL requires a prefix length when indexingTEXT/BLOBcolumns. - Fixed destructive MySQL cache upserts: folder refresh and message-header refresh now use
INSERT ... ON DUPLICATE KEY UPDATEinstead ofREPLACE 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 importsrusqlite::OptionalExtensionwithout colliding with RustBox's ownOptionalExtension, and MySQL/PostgreSQL transaction batch execution now uses the typed SQLx transaction helpers instead of the lifetime-problematicraw_sqlexecutor path. - Unified the storage model:
database_backend = sqlite | mysql | pgsqlnow selects the database engine for the whole application instead of only the SQL session store;session_backend = database | rediseither 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.sqlitedatabases atPRAGMA user_version = 46into the configured backend. The source database is renamed todb.sqlite.pre-0.1.1.bakonly 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.sqlfiles: sessions are part of each engine's completeschema.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/andbackend/tests/as RustBox-owned review-only areas so schemas and native tests are never overwritten automatically. - Removed the accidental runtime log
qar.txtfrom 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-V046are applied; session migrationV047is 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_historybridge; RustBox now has one canonical user-database migration runner. - Removed unused test-only session removal helpers that emitted
dead_codewarnings duringcargo test. - Strengthened
scripts/build-release.shto 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
CachedMessagecolumn 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-sysCargo links conflict by usingrusqlitefor SQLite session persistence and limitingsqlxto 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.sqliteis 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 undermigrations/{sqlite,mysql,pgsql}/; SQLite user migrations remainV001-V046and sessions useV047__sessions.sqlacross SQL dialects.
0.0.7
- Added
allow-downloadsto 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.logand 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 = 10per uploaded file andmax_message_size_mb = 50for 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_verifyis 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.rsnow 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 inOUT_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 staleAccountSessiontest 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_pathUI 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_skindisplay 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 embeddedsrc/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-passphraseand a keyring UI action, including an explicit warning before removing passphrase protection. - Added optional
RUSTBOX_PGP_GPG_BINARYoverride for deployments where the GnuPG binary is not namedgpg. - 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/andexamples/. - 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; ordinarycargo run,cargo testandcargo build --releasenow 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
Formattrait forToml::file, and removed an unusedSieveCapabilitiesre-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_hostto 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/; Cargobuild.rsbundles 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
.emlimport into any selected IMAP folder using APPEND, followed by cache invalidation and realtime folder refresh. - Added
List-Unsubscribehandling 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 REPLACEto 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 onlyremote-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
Referencesuses 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
Ccompose,Vselection mode andXselect/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
currentdatewithdate+relationalrequirements 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/readyalongside 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 · Linuxwhile 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-IDsearch, 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
.partfiles 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 standaloneui/assets synchronized with embeddedsrc/web/sources. - Fixed the Axum 0.8
E0277 Handlerfailure 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 inso 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.