Commit Graph
2896 Commits
Author SHA1 Message Date
Linus Rath e31f55064e fix: use the current calendar and contacts icons in the Mountain View side panel 2026-10-25 12:56:48 +01:00
Linus Rath cb663d2222 fix: keep settings switches full width next to long labels 2026-10-25 12:49:55 +01:00
Linus Rath 0b1463b7d5 feat: show attachment and code chips as Gmail pills in Mountain View 2026-10-25 12:48:49 +01:00
Linus Rath 39c8b14574 fix: open the admin panel in the desktop layout without a phone-layout flash 2026-10-25 12:42:02 +01:00
Linus Rath 5a9c318ec5 fix: keep mails that paint their own page background from flashing white in dark mode 2026-10-25 12:39:28 +01:00
Linus Rath 07627b3a60 fix: give every app's sidebar header and toolbar the same height as mail 2026-10-25 12:30:23 +01:00
Linus Rath 9c360694bf fix: send paragraphs with the spacing the composer shows #1340 2026-10-25 12:27:13 +01:00
Linus Rath 171fd1ea4c perf: load React DOM and the UI kit only in plugin frames that draw 2026-10-25 02:56:14 +01:00
Linus Rath a7cfa5b160 fix: rebuild the plugin sandbox while npm run dev runs, and build it for the integration image 2026-10-25 02:26:18 +01:00
Linus Rath f20892ccec fix: start plugins when the sign-in races the first plugin start 2026-10-25 02:24:41 +01:00
Linus Rath 5edbbf0816 perf: start plugin slot frames without waiting for the plugin's own frame 2026-10-25 02:24:08 +01:00
Linus Rath e38e326efb perf: load plugin frames as a plain page instead of a Next app
Every plugin iframe loaded /plugin-sandbox, a force-dynamic Next page.
Each frame then fetched, parsed and hydrated Next's client router on top
of React and the runtime, and the server rendered the page once per
frame, one after another when a dozen plugins started together.
Sandboxed frames have opaque origins, so the browser's code cache never
helps, and they run on the host page's main thread: with 12 plugins
the frames took 2.5-3 s to come up after the app had loaded.

The sandbox routes now return a small HTML page with the UI kit's
stylesheet and the runtime as an ES module, both built ahead of time:

- `scripts/build-plugin-sandbox.mjs` bundles the runtime with esbuild
  and compiles `plugin-kit.css` with the app's Tailwind setup into
  `public/plugin-sandbox-assets/`, with a manifest. Named Tabler imports
  are pointed at the icons' own files, so the full icon set stays in a
  chunk that only loads for an icon name the kit doesn't ship.
- `npm run build`, `npm run dev`, the Dockerfile and the perf-guard
  workflow run it before `next build`.
- `lib/plugin-sandbox/sandbox-document.ts` writes the page; proxy.ts
  still sets the sandbox CSP and the script carries its nonce.
- The assets are served from public/ with CORS and immutable caching.

