# Change Log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [0.16.14] - 2026-07-XX If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - Use of Voluntary Application Server Identification (VAPID) in JMAP Web Push ([RFC 9749](https://datatracker.ietf.org/doc/html/rfc9749)). ## Changed ## Fixed - IMAP: - Mailbox object-quota only enforced in JMAP. - Pipelined `STORE` and `EXPUNGE` can execute out of order. - JMAP: - Read-only sharee cannot set `isSubscribed` on a shared mailbox. - Web Push payloads with `Content-Encoding: aes128gcm` should not be base64-encoded but sent as raw bytes. - Stale push subscription can block verification of a new one. - `PushSubscription/set` rejects the unpadded base64url keys the W3C Push API produces. - `Email/import` does not send push notifications for imported messages. - `CalendarEvent/set` silently ignores `ifInState`. - CalDAV: `calendar-query` REPORT returns empty calendar-data for JMAP-created events. - MTA: - DMARC is skipped when MAIL FROM SPF is unavailable. - `queue_name` variable not available in rate limiter expressions. - Calendar: - No expanded occurrences are returned for a daily recurrences crossing DST. - Uppercase `MAILTO` calendar addresses become invalid SMTP recipients. - Scheduling invitations on a shared, non-owned calendar fail with `MAIL FROM unauthorized`. - HTTP: Disable `allowedEndpoints` expression in recovery mode. - Telemetry: Tasks are serialized to the wrong store when using separate stores for telemetry and data. ## [0.16.13] - 2026-07-12 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - FreeBSD support. ## Changed ## Fixed - OAuth resource indicators: Accept `imap`, `smtp`, `pop3` and `sieve` as valid resource indicators for OAuth access tokens. - PostgreSQL: Incomplete channel binding implementation. - JMAP: - VacationResponse: `isEnabled` reset to false whenever properties are changed. - Capabilities: Return RFC-3339-conformant UTCDate literals in capabilities: min `0001-01-01T00:00:00Z`, max `9999-12-31T23:59:59Z`. - Directory: Update local groups only when the external directory includes a group attribute. - DNS Management: - CAA management deletes too third-party CAA entries. - Multiple provider fixes (see `dns-update` crate changelog). - Reject invalid duration values (e.g. `1h30m`). - Branding: Custom logos for domains do not work. - Sieve: add `Received` headers to auto-generated messages and detect loops. - MTA: Resume queue processing does not work. - Misconfigured in-memory store cannot be recovered in recovery mode. ## [0.16.12] - 2026-07-06 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - DKIM2 implementation ([draft-ietf-dkim-dkim2-spec-04](https://datatracker.ietf.org/doc/draft-ietf-dkim-dkim2-spec/)). - DMARCbis implementation: - Domain-based Message Authentication, Reporting, and Conformance (DMARC) ([RFC 9989](https://datatracker.ietf.org/doc/html/rfc9989)) - DMARC Aggregate Reporting ([RFC 9990](https://datatracker.ietf.org/doc/html/rfc9990)) - DMARC Failure Reporting ([RFC 9991](https://datatracker.ietf.org/doc/html/rfc9991)) ## Changed ## Fixed - DANE: Treat DNSSEC `bogus` as a temporary failures to prevent downgrade attacks. - OIDC provider: - `ECDSA` private key support for `SEC1` format. - Allow ports in `redirect_uri` for loopback addresses. - OIDC directory: - Removing a user from all groups does not sync the changes correctly. - Fetch `name` and `group` claims from userinfo endpoint when missing from the JWT token. - PostgreSQL: Include error chain in error messages. - Prometheus: event counters are exported with incorrect metric names. - Registry: Changing the type of an existing account from `user` to `group` panics. - Masked emails: Return `UnknownRecipient` only for disabled or expired masked emails. - IDN: `sanitize_email` rejects valid Punycode domains. - Auto-ban: IP block expiration ignores per-reason ban durations. - Meilisearch: Limit the text search scope using `attributesToSearchOn`. - CalDAV: `calendar-query` REPORT returns invalid HTTP `404` when no events match the query. - Snowflake past id generation fails when the provided duration is longer than 4 years. - Calendar scheduling: Wrong RSVP base URL is used. - Network listener: Accept loop spins all CPU cores with no back-off when the process hits `EMFILE` (too many open files). - Cluster: Broadcast MTA queue refresh events to all nodes. ## [0.16.11] - 2026-06-25 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - Encryption-at-rest: Support for `AES-256-GCM` and `ChaCha20-Poly1305` for S/MIME (#161). - S3: Support for `allowInvalidCerts` option to allow connecting to S3 endpoints with invalid TLS certificates. - Redis Sentinel support as an in-memory store and cluster coordinator backend (#2430). ## Changed ## Fixed - DANE: Verify DNSSEC is supported by the resolver before attempting to validate TLSA records. - TLS: Update search index when file-backed certificates are refreshed. - JMAP: `Principal/query` returns broad results when a `name` or `email` filter cannot be resolved. - Webhooks: event IDs collide for same event type emitted in the same second. ## [0.16.10] - 2026-06-21 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - International Domain Names (IDN) support (#207). - OAuth: - OAuth Profile for Open Public Clients ([draft-ietf-mailmaint-oauth-public](https://datatracker.ietf.org/doc/draft-ietf-mailmaint-oauth-public/)) - Client secret verification for confidential clients. - HTTP: Add `redirectRoot` option to `Http` object to allow redirecting requests to the root path to a different path (e.g. `/account`). - ACME: `reuseKey` option to allow reusing private keys in renewals. - IMAP: - IMAP Extension for Object Identifiers ([draft-ietf-mailmaint-imap-objectid-bis](https://datatracker.ietf.org/doc/draft-ietf-mailmaint-imap-objectid-bis/)) - `GETJMAPACCESS` command to discover the JMAP session resource URL (#2736). ## Changed ## Fixed - JMAP conformance (pass the [jmap-test-suite](https://github.com/jmapio/jmap-test-suite) tests): - Methods are only available if their capability is in `using`. - Reject requests that do not specify `application/json` in the `Content-Type` header. - Require `accountId` argument on requests. - Return unparsable ids in `notFound` / `notUpdated` / `notDestroyed` / `notCopied` instead of dropping them. - Default calendars and address books are not subscribed by default. - `*/set`: Unchanged immutable `id` property is rejected on update. - `*/query` and `*/queryChanges`: null` rejected as `notRequest`. - `Email/query`: * Improper `anchor` handling. * Total miscount when `collapseThreads` is enabled. * Wrong sort order on `hasKeyword`, `allInThreadHaveKeyword`, and `someInThreadHaveKeyword` conditions. * Non-standard header values are not searchable. - `Email/copy`: Take the source message id from the value's `id` property. - `Email/set`: Bump reference-resolution max_depth from 1 to 2. - `Email/import`: Reject blobs that do not contain valid messages. - `EmailSubmission/set`: return `sendAt` and `undoStatus` in the created response. - `Mailbox/set`: Return `alreadyExists` instead of `invalidProperties` when creating a mailbox with an existing name. - `SearchSnippet/get`: incorrect response structure. - `Thread/changes`: emit a container delete when a thread becomes empty. - `VacationResponse/set`: incorrect singleton handling. - IMAP: Discard oversized non-synchronizing literals (#2768). - DANE: Improper `TLSA` record validation (#2328 - credits to @vdukhovni). - OIDC: Add default domain name to groups that are not email addresses. - RocksDB: Enable blob garbage collection to reclaim disk space from deleted blobs. - Sieve: `include` statements ignore capitalisation of sub-script names (#1643) - Cache: Invalidate negative email caches when an account is created. - Troubleshoot tool: Use the configured source IP address when connecting to remote servers (#2867). ## [0.16.9] - 2026-06-15 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - ACME: Allow specifying a preferred certificate chain. ## Changed ## Fixed - JMAP: `*/changes` methods leak ids of non-shared objects (reported by @5ud0er). - Sieve: Do not allow invalid certs in `http_header` function. - FoundationDB: Fix read version cache expiration logic. - MTA: Re-scheduling or editing a queued message reports success but persists nothing for recipients in a non-`default` virtual queue. - CardDAV: Version requests included in `address-data` are ignored. - ACME: Add freshness check when renewing certificates. - Autodiscover v2: Read email address from query parameters. - Sieve: Do not keep copies of redirected messages when `keep` is not specified. - Registry: Object ids are parsed as numbers. ## [0.16.8] - 2026-06-06 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added ## Changed - OAuth: Rework access tokens to an `AES-256-GCM-SIV` AEAD format that carries the account name for proxy routing. - Added more internal TLDs to the domain validation. ## Fixed - MTA: - Sub-addressing with external directories returns `550 Mailbox not found`. - Disabled aliases continue receiving messages. - JMAP for File Storage: `FileNode/get` returns a stale state string. - Make `SieveSystemInterpreter.defaultReturnPath` and `MtaQueueQuota.match` optional expressions. - Rate limiter panics when periods under 1 second are used. - CalDAV/CardDAV: Calendar events, contacts, calendars and address books deleted via JMAP do not write a vanished tombstone. - DNS updater: bump to `dns-update-v0.5.1`. ## [0.16.7] - 2026-05-28 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - RateLimit header fields for HTTP ([draft-ietf-httpapi-ratelimit-headers-10](https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-ratelimit-headers-10)) - MTA: Implement `spamtest` in trusted Sieve scripts. ## Changed ## Fixed - Log rejected messages to tracing store. - MTA: - Always update next DSN notify times. - Expand lists and resolve catch-all addresses when building autogenerated messages. - Sharing: Includes resource that themselves carry a direct ACL grant and are leaves. - Tasks cannot be deleted in OSS builds. - Directory: Per-domain external directory resolution fails. - DNS updater: Keep external `TXT` records when updating RRSet. - HTTP: Reject requests from blocked IPs when `Keep-Alive` is enabled. ## [0.16.6] - 2026-05-20 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - Added 58 new DNS provider integrations (see [dns-update](https://github.com/stalwartlabs/dns-update/blob/main/CHANGELOG.md#dns-update-040) crate for details). - DNS updater: Log DNS record types and values. - Sieve: Allow User Sieve scripts to access `orcpt`. - MTA: Log when messages are rejected or discarded by the spam classifier. ## Changed - Bump JMAP File Storage to [draft-ietf-jmap-filenode-14](https://datatracker.ietf.org/doc/html/draft-ietf-jmap-filenode-14). - Accept password hashes with `$` or `{` prefixes as secure secrets. ## Fixed - DAV: `acl-principal-prop-set` REPORT enforced the wrong privilege. - JMAP: `Thread/get` did not filter by per-mailbox ACLs on shared accounts. - IMAP: `UID FETCH N:*` could miss messages moved into a SELECTed mailbox by another connection. - DNS updater: - Skip `v=spf1 a -all` records for apex domains. - RFC2136 TSIG: regression related to multiplexer. - Route53: Chunk `TXT` records when they exceed 255 characters. - ACME: - Update `defaultCertificateId` when renewing a certificate that is currently set as default. - Perform `DNS-01` authorizations sequentially to avoid race conditions in some DNS providers. - Allow internal TLDs and special characters in e-mail addresses. - Websocket: Perform case insensitive matching during upgrade. - LDAP: Synchronize accounts when expanding mailing list recipients. - Sieve: `replace` action adds an extra `From` header. - ACL: Orphaned ACL entries for deleted accounts cause JMAP session errors. ## [0.16.5] - 2026-05-11 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - `is_ip_in_cidr` expression function for CIDR matching. ## Changed - Bump `mail-auth` to 0.9 (which bumps `hickory-resolver` to 0.26). - Deprecated RFC2136 SIG(0) support as it is no longer supported by `hickory`. ## Fixed - JMAP: - Patching ids containing digits in JSON Pointers fails. - Patching nested objects with `null` values fails. - External directories: - SQL: Return `Failed` instead of `Error` when the query returns no results. - LDAP: Impersonation fails when the user has not logged in before. - Network: Attempt binding to IPv4 when binding to IPv6 fails with `EAFNOSUPPORT` error. - Bootstrap: Timeout after 30 seconds when probing the data store. - HTTP: Use permissive CORS headers for `.well-known` endpoints. - ACME: - Include apex domains when requesting certificates for subdomains. - Use the public suffix list to determine the zone name when no origin is provided. - MTA: - Allow rescheduling recipients with permanent failures. - Process reports using original `RCPT` before rewriting. - Autodiscover v2 endpoint unreachable. - DNS update (via `dns-update` crate): - OVH + Google Cloud DNS: Fix FQDN handling for `MX` and `SRV` records. - Route53: Fix changeset error resolution. - deSEC: Use empty `subname` for apex records instead of `@`, which the API rejects. - Cloudflare: Wrap `TXT` record content in double quotes (RFC 1035) to suppress dashboard warnings. - iCalendar/JSCalendar (via `calcard` crate): - Support `STATUS:CANCELLED` mapping from `VTODO` to JSCalendar. - Fixed duration parsing for zero duration `PT0S`. ## [0.16.4] - 2026-05-05 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added ## Changed ## Fixed - Live tracing in community and OSS versions. - Timezone changes from the `AccountSettings` object return `invalidProperties`. - `mail-parser` panic with certain messages containing corrupted attachments. - Pagination by anchor for queued messages, tasks and metrics. - Spam filter: Use original instead of rewritten `RCPT` on checks. - JMAP: - References in nested objects not resolved. - `AddressBook/query` fetches wrong resources. - Import tool fails to restore registry entries. - FDB: Allow multiple FoundationDB instances in the same process. - Autoconfig: Return `%EMAILADDRESS%` when no email address is provided. - Quota: Include Sieve scripts in quota recalculations. ## [0.16.3] - 2026-04-30 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added ## Changed - Replaced `STALWART_HTTPS_PORT` with `STALWART_PUBLIC_URL`. - App Passwords now begin with `app_` instead of `app ` to avoid issues with some clients that do not support spaces in passwords. ## Fixed - Directory: - Invalidate caches when group memberships change on an external directory. - OIDC: errors instead of "failed to decode token". - OIDC: Recovery admin access. - User impersonation. - Tasks: - Delete locked tasks. - Queue pagination by anchor. - Log viewer: All events show as `INFO`. - Registry: Allow changing object variants. - Node id renewal. - DNS Updater: Fix Route53 serialization format. ## [0.16.2] - 2026-04-28 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - OIDC: Fallback to `userinfo` endpoint when JWT token does not contain an email claim. - S3: `verifyAfterWrite` option to verify that objects have persisted after writing. ## Changed - Allow HTTP to be used for configuring the server. ## Fixed - LDAP: Generate valid `credentialId` when there are password changes. - TLS: Disable cipher suited option disables wrong ciphers. - DNS Updater: - BunnyDNS: Use subdomain as name of record instead of FQDN. - RFC2136: Chunk TXT records. - Skip invalid entries in log files. ## [0.16.1] - 2026-04-25 If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - OIDC: Extract username from JWT token. - `system('node_hostname')` and `system('node_role')` expression variables to retrieve the local node hostname and cluster role respectively. ## Changed ## Fixed - JMAP: - Invalid `receivedAt` headers after importing (#2939). - Sorting order issues when emails lack `receivedAt` headers. - IMAP: Fix `BINARY` fetch responses (#2940). - WebDAV: Fix ACL validation for target folders. - ACME: Allow requesting apex domain certificates. - Hostname issues: - Accept RFC 6761 reserved TLDs during bootstrap. - Allow hostnames without TLDs in remote server settings. - Reverse proxy issues. - OSS builds. - DNS Updater: - RFC2136: TSIG secret not base64 decoded. - Google DNS: Chunk TXT records when they exceed 255 characters. - Cloudflare: - Fix `CAA` record updates. - Check zone subdomains when finding zones ## [0.16.0] - 2026-04-20 This version includes **multiple breaking changes**. If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added - [Web UI](https://github.com/stalwartlabs/webui) rewritten from the ground up using the JMAP management API, featuring a refreshed design and addressing 76 enhancement requests and bug fixes. - [CLI](https://github.com/stalwartlabs/cli) rewritten from the ground up to use the JMAP management API. - Security enhancements: - Password strength enforcement using the `zxcvbn` algorithm - Password expiration, rotation policies and IP address restrictions for user accounts - App Passwords with limited access (#1609), labels (#2255), IP address restrictions and expiration dates - API keys with limited access, labels, IP address restrictions and expiration dates - Auto-ban comments and details about the triggering event (#1321) - Auto-ban expiration after a configurable time period (#964) - DNS Management: - Automatic DNS management of `MX`, `TXT`, `CNAME`, `SRV`, `CAA` and `TLSA` records (#463 #1017 #1419 #2438 #1370 #1406 #1371) - Automatic update of `TLSA` records when ACME certificates change (#1664) - RFC2136 `SIG(0)` support (#856) - Route53 provider support (contributed by @jimmystewpot) - Google Cloud DNS provider support (contributed by @jimmystewpot) - Bunny provider support (contributed by @angeloanan) - Porkbun provider support (contributed by @jeffesquivels) - DNSimple provider support (contributed by @NelsonVides) - Spaceship provider support (contributed by @matserix) - DKIM: - Automatic DKIM key generation, rotation and DNS management (#368 #961) - Store DKIM keys in the database (#1264) - Ignore insecure signatures when verifying DKIM (#1068 #467) - ACME/TLS: - `DNS-PERSIST-01` ACME challenge support (#2837) - Renew certificates on demand, view certificate details (#675 #1162 #2566) - `CAA` record support (#468) with `accounturi` parameter (#1933) - `TLSA` records publishing restricted to `3 1 1` and `2 1 1` (#2193) - OIDC and OAuth: - JWT token validation without requesting userinfo from the OIDC provider. - Audience (`aud`) claim (#2603) and scope validation support. - Groups support (#1448) - RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients - LDAP: - Separate filter for groups (#1841) - Improve support for OpenLDAP schemas (#760) - Improve and simplify LDAP settings (#2194 #2174) - Directory: - Masked email addresses for enhanced privacy (*Enterprise*) - Domain aliases (#583) - E-mail alias descriptions and option to disable aliases (#506) - Account archiving and un-deletion (#2767) (*Enterprise*) - Per-domain directory backends (*Enterprise*) - Account configuration and discovery: - Automatic Configuration of Email, Calendar, and Contact Server Settings ([draft-mailmaint-uaautoconf-04](https://datatracker.ietf.org/doc/html/draft-eggert-mailmaint-uaautoconf-04)) (#2201) - MS Autodiscover V2 support (#679) - Sieve: Allow deactivating scripts without deleting them (#1251). - Tracing: Enable events only mode (#2276) - Clustering: - Automatic cluster node ID generation and management. - Unified cluster management (#960) - Outbound MTA role (#1692) ## Changed - Replaced REST API with JMAP API (#2262 #959 #1480) - Removed support for Authenticated Received Chain (ARC) sealing ([learn more](https://mailarchive.ietf.org/arch/msg/dmarc/KvX3-H1SL0Gh3IDl7FuR2hoR87M/)). - Directory: Removed `smtp`, `imap` and `memory` directory backends. - Use `aws-lc` for cryptographic operations instead of `ring`. - Use `rustls-platform-verifier` for TLS certificate verification instead of `webpki` (#247). ## Fixed - Directory: - Cannot remove built-in "admin" role from user once it was assigned (#1467) - Delete associated records (#963) - Updated Role permissions not applied (#2038) - Recreated account cannot log in until server is restarted (#1469) - Subaddressing does not work for groups (#475) - New LDAP aliases are rejected (#1318). - Validate account and group names (#2209) - MTA: - RCPT TO stage settings improvements (#2217 #394) - Relay to IP addresses (#838) - Duplicate delivery inverted check - SASL challenge responses include invalid `Go ahead` text - JMAP: - Fix `inMailboxOtherThan` query logic. - Fix `hasAttachment` search field (#2778) - IMAP: - Increment argument max length to `8000` bytes - ACL: Add `RIGHTS` capability (#2762) - ACL: Fix `ACL SET` permission override. - WebDAV: - Return `304` `NOT_MODIFIED` on `If-None-Match` - Use RFC 2616 instead of RFC 1123 for date formatting - Fix ACL container/item mismatch in reports. - CalDAV: Allow organized properties to be present in `PUT` requests if they are equal to the existing ones. - CalDAV: Enforce cumulative iCalendar instances cap in CalDAV free-busy REPORT handler - Configuration: Prefix parsing issues (#2495) - OIDC: JWKS Exposes Symmetric Signing Key - SQLite: Fix thread pool exhaustion. - PostgreSQL: Use clean recycling method on connection pool - Meilisearch: Make `id` sorteable. - ACME: Fix wrong origin for subdomain updates (#2360) - Spam filter: Skip invalid messages during training. - Calendar: Include minutes in localized invite templates (#2828) - HTTP: Fix `204` CORS preflight responses ## [0.15.5] - 2026-02-14 If you are upgrading from v0.14.x and below, this version includes **multiple breaking changes**. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. If you are upgrading from v0.15.x, replace the binary and update the webadmin. ## Added ## Changed ## Fixed - IMAP/JMAP: OOM when `mail-parser` returns cyclical MIME structures [CVE-2026-26312](https://github.com/stalwartlabs/stalwart/security/advisories/GHSA-jm95-876q-c9gw). - Tracing: Fix tracing indexing when using separate stores. - JMAP: Fix `upToId` computation in `*/queryChanges`. - JMAP: Include createdIds when the property is present. - JMAP: Respect query arguments in `Email/queryChanges`. - JMAP: Return the correct container/item change id when there are no changes. ## [0.15.4] - 2026-01-19 If you are upgrading from v0.14.x and below, this version includes **multiple breaking changes**. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. If you are upgrading from v0.15.x, replace the binary and update the webadmin. ## Added - IMAP: Map `HEADER SUBJECT/FROM/TO` searches to `SUBJECT/FROM/TO` queries. - Sieve: Update spam status on user scripts. ## Changed ## Fixed - Search: Return all document ids when no filters are provided. - Search: Filters not applied when a single message is in the account. - IMAP: Return `ALREADYEXISTS` code when creating existing mailboxes. - IMAP: Do not return quota resources if no quota is set. - JMAP/changes: Update `newState` with last changeId if an invalid fromChangeId is provided. - JMAP/CalendarIdentity: Do not update invalid calendar identities. - AI API: Include request error details if available. ## [0.15.3] - 2025-12-29 If you are upgrading from v0.14.x and below, this version includes **multiple breaking changes**. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. If you are upgrading from v0.15.x, replace the binary and update the webadmin. ## Added - Polish locale support (contributed by @mrxkp) (#2480) ## Changed ## Fixed - Meilisearch: Return correct error messages when failing to create indexes (#2574) - PostgreSQL search: Truncate emails to 650kb for full-text search indexing. - FoundationDB search: Batch large transactions (#2567). - Spam filter: Fix training sample size checks - IMAP: Fix UTF7 encoding with Emojis (contributed by @dojiong) (#2564). ## [0.15.2] - 2025-12-22 If you are upgrading from v0.14.x and below, this version includes **multiple breaking changes**. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. If you are upgrading from v0.15.x, replace the binary and update the webadmin. ## Added - OAuth: Add device authorization endpoint (#2225). ## Changed - Antispam: Only auto-learn spam from traps or multiple RBL hits. ## Fixed - mySQL search: Use `MEDIUMTEXT` field type for email body and attachments (#2544). - PostgreSQL search: Truncate large text fields. - ElasticSearch: Implement pagination (#2551). - Antispam: Fix `NO_SPACE_IN_FROM` spam tag detection logic (#2372). - IMAP: Fix shared folder double nesting (test suite credits to @ochnygosch) (#2358). - JMAP: Use latest `Received` header in JMAP `Email/import` (credits to @apexskier) (#2374). - JMAP: Return unsorted search results when the index is not ready (#2544). - LDAP: Lowercase attribute comparison (credits to @pdf) (#2363). - CLI: Fix same-host JMAP redirection on non-standard ports (#2271). ## [0.15.1] - 2025-12-17 This version includes **multiple breaking changes**. If you are upgrading from v0.14.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. ## Added ## Changed ## Fixed - PostgreSQL: Sanitize search index values (#2533) - Elasticsearch: Ignore `resource_already_exists_exception` errors when creating indexes (#2535) - Migrate 0.13.x data (#2534) ## [0.15.0] - 2025-12-16 This version includes **multiple breaking changes**. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_15.md) for more information on how to upgrade from previous versions. ## Added - Linear spam classifier using FTRL-Proximal and feature/cuckoo hashing. - Meilisearch store backend implementation (#1482). - PostgreSQL and mySQL native full-text search support. - Multiple performance improvements and database access optimizations. - Encryption-at-rest: Spam training privacy setting. - Enterprise: Undelete e-mail feature now includes From/Subject/Received information. - IMAP: Implemented new keywords and mailbox attributes described in [draft-ietf-mailmaint-messageflag-mailboxattribute-13](https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-messageflag-mailboxattribute-13) ## Changed - IMAP: Always return special use flags in responses. ## Fixed - JMAP: `FileNode/set` fails to delete files (#2485). - JMAP: Return error when using `blobId` in JSContact and JSCalendar (#2431). - Directory: Deletion of list or domain issues (#2415). - MTA: Headers and body stripped from mail delivery subsystem failure notifications (#2344). - MTA: Hooks only run if sieve script, milter or rewrite is configured (#2317). - Autodiscover: Endpoint should be case insensitive (#2440). - Housekeeper: Panic during DST transition (#2366). - Import/Export: Fix import/export utility (#1882). - Enterprise: Remove tenant admin permissions when license is invalid. ## [0.14.1] - 2025-10-28 If you are upgrading from v0.13.4 and below, this version includes **breaking changes** to the internal directory, calendar and contacts. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_14.md) for more information on how to upgrade from previous versions. ## Added - Autoconfig for CalDAV, CardDAV and WebDAV (#1937) ## Changed - HTTP: Remove HTTP STS `preload` directive. ## Fixed - Directory: Keep OTP Auth and AppPasswords unless the remote directory provides new ones (#2319) - JMAP: Fix `ContactCard/set` and `CalendarEvent/set` destroy methods (#2308). ## [0.14.0] - 2025-10-22 If you are upgrading from v0.13.4 and below, this version includes **breaking changes** to the internal directory, calendar and contacts. Please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_14.md) for more information on how to upgrade from previous versions. ## Added - JMAP for Calendars ([draft-ietf-jmap-calendars](https://datatracker.ietf.org/doc/draft-ietf-jmap-calendars/)). - JMAP for Contacts ([RFC 9610](https://datatracker.ietf.org/doc/rfc9610/)). - JMAP for File Storage ([draft-ietf-jmap-filenode](https://datatracker.ietf.org/doc/draft-ietf-jmap-filenode/)). - JMAP Sharing ([RFC 9670](https://datatracker.ietf.org/doc/rfc9670/)) - CalDAV: support for `supported-calendar-component-set` (#1893) - i18n: Greek language support (contributed by @infl00p) - i18n: Swedish language support (contributed by @purung) ## Changed - **Breaking Database Changes** (migrated automatically on first start): - Internal directory schema changed. - Calendar and Contacts storage schema changed. - Sieve scripts storage schema changed. - Push Subscriptions storage schema changed. - Replaced `sieve.untrusted.limits.max-scripts` and `jmap.push.max-total` with `object-quota.*` settings. - Cluster node roles now allow sharding. ## Fixed - Push Subscription: Clean-up of expired subscriptions and cluster notification of changes (#1248) - CalDAV: Per-user CalDAV properties (#2058) ## [0.13.4] - 2025-09-30 If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added ## Changed - JMAP: Protocol layer rewrite for zero-copy deserialization and architectural improvements. ## Fixed - IMAP: Unbounded memory allocation in request parser ([CVE-2025-61600 ](https://github.com/stalwartlabs/stalwart/security/advisories/GHSA-8jqj-qj5p-v5rr)). - IMAP: Wrong permission checked for GETACL. - JMAP: References to previous method fail when there are no results (#1507). - JMAP: Enforce quota checks on `Blob/copy`. - JMAP: `Mailbox/get` fails without `accountId` argument (#1936). - JMAP: Do not return `invalidProperties` when email update doesn't contain changes (#1139) - iTIP: Include date properties in `REPLY` (#2102). - OIDC: Do not set `username` field if it is the same as the `email` field. - Telemetry: Fix `calculateMetrics` housekeeper task (#2155). - Directory: Always use `rsplit` to extract the domain part from email addresses. ## [0.13.3] - 2025-09-10 If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - CLI: Health checks (contributed by @Codekloeppler) ## Changed - WebDAV: Assisted discovery v2 ## Fixed - iTIP: Do not send a REPLY when deleting an event that was not accepted. - iTIP: Include event details in REPLY messages (#2102). - iTIP: Add organizer to iMIP replies if missing to deal with MS Exchange 2010 bug. - OIDC: Do not overwrite locally defined aliases (#2065). - HTTP: Scan ban should only be triggered by HTTP parse errors. - HTTP: Skip scanner fail2ban checks when the proxy client IP can't be parsed (#2121). - JMAP: Do not allow roles to be removed from system mailboxes (#1977). - JMAP WS: Fix panic when using invalid server url. - SMTP: Do no send `EHLO` twice when `STARTTLS` is unavailable (#2050). - IMAP: Allow `ENABLE UTF8` in IMAPrev1. - IMAP: Include `administer` permission in ACL responses. - IMAP: Add owner rights to ACL get responses. - IMAP: Do not auto-train Bayes when moving messages from Junk to Trash. - IMAP/ManageSieve: Increase maximum quoted argument size (#2039). - CalDAV: Limit recurrence expansions in calendar reports ([CVE-2025-59045](https://github.com/stalwartlabs/stalwart/security/advisories/GHSA-xv4r-q6gr-6pfg)). - WebDAV: Do not fix percent encoding on WebDAV FS (#2036). ## [0.13.2] - 2025-07-28 If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - ACME: DeSEC cloud DNS provider support (contributed by @Tyr3al). - ACME: OVH cloud DNS provider support (contributed by @srachner). - CalDAV Scheduling: Catalan language support (contributed by @jolupa) (#1873). - MTA: Allow to send e-mails as group, while member of that group (#485). - OIDC: Allow local access tokens to be used with third-party OIDC backends (#1311 stalwartlabs/webadmin#52). ## Changed - IMAP: Return `OK` when moving/copying non-existent messages (#670). - IMAP: Copy flags when copying/moving messages between accounts. ## Fixed - MTA: Do not convert e-mail local parts to lowercase (#1916). - Sieve: `fileinto` should override spam filter (#1917). - JMAP: Incorrect `accountId` used in email set and import methods (#1777). - WebDAV: Always return `MULTISTATUS` when calendar-query yields no results. - LDAP: Only set account name if not returned in LDAP query (#1471). - Enterprise: Invalidate logo cache when changes are made (#1856). - Enterprise: Fix tenant quota update API. ## [0.13.1] - 2025-07-16 If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - ACME: DigitalOcean cloud DNS provider support (#1667). ## Changed ## Fixed - Migration: Old queue events not deleted causing high CPU usage in some deployments (#1833). - MTA: `mta-sts` setting parsing issue (#1830). - JMAP: `sortOrder` should not be null (#1831). - Allow invalid TOML when parsing database settings (#1822). ## [0.13.0] - 2025-07-15 If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - MTA queue enhancements (#1246 #1035 #457). - Danish locale support (contributed by @Fadil2k) (#1772). - DKIM support for `stalwart-cli` (contributed by @rmsc) (#1804). ## Changed - Invalidate access token caches in a cluster using pub/sub (#1741). - Allow updating secrets for all directory types. ## Fixed - WebDAV: Return all shared resources in `calendar-home-set` and `addressbook-home-set` (#1796). - WebDAV ACL: Fix write permission and `multiget` reports (#1768). - CalDAV Scheduling: Include `DTSTART`/`DTEND` properties in iMIP `CANCEL` messages (#1775). - HTTP: Do not include `WWW-Authenticate` headers in API responses (#1795). - API: Allow API keys to be used with external directories (#1815). - IMAP: Fix issue creating subfolders under INBOX for group shared folder (#1817). - IMAP: Custom Name for Shared Folders ignored (#1620). - LDAP: `local` placeholder should return username when its not an email address (#1784). ## [0.12.5] - 2025-06-25 If you are upgrading from v0.11.x, this version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - Calendar Scheduling Extensions to CalDAV - RFC6368 (#1514) - Calendar E-Mail Notifications (#1514) - Limited i18n support for calendaring events. - Assisted CalDAV/CardDAV shared resource discovery (#1691). ## Changed - JMAP: Allow unauthenticated access to JMAP session object. ## Fixed - WebDAV: Return NOTFOUND error instead of MULTISTATUS on empty PROPFIND responses (#1657). - WebDAV: Update account name when refreshing DAV caches (#1694). - JMAP: Do not include email address in identity names (#1688). - IMAP: Normalize `INBOX` name when creating/renaming folders (#1636). - LDAP: Request `secret-changed` attribute in LDAP queries (#1409). - Branding: Unable to change logos (#1652). - Antispam: Skip `card-is-ham` override when sender does not pass DMARC (#1648). - FoundationDB: Renew old/expired FDB read transactions after the `1007` error code is received rather than estimating expiration time. ## [0.12.4] - 2025-06-03 If you are upgrading from v0.11.x, this version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - LDAP authentication enhancements (#1269 #1471 #795 #1496). - MTA: Return Queue IDs during message acceptance (#927). ## Changed - LDAP: `bind.auth.enable` is now `bind.auth.method`, read the updated [LDAP documentation](https://stalw.art/docs/auth/backend/ldap) for more information. ## Fixed - DNS: `hickory-resolver` bug hitting 100% CPU usage when resolving DNSSEC records. - IMAP: Return the message UID in the destination mailbox if the message already exists (#1201). - MTA: TLS reports being issued for sent TLS reports (infinite loop) (#1301). - WebDAV: Return `CTag` on `/dav/cal/account` resources to force iOS synchronize. - CardDAV: Strict vCard parsing (#1607). - WebDAV: Dead property updates (#1611). - WebDAV: Use last change id in `CTag`. ## [0.12.3] - 2025-05-30 If you are upgrading from v0.11.x, this version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - Store vanished IMAP UIDs and WebDAV paths in the changelog. ## Changed ## Fixed - XML `CDATA` injection (credits to @andreymal for the report). - Macro references are replaced with their content when writing config file (#1595). - Double nested CalDAV and CardDAV property tags (#1591). - Allow empty properties in PROPPATCH requests (#1580). ## [0.12.2] - 2025-05-27 If you are upgrading from v0.11.x, this version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added - CardDAV: Legacy vCard 2.1 and 3.0 serialization support. - WebDAV: Add SRV Records to help DAV autodiscovery (closes #1565). ## Changed ## Fixed - Report list attempts to deserialize empty values (#1562) - Refresh expired FoundationDB transactions while retrieving large blobs (#1555). ## [0.12.1] - 2025-05-26 If you are upgrading from v0.11.x, this version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ## Added ## Changed ## Fixed - Migration tool to generate the correct next id (#1561). - Failed to parse setting dav.lock.max-timeout (closes #1559). - Failed to build OpenTelemetry span exporter: no http client specified (#1571). ## [0.12.0] - 2025-05-26 This version includes **breaking changes** to the database layout and requires a migration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - [Collaboration](https://stalw.art/docs/collaboration/overview) features including [Calendars over CalDAV](https://stalw.art/docs/http/calendar/), [Contacts over CardDAV](https://stalw.art/docs/http/contact/) and [File Storage over WebDAV](https://stalw.art/docs/http/file-storage/). - Peer-to-peer [cluster coordination](https://stalw.art/docs/cluster/coordination/overview) or with Apache Kafka, Redpanda, NATS or Redis. - Incremental caching of emails, calendars, contacts and file metadata. - Zero-copy deserialization. - Train spam messages as ham when the sender is in the user's address book. - `XOAUTH2` SASL mechanism support (#1194 #1369). - Support for RFC9698, the `JMAPACCESS` Extension for IMAP. - Search index for accounts and other principals (#1368). - Add `description` property to OIDC ID token (#1234). ### Changed - Deprecated gossip protocol in favor of the new [coordinator](https://stalw.art/docs/cluster/coordination/overview) options. - Renamed Git repository from `stalwartlabs/mail-server` to `stalwartlabs/stalwart` and the Docker image from `stalwartlabs/mail-server` to `stalwartlabs/stalwart`. - Renamed multiple settings: - `server.http.*` to `http.*`. - `jmap.folders.*` to `email.folders.*`. - `jmap.account.purge.frequency` to `account.purge.frequency`. - `jmap.email.auto-expunge` to `email.auto-expunge`. - `jmap.protocol.changes.max-history` to `changes.max-history`. - `storage.encryption.*` to `email.encryption.*`. - Deprecated `lookup.default.*` settings in favor of `server.hostname` and `report.domain`. v0.11 and before supported both, v0.12 will only support the new settings. ### Fixed - Allow undiscovered UIDs to be used in IMAP `COPY`/`MOVE` operations (#1201). - Refuse loopback SMTP delivery (#1377). - Hide the current server version (#1435). - Use the newest `X-Spam-Status` Header (#1308). - MySQL Driver error: Transactions couldn't be nested (#1271). - Spawn a delivery thread for `EmailSubmission/set` requests (#1540). - ACME: Don't restrict challenge types (#1522). - Autoconfig: return `%EMAILADDRESS%` if no e-mail address is provided (#1537). ## [0.11.8] - 2025-04-30 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added ### Changed ### Fixed - Allow undiscovered UIDs to be used in `COPY`/`MOVE` operations (#1201). ## [0.11.7] - 2025-03-23 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - LDAP attribute to indicate password change (#1156). ### Changed - Lazy DKIM key parsing (#1211). - Enable `edns0` for system resolver by default (#1282). - Bump FoundationDB to `7.3`. ### Fixed - Fix incorrect `UIDNEXT` when mailbox is empty (#1201). - Sender variable not set when evaluating `must-match-sender` (#1294). - Do not panic when mailboxId is not found (#1293). - Prioritize local over span keys when serializing webhook payloads (#1250). - Allow TLS name mismatch as per RFC7671 Section 5.1. - Try with implicit MX when no MX records are found. - SQL `secrets` directory query. ## [0.11.5] - 2025-02-01 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added ### Changed - Open source third party OIDC support. ### Fixed - Case insensitive flag parsing (#1138). - BCC not removed from JMAP EmailSubmissions (#618). - Group pipelined IMAP FETCH and STATUS operations (#1096). ## [0.11.4] - 2025-01-29 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - RFC 9208 - IMAP QUOTA Extension (#484). ### Changed - `session.throttle.*` is now `queue.limiter.inbound.*`. - `queue.throttle.*` is now `queue.limiter.outbound.*`. - Changed DNSBL error level to debug (#1107). ### Fixed - Creating a mailbox in a shared folder results in wrong hierarchy (#1128). - IMAP LIST-STATUS (RFC 5819) returns items in wrong order (#1129). - Avoid non-RFC SMTP status codes (#1109). - Do not DNSBL check invalid domains (#1107). - Sieve message flag parser (#1059). - Sieve script import case insensitivity (#962). - `mailto:` parsing in HTMLs. ## [0.11.2] - 2025-01-17 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Automatic revoking of access tokens when secrets, permissions, ACLs or group memberships change (#649). - Increased concurrency for local message delivery (configurable via `queue.threads.local`). - Cluster node roles. - `config_get` expression function. ### Changed - `queue.outbound.concurrency` is now `queue.threads.remote`. - `lookup.default.hostname` is now `server.hostname`. - `lookup.default.domain` is now `report.domain`. ### Fixed - Distributed locking issues in non-Redis stores (#1066). - S3 incorrect backoff wait time after failures. - Panic parsing broken HTMLs. - Update CLI response serializer to v0.11.x (#1082). - Histogram bucket counts (#1079). - Do not rate limit trusted IPs (#1078). - Avoid double encrypting PGP parts encoded as plain text (#1083). - Return empty SASL challenge rather than "" (#1064). ## [0.11.0] - 2025-01-06 This version includes breaking changes to the configuration file, please read [UPGRADING.md](UPGRADING.md) for details. To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Spam filter rewritten in Rust for a significant performance improvement. - Multiple spam filter improvements (#947) such as training spam/ham when moving between inbox and spam folders (#819). - Improved distributed locking and handling of large distributed SMTP queues. - ASN and GeoIP lookups. - Bulk operations REST endpoints (#925). - Faster S3-FIFO caching. - Support adding the `Delivered-To` header (#916). - Semver compatibility checks when upgrading (#844). - Sharded In-Memory Store. ### Changed - Removed authentication rate limit (no longer necessary since there is fail2ban). - Pipes have been deprecated in favor of MTA hooks. ### Fixed - OpenPGP EOF error (#1024). - Convert emails obtained from external directories to lowercase (#1004). - LDAP: Support both name and email fields to be mapped to the same attribute. - Admin role can't be assigned if an account with the same name exists. - Fix macro detection in DNS record generation (#978). - Use host FQDN in install script (#1003). ## [0.10.7] - 2024-12-04 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Delivery and DMARC Troubleshooting (#420). - Support for external email addresses on mailing lists (#152). - Azure blob storage support. ### Changed ### Fixed - Some mails can't be moved out of the junk folder (#670). - Out of bound index error on Sieve script (#941). - Missing `User-Agent` header for ACME (#937). - UTF8 support in IMAP4rev1 (#948). - Account alias owner leak on autodiscover. - Include all events in OTEL traces + Include spanId in webhooks. - Implement `todo!()` causing panic on concurrency and rate limits. - Mark SQL store as active if used as a telemetry store. - Discard empty form submissions. ## [0.10.6] - 2024-11-07 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Enterprise license automatic renewals before expiration (disabled by default). - Allow to LDAP search using bind dn instead of auth bind connection when bind auth is enabled (#873) ### Changed ### Fixed - Include `preferred_username` and `email` in OIDC `id_token`. - Verify roles and permissions when creating or modifying accounts (#874) ## [0.10.5] - 2024-10-15 To upgrade replace the `stalwart-mail` binary. ### Added - Data store CLI. ### Changed ### Fixed - Tokenizer performance issue (#863) - Incorrect AI model endpoint setting. ## [0.10.4] - 2024-10-08 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Detect and ban port scanners as well as other forms of abuse (#820). - ACME External Account Binding support (#379). ### Changed - The settings `server.fail2ban.*` have been moved to `server.auto-ban.*`. - The event `security.brute-force-ban` is now `security.abuse-ban`. ### Fixed - Do not send SPF failures reports to local domains. - Allow `nonce` in OAuth code requests. - Warn when there are errors migrating domains rather than aborting migration. ## [0.10.3] - 2024-10-07 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. Enterprise users wishing to use the new LLM-powered spam filter should also upgrade the spam filter rules. ### Added - AI-powered Spam filtering and Sieve scripting (Enterprise feature). ### Changed - The untrusted Sieve interpreter now has the `vnd.stalwart.expressions` extension enabled by default. This allows Sieve users to use the `eval` function to evaluate expressions in their scripts. If you would like to disable this extension, you can do so by adding `vnd.stalwart.expressions` to `sieve.untrusted.disabled-capabilities`. ### Fixed - S3-compatible backends: Retry on `5xx` errors. - OIDC: Include `nonce` parameter in `id_token` response. ## [0.10.2] - 2024-10-02 To upgrade first upgrade the webadmin and then replace the `stalwart-mail` binary. If you read these instructions too late, you can upgrade to the latest web-admin using `curl -k -u admin:yourpass https://yourserver/api/update/webadmin`. ### Added - OpenID Connect server (#298). - OpenID Connect backend support (Enterprise feature). - OpenID Connect Dynamic Client Registration (#4) - OAuth 2.0 Dynamic Client Registration Protocol ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591)) (#136) - OAuth 2.0 Token Introspection ([RFC7662](https://datatracker.ietf.org/doc/html/rfc7662)). - Contact form submission handling. - `webadmin.path` setting to override unpack directory (#792). ### Changed ### Fixed - Missing `LIST-STATUS` from RFC5819 in IMAP capability responses (#816). - Do not allow tenant domains to be deleted if they have members (#812). - Tenant principal limits (#810). ## [0.10.1] - 2024-09-26 To upgrade replace the `stalwart-mail` binary. ### Added - `OAUTHBEARER` SASL support in all services (#627). ### Changed ### Fixed - Fixed `migrate_directory` range scan (#784). ## [0.10.0] - 2024-09-21 This version includes breaking changes to how accounts are stored. Please read [UPGRADING.md](UPGRADING.md) for details. ### Added - Multi-tenancy (Enterprise feature). - Branding (Enterprise feature). - Roles and permissions. - Full-text search re-indexing. - Partial database backups (#497). ### Changed ### Fixed - IMAP `IDLE` support for command pipelining, aka the Apple Mail iOS 18 bug (#765). - Case insensitive INBOX `fileinto` (#763). - Properly decode undelete account name (#761). ## [0.9.4] - 2024-09-09 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Support for global Sieve scripts that can be used by users to filter their incoming mail. - Allow localhost to override HTTP access controls to prevent lockouts. ### Changed - Sieve runtime error default log level is now `debug`. ### Fixed - Ignore INBOX case on Sieve's `fileinto` (#725) - Local keys parsing and retrieval issues. - Lookup reload does not include database settings. - Account count is incorrect. ## [0.9.3] - 2024-08-29 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Dashboard (Enterprise feature) - Alerts (Enterprise feature) - SYN Flood (session "loitering") attack protection (#482) - Mailbox brute force protection (#688) - Mail from is allowed (`session.mail.is-allowed`) expression (#609) ### Changed - `authentication.fail2ban` setting renamed to `server.fail2ban.authentication`. - Added elapsed times to message filtering events. ### Fixed - Include queueId in MTA Hooks (#708) - Do not insert empty keywords in FTS index. ## [0.9.2] - 2024-08-21 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Message delivery history (Enterprise feature) - Live tracing and logging (Enterprise feature) - SQL Read Replicas (Enterprise feature) - Distributed S3 Blob Store (Enterprise feature) ### Changed ### Fixed - Autodiscover request parser issues. - Do not create tables when using SQL as an external directory (fixes #291) - Do not hardcode logger id (fixes #348) - Include `Forwarded-For IP` address in `http.request-url` event (fixes #682) ## [0.9.1] - 2024-08-08 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Metrics support (closes #478) - OpenTelemetry Push Exporter - Prometheus Pull Exporter (closes #275) - HTTP endpoint access controls (closes #266 #329 #542) - Add `options` setting to PostgreSQL driver (closes #662) - Add `isActive` property to defaults on Sieve/get JMAP method (closes #624) ### Changed - Perform `must-match-sender` checks after sender rewriting (closes #394) - Only perform email ingest duplicate check on the target mailbox (closes #632) ### Fixed - Properly parse `Forwarded` and `X-Forwarded-For` headers (fixes #669) - Resolve DKIM macros when generating DNS records (fixes #666) - Fixed `is_local_domain` Sieve function (fixes #622) ## [0.9.0] - 2024-08-01 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. This version includes breaking changes to the Webhooks configuration and produces a slightly different log output, read [UPGRADING.md](UPGRADING.md) for details. ### Added - Improved and faster tracing and logging. - Customizable event logging levels. ### Changed ### Fixed - ManageSieve: Return capabilities after successful `STARTTLS` - Do not provide `{auth_authen}` Milter macro unless the user is authenticated ## [0.8.5] - 2024-07-07 To upgrade replace the `stalwart-mail` binary. ### Added - Restore deleted e-mails (Enterprise Edition only) - Kubernetes (K8S) livenessProbe and readinessProbe endpoints. ### Changed - Avoid sending reports for DMARC/delivery reports (#173) ### Fixed - Refresh old FoundationDB read transactions (#520) - Subscribing shared mailboxes doesn't work (#251) ## [0.8.4] - 2024-07-03 To upgrade replace the `stalwart-mail` binary. ### Added ### Changed ### Fixed - Fix TOTP validation order. - Increase Jemalloc page size on armv7 builds. ## [0.8.3] - 2024-07-01 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin. ### Added - Two-factor authentication with Time-based One-Time Passwords (#436) - Application passwords (#479). - Option to disable user accounts. ### Changed - DANE success on EndEntity match regardless of TrustAnchor validation. ### Fixed - Fix ManageSieve GETSCRIPT response: Add missing CRLF (#563) - Do not return CAPABILITIES after ManageSieve AUTH=PLAIN SASL exchange (#548) - POP3 QUIT must write a response (#568) ## [0.8.2] - 2024-06-22 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin and spam filter versions. ### Added - Webhooks support (#480) - MTA Hooks (like milter but over HTTP) - Manually train and test spam classifier (#473 #264 #257 #471) - Allow configuring default mailbox names, roles and subscriptions (#125 #290 #458 #498) - Include `robots.txt` (#542) ### Changed - Milter support on all SMTP stages (#183) - Do not announce `STARTTLS` if the listener does not support it. ### Fixed - Incoming reports stored in the wrong subspace (#543) - Return `OK` after a successful ManageSieve SASL authentication flow (#187) - Case-insensitive search in settings API (#487) - Fix `session.rcpt.script` default variable name (#502) ## [0.8.1] - 2024-05-23 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin and spam filter versions. ### Added - POP3 support. - DKIM signature length exploit protection. - Faster email deletion. - Junk/Trash folder auto-expunge and changelog auto-expiry (#403) - IP allowlists. - HTTP Strict Transport Security option. - Add TLS Reporting DNS entry (#464). ### Changed - Use separate account for master user. - Include server hostname in SMTP greetings (#448). ### Fixed - IP addresses trigger `R_SUSPICIOUS_URL` false positive (#461 #419). - JMAP identities should not return null signatures. - Include authentication headers and check queue quotas on Sieve message forwards. - ARC seal using just one signature. - Remove technical subdomains from MTA-STS policies and TLS records (#429). ## [0.8.0] - 2024-05-13 This version uses a different database layout which is incompatible with previous versions. Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - Clustering support with node auto-discovery and partition-tolerant failure detection. - Autoconfig and MS Autodiscover support (#336) - New variables `retry_num`, `notify_num`, `last_error` add `last_status` available in queue expressions. - Performance improvements, in particular for FoundationDB. - Improved full-text indexing with lower disk space usage. - MTA-STS policy management. - TLSA Records generation for DANE (#397) - Queued message visualization from the web-admin. - Master user support. ### Changed - Make `certificate.*` local keys by default. - Removed `server.run-as.*` settings. - Add Microsoft Office Macro types to bad mime types (#391) ### Fixed - mySQL TLS support (#415) - Resolve file macros after dropping root privileges. - Updated order of SPF Records (#395). - Avoid duplicate accountIds when using case insensitive external directories (#399) - `authenticated_as` variable not usable for must-match-sender (#372) - Remove `StandardOutput`, `StandardError` in service (#390) - SMTP `AUTH=LOGIN` compatibility issues with Microsoft Outlook (#400) ## [0.7.3] - 2024-05-01 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin version. ### Added - Full database export and import functionality - Add --help and --version command line arguments (#365) - Allow catch-all addresses when validating must match sender ### Changed - Add `groupOfUniqueNames` to the list of LDAP object classes ### Fixed - Trim spaces in DNS-01 ACME secrets (#382) - Allow only one journald tracer (#375) - `authenticated_as` variable not usable for must-match-sender (#372) - Fixed `BOGUS_ENCRYPTED_AND_TEXT` spam filter rule - Fixed parsing of IPv6 DNS server addresses ## [0.7.2] - 2024-04-17 To upgrade replace the `stalwart-mail` binary and then upgrade to the latest web-admin version. ### Added - Support for `DNS-01` and `HTTP-01` ACME challenges (#226) - Configurable external resources (#355) ### Changed ### Fixed - Startup failure when Elasticsearch is down/starting up (#334) - URL decode path elements in REST API. ## [0.7.1] - 2024-04-12 To upgrade replace the `stalwart-mail` binary. ### Added - Make initial admin password configurable via env (#311) ### Changed - WebAdmin download URL. ### Fixed - Remove ASN.1 DER structure from DKIM ED25519 public keys. - Filter out invalid timestamps on log entries. ## [0.7.0] - 2024-04-09 This version uses a different database layout and introduces multiple breaking changes in the configuration files. Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - Web-based administration interface. - REST API for management and configuration. - Automatic RSA and ED25519 DKIM key generation. - Support for compressing binaries in the blob store (#227). - Improved performance accessing IMAP mailboxes with a large number of messages. - Support for custom DNS resolvers. - Support for multiple loggers with different levels and outputs. ### Changed ### Fixed - Store quotas as `u64` rather than `u32`. - Second IDLE connections disconnects the first one (#280). - Use relaxed DNS parsing, allowing underscores in DNS labels (#172). - Escape regexes within `matches()` expressions (#155). - ManageSieve LOGOUT should reply with `OK` instead of `BYE`. ## [0.6.0] - 2024-02-14 This version introduces breaking changes in the configuration file. Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - Distributed and fault-tolerant SMTP message queues. - Distributed rate-limiting and fail2ban. - Expressions in configuration files. ### Changed ### Fixed - Do not include `STATUS` in IMAP `NOOP` responses (#234). - Allow multiple SMTP `HELO` commands. - Redirect OAuth using a `301` instead of a `307` code. ## [0.5.3] - 2024-01-14 Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - Built-in [fail2ban](https://stalw.art/docs/server/fail2ban) and IP address/mask blocking (#164). - CLI: Read URL and credentials from environment variables (#88). - mySQL driver: Add `max-allowed-packet` setting (#201). ### Changed - Unified storage settings for all services (read the [UPGRADING.md](UPGRADING.md) for details) ### Fixed - IMAP retrieval of auto-encrypted emails (#203). - mySQL driver: Parse `timeout.wait` property as duration (#202). - `X-Forwarded-For` header on JMAP Rate-Limit does not work (#208). - Use timeouts in install script (#138). ## [0.5.2] - 2024-01-07 Please read the [UPGRADING.md](UPGRADING.md) file for more information on how to upgrade from previous versions. ### Added - [ACME](https://stalw.art/docs/server/tls/acme) support for automatic TLS certificate generation and renewal (#160). - TLS certificate [hot-reloading](https://stalw.art/docs/management/database/maintenance#tls-certificate-reloading). - [HAProxy protocol](https://stalw.art/docs/server/proxy) support (#36). ### Changed ### Fixed - IMAP command `SEARCH ` is using UIDs rather than sequence numbers. - IMAP responses to `APPEND` and `EXPUNGE` should include `HIGHESTMODSEQ` when `CONDSTORE` is enabled. ## [0.5.1] - 2024-01-02 ### Added - SMTP smuggling protection: Sanitization of outgoing messages that do not use `CRLF` as line endings. - SMTP sender validation for authenticated users: Added the `session.auth.must-match-sender` configuration option to enforce that the sender address used in the `MAIL FROM` command matches the authenticated user or any of their associated e-mail addresses. ### Changed ### Fixed - Invalid DKIM signatures for empty message bodies. - IMAP command `SEARCH BEFORE` is not properly parsed. - IMAP command `FETCH` fails to parse single arguments without parentheses. - IMAP command `ENABLE QRESYNC` should also enable `CONDSTORE` extension. - IMAP response to `ENABLE` command does not include enabled capabilities list. - IMAP response to `FETCH ENVELOPE` should not return `NIL` when the `From` header is missing. ## [0.5.0] - 2023-12-27 This version requires a database migration and introduces breaking changes in the configuration file. Please read the [UPGRADING.md](UPGRADING.md) file for more information. ### Added - Performance enhancements: - Messages are parsed only once and their offsets stored in the database, which avoids having to parse them on every `FETCH` request. - Background full-text indexing. - Optimization of database access functions. - Storage layer improvements: - In addition to `FoundationDB` and `SQLite`, now it is also possible to use `RocksDB`, `PostgreSQL` and `mySQL` as a storage backend. - Blobs can now be stored in any of the supported data stores, it is no longer limited to the file system or S3/MinIO. - Full-text searching con now be done internally or delegated to `ElasticSearch`. - Spam databases can now be stored in any of the supported data stores or `Redis`. It is no longer necessary to have an SQL server to use the spam filter. - Internal directory: - User account, groups and mailing lists can now be managed directly from Stalwart without the need of an external LDAP or SQL directory. - HTTP API to manage users, groups, domains and mailing lists. - IMAP4rev1 `Recent` flag support, which improves compatibility with old IMAP clients. - LDAP bind authentication, to support some LDAP servers such as `lldap` which do not expose the userPassword attribute. - Messages marked a spam by the spam filter can now be automatically moved to the account's `Junk Mail` folder. - Automatic creation of JMAP identities. ### Changed ### Fixed - Spamhaus DNSBL return codes. - CLI tool reports authentication errors rather than a parsing error. ## [0.4.2] - 2023-11-01 ### Added - JMAP for Quotas support ([RFC9425](https://www.rfc-editor.org/rfc/rfc9425.html)) - JMAP Blob Management Extension support ([RFC9404](https://www.rfc-editor.org/rfc/rfc9404.html)) - Spam Filter - Empty header rules. ### Changed ### Fixed - Daylight savings time support for crontabs. - JMAP `oldState` doesn’t reflect in `*/changes` (#56) ## [0.4.1] - 2023-10-26 ### Added ### Changed ### Fixed - Dockerfile entrypoint script. - `bayes_is_balanced` function. ## [0.4.0] - 2023-10-25 This version introduces some breaking changes in the configuration file. Please read the [UPGRADING.md](UPGRADING.md) file for more information. ### Added - Built-in Spam and Phishing filter. - Scheduled queries on some directory types. - In-memory maps and lists containing glob or regex patterns. - Remote retrieval of in-memory list/maps with fallback mechanisms. - Macros and support for including files from TOML config files. ### Changed - `config.toml` is now split in multiple TOML files for better organization. - **BREAKING:** Configuration key prefix `jmap.sieve` (JMAP Sieve Interpreter) has been renamed to `sieve.untrusted`. - **BREAKING:** Configuration key prefix `sieve` (SMTP Sieve Interpreter) has been renamed to `sieve.trusted`. ### Fixed ## [0.3.10] - 2023-10-17 ### Added - Option to allow invalid certificates on outbound SMTP connections. - Option to disable ansi colors on `stdout`. ### Changed - SMTP reject messages are now logged as `info` rather than `debug`. ### Fixed ## [0.3.9] - 2023-10-07 ### Added - Support for reading environment variables from the configuration file using the `!ENV_VAR_NAME` special keyword. - Option to disable ANSI color codes in logs. ### Changed - Querying directories from a Sieve script is now done using the `query()` method from `eval`. Your scripts will need to be updated, please refer to the [new syntax](https://stalw.art/docs/smtp/filter/sieve#directory-queries). ### Fixed - IPrev lookups of IPv4 mapped to IPv6 addresses. ## [0.3.8] - 2023-09-19 ### Added - Journal logging support - IMAP support for UTF8 APPEND ### Changed - Replaced `rpgp` with `sequoia-pgp` due to rpgp bug. ### Fixed - Fix: IMAP folders that contain a & can't be used (#90) - Fix: Ignore empty lines in IMAP requests ## [0.3.7] - 2023-09-05 ### Added - Option to disable IMAP All Messages folder (#68). - Option to allow unencrypted SMTP AUTH (#72) - Support for `rcpt-domain` key in `rcpt.relay` SMTP rule evaluation. ### Changed ### Fixed - SMTP strategy `Ipv6thenIpv4` returns only IPv6 addresses (#70) - Invalid IMAP `FETCH` responses for non-UTF-8 messages (#70) - Allow `STATUS` and `ACL` IMAP operations on virtual mailboxes. - IMAP `SELECT QRESYNC` without specifying a UID causes panic (#67) - Milter `DATA` command is sent after headers which causes ClamAV to hang. - Sieve `redirect` of unmodified messages does not work. ## [0.3.6] - 2023-08-29 ### Added - Arithmetic and logical expression evaluation in Sieve scripts. - Support for storing query results in Sieve variables. - Results of SPF, DKIM, ARC, DMARC and IPREV checks available as environment variables in Sieve scripts. - Configurable protocol flags for Milter filters. - Fall-back to plain text when `STARTTLS` fails and `starttls` is set to `optional`. ### Changed ### Fixed - Do not panic when `hash = 0` in reports. (#60) - JMAP Session resource returns `EmailSubmission` capabilities using arrays rather than objects. - ManageSieve `PUTSCRIPT` should replace existing scripts. ## [0.3.5] - 2023-08-18 ### Added - TCP listener option `nodelay`. ### Changed ### Fixed - SMTP: Allow disabling `STARTTLS`. - JMAP: Support for `OPTIONS` HTTP method. ## [0.3.4] - 2023-08-09 ### Added - JMAP: Support for setting custom HTTP response headers (#52) ### Changed ### Fixed - SMTP: Missing envelope keys in rewrite rules (#25) - SMTP: Remove CRLF from Milter headers - JMAP/IMAP: Successful authentication requests should not count when rate limiting - IMAP: Case insensitive Inbox selection - IMAP: Automatically create Inbox for group accounts ## [0.3.3] - 2023-08-02 ### Added - Encryption at rest with **S/MIME** or **OpenPGP**. - Support for referencing context variables from dynamic values. ### Changed ### Fixed - Support for PKCS8v1 ED25519 keys (#20). - Automatic retry for import/export blob downloads (#14) ## [0.3.2] - 2023-07-28 ### Added - Sender and recipient address rewriting using regular expressions and sieve scripts. - Subaddressing and catch-all addresses using regular expressions (#10). - Dynamic variables in SMTP rules. ### Changed - Added CLI to Docker container (#19). ### Fixed - Workaround for a bug in `sqlx` that caused SQL time-outs (#15). - Support for ED25519 certificates in PEM files (#20). - Better handling of concurrent IMAP UID map modifications (#17). - LDAP domain lookups from SMTP rules. ## [0.3.1] - 2023-07-22 ### Added - Milter filter support. - Match IP address type using /0 mask (#16). ### Changed ### Fixed - Support for OpenLDAP password hashing schemes between curly brackets (#8). - Add CA certificates to Docker runtime (#5). ## [0.3.0] - 2023-07-16 ### Added - **LDAP** and **SQL** authentication. - **subaddressing** and **catch-all** addresses. - **S3-compatible** storage. ### Changed - Merged the `stalwart-jmap`, `stalwart-imap` and `stalwart-smtp` repositories into `stalwart-mail`. - Removed clustering module and replaced it with a **FoundationDB** backend option. - Integrated Stalwart SMTP into Stalwart JMAP. - Rewritten JMAP protocol parser. - Rewritten store backend. - Rewritten IMAP server to have direct access to the message store (no more IMAP proxy). - Replaced `actix` with `hyper`. ### Fixed