Commit Graph
672 Commits
Author SHA1 Message Date
Linus Rath 8583c9efef feat: hide the version from the connector probe when the login page hides it #896 2026-10-17 19:18:21 +02:00
Linus Rath b611d9c028 feat: refresh sender icons that changed on the sender's website #960 2026-10-17 19:18:18 +02:00
Linus Rath deb106736e fix: load the admin panel when the config is read-only #1249 2026-10-17 19:17:48 +02:00
Linus Rath a854447346 fix: apply admin policy defaults to user settings #1248 2026-10-17 19:17:46 +02:00
Linus Rath 76d12cff30 feat: ask before leaving the admin panel with unsaved changes #1255 2026-10-16 22:44:38 +02:00
Linus Rath 20b0c9b0b5 fix: refuse OAuth auto-setup before touching Stalwart when the config is read-only #1250 2026-10-16 22:35:07 +02:00
Linus Rath 0b49d01a76 fix: keep synced calendar subscriptions from stale devices and past deletions #1064 2026-10-15 23:54:37 +02:00
Linus Rath a852001d4f feat: let admins turn off the custom From address in the composer 2026-10-15 14:43:07 +02:00
Linus Rath 1cc949416c perf: load the mail view's code while the login form is shown 2026-10-15 03:24:05 +02:00
Linus Rath db2c0aff3d perf: load conversation sizes with the folder page instead of in a second request 2026-10-15 00:14:57 +02:00
Linus Rath e7bf3c6e42 test: add a benchmark-sized message corpus to the dev mock 2026-10-14 23:51:17 +02:00
Linus Rath 15edc5943b feat: check the extension directory's signature before installing from the marketplace 2026-10-14 21:36:50 +02:00
Linus Rath 3d5c46bbcf fix: make plugin sidebar rows as tall as folder rows on phones 2026-10-14 18:49:56 +02:00
Linus Rath eba711bd54 Merge branch 'feat/plugin-system-audit' 2026-10-14 18:09:19 +02:00
Linus Rath 7464e4db93 fix: reset the browser's button look on kit components that are a button themselves 2026-10-14 14:08:41 +02:00
Linus Rath 633df44090 fix: keep the sign-in response small enough for proxies with large OIDC tokens #1237 2026-10-14 13:59:41 +02:00
Linus Rath 1bd4f743a1 feat: give plugins the app's own controls and draw their dialogs like the app's dialogs 2026-10-14 11:10:14 +02:00
Linus Rath 607f1b2496 feat: let plugin notifications carry a link to the plugin's own server 2026-10-14 10:58:19 +02:00
Linus Rath c3cf0ddcff feat: tell plugins whether the admin has set up their accounts and keys 2026-10-14 08:24:28 +02:00
Linus Rath 49511dff38 feat: let plugins read their own non-secret admin settings without the admin permission 2026-10-14 06:23:10 +02:00
Linus Rath 86e593a752 feat: add a command palette on Ctrl+K where plugins can add their own commands 2026-10-14 05:10:10 +02:00
Linus Rath b8b7a4ed15 feat: let plugins add pages of their own with an entry in the navigation 2026-10-14 04:57:00 +02:00
Linus Rath 5d9268c923 feat: let plugins add buttons, calendar day labels and pages, and use connected accounts from the sandbox 2026-10-14 04:31:43 +02:00
Linus Rath 60257bb732 feat: let users connect accounts for plugins in a dialog the plugin can't read, and disconnect them in settings 2026-10-14 04:14:13 +02:00
Linus Rath 022b83c005 feat: let plugins use accounts and API keys through the server without seeing them
Plugins that talk to Nextcloud, Paperless or an AI provider used to need
the password or key in their own settings, readable by the plugin and
stored in the browser. A plugin can now declare credentials in its
manifest and send requests "with credential X" through the server:

- `credentials` in the manifest: admin scope (secret and server from the
  admin config) or user scope (the user connects an account; the server
  address is fixed or chosen by the user)
- `/api/plugin-secrets`: the user's connected accounts, encrypted per
  mail account under `PLUGIN_SECRETS_DIR`; listing never returns secrets
- `/api/plugin-proxy`: adds the secret and forwards only to the
  credential's own origin, through the SSRF guard unless the admin set
  the server up or listed it in `PLUGIN_PROXY_PRIVATE_ORIGINS`; no
  redirects or WebDAV moves to other servers, streamed bodies capped at
  512 MB up and 2 GB down, 300 requests a minute per plugin, 8 at once
  per user, and one audit line per request without paths or bodies
- a capture mode that stores a secret from a sign-in response (Nextcloud
  Login Flow v2) and removes it from what the plugin gets back
2026-10-14 04:00:36 +02:00
Linus Rath 606861eb71 feat: tell plugins about the app's lifecycle and navigation on every page, not only in mail 2026-10-14 03:19:54 +02:00
Linus Rath ada81d5f8f fix: hide the Next.js dev badge inside plugin slots and warn that dev sandboxes are not isolated 2026-10-14 03:01:13 +02:00
Linus Rath 15cec58a46 fix: serve plugin bundles only to signed-in users 2026-10-14 02:27:35 +02:00
Linus Rath 9408daaf5e fix: keep an extension's admin state on re-upload and remove its config when it is deleted 2026-10-14 02:25:45 +02:00
Linus Rath 592db209db fix: sign plugin bundles when they are installed and require the signature for privileged plugins 2026-10-14 02:05:47 +02:00
Linus Rath e720be7e17 feat: let users install their own plugins, with admin review of the actual code
The admin page offered "User Plugin Uploads" and "Require Admin
Approval", but nothing in Settings used them: there was no upload, no
uninstall and no way to ask for approval, and the admin had no list of
requests. The approval code that existed pinned a hash of the code only
and showed the admin a manifest the browser sent, never the code.

