Commit Graph
322 Commits
Author SHA1 Message Date
Linus Rath 51b2198f3f Merge pull request #1003 from lucamzanon/fix/navigation-protocol-account-limit
fix: detect HTTP/2 from the initial navigation timing so accounts aren't capped at five
2026-09-11 11:59:43 +02:00
dealerweb 1c00812ab7 fix: hide body-embedded cid parts declared as octet-stream from the attachment list
Some senders ship the images their HTML body embeds via cid: as
application/octet-stream with no Content-Disposition and no filename.
The body rendered them fine, but the "hide inline images" check only
recognised parts declared inline with an image/* type, so they also
showed up as nameless "Attachment" chips next to the real files.

Both viewers now scan the HTML they actually render for cid: references
(the same pattern the renderer rewrites to blob URLs) and hide a
referenced part when it is an image or generically typed. An explicit
attachment disposition always keeps its chip, as does a referenced part
with a real non-image type, since that chip is its only download. Plain
text rendering references nothing, so nothing is hidden there. The
shared rule lives in lib/attachment-visibility.ts so the desktop viewer,
the thread view and the decrypted-message path cannot drift apart.
2026-09-10 10:45:45 +02:00
lucamzanon 335347a56f fix: detect HTTP/2 from the initial navigation timing so accounts aren't capped at five
isHttp2Available() only inspected "resource" timing entries, which can be
empty right after a fresh login or session restore, before any subresource
finishes loading. On an HTTP/2 page this made getMaxAccounts() fall back to
the HTTP/1.1 cap of five accounts. Include the "navigation" timing entry,
whose nextHopProtocol is known immediately, so h2/h3 is recognized on first
load. Environments without timing data still return false (no h2 assumed).
2026-09-10 10:14:25 +02:00
Linus Rath 565d5c1095 feat: choose exact-address or same-domain matching for reply from received address #1000 2026-09-09 19:27:08 +02:00
Linus Rath c395226926 fix: reject wrong passwords server-side so the browser never shows its Basic Auth dialog #969 2026-09-09 19:21:40 +02:00
Linus Rath b91b438076 test: keep stray fetches and timers from leaking across resilience tests 2026-09-09 18:56:51 +02:00
Linus Rath 9796b0b14d fix: index newer settings and flat calendar toggles in the settings search 2026-09-09 18:40:15 +02:00
Linus Rath 8d8ef7e2f1 fix: unreadable native <select> option lists in dark themes #999
The browser paints a native <select>'s option list itself, so the
bg-muted / text-foreground classes on the control never reach it. Themes
whose --color-muted is translucent (Aurora Glass dark uses
rgba(255,255,255,0.05)) composited to a light popup with near-white
text, leaving every unselected option almost invisible.

Pin option background/colour to the popover tokens, which every built-in
theme defines as an opaque surface, and set color-scheme: dark on
selects under .dark so Safari (which ignores option colours) renders a
dark popup too. Fixes all ~40 native selects at once.

Adds a stylesheet test that locks the rules and asserts every built-in
theme's --color-popover stays opaque in each variant.
2026-09-09 18:30:59 +02:00
Linus Rath ae403b06af feat: setting to turn off free scrolling in the calendar 2026-09-09 18:27:01 +02:00
Linus Rath 15a5497a12 feat: freely scrolling month, week and day views #759 2026-09-09 16:38:55 +02:00
Linus Rath 26358c7a63 Merge pull request #991 from rotterp/fix/shared-mailbox-send-identity
fix(composer): send from the address a message was delivered to
2026-09-07 22:38:51 +02:00
Linus Rath d28d8dcd86 fix: report calendar clear failures instead of counting zero #434 2026-09-07 22:34:47 +02:00
Linus Rath 07bbde4786 fix: make the iCal subscription size limit configurable and show the real error #692 2026-09-07 22:34:47 +02:00
Linus Rath 928e2e3794 feat: add a server-side switch for the Stalwart JMAP passthrough #904 2026-09-07 22:34:47 +02:00
Linus Rath e98109b80d fix: require a session for the translate API #903 2026-09-07 22:34:47 +02:00
Linus Rath 4afc2a5db0 fix: surface Email/set failures on delete and move #956 2026-09-07 22:34:47 +02:00
Linus Rath e095805851 fix: use the selected server's issuer for SSO discovery #952 2026-09-07 22:34:47 +02:00
Linus Rath 40e38d1679 fix: retry the JMAP session fetch when a redirect drops the auth header #892 2026-09-07 22:34:47 +02:00
Linus Rath faed1591ef fix: fail fast when the plugin storage database is blocked #840 2026-09-07 22:34:47 +02:00
Linus Rath b4f12b6786 fix: resolve push previews for shared and group mailboxes #839 2026-09-07 22:34:47 +02:00
Linus Rath 2b186910d5 fix: subscribe newly created mailboxes #951 2026-09-07 22:34:47 +02:00
Linus Rath af234f64a4 fix: drop max_age=0 from OIDC re-authentication requests #938 2026-09-07 22:34:47 +02:00
Patrick RotterandClaude Opus 5 4fc7b8b50b fix(composer): send from the address a message was delivered to
On a shared, group or aliased mailbox every reply, reply-all and forward
went out as `identities[0]` - the account owner - whichever mailbox was
open. `autoSelectReplyIdentity` fused two behaviours: matching one of the
user's OWN identities, which never rewrites `From:`, and the domain
catch-all, which puts an address they have not configured into `From:`.
Only the first is safe for everyone, so it is now unconditional; the
rewrite stays behind the setting, which is what its description promises.
`findReplyIdentityId` already implemented that match and was referenced
only from tests.

`forward` is admitted to the match - it was excluded, so a forward from a
shared mailbox went out as the owner - but never takes the rewrite: a reply
continues a thread whose participants know the addressing, while a forward
introduces a rewritten From to a recipient the user just typed. Quick reply
matches own identities only, having no From row to show or correct a
rewrite, and now falls back to the primary's signature as the composer
does, so a shared-mailbox quick reply is still signed.

`findReplyIdentityId` now scans recipients in To, Cc, Bcc order rather than
scanning identities, and prefers an untagged identity over a differently
tagged sibling. Scanning identities let their order decide, and
`sortIdentities` puts the login's own address first - so `To: team@,
Cc: you@` replied as you, the case this is meant to fix.

Automatic selection is restricted to the active account: `composerClient`
follows the chosen identity, and a reply or forward still carries blobIds
only its own account's server can resolve. The dropdown still offers every
account's identities to pick by hand.

New messages are deliberately left gated: `composeFromAccountEmail` falls
back to `AccountEntry.email`, written once at first login, so resolving it
unconditionally would override a user-chosen default sender identity (#507).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 20:37:29 +02:00
Linus Rath e11e40f0e7 Merge pull request #928 from hildebrandttk/fix/truncated-body-blank-render
fix(email): refetch body value when JMAP truncates the displayed part
2026-09-07 17:55:15 +02:00
Linus Rath 93b8d99ff9 fix(): refill missing managed bundles from the server #636 2026-09-07 16:52:20 +02:00
Stefan Hildebrandt 242fe6aa2d fix(mail): unified mailbox missed accounts that had not connected yet
After a reload the unified mailbox showed only the active account's mail;
other accounts appeared only once visited. Intermittent (~1 in 14), and
not a timeout - nothing on this path uses setTimeout/AbortSignal/race.

checkAuth awaits only the active account and restores the rest in a
fire-and-forget background loop, registering each client only after
connect() resolves. buildUnifiedAccountClients drops accounts with no
live client (`if (!c) continue`). And isConnected was persisted, so it
rehydrated stale-true: the account passed the isConnected filter while
failing the client lookup, and connectedAccountsSignature already looked
complete at mount so nothing re-fired - and the effects keyed on it only
recompute counts, never the list.

Clear isConnected/hasError on rehydrate so both the filter and the
signature describe this session, and refetch the open unified/cross list
when an account joins the connected set (growth only, not on first
render, not while a search owns the list). Extracted
connectedAccountsGrew so the membership check is testable without
rendering MailApp.

Verified the reset cannot block reconnection: checkAuth reads the full
account list and never filters on isConnected.

Fixes #950
2026-09-02 22:15:50 +02:00
Stefan Hildebrandt 2cf7427e32 fix(email): refetch body value when JMAP truncates the displayed part
Large HTML emails (e.g. image-only reports with a data:image src cut
mid-tag by the 256 KB body cap) rendered completely blank because
Email.bodyValues[partId].isTruncated was declared but never acted on.
On truncation, issue one follow-up Email/get with a much larger cap
for the parts actually shown, batched across a thread instead of one
refetch per message.

Closes #884
2026-09-02 08:34:31 +02:00
Linus Rath 0c7437f67a feat: open global search hits through the owning login on every surface #847 2026-09-01 20:55:13 +02:00
Linus Rath a210b22e49 fix: set name.full on all contact write paths so vCards carry mandatory FN #430 2026-08-31 23:53:24 +02:00
Linus Rath ca7fbbe416 feat: WOPI office document editing in Files (Collabora/OnlyOffice/EuroOffice) #425 2026-08-31 23:16:19 +02:00
Linus Rath d60eb59575 fix: pad attachment preview overlays for the iOS PWA safe area #936 2026-08-31 21:03:08 +02:00
Linus Rath a69b3651fd fix: render plain-text-only mail as text in the mobile thread view #489 2026-08-31 20:41:45 +02:00
Linus Rath b11cf4b1a5 feat: offer deleting a non-empty folder with its messages 2026-08-29 18:23:09 +02:00
Linus Rath 03b588096d feat: filter advanced search by message size 2026-08-29 18:20:21 +02:00
Linus Rath cc90903f05 feat: request delivery notifications and REQUIRETLS when sending 2026-08-29 18:16:52 +02:00
Linus Rath e54d179f32 feat: surface CalendarEventNotification invitations and updates 2026-08-29 18:11:50 +02:00
Linus Rath 14cdb2f6ff feat: organize invitations as the default ParticipantIdentity 2026-08-29 18:07:47 +02:00
Linus Rath e8c594001d feat: show attendee free/busy via Principal/getAvailability 2026-08-29 18:03:26 +02:00
Linus Rath 6e5aca60a9 feat: share mail folders with other users via mail:share 2026-08-29 17:53:54 +02:00
Linus Rath b408b2597a feat: highlight search hits with SearchSnippet/get 2026-08-29 17:47:23 +02:00
Linus Rath 1807b2df6b feat: allow setting an address book as default (#924) 2026-08-29 17:15:50 +02:00
Linus Rath 39dcc6b219 fix: invalidate persisted update status after an upgrade 2026-08-29 12:46:39 +02:00
Linus Rath 1e2409f8b9 fix: keep basePath when normalizing Chinese Accept-Language 2026-08-29 12:35:38 +02:00
Linus Rath 42f736b96d Merge pull request #932 from kchuang1015/feat/zh-tw-locale
feat(i18n): add Traditional Chinese (Taiwan) locale
2026-08-29 12:32:02 +02:00
Linus Rath 4fe5701b3b feat: default sidebar apps for all users #931 2026-08-29 12:31:17 +02:00
Linus Rath d800689924 feat: use Stalwart synthetic ids for recurring occurrences #140 2026-08-29 11:03:48 +02:00
Kuan-Chieh Huang f1736b63c9 fix(i18n): preserve locale cookie precedence 2026-08-29 13:04:25 +08:00
Kuan-Chieh Huang 9fab1d1f4a fix(i18n): normalize Chinese proxy locale detection 2026-08-29 11:44:40 +08:00
Linus Rath 19756e4337 fix: pin resolved IP for stored custom JMAP endpoints and branding URLs 2026-08-26 23:02:19 +02:00
Linus Rath 3288589e52 fix: pin resolved IP at connect time to block DNS-rebinding SSRF (GHSA-24w9-8r42-8jwm) 2026-08-26 22:11:06 +02:00