A feature release, the first since 4.4.0. You can now select every message in a folder or a search, not just the page on screen, and act on all of them at once. Two new plugins: one keeps reusable messages as templates, the other translates mail through DeepL. Thunderbird's 1 to 5 tag keys work, and the Nextcloud integration gets a default save folder.
Worth taking for the security fixes alone if you open mail from strangers, which is everybody: a sender could make its own message show as DKIM verified, and an IMAP keyword could put markup into the message view.
Security
- A sender could vouch for its own message.
AuthStatuses()read everyAuthentication-Resultsheader without looking at who wrote it, so a sender could attachdkim=passfor its own From domain. On unsigned mail that forged line was the only DKIM result left, so the message view showed the From address as verified and a+dkimremote-image rule loaded tracking images without asking. A result now has to come from a server the install trusts. The newsecurity.trusted_authserv_idssetting names those servers; left empty, the topmost header's authserv-id is taken as the local one. That default needs the receiving server to strip headers carrying its own id, as RFC 8601 tells it to. If your server adds no results of its own, set the option, or the sender's header is still the topmost one. Inherited from SnappyMail. Reported by @ZaphodB (GHSA-vqwv-r925-cmrq) - An IMAP keyword was rendered as HTML in the message view. The tag label was built from the raw keyword and bound with
html:, and an IMAP atom may contain<,>and=. A Sieve script that copies a header into a flag, or another user on a shared folder, could therefore put an<img>there that loaded when the message was opened. Script does not run under the shipped CSP, but it would on an install that addedunsafe-inlinefor a plugin. The tag area sits outside the message body, so neither the sanitizer nor the remote-image consent covered it. Inherited from SnappyMail. Reported by @ZaphodB (GHSA-vqwv-r925-cmrq) - The DKIM signer was matched against the From address with
strpos()used as a boolean, which was wrong both ways. An exact match at offset 0 counted as no match. A signature fromexample.orgpassed mail fromevil-example.org, and a DKIM pass is what unlocks BIMI and favicon avatars. Both sides are now compared as domains, and a subdomain of the signing domain still counts - Auto-logout was only a timer in the browser. Closing the tab stopped it, the cookies outlived the tab, and a new tab got straight back in for up to three hours. The server now refuses a session idle for longer than the user's auto-logout setting plus three minutes. The same exemptions apply as before: "never", and a "stay signed in" login. A session open at upgrade time starts counting from its next request, so nobody is logged out by the upgrade. Reported by @florihupf (#185)
- Stored data is no longer passed through
unserialize(). Two places fell back to it for the format very old versions wrote. The settings decoder did it on decrypted storage with no class allow-list, and two-factor-auth did it for records from before JSON. Data that old is no longer converted. Thanks to @ZaphodB (#184) - A two-factor record that cannot be read now refuses the login. Before, an empty, damaged or unreadable record counted as "no second factor", so the password alone got in. A restore that set the wrong file owner was enough to cause it. The log line names the record, because removing it by hand is the only way back in for that user. Worth knowing before you restore a backup. An open session still loads with 2FA forced, rather than failing with a 500. Thanks to @ZaphodB (#184)
Added
- Select every message in a folder or search, not just the page. Tick the page and a banner offers the rest: "Select all messages in this folder", or "that match this search". Move, copy, archive, spam, delete, drag and drop, read, flagged and tags then act on all of them. A move, copy or delete of the whole selection asks first and names the count. With threads on, the rest of each matching thread comes along. Forward, the downloads and the Nextcloud .eml save work on the loaded messages only, so they are off while everything is selected. Not offered for a search across folders. Asked for by @lvarnava (#182)
- Mail Templates plugin. Save the message you are writing as a template and insert it into a later one. A template is a message in a "Templates" folder, which is where Thunderbird keeps its own, so they are in your mailbox backup and other clients see the same list. Asked for by @GodfreyJH (discussion #176)
- DeepL Translate plugin. Translates a received message in place with its formatting kept, or a draft into the recipient's language before sending, with a second click to undo. It only runs when you click, since the text goes to a third party. Works with Free and Pro keys. Every DeepL call is made by the server, so the key never reaches the browser. The key can be the user's own, the admin's (stored encrypted), or
TACHYON_DEEPL_AUTH_KEYfrom the environment - Keys 1 to 5 toggle the Thunderbird labels on the selected messages, and 0 removes all five. Requested by @pzystorm (#171)
- Settings, Folders shows the total number of messages across every folder, Trash and Spam included, so you can check a backup or an import against it. It needs the IMAP LIST-STATUS extension and stays hidden without it, because without it the count would come up short and still look complete. Asked for by @lvarnava (discussion #181)
- A Nextcloud tab under Settings sets the folder attachments and messages are saved to, and whether to ask every time. With asking off, a save goes straight there. Asked for by @lvarnava (#117)
- Two community helpers under
contrib/: one checks for a new release, one sets file permissions for the web updater. Thanks to @GodfreyJH (#179, #180) - For plugin authors: named slots for a plugin control in the compose window (
rl.addComposeHeaderRow,rl.addComposeButton) and in the message view's toolbar and menu. Plugins no longer have to splice markup into core templates they do not own. send-save-in and nextcloud have moved onto them
Fixed
- Pressing Enter at the top of a reply lost the new line in Firefox, so only a second Enter appeared to work. Shift+Enter at the end of a line had the same symptom in both Firefox and Chromium. Pasting or inserting HTML that ended in a line break inserted nothing. Reported by @daniu-de (#165)
- Choosing Arial in the font menu wrote no font. Unstyled text showed as Arial, the app's own font, so picking Arial changed nothing and the mail went out with no font set. Unstyled text now shows as "Default". The serif group was labelled "sans", and the Arial stack put Arial Unicode MS first for recipients with Office. Compact Composer had the same menu and gets the same fixes. Reported by @dertinger (discussion #177)
- Some marketing mail rendered as a column about 150px wide. A fixed-width mail inside a wrapper table with no width of its own had nothing for its percentage widths to resolve against. Reported by @GodfreyJH (discussion #178)
- A reply to a message carrying a whole HTML document inside a quote quoted that document and dropped what the sender had written above it. Also reported upstream as snappymail#2089
- SPF and DMARC showed "none" on mail the server had passed when the result carried no identity, which GMX among others writes. Reported by @ivnmad (#168)
- A subject folded before an encoded word lost the space there ("voséquipements"), and every other fold left two spaces, which carried into reply subjects. Thanks to @FathiBenNasr (#170)
- The tag menu listed private keywords other clients set, such as
$Filteredand$has_cal, and listed every Thunderbird label twice when the server reported$Label1in mixed case. Cancelling "New tag" threw an error (#171) - A contact photo never showed up for a sender once an avatar lookup had found nothing. With contacts as the only source, which is the default, the photo was never even requested. Reported by @florihupf (#172)
- A CalDAV event or a contact whose file name held a space never synced, failing with "Malformed input to a URL function". Reported by @florihupf (#174)
- A search across folders showed only the time on each row, with the date hidden in the tooltip. Reported by @remmmi (#150)
- Nextcloud: saving a message as .eml always reported failure, including when it worked. The folder dialog was broken in the NextcloudV25+ theme, the default inside Nextcloud, with radios floating mid-row and no visible way to open a folder. The root folder could not be chosen once a subfolder had been remembered. A second batch of file links joined the end of the previous line. The text tab now comes forward after links are inserted, and a successful save shows a check. Checked on Nextcloud 34 with group folders. Reported by @lvarnava (#117)
- Inserting anything next to a link left an empty copy of that link in the message
\Tachyon\APIdid not resolve on a case-sensitive filesystem when a request reached it first, whichimapsync.phpdoes. Also fixed upstream as snappymail#2008- The gpg helpers used the backtick operator, which is deprecated in PHP 8.5
Changed
- "Remember Me" on the login page now says what it does: it keeps you signed in for 30 days and turns auto-logout off. Several people took it to mean "remember my username" (#185)
- Translations updated for Czech, German, Finnish, Polish and Russian, with Czech and German now complete