A frame on an idle page is ready in 255 ms instead of 362 ms, eleven at
once in 1.0 s instead of 2.1 s.
2026-10-25 02:01:47 +01:00
Linus Rath 6be0f70452 perf: skip plugin round trips when a slot re-renders with the same props 2026-10-25 02:40:43 +02:00
Linus Rath 181a0d7d88 perf: send plugin frames only the translations of the current language 2026-10-25 02:26:17 +02:00
Linus Rath 52959e8135 fix: stop plugin panels flashing white in the dark theme 2026-10-25 02:22:59 +02:00
Linus Rath c066d40180 perf: check cached plugin bundles without reading them, and download in parallel 2026-10-25 02:18:18 +02:00
Linus Rath be8adde945 perf: fetch the server plugin list once per page load 2026-10-25 02:15:13 +02:00
Linus Rath 9a568aa4f4 perf: write the plugin list to storage once per burst of changes 2026-10-25 02:12:50 +02:00
Linus Rath 782d4f8bf5 perf: stop loading the app's stores in every plugin frame 2026-10-25 02:09:37 +02:00
Linus Rath 23eb3c5a2f fix: start plugins after signing in, not only after the next reload 2026-10-25 02:06:35 +02:00
Linus Rath 4efb9a2a75 docs: list the private monthly sponsor in the 1.17.2 changelog 1.17.2 2026-10-24 22:59:08 +02:00
Linus Rath 5872bf20e9 chore: release 1.17.2 2026-10-24 22:46:52 +02:00
Linus Rath af07bb3cd3 fix: list admin plugins when the browser can't cache their code #1327 2026-10-24 22:37:16 +02:00
Linus Rath a49ab079ec fix: sanitize quoted and signature HTML in re-opened drafts (GHSA-g35q-3gpc-x2rr) 2026-10-24 22:13:19 +02:00
Linus Rath 89e93e330e fix: send a sub-address of your own address from your account, not a shared catch-all 2026-10-24 17:58:45 +02:00
Linus Rath 16e88e8a1b fix: end every push with a notification so Safari keeps the subscription #1322 2026-10-24 17:58:21 +02:00
Linus Rath 35660690d2 fix: fire task alerts from the start when they are relative to it #1328 2026-10-24 17:57:56 +02:00
Linus Rath 0d4631c5a8 test: bound the impersonation expiry by both ends of the handoff 2026-10-24 17:56:38 +02:00
Linus Rath 6d459674f8 Merge pull request #1109 from hildebrandttk/fix/group-identity-sent-copy
fix: save a group identity's drafts in the group account's Drafts (#1…
2026-10-24 17:55:10 +02:00
Linus Rath 7370b6bad0 Merge pull request #1335 from tobiasge/feat/plugin-regional-formatting
feat: mirror regional presentation settings to plugin sandboxes
2026-10-24 17:55:06 +02:00
Linus Rath 1bd1a6b123 Merge pull request #1334 from HOLOEYE-JZ/feat/sidebar-tags-first
feat: admin policy gate to list the Tags above the shared mailboxes
2026-10-24 17:55:01 +02:00
Linus Rath 6d44e9320c Merge pull request #1333 from HOLOEYE-JZ/feat/plugin-keywords-update-remove
feat: let plugins update and remove the tags they added
2026-10-24 17:54:58 +02:00
Linus Rath 3b8dd4cd82 Merge pull request #1317 from LeonardNJU/feat/plugin-sidebar-heading-actions
feat(plugins): allow inline actions in collapsible sidebar headers
2026-10-24 17:54:53 +02:00
Linus Rath 10caa9e2f3 Merge pull request #1316 from ghozty/feat/app-name-strings
feat: name the app with the configured APP_NAME in user-facing strings
2026-10-24 17:54:49 +02:00
Linus Rath bf725814ad Merge pull request #1326 from VasilisNtovolos/fix/bulk-move-client-routing
fix: route bulk move by authenticated client
2026-10-24 17:54:44 +02:00
Linus Rath bec2796f1d Merge pull request #1307 from VasilisNtovolos/fix/bulk-delete-client-routing
fix: route bulk delete and trash by authenticated client
2026-10-24 17:54:39 +02:00
Linus Rath a2e795d132 Merge pull request #1306 from VasilisNtovolos/fix/zip-export-failure-retry
fix: reject incomplete email ZIP exports and allow retry
2026-10-24 17:54:35 +02:00
Linus Rath 225d84bf2b Merge pull request #1311 from vladonv/fix/uk-translation-forward-move-to
fix(i18n): correct Ukrainian "forward" and "move to" translations
2026-10-24 17:54:31 +02:00
Tobias Genannt 2b5a9dbfc5 feat: mirror regional presentation settings to plugin sandboxes
Plugins running in iframe sandboxes previously lacked access to the user's regional formatting settings (dateLocale, timeFormat 12h/24h, timeZone, and firstDayOfWeek) unless they requested privileged settings:read permissions.

This mirrors the host's resolved presentation preferences into the plugin sandbox:
- Adds RegionalSnapshot (locale, dateLocale, hour12, timeZone, firstDayOfWeek) to BackgroundInit, SlotInit, and LocaleChangeMsg.
- Implements snapshotRegionalSettings() in host-bridge, reusing host resolveDateLocale() and getEffectiveTimeZone().
- Subscribes stores/plugin-store.ts to useSettingsStore to broadcast updates to running sandboxes when regional preferences change.
- Exposes api.i18n.formatTime(date, options) and api.i18n.formatDate(date, options) along with regional getters on api.i18n.
2026-10-24 11:01:13 +02:00
Jacob ZeitzandClaude Opus 5.5 96526c1b41 feat: admin policy gate to list the Tags above the shared mailboxes
A new feature gate, tagsAboveSharedEnabled (default off, so the sidebar
keeps its order), lists the Tags section above the shared mailboxes
instead of below them. With many shared mailboxes expanded, the tags
otherwise end up out of sight. In Mountain View the tags then follow the
Labels list directly, also when More is open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:54:23 +02:00
Jacob ZeitzandClaude Opus 5.5 372fc9ec71 feat: let plugins update and remove the tags they added
keywords.add now records the plugin on each definition it adds
(addedBy). keywords.update changes the label, colour or visibility of
those definitions, never their id; keywords.remove deletes them, as
Settings > Tags does, and leaves the keywords on messages alone. Both
need settings:write and skip every other definition, so a plugin cannot
rename or delete the user's own tags or another plugin's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:54:23 +02:00
VasilisNtovolos 423c1bb329 fix: route bulk move by authenticated client 2026-10-23 13:16:26 +03:00
Linus Rath d1f4ccaccf Update CHANGELOG for version 1.17.1 release
Updated the changelog to reflect the release of version 1.17.1 and removed the unreleased section for version 1.17.2.
2026-10-22 23:49:30 +02:00
Linus Rath 8a31a83bc9 fix: update next.js and dompurify for published advisories 1.17.1 2026-10-22 23:39:03 +02:00
Linus Rath 2be5408be5 chore: release 1.17.1 2026-10-22 23:22:40 +02:00
Linus Rath a037f9a6e9 fix: do not offer push onboarding while the resync is restoring the subscription #1321 2026-10-22 23:15:32 +02:00
Linus Rath 7049844cf3 fix: keep the message list within the screen on phones 2026-10-22 23:08:39 +02:00
Linus Rath 310f910a6a fix: hand a mobile sign-in to the app when the browser was already signed in 2026-10-22 08:02:08 +02:00
lsamc 51404ed015 feat(plugins): allow inline actions beside sidebar section headings 2026-10-21 21:20:29 -04:00
ghoztyandClaude Opus 5.5 30f51e5ca4 feat: name the app with the configured APP_NAME in user-facing strings
Some user-facing strings still said "Bulwark" on a deployment with its own
APP_NAME: Settings > General > Default apps (protocol handlers), the "Open
Bulwark" notification, the rate-limit banner and toast, the plugin connect
dialog, one plugin permission text and the connector page.

These strings now take an {appName} placeholder, filled by productName():
the configured APP_NAME, or "Bulwark" when it is unset or the default
"Webmail" (the same rule as the TOTP issuer and the About card, #1160).
A stock install reads as before.

The settings search (the settings page and api.app.searchSettings) indexes
these texts with the name filled in, so "bulwark" or the configured name
finds Default apps and no result carries the raw placeholder.

Locales: the 13 keys in every locale that has "Bulwark" in them. Languages
that inflect the name (cs, et, hu, ko, ro, sk, tr) use a neutral form such
as "{appName} uygulamasında" instead of a declined "Bulwark'ta"; a native
check of those is welcome.

Not changed on purpose: the mobile app, push relay, Lite, demo and admin
texts, which speak about Bulwark itself.

Closes #1314

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:14:54 +03:00