Now:
- Settings > Plugins has an install button (when uploads are allowed),
  a remove button for the user's own plugins, and lists in plain
  language what each plugin may do, high-risk items first
- an install sends the ZIP to the server, which reads the manifest and
  code itself and pins the request to a hash of both
- the admin Plugins tab lists requests with the code and approves or
  denies them; a user may have 10 open requests
- a user plugin is checked again on every start, so a revoked approval
  or turning user plugins off takes effect
- the consent dialog and the plugin settings are translated, use the
  theme colours, and show the sites a plugin may send data to
2026-10-14 02:03:26 +02:00
Linus Rath e9f87c7970 fix: install Theme API v2 themes and their skins from the admin page and the marketplace 2026-10-14 01:47:58 +02:00
Linus Rath e57b7a2c18 fix: check plugin and theme packages the same way on every install path
The Settings upload, the admin upload, the marketplace install and the
marketplace preview each parsed the ZIP and manifest with their own copy
of the code, and the copies had drifted. A `permissions` string skipped
validation and was then matched by substring, a small ZIP could inflate
to hundreds of megabytes on the server, the Settings upload dropped
`locales` and took origin lists unchecked, and settings schemas were
never checked at all.

All of them now go through `lib/extension-package.ts`:
- every file is inflated through a byte cap, with a limit on entries
- one manifest check: types, permissions, entrypoint, version,
  minAppVersion, settingsSchema, configSchema, locales and origin lists
- only checked fields are stored
2026-10-14 01:43:43 +02:00
Linus Rath 0dd04ed21d fix: stop forcing a theme after the admin deletes or disables it 2026-10-14 01:34:40 +02:00
Linus Rath 468c1aac0c fix: refuse marketplace bundles whose id differs from the directory entry 2026-10-14 01:32:44 +02:00
Linus Rath 25cbbf8c10 fix: restore the full screen height when the iOS app resumes #1226 2026-10-13 14:53:23 +02:00
Linus Rath 8ad072e458 feat: generate a session secret on first start when none is configured 2026-10-13 13:17:34 +02:00
Linus Rath 3da46b5a0d feat: remember every sign-in unless the admin shows the remember me box 2026-10-13 13:13:56 +02:00
Linus Rath f160dae25c fix: stop the panes sliding when animations are turned off #1215 2026-10-12 01:55:57 +02:00
Linus Rath c652fec371 feat: give Mountain View's compose window Gmail's title bar and bottom bar 2026-10-12 01:26:03 +02:00
Linus Rath 1980de68c8 feat: give Mountain View's open message Gmail's toolbar, pager and header 2026-10-12 01:10:10 +02:00
Linus Rath 20b52a060f feat: draw Mountain View's message rows like Gmail's 2026-10-12 01:01:09 +02:00
Linus Rath cf558e7e9f feat: lay out Mountain View's navigation like Gmail's, with a Labels section 2026-10-12 00:46:48 +02:00
Linus Rath ae151cec25 feat: set Mountain View's content on a rounded card over a tinted canvas 2026-10-12 00:37:59 +02:00
Linus Rath 4af42858f0 Merge pull request #1168 from lucamzanon/feat/mountain-view-layout
feat: add Mountain View, an optional alternative layout
2026-10-10 19:23:59 +02:00
lucamzanon 9560a8b74f feat: optional encrypted backup of the account list
Users with several accounts can save the list of accounts in their browser
(address, server, label, colour) on the webmail server and bring it back on
another device. The list is encrypted in the browser with a password the user
chooses (PBKDF2-SHA-256, 600,000 iterations, AES-256-GCM, owner bound as
additional data); the server stores only the envelope, one file per owner
under SETTINGS_DATA_DIR/account-archives. No mailbox passwords are included.

Off by default behind the admin feature gate accountArchiveEnabled, pinned
off in Lite. Every method of /api/account-archive needs a session cookie of
the owner, matched without regard to case, whose credential is checked
against the mail server on each call; listing included.

Restored accounts this browser lacks are listed as awaiting sign-in: they
survive a reload, and opening one leads to the sign-in form with the address
filled in. Accounts already present get their archived label and colour.
2026-10-09 10:54:38 +02:00
Linus Rath a2e36e6e86 fix: open read-only documents in ONLYOFFICE without the -103 warning #1187 2026-10-08 14:32:39 +02:00
lucamzanon ade30622f2 Merge remote-tracking branch 'origin/main' into up/feat/mountain-view-layout
# Conflicts:
#	components/mail/mail-app.tsx
2026-10-08 10:05:29 +02:00
Linus Rath f87be32388 fix: keep an empty draft subject empty so send still warns #1189 2026-10-07 20:22:51 +02:00
Oğuz YılmazandClaude Opus 5.5 54ec8c6584 feat: let operators keep the message subject out of the tab title
Opening a message puts its subject in the browser-tab title. The title does
not stay in the tab strip: browsers keep it in history and in the
session-restore list, and screen shares show it. For mailboxes that hold
other people's correspondence that is a leak nobody audits.

A new feature gate, tabTitleSubjectEnabled ("Subject in Tab Title" under
Admin -> Policy), is on by default, so nothing changes for existing
installs. With it off, the title names the folder instead, so the tab still
says where you are. It is an admin gate rather than a user setting: whose
mail the boxes hold is a deployment decision.

The gate counts as off until the policy has loaded, so a subject never
slips into history while the setting is still unknown.

Refs #1159

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 08:26:51 +03:00