This is a third security release in the continuation of 1.30.x, mostly to address some severe PHP vulnerabilities and update our official default Docker images (Debian) (but not our alternative Alpine images yet, which are delayed).
Note that our rolling-release channel (edge) is recommended for faster security patches.
docs: contributor docs are excluded from prettier checks (#28062)
lint: eslint fails to parse vitest.config.ts in admin/server packages (#28064)
lint: extra-policy oxlint perf on the blocking gate (#27671)
review-workflows: migrate unit tests from jest to vitest (#27388)
review-workflows: stop passing ignored populate to workflow create and update (#27865)
types: centralise the window.strapi type in @strapi/types (#26213)
upload: enforce the media MCP ambient guard by construction (#27617)
π Enhancement
database: describe connection pool timeouts (#28000)
utils: avoid rebuilding curried traversal wrappers on every call (#27947)
utils: remove per-key allocations from the query traversal (#27233)
β οΈ Changes to be aware of
Database driver update (knex 3.3.0)
Custom code that uses strapi.db.connection and calls delete() with limit or having, or truncate() with where, having or limit, now throws on PostgreSQL and SQLite. MySQL now applies the LIMIT. Before, the limit was ignored and every matching row was deleted, so check plugins or scripts that build such queries. Connection pool timeout errors now include the underlying connection error, and knex warnings now appear in the Strapi log as [database] knex: β¦.
Token and role names are limited to 255 characters
The name and description of API tokens, admin tokens, transfer tokens and admin roles now accept at most 255 characters. Longer values get a validation error under the field. Before, PostgreSQL returned a generic server error. Existing tokens with longer values keep working, but the admin rejects that long text on save until you shorten it.
Strapi now uses undici 8, which requires Node.js 22.19.0 or later. The engines field still says >=20.0.0, so check your runtime: this release was only tested on Node 22.20 and later.
The upload plugin now applies sharp.limitInputPixels. Strapi refuses to start if the value is not true, false or an integer of 0 or more. A value read straight from an environment variable is a string, so use env.int().
Known issue: deleting an entry changes past releases
When you delete an entry that belongs to a release that was already published, the entry is removed from that release, and the release status changes from "done" to "empty" or "ready". The published content is not affected. This already happened for localized entries, and it now happens for all entries.
In Settings > Webhooks, if you clear the last header row and type a new header name, the old text can stay in front of it (for example X-CX-D instead of X-D). Check the header names before you save.
1.16.0 regroups the settings into fewer pages with an Advanced switch for the power-user options, shows the message list as columns on request, turns @mentions into contact chips, and opens the company directory in contacts and the composer. The marketplace can install any version of an extension and roll back to a replaced one, admins get policies for the colour mode, archiving and the provider sign-out, and the Estonian locale arrives. A security audit of the whole app fixed cross-account actions on repeated message ids and about thirty smaller findings.
Mail: Delete, move and drag in merged views and cross-account search act on the clicked message. When two accounts had messages with the same id, the action could hit the other account's message, which also made sent mail vanish from the Sent folder (#857, GHSA-8x23-qw3w-mhrx, thanks @FeliceBalsamo and @knittingcode)
Mail: HTML attachments preview as sanitised text in a locked frame. The preview used to open the sender's HTML as a same-origin document that could run script in the webmail origin
Mail: A crafted style attribute, read-receipt header, mail body or subject no longer freezes the reader or the message list
Mail: Only an SPF or DKIM pass aligned with the From domain counts as sender verification, and oversized winmail.dat and embedded message parts stay attachments instead of being decoded on open
Mail: Attachment names show without directional override characters, and imported and synced HTML templates are sanitised before the composer previews them
Login: The login page asks before handing a sign-in to the mobile app, and only hands it to the app's own callback link
Login: Failed sign-ins are capped per client at 5 in 15 minutes, and the client address is forwarded to the mail server as X-Forwarded-For so the server's own limits hit the client instead of the webmail. Add the webmail to Stalwart's server.proxy.trusted-networks for that to take effect
Login: Synced settings are keyed on the account a token login resolves to, not on the claimed name, so two users can no longer share a settings blob
Admin: OAuth client secrets and the session secret stay out of the admin audit log, the config API and dashboard writes
Admin: OAuth discovery no longer follows a redirect to another host, the extension directory URL cannot point at a private address, a directory keyring older than the newest one seen is refused, marketplace versions are validated and a silent downgrade on update is refused, and the installer writes its env file readable by its owner only
Plugins: Plugin POSTs stay off the plugin proxy, secrets, agenda, ical and translate routes, only a plugin known to the server can connect and use credentials, plugin-authored HTML drops remote images, and a plugin frame that navigated to another document gets no more host messages
Server: TLS responses carry HSTS and the X-Powered-By header is gone. Upstream mail server requests get a deadline, CalDAV discovery probes and concurrent favicon fetches are bounded, and calendar feeds, synced settings blobs and the settings route have size caps
Features
Settings: The settings are regrouped into Account, Security, Notifications, General and Appearance, the mail pages Message list, Reading, Composing, Folders & tags, Filters and Out of office, then Calendar, Contacts, Files and Add-ons with the plugin pages under it, and Backup & reset. Every page has a jump row to its sections, settings links can name a section, and old settings links keep working
Settings: An Advanced switch hides power-user settings until turned on. Search results and section links that point at a hidden setting turn it on
Settings: Themes show as one row with a Show all button, and the settings search box looks like the mail search box
UI: The message list can show as columns with one-line conversation rows (#262, thanks @fdisamuel)
Composer: Typing @ offers contacts and adds the picked one as a recipient. Mentions become chips with a contact card on hover, in the composer and in received mail
Contacts: The company directory can be browsed in contacts and the composer (#1253, thanks @diegonix)
Mail: "Remove from this folder" takes a message out of just the open folder when it is in several (#615, thanks @arnauda-gh)
Mail: n jumps to the next unread message (#514, thanks @muelli)
Mail: Shift+arrow keys extend the selection (#992, thanks @IntExCZ), and while selecting, a click anywhere on a row ticks it (#1014, thanks @mmomjian)
Mail: Search results from all folders show the folder (#1172, thanks @PoltoS)
Mail: Your own folders are listed in a separate section of the sidebar (#1205, thanks @roedy-dev)
Mail: The counter can be set per folder, e.g. keep the Drafts count with totals off (#982, thanks @mbjboon-netizen)
Mail: The account dot in the unified view can be hidden (#912, thanks @mmomjian)
Mail: Sender icons are refreshed when they changed on the sender's website (#960, thanks @IntExCZ)
Composer: Templates get numeric date, day, month and year placeholders (#1284, thanks @Yahatix)
Accounts: When the admin turns on "Account List Backup: Passwords", saving the account list offers to include the passwords of accounts signed in with a plain password, encrypted in the browser. Restoring signs those accounts in in the background (#1247, thanks @lucamzanon)
Admin: The theme policy can set and lock the colour mode (#1280, thanks @chodid)
Admin: A configured logout URL ends the provider session for providers whose discovery has no end_session_endpoint (#1279, thanks @chodid)
Admin: The admin panel asks before leaving with unsaved changes (#1255, thanks @passibe15)
Admin: The version is hidden from the connector probe when the login page hides it (#896, thanks @x86dev)
Marketplace: Any version of an extension can be installed. The detail page lists every version, previews the picked one and warns about withdrawn versions, advisories, deprecations and suspensions, the listing can be sorted and filtered to installed extensions with an updates strip, and an install link can name the version to offer
Marketplace: Replaced plugin and theme versions are kept and can be rolled back to
Plugins: The UI kit gets a Combobox (#1251, thanks @tobiasge)
Translations: Estonian is a new locale, including the company directory and the strings added since (#1254, thanks @raudraido)
Demo: The demo follows one persona with a work account, a personal account and a shared Support mailbox, with real headers, an invitation, mentions, tags, templates and files
Changes
Marketplace: The marketplace talks to the extension directory's v2 API only. A self-hosted directory older than 2026-10-14 no longer works with it
Plugins: A user credential now exists only for a registry plugin or an admin-approved upload whose manifest declares it. Approvals made before this version need a fresh approval request before the plugin can use credentials
UI: The whole app uses the theme's sans font (#1278, thanks @chodid)
UI: The app switcher uses simpler calendar, contacts and files icons, and the calendar, contacts, files and settings sidebar headers have the mail header's height
Performance: Starting a search no longer re-renders every row
Fixes
Mail: Push notifications can be enabled for an account with access to a shared folder (#1050, thanks @magnetic6)
Mail: The list shows the mail's own date and keeps it on .eml import (#891, thanks @johnnyq)
Mail: PGP and S/MIME messages inside conversations are decrypted (#902, thanks @rajil)
Mail: Attachments preview in the installed app instead of opening a blank window (#865, thanks @navidrast)
Mail: Message previews drop plain-text emphasis markers (#1260, thanks @mmomjian)
Mail: Today's and yesterday's mail are told apart by the time zone setting in the list and the sender line (#1259, #1262, thanks @mmomjian and @balabommablock-cpu)
Mail: The category tab filter is kept when the mailbox refreshes, and the whole folder comes back after a restart when a category tab was open (#1264, #1265, thanks @alyyousuf7)
Mail: Shared folders from other servers are kept when they reuse an account id, and a shared folder reachable through two logins is listed once in cross views (#1108, thanks @hildebrandttk)
Mail: Renaming a tag follows it into the filter rules that name it, and keeps vacation forwarding and plugin vetoes while doing so (#854, thanks @dev-hive-kazniisa)
Mail: Bulk archive across accounts is routed by the owning account, and Archive is only created where the account allows it (#1178, thanks @VasilisNtovolos)
Mail: Conversation blobs are fetched from the message they belong to, and file previews stay open in development Strict Mode (#1287, #1288, thanks @VasilisNtovolos)
Mail: A shared conversation is marked read on the owner account, and the mark-as-read delay is followed when expanding a conversation or opening a Pro folder row (#1272, thanks @Peterka35)
Mail: The reader's Move, Tag and Rules flyouts open on the side with room (#1261, thanks @beja19)
Mail: Vacation filter rules are skipped on shared accounts without Sieve (#1263, thanks @somus)
Mail: Nextcloud filter markers inside rule text are ignored
Composer: A reply to a message from another connected account is sent from that account to the right recipient (#703, #1270, thanks @jesperordrup and @vixh)
Composer: Replies whose From is picked after the composer opens are signed (#842, thanks @mmomjian)
Composer: A contact group whose member is not an address is no longer sent (#795, thanks @brambuijs)
Composer: Your own address stays out of reply-all before your identities have loaded (#803, thanks @lucletoffe)
Composer: Sent mail keeps blank lines instead of collapsing them (#1015, thanks @mbjboon-netizen)
Composer: Inline images in replies and forwards are attached once (#1125, thanks @guisea)
Composer: The quote containment styles stay in the editor and out of the sent mail, and a quoted original can no longer paint over the composer
Composer: The composer opens when the mail client can't report directory support
Composer: A click on a mention chip opens the contact card instead of the mailto handler in Firefox
Calendar: Zero-length events end at their start instead of midnight (#837, thanks @Flying-Bas)
Calendar: Invitation times show in your time zone (#1252, thanks @TomekCodeWave)
Calendar: Answering an invite sent to a non-primary identity works (#1283, thanks @taranasus)
Calendar: The visible range is refetched after creating a recurring event (#1268, thanks @sanitz)
Calendar: Month view day columns align with the header (#1286, thanks @tobiasge)
Tasks: An all-day task's due and start are sent as a LocalDateTime (#1256, thanks @sanitz)
Notifications: Push notifications stay silent when the notification sound is off (#1289, thanks @chreds)
Admin: The admin panel loads when the config is read-only, policy defaults are applied to user settings, and OAuth auto-setup is refused before touching Stalwart when the config is read-only (#1248, #1249, #1250, thanks @chodid)
Accounts: Restored sign-ins are remembered only when the restoring account is remembered, and contact and calendar data that arrives after switching accounts is dropped instead of landing in the other account
Plugins: api.email.get reads a listed message of a shared account and no longer reads mail of other connected logins (#1273, #1274, thanks @alyyousuf7)
Plugins: A plugin slot's callbacks keep working when its props change while it loads (#1266, thanks @dedoitalia)
Plugins: Plugin dropdown messages are checked before the host draws them
Lite: Demo portraits load from the mount prefix so a bundle under a subpath stays self-contained, and the dev server stays inside its export directory
Translations: German strings that still showed in English (#1285, thanks @dealerweb), contact field types and more French strings
If you like Part-DB, consider donating to support the development. Press the sponsor button on the main github page, for more info.
Note
If you are using Part-DB it would be helpful if you fill out this short survey on your usage of Part-DB (Google Forms): https://forms.gle/Q15twx3YYq3qCNfe8
Part-DB 2.20.2
New features / Improvements
Added form to directly create parts from info providers using a known ID (#1605)
Allow to paste files from clipboard into the URL field of attachments to upload them
Allow to create new attachments from an image in the clipboard
Added an "Export as CSV (formula escaped)" mode to avoid formula injection when importing CSVs into excels
1.15.0 opens the plugin system up: plugins can add UI in most places of the app, hear and stop most actions, and use accounts and API keys through the server without seeing them, and users can install their own plugins once an admin has reviewed the code. Opening folders and messages is faster, with far fewer re-renders and requests. Calendars get default reminders, notifications can be muted per folder or account, and every sign-in is now remembered unless the admin shows the Remember me box.
Notifications: Folders and whole accounts can be muted from the folder context menu. A muted folder or account sends no push notifications and shows a muted mark in the sidebar (#1169, thanks @xnilsit)
Calendar: Each calendar has default reminders, set in calendar management. New events start on them, an event that switches back to the defaults picks up the current ones, and the event popover lists every reminder (#1209, thanks @rich0)
Calendar: Each reminder can be a notification or an email (#1209, thanks @rich0)
Accounts: Shared mail accounts can be hidden from the sidebar, from their context menu or under Settings > Layout (#1228, thanks @chodid)
Mail: The prompt before deleting several messages can be turned off (#1225, thanks @mmomjian)
UI: In Mountain View, several messages of a conversation can be open at once, the compose window stays open while reading other mail, and the selection is kept while reading a message (#1222, #1229, #1231, thanks @mmomjian)
UI: Ctrl+K opens a command palette, and a notifications panel collects plugin notifications and app errors
Admin: "Custom From Address" under Admin > Policy turns off the free-text sender address in the composer, so users can only send as their identities
Admin: Without a configured SESSION_SECRET, one is generated on first start and kept in data/admin-state. Keep that folder on a persistent volume
Plugins: Users can install their own plugins from Settings > Plugins when the admin allows uploads. The server reads the manifest and code itself, the admin reviews the actual code in the Plugins tab before approving, and the approval is checked again on every start. Settings lists in plain words what each plugin may do
Plugins: Plugins can add UI to the message list, reader, composer, sidebar, top bar, calendar, contacts, tasks, files and settings, and pages of their own with a navigation entry. Every area has its own permission
Plugins: Plugins are told about sign-in, navigation, mail, folder, calendar, contact, task, file, template, identity, filter, preference and theme changes, and can stop most of them
Plugins: Plugins can read messages and folders, move and archive messages, open a filled-in composer or a reply, edit the message being written, save drafts, read and change events and tasks, and manage templates, signatures and the out-of-office reply
Plugins: Users connect accounts for plugins in a dialog the plugin can't read, and plugins use those accounts and admin-set API keys through the server without seeing them
Plugins: The UI kit gives plugins the app's own controls and dialogs, plus side panels, detail rows, colour dots, labelled check boxes and a change preview
Plugins: Marketplace installs check the extension directory's signature
Changes
Login: The Remember me box is hidden by default and every sign-in is remembered. Set LOGIN_SHOW_REMEMBER_ME=true to show the box again
Performance: Opening a message, switching folders and searching render much less. Message rows, the folder sidebar and the reading pane only redraw what changed, a visited folder reopens without reloading, and a message starts loading when the mouse is pressed on it
Performance: Login loads the mailboxes and first page once instead of twice, the mail view's code loads while the login form is shown, and large HTML messages open with one request instead of two
Performance: Search results show before their highlighted excerpts arrive, and the list stays on screen while a search runs
Fixes
Send: Attachments stay sendable after the server's upload time limit runs out (#1243, thanks @lemourin)
Send: Uploads over 10 MB that pass through the server, such as office documents saved from the editor, are no longer cut off
Login: The sign-in response stays small enough for proxies when OIDC tokens are large, so logins on a subdomain no longer fail with a 502 (#1237, thanks @kadogams)
Login: Lite reloads into the login page instead of a missing route
Mail: The storage quota counts against the soft limit when the server sets one (#1242, thanks @somus)
Mail: The All mail and All unread views leave out a server's own "all" mailbox (#1241, thanks @somus)
Mail: Contacts, filters, calendars and files are only offered for shared accounts that support them (#1239, thanks @somus)
Mail: User folders named like system folders, such as "Spam reports", get the plain folder icon (#1235, thanks @dlrudie)
Mail: ISO timestamps are no longer offered as verification codes (#1236, thanks @mmomjian)
Mail: Shift-click selects the rows shown between the two ends instead of messages in other conversations from that time span (#1230, thanks @mmomjian)
Mail: The message list no longer reorders or repaints when switching accounts, and the loading skeleton no longer flickers after a reload or account switch
Mail: In Mountain View, a message opens together with its conversation, and threads open as a conversation on the phone (#1223, #1224, thanks @mmomjian)
Identities: A new identity is created without blank signatures (#1240, thanks @somus)
Composer: A cell range pasted from Excel becomes a table instead of an image (#1233, thanks @soringabrielalbu)
Composer: Text typed under the signature stays when the signature is swapped or removed, and picking a From address without a signature removes the old one
Composer: Dropped files no longer insert their path into the message body
Composer: The top and bottom bar buttons are easier to hit on a phone
Calendar: Invitations and replies carry the sender's Message-ID
Contacts: The contact name stays readable when the detail pane is narrow
UI: The iOS app gets its full screen height back after resuming (#1226, thanks @mmomjian)
UI: An attachment's download and menu buttons show when the keyboard reaches them
Plugins: A message is never sent when a plugin that checks it before sending fails or does not answer, and plugins can no longer block or stall sign-out
Plugins: Privileged plugins need a signed bundle, plugin network access is limited to the origins in the manifest, plugin bundles are only served to signed-in users, and slot plugins only get messages, events or contacts with the matching read permission
Plugins: Plugin and theme packages are checked the same way on every install path, marketplace bundles whose id differs from the directory entry are refused, and Theme API v2 themes install from the admin page and the marketplace
Plugins: A deleted or disabled theme is no longer forced, an extension keeps its admin state on re-upload, and a plugin's stored data is cleared when the admin removes it
Plugins: Plugins start once on every page, get their default settings, follow setting and language changes without a reload, and lay out right-to-left in Arabic, Hebrew and Persian
Plugins: Actions a plugin stopped are no longer reported as done
Plugins: Plugin buttons and panels fold away in narrow composers, toolbars and phone layouts instead of overlapping, and plugin frames keep the app's theme in dark mode
Translations: The new plugin, calendar reminder and notification strings are translated, and "composer" and the certificate subject are no longer translated as a music composer and an email subject
This release fixes backup handling across older Docker daemons and S3, improves health and scheduler reliability, and reduces live-stats rendering costs.
Backups and storage
Bind-mount volume subpaths when backing up on daemons older than API 1.45. (#4399) @kmendell
Send S3 request checksums only when required, improving GCS compatibility. (#4401) @kmendell
Write S3-only system backups directly to S3 without a local repository. (#4400) @kmendell
Include the absolute path and UID in project-directory permission errors. (#4404) @kmendell
Containers, projects, and scheduling
Report Francis as down when its host exits and extend its health-check deadline. (#4402) @kmendell
Exclude Swarm task containers from the standalone-container filter. (#4405) @kmendell
Preserve build image references when Compose fails to load, and document the update-check label. (#4406) @kmendell
Reset invalid cron settings to defaults at startup. (#4425) @kmendell
Clear caches when refreshing a workspace. (#4427) @kmendell
Allow manual updates for services with the updater disabled. (#4430) @kmendell
Registries, updates, and access
Retry digest lookups after TLS handshake timeouts. (#4428) @kmendell
Remove the stale digest name left behind when a frozen pull is tagged. (#4409) @kmendell
Stop resending image-update push notifications on every poll. (cd7c39cfcb6c364751d4b55bab887c11b5ebd859) @kmendell
Restrict SSH host-key algorithms to entries in known_hosts. (#4403) @kmendell
Match user email lookups without regard to case. (#4429) @kmendell
Interface and performance
Fix virtualized table cells being clipped by locking column widths in pixels. (#4407) @kmendell
Localize settings backup cards and role presets, and prevent long labels from overflowing. (#4408) @kmendell
Batch live stats by environment to reduce table rendering costs. (3330f4e0f53bb152cc4720be8ae724cdb1bd8cbb) @kmendell
Maintenance
Merge all-environment resource lists on the server. (#4419) @kmendell
Simplify registry helpers with composite literals and inline helpers. (00daf4441a6724cc9ff991f2927d73dcd61f4b89) @kmendell
This release adds OpenTelemetry support, a redesigned multiplexed edge tunnel, and useful CLI previews and self-update tooling. It also improves container and project workflows while fixing issues across authorization, databases, and connectivity.
Interface and container workflows
Prevent duplicate role assignments from causing a 500 in the user editor. (#4332; @DominikZublasing)
If you like Part-DB, consider donating to support the development. Press the sponsor button on the main github page, for more info.
Note
If you are using Part-DB it would be helpful if you fill out this short survey on your usage of Part-DB (Google Forms): https://forms.gle/Q15twx3YYq3qCNfe8
Part-DB 2.20.1
Improvements
Prefetch tree view links on hover (instantclick similar to normal links). that should make feel the UI more responsive
Removed redundant render call for empty datatables
Make IC logo tool images lazy loading
Bug fixes
Fix Generic Web imports of offers without a price by @00200200 in #1596
Fixed generic web provider compatibility with websites that return incorrect data (#1595)
Other changes
Update KiCad symbols and footprints lists by @jbtronics in #1597
1.14.2 brings Mountain View closer to Gmail: the open message shows the whole conversation, replies are written in place under it, and a side panel holds calendar, tasks and contacts. Tasks can now be moved into calendars shared with you, and the "Date sent" list order works again.
UI: In Mountain View, the open message shows the whole conversation around it, and replies are written in place under the conversation instead of in a separate window
UI: Mountain View has Gmail's side panel with calendar, tasks and contacts, and its advanced search form
UI: Mountain View's message menu has Find emails from, and the Move to menu in the bulk actions can be searched
Changes
UI: Mountain View looks more like Gmail: the content sits on a rounded card over a tinted canvas, the navigation has a Labels section, and the message rows, open message toolbar, compose window, account card, message menu and bulk actions follow Gmail's layout and order. The keyboard shortcuts sit behind a help button in the top bar
Fixes
Mail: The "Date sent" list order sorts by date sent again instead of falling back to date received (#1219, thanks @Area128)
Mail: In Mountain View, the dark backdrop behind a message body spans its full width
Tasks: Tasks in calendars shared with you show up, and tasks can be created in, moved into, edited and deleted in those calendars (#1204, thanks @mmomjian)
1.14.0 adds Mountain View, an optional layout with a top bar and a wide search field, and gives the Files app and the calendar a new layout. Dark mode now recolours messages instead of inverting them, so brand colours stay as sent. Push can be turned on for several accounts at once, and the account list can be backed up encrypted and restored on another device. The composer got a long round of send fixes. With several accounts open, batch actions no longer hit another account's message that happens to share an id with the selected one.
UI: Mountain View is an optional layout, chosen under Settings > Layout > Interface layout. On desktop it has a top bar with a wide search field, an apps grid and the account avatar in place of the left rail, a Compose pill, a docked compose window, an account popover with unread counts per account, and j/k, x and g shortcuts. Calendar, Contacts, Files and Settings use the same top bar. The default layout is unchanged (#1168, thanks @lucamzanon)
Files: The Files app is laid out like Contacts and Calendar: a sidebar with a New menu, the folder tree, Starred, Recent and Shared with me, a header with breadcrumbs, search, sort and a list/grid switch, a details panel, right-click menus in the sidebar and arrow-key navigation. On touch, a tap opens and a long press selects. Folders in the tree can be renamed and deleted, recent files open in their folder, and the view, sort and hidden-files settings now apply
Files: Image previews in Files and in attachments zoom with the wheel or a pinch, pan by dragging or with the arrow keys, switch between fit and full size on double-click, and close on a click beside the image
Files: Uploads show as a toast with their progress and a Cancel button. The large file warning is gone
Calendar: On wide screens, clicking or dragging over empty time opens a quick editor next to the slot, and clicking an event opens a card with edit, delete and more actions. Busy month cells show "+N more", the agenda lists each day as a row with the date beside its events, and the dates in the week header open that day. Calendar lists in the sidebar fold away and show their options on hover. Phones keep the full editor
Push: The notification settings list every connected account and turn push on or off for several of them at once, with a single browser permission prompt (#1054, thanks @lucamzanon)
Accounts: Users with several accounts can save their account list on the webmail server, encrypted in the browser with a password they choose, and restore it on another device. No mailbox passwords are stored. Admins turn it on with "Account List Backup" under Admin > Policy (#1201, thanks @lucamzanon)
Filters: The folder context menu runs a saved rule on the messages already in that folder (#1166)
Composer: Schedule send offers tomorrow at 8:00, tomorrow at 13:00 and next Monday at 8:00 as one-click times
Settings: The language picker has a search field and flags, and every date format and region option shows a live sample
Plugins: A plugin can run a message-list search with a JMAP Email filter (#1024)
Plugins: Calendar event actions get the event's uid and attendees, and the form-save hook now fires and can change the meeting link that is saved with the event (#1202, thanks @siennathesane)
Changes
Mail: Dark mode recolours messages instead of inverting them. Light backgrounds are darkened in their own hue, brand colours and dark fills stay as sent, and text only changes when it lacks contrast. A message's own dark mode styles follow the app theme instead of the system's
Mail: A folder opened before shows its messages at once and refreshes them in the background. A failed load leaves them on screen (#1195, thanks @lucamzanon)
Composer: On a phone, the formatting toolbar folds away behind a Formatting button and its buttons are larger. The send options sit together in one menu
Files: File sizes are rounded the way people read them, like 67 KB or 2.1 MB
Fixes
Mail: In views that merge several accounts, selecting a message no longer also selects a message with the same id in another account. Batch delete, move, archive, copy, mark read, tag and spam act only on the ticked messages, each through its own account. Before, a permanent delete could remove the other account's message (#1061, thanks @lucamzanon)
Mail: A message with two spaces in a row in its subject no longer freezes the tab (#1193, thanks @dealerweb)
Mail: Blocking remote content no longer drops a message's style sheets, so messages keep their layout before images are loaded
Mail: The list shows no paperclip on a message that only has inline images
Mail: The "via" badge is hidden when it repeats the sender's name, and a draft shows one Edit button
Send: Signed and encrypted messages reach Bcc recipients (#1206)
Send: After a plugin send, such as S/MIME, the composer closes, and a failed plugin send keeps the draft (#1207)
Send: A failed send removes its unsent copy from Drafts and explains the failure in plain words. A send while offline says so and keeps the message
Send: Typed addresses are split on commas, and a message with an invalid address is not sent. The address field marks which ones to fix
Send: Undo send disappears once the delay is over and says so when an undo fails
Send: Discard deletes the draft, also one reopened from Scheduled, and closing an autosaved draft no longer asks about unsaved changes
Send: The missing subject warning comes once per message, and the scheduled time shows its date, rounded to the minute
Composer: Tabbing into a reply or forward keeps the quoted message, and tabbing into a new message starts at the top of the body
Composer: A reply opens with the caret in the body, and the composer is titled Reply, Reply All or Forward instead of New Message
Composer: A reopened draft takes its text from the message body only. An attached .csv or .txt no longer turns up as the message text (#1213, thanks @shukiv)
Composer: A long attachment list scrolls instead of pushing the Send button out of view (#1212, thanks @shukiv)
Composer: The plain-text part of sent mail marks quotes and list items, and the signature has one separator
Composer: Enter adds the highlighted suggestion instead of the typed text, and the suggestions close once the address is added and line up with the typed text. On a phone they span the whole row and show the name above the address
Composer: Body text no longer shows through the pinned formatting toolbar (#1200, thanks @lucamzanon)
Composer: On a phone, sending a new message returns to the message list, and the Continue draft banner no longer flashes after a send
Composer: Bitwarden no longer offers logins in the recipient fields, the mail search box or the event participant field
Login: A remembered sign-in survives a server timeout or an origin switch during restore instead of signing out (#1167)
Login: Signing out of one account keeps the other accounts, and a reload with only accounts awaiting sign-in shows the login page instead of a connection error (#1201, thanks @lucamzanon)
Login: A reload without "Remember me" no longer reports an expired session
Unified: Switching to another account keeps the unified mailbox on (#1144, thanks @lucamzanon)
Push: Push is renewed for every connected account, not only the active one, so accounts no longer stop notifying after seven days. The all-accounts panel shows each account's real state and why an account failed (#1054, thanks @lucamzanon)
Filters: Forward is hidden in filter rules when the server allows no redirects (#1208)
Calendar: Save is blocked while a plugin's form-save hook runs, so a double press no longer creates the event twice (#1202, thanks @siennathesane)
Calendar: Participant suggestions are no longer cut off by the event form
Files: Canceling an upload stops the file in flight and says the upload was canceled instead of counting every file as done
Files: A drag selection keeps its items after letting go, and Files shows a loading state instead of "No files yet" before the first listing
Files: Read-only documents open in ONLYOFFICE without the -103 warning (#1187)
Contacts: The contact popover shows the sender's name when the saved contact has none, and Contacts shows placeholders instead of "No contacts yet" while loading
UI: The close and back buttons in the composer and conversation view have names for screen readers, and the composer toolbar buttons are labelled
UI: Reply All stays on one line in the conversation view, and the welcome banner gives touch tips on a phone
Translations: The new composer, send, Files and filter strings are translated
If you like Part-DB, consider donating to support the development. Press the sponsor button on the main github page, for more info.
Note
If you are using Part-DB it would be helpful if you fill out this short survey on your usage of Part-DB (Google Forms): https://forms.gle/Q15twx3YYq3qCNfe8
Part-DB 2.20.0
New features
Added "Create from file" feature to extract a part from a datasheet, manual, etc. using AI. Both text and images are supported
Fixed TFA enforcement to use effective permissions (#28176)
Policies with an IP allow list are now accounted for when enforcing TFA within the allowed range.
Improved license handling so a failed license request keeps the current license in effect and is retried by a scheduled license check, with a warning in the app showing why the license could not be renewed and when it lapses (#28331)
The /server/license response no longer includes downgrade_reason. Read invalid_reason instead, which also reports why a license that is still in effect could not be renewed.
@directus/errors no longer exports LicenseManagedByEnvError, LicenseOfflineUnsupportedError, LicenseResolveIncompleteError or LicenseServiceUnavailableError, or their error codes. License request failures now surface as LICENSE_INVALID with a failure extension, or as the standard FORBIDDEN, INVALID_PAYLOAD, REQUESTS_EXCEEDED and SERVICE_UNAVAILABLE errors.
Removed the ip-matching dependency (#28243)
Policy ip_access and IMPORT_IP_DENY_LIST values are now more strictly validated. Subnets with a malformed prefix such as 10.0.0.0/ 24 or 10.0.0.0/+24, are no longer accepted.
Existing policies that already store such a value will fail every request for users with that policy.
Fixed requests failing after a process was stopped during schema building (#28316) CACHE_SCHEMA_MAX_ITERATIONS has been removed. CACHE_SCHEMA_SYNC_TIMEOUT now also limits the schema build itself and defaults to 60000 ms.
If you have configured a lower value, make sure it is long enough for your schema to finish building.
Updated outdated type definitions for directus_notifications, directus_permissions, directus_extensions, directus_fields, directus_activity, directus_collections, and directus_revisions (#28072)
Breaking changes in @directus/sdk:
DirectusNotification.id is now correctly typed as number.
DirectusField.schema is now nullable.
FieldMetaConditionOptionType has been removed; condition options is now Record<string, any>.
FieldMetaConditionType.hidden, readonly, required, and options are now optional, and rule is typed as a filter.
All ExtensionSchema properties are now optional, and DirectusExtension.schema can also be an ExtensionSchemaEntry.
Breaking changes in @directus/types:
Notification.id is now correctly typed as number.
Notification.status and timestamp are now nullable.
@directus/api
Improved license handling so a failed license request keeps the current license in effect and is retried by a scheduled license check, with a warning in the app showing why the license could not be renewed and when it lapses (#28331 by @ComfortablyCoding)
Removed the ip-matching dependency (#28243 by @Nitwel)
Fixed requests failing after a process was stopped during schema building (#28316 by @Nitwel)
@directus/errors
Improved license handling so a failed license request keeps the current license in effect and is retried by a scheduled license check, with a warning in the app showing why the license could not be renewed and when it lapses (#28331 by @ComfortablyCoding)
@directus/utils
Removed the ip-matching dependency (#28243 by @Nitwel)
@directus/types
Updated outdated type definitions for directus_notifications, directus_permissions, directus_extensions, directus_fields, directus_activity, directus_collections, and directus_revisions (#28072 by @kheiner)
@directus/sdk
Updated outdated type definitions for directus_notifications, directus_permissions, directus_extensions, directus_fields, directus_activity, directus_collections, and directus_revisions (#28072 by @kheiner)
β¨ New Features & Improvements
@directus/app
Added a Preview Base URL project setting, selectable as a variable in a collection's Preview URL (#28227 by @robluton)
Added header bar buttons to set multiple selected Flows to active or inactive (#28321 by @robluton)
Added a confirmation dialog when saving Public policy permission changes on system collections (#28311 by @robluton)
Added a persistent warning notice when editing the Public policy (#28310 by @robluton)
Added support for linking images in the WYSIWYG editor: select an image and use the link toolbar button (or Mod+K) to wrap it in an anchor; stored <a href><img></a> markup now survives loading without triggering the normalization warning (#28289 by @alvarosabu)
@directus/api
Added a Preview Base URL project setting, selectable as a variable in a collection's Preview URL (#28227 by @robluton)
@directus/memory
Added opt-in hash option to redis memory, improving cache clear performance (#28214 by @Nitwel)
Added optional lock settings to usingLock to override the lock's duration and retry count. A signal is now passed to the callback that aborts if the lock is lost before it finishes (#28331 by @ComfortablyCoding)
@directus/system-data
Added a Preview Base URL project setting, selectable as a variable in a collection's Preview URL (#28227 by @robluton)
@directus/types
Added a Preview Base URL project setting, selectable as a variable in a collection's Preview URL (#28227 by @robluton)
@directus/sdk
Added a Preview Base URL project setting, selectable as a variable in a collection's Preview URL (#28227 by @robluton)
@directus/constants
Added a persistent warning notice when editing the Public policy (#28310 by @robluton)
@directus/env
Exported the default environment values as DEFAULTS (#28077 by @br41nslug)
π Bug Fixes & Optimizations
@directus/app
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
Update license validation to only accept Directus keys and tokens (#28331 by @ComfortablyCoding)
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
Improved license handling so a failed license request keeps the current license in effect and is retried by a scheduled license check, with a warning in the app showing why the license could not be renewed and when it lapses (#28331 by @ComfortablyCoding)
Fixed tooltips not appearing on keyboard focus (#28263 by @robluton)
Fixed Norwegian time format patterns that displayed raw timestamps instead of times in datetime fields (#28332 by @u12206050)
Fixed the module navigation scrolling back to the top when navigating to another page (#28269 by @khanahmad4527)
Fixed AI translations creating duplicate target language rows when streaming multiple fields. (#28074 by @xmflsct)
Updated outdated type definitions for directus_notifications, directus_permissions, directus_extensions, directus_fields, directus_activity, directus_collections, and directus_revisions (#28072 by @kheiner)
Cleaned unsupported markup from pasted content in the WYSIWYG editor and flagged it inline, with a view of what was removed and the choice to undo the paste or redo it raw in the raw HTML editor (#28238 by @alvarosabu)
@directus/api
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
Update license validation to only accept Directus keys and tokens (#28331 by @ComfortablyCoding)
Fixed OpenAPI spec version to only change when the generated spec does (#28109 by @kheiner)
Fixed creating a collection with neither schema nor meta returning a misleading 403 instead of a 400 validation error (#28258 by @kheiner)
Fixed filtering and GraphQL typing of geometry subtype fields (e.g. geometry.Point) (#28308 by @PINYOPATTANAWASANPORN)
Fixed GraphQL marking not-null fields with a default value as nullable in queries and fields with falsey default values as required in create mutations (#28280 by @Dextheking1)
Added opt-in hash option to redis memory, improving cache clear performance (#28214 by @Nitwel)
Fixed TFA enforcement to use effective permissions (#28176 by @psang39)
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
Fixed GraphQL fragments on the union type of one M2A field returning no data when spread into another M2A field (#28305 by @Nitwel)
Unified related collection lookups to use getRelationInfo (#28246 by @Nitwel)
Fixed a GraphQL query with a __proto__ field alias being able to write a property onto Object.prototype. (#28211 by @datrixlab)
Improved validation of storage locations and paths for files (#28077 by @br41nslug)
@directus/extensions-sdk
Fixed directus-extension validate passing or crashing on missing extension paths (#28320 by @PINYOPATTANAWASANPORN)
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
@directus/composables
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/extensions
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
@directus/stores
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
@directus/themes
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
@directus/types
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/utils
Updated proxy-addr, braintrust, MCP SDK, sharp, vue, dompurify, source-map-js and serialize-javascript to address CVEs (#28334 by @br41nslug)
Fixed filtering and GraphQL typing of geometry subtype fields (e.g. geometry.Point) (#28308 by @PINYOPATTANAWASANPORN)
Unified related collection lookups to use getRelationInfo (#28246 by @Nitwel)
@directus/specs
Fixed creating a collection with neither schema nor meta returning a misleading 403 instead of a 400 validation error (#28258 by @kheiner)
@directus/cli
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/storage-driver-cloudinary
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/storage-driver-supabase
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/update-check
Updated undici, axios, nodemailer, basic-ftp, ip-address, and fast-uri to address CVEs (#28330 by @br41nslug)
@directus/env
Fixed requests failing after a process was stopped during schema building (#28316 by @Nitwel)
@directus/sdk
Fixed readActivity, deletePermission, readPermission, updatePermission, readItemPermissions, readNotification, and readRevision not rejecting a null or undefined key or collection (#28072 by @kheiner)
1.13.0 turns the vacation settings into an Out of Office page that can also forward mail, lets filter rules run only for a date range, and copies messages into another connected account. Files from the Files app can be attached in the composer, tags can be set on many messages at once and folders moved in bulk. Messages whose sender can't be verified now carry a warning. It also stops one account's settings and templates from carrying over to the next account signed in on the same browser.
Settings: Signing out and then signing in with another account in the same browser no longer shows the previous account's settings, tags and templates, and no longer saves them to the new account's synced settings (#1185)
Features
Mail: A message whose sender fails the From domain's checks, or that passes neither SPF nor DKIM, shows a warning above the message and a badge next to the sender. "Always trust this sender" is not offered for it
Mail: "Copy to account..." in the message menu files a copy in a folder of another connected account and leaves the original where it is. Copies keep their original date (#1150, thanks @lucamzanon)
Mail: The selection toolbar and the right-click menu put a tag on, or take it off, every selected message at once (#1077)
Out of office: The vacation settings are now an Out of Office page: the period on top, then the automatic reply and forwarding, each with its own switch. Forwarding works with or without the reply, never forwards spam and can keep a copy in the inbox. The reply can go to all senders, internal senders only or external senders only (#1152, thanks @dealerweb)
Filters: A rule can be limited to a period, and the rule list shows whether it is scheduled, active or expired (#1152, thanks @dealerweb)
Filters: The new "All messages" condition matches every message (#1154, thanks @dealerweb)
Composer: "Attach from Files" attaches files from the Files app, including files shared with you, without downloading and uploading them again (#1179)
Composer: Typing @ in the message body offers the To and Cc recipients and inserts the chosen one's first name. Bcc recipients are never offered. "Mention recipients with @" in the composer settings turns it off (#1134, thanks @dealerweb)
Folders: The folder settings can select several folders, with Shift+click for a range, and move them together under another folder or to the top level (#1173)
Calendar: The day and week views can be limited to working hours, and the week view can leave out non-working days. Events outside the visible hours are counted at the top and bottom of each day and open from there, and a button in the view shows all hours (#1164)
Login: LOGIN_SHOW_TOKEN_LOGIN=true offers "Sign in with an access token", for JMAP servers that take API tokens instead of passwords, such as Fastmail
Login: A server in JMAP_SERVERS whose oauth block has both a clientId and a buttonLabel gets its own sign-in button on the login page, even while OAuth is off globally. This allows a "Sign in with Google" button for a Gmail bridge next to servers that use passwords (#1135, thanks @lucamzanon)
UI: The browser tab title names the active account, as in "Inbox - alice@example.com - Webmail", and Settings, Calendar, Contacts and Files set their own title. Turning off "Subject in Tab Title" under Admin > Policy keeps message subjects out of the title, and with it out of the browser history (#1186, thanks @oguzyilmaznet)
Unified: While logins reconnect after a page load, the "All accounts" header shows how many are already counted, such as "4/10" (#1140, thanks @lucamzanon)
Push: A message that reaches several of your accounts rings once. For 30 seconds after an alert, notifications from your other accounts arrive silently (#1141, thanks @lucamzanon)
Server: SOURCE_CODE_URL points the source code link in Settings > About at the code of a modified build, as AGPL section 13 asks of anyone running one (#1161)
Changes
Calendar: The day and week views show 08:00 to 20:00 by default. "Limit visible hours" in the calendar settings changes the range or turns it off (#1164)
Tags: Tag views and their counts leave out messages in Trash and Spam (#1156)
Mail: In a shared mailbox, the Move menus list that mailbox's folders first and your own folders after them, under your account name (#1149)
Dependencies: sharp 0.35.5 and source-map-js 1.2.2 (npm audit)
Docs: CONTRIBUTING.md explains what belongs in core and what in a plugin, and which changes need an agreed issue before a pull request
Fixes
Mail: Attachments, inline images and .eml downloads of messages in shared folders are fetched from the account that owns them. On Cyrus they failed with "failed to find blob by id" (#1188, thanks @VasilisNtovolos)
Mail: Archive creates an Archive folder when the account has none, instead of only reporting that it is missing (#1176, thanks @cybersmurf)
Mail: Opening the webmail starts in the inbox instead of a folder from an earlier visit, such as Trash
Mail: Opening another folder, tag, account or search starts the message list at the top instead of where the last one was scrolled to (#1138, thanks @dealerweb)
Mail: Previews no longer start with a style sheet ("@media screen and ...") in the message list and in push notifications (#1136, thanks @lucamzanon)
Search: Searching from the unified All mail view finds sent mail too
Send: A draft saved without a subject reopens with an empty subject, so Send warns about it again instead of sending "(No Subject)" (#1189)
Send: When the server does not confirm that a message was sent, the draft is kept and the composer asks you to check Sent before sending again (#1019, thanks @lucamzanon)
Send: A message the server refuses shows the server's reason instead of "Invalid reference to non-existing object"
Send: A forward sent from another account's address no longer fails with blobNotFound. Its attachments and inline images are copied to the sending account first (#1142, thanks @lucamzanon)
Push: Push turns itself back on when the browser lost its subscription, retrying at most every 15 minutes (#1147, thanks @lucamzanon)
Push: The notification settings check push again when you come back to the tab, so push turned off in the browser or another tab no longer shows as on (#1148, thanks @lucamzanon)
Push: When the new message cannot be read, the notification no longer announces another unread message from the Inbox in its place, and a failed lookup shows a generic notification instead of none (#1041, thanks @lucamzanon)
Filters: "Stop processing further rules" also stops after "Delete silently" and "Reject", so later rules no longer file the message. Rules whose name contains double spaces, a tab or a trailing space no longer gain a copy on every save, and the copies earlier saves left are removed (#1153, thanks @dealerweb)
Filters: The forwarding limit counts the forwards one message can collect, instead of adding up every enabled rule, and warns when the rule order lets one message go over it (#1155, thanks @dealerweb)
Filters: A condition with several values wraps inside its card in the expanded rule view (#1139, thanks @dealerweb)
Filters: An open rule dialog or Sieve editor, and what was typed in it, survives a filter change from another tab or device (#1162, thanks @dealerweb)
Templates: A tab or device that had not reloaded no longer deletes templates created elsewhere when it saves its settings
Calendar: Duplicating an event keeps its meeting link (#1170)
Calendar: The Calendar Agenda plugin shows events from shared and group calendars (#1175, thanks @cybersmurf)
Files: Folders shared with you can be opened, and your own folders shared, in both folder layouts (#1181)
Files: Office editing works behind a reverse proxy where the editor and the browser reach the webmail at different addresses. The WOPI client URL may be an internal address (#1130)
Login: When Stalwart accepts a password and TOTP code but refuses to issue tokens, the login page points at the OAuth client settings instead of opening the browser's own sign-in dialog and reporting a wrong code
Branding: With APP_NAME set, the authenticator app entry for two-factor sign-in, the About card and the Files preview use the configured name and logo (#1177, thanks @cybersmurf)
UI: Text fields in dialogs keep the focus when the page behind updates, which happened every 30 seconds and on new mail (#1162, thanks @dealerweb)
UI: Buttons, menu items, tabs and other controls show the pointer cursor again (#1184, thanks @gwku)
UI: The account group labels in the From dropdown are readable in dark themes (#1157, thanks @dealerweb)
Translations: Czech is fully translated (#1174, thanks @cybersmurf), and missing placeholders are restored in Persian, Hebrew, Hungarian, Mongolian and Slovak (#1165, thanks @owgreen-dev)
This release fixes Compose path and image handling, improves backup and update reliability, and adds a setting for Signal notifications.
It also includes fixes for remote environments, authentication, and environment navigation.
Compose and updates
Interpolate variables in Compose include paths (#4298) β @kmendell
Preserve Compose image spelling during project updates and self-updates (#4330) β @kmendell
Keep the selected tag during self-updates and refresh stale project update status (commit e862615fc4e47c8bf7fbfc089254bf509d0a82c7) β @kmendell
Environments, notifications, and authentication
Resolve webhook target names in remote environments (#4299) β @kmendell
Default notifySelf to true and add a setting for Signal notifications (#4302) β @Shraymonks
Prevent logout from hanging on permission errors after OIDC login (#4309) β @kmendell
Navigate to the selected environment on environment-scoped routes (#4320) β @kmendell
Backups and maintenance
Prevent system backups from failing when project files are in use (#4311) β @kmendell
Allow deleting backups when their S3 repository no longer exists (#4319) β @kmendell
Report accurate reclaimed space in scheduled pruning (#4317) β @kmendell
Store Francis actor state in its own SQLite database (commit 93a740597df7a6aa47d5925d9d8dc5499934af05) β @kmendell
Use persistent Git storage for SSH host keys on native installs (#4300) β @kmendell