Commit Graph
602 Commits
Author SHA1 Message Date
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 06d00e10ee perf: keep the list on screen while a search runs and stop re-rendering on every keystroke 2026-10-15 00:12:59 +02:00
Linus Rath 2d67442a2b perf: list search results without waiting for the highlighted excerpts 2026-10-14 23:51:17 +02:00
Linus Rath 3fac196d3f fix: ask plugins before creating archive folders and marking whole folders read 2026-10-14 20:08:37 +02:00
Linus Rath f8448c6a45 fix: stop reporting calendar, task and contact changes as done when a plugin stopped them 2026-10-14 19:56:06 +02:00
Linus Rath 8204678847 fix: stop reporting mail actions as done when a plugin stopped them 2026-10-14 19:44:54 +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 78f72e0c03 fix: give plugins settings that change after they started, let their frames copy to the clipboard and tell them the user's time zone 2026-10-14 09:01:03 +02:00
Linus Rath 7a6a0fc67f Merge branch 'slots/nav' into feat/plugin-system-audit
# Conflicts:
#	lib/__tests__/plugin-slot-catalog.test.ts
2026-10-14 05:30:34 +02:00
Linus Rath 8bf4df4513 feat: add a notifications panel for plugin notifications and app errors 2026-10-14 05:25:16 +02:00
Linus Rath eb34caa381 feat: let plugins add entries to file menus and the selection toolbar, and a section to file previews 2026-10-14 04:58:21 +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 1307280fd8 Merge branch 'hooks/settings' into feat/plugin-system-audit 2026-10-14 04:05:47 +02:00
Linus Rath 0a98ffa711 fix: give plugins plain message data, let them add only real messages to search results and skip a draft save 2026-10-14 04:05:43 +02:00
Linus Rath c464ca2030 Merge branch 'hooks/mailstore' into feat/plugin-system-audit 2026-10-14 04:00:59 +02:00
Linus Rath cc9553590c Merge branch 'hooks/mailui' into feat/plugin-system-audit 2026-10-14 04:00:45 +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 122ca1dc8b feat: tell plugins when the selection or the open folder changes 2026-10-14 04:00:14 +02:00
Linus Rath 58b6e914b3 feat: let plugins change a search's query and filters before it runs 2026-10-14 03:58:47 +02:00
Linus Rath 7323310b21 feat: tell plugins about new inbox mail, sync progress and the live-update connection 2026-10-14 03:56:37 +02:00
Linus Rath fb397d7457 feat: tell plugins when the password, two-factor sign-in, app passwords, encryption or display name change 2026-10-14 03:55:20 +02:00
Linus Rath 77d8b604ae feat: tell plugins when folders are created, renamed, deleted or emptied, and when the quota changes 2026-10-14 03:55:18 +02:00
Linus Rath 286cce6877 feat: tell plugins when messages are deleted, moved, archived, marked or tagged, and let them stop it 2026-10-14 03:54:40 +02:00
Linus Rath e93c9f89ae feat: tell plugins about the out-of-office reply, and let them stop a change to it 2026-10-14 03:52:00 +02:00
Linus Rath 7b2119456d feat: let plugins stop or prefill the composer and mailto links, and tell them when it opens, closes and saves a draft 2026-10-14 03:50:55 +02:00
Linus Rath 8e72c05a8f feat: tell plugins when filter rules are loaded or edited, and let them stop a save 2026-10-14 03:49:17 +02:00
Linus Rath f9c53e5582 feat: tell plugins when templates change or are inserted, and let them rewrite a template before it goes in 2026-10-14 03:45:12 +02:00
Linus Rath 74b194c3e5 feat: tell plugins about sender identity changes and the chosen From, and let them stop a change or rewrite the signature 2026-10-14 03:44:33 +02:00
Linus Rath be26f96bea Merge branch 'hooks/calendar' into feat/plugin-system-audit 2026-10-14 03:44:13 +02:00
Linus Rath 0cf80c1689 feat: tell plugins when tasks are loaded, created, changed, checked off, deleted or filtered, and let them stop changes 2026-10-14 03:43:33 +02:00
Linus Rath 77c7589e04 Merge branch 'hooks/contacts' into feat/plugin-system-audit 2026-10-14 03:40:05 +02:00
Linus Rath 051e82b487 feat: tell plugins about layout changes, drag and drop, and sidebar apps 2026-10-14 03:40:04 +02:00
Linus Rath 6b98fccead feat: tell plugins when a folder is opened, files are selected or starred, and an action is undone 2026-10-14 03:39:30 +02:00
Linus Rath 8e2f9d7c94 feat: tell plugins when the calendar view, its calendars or subscriptions change 2026-10-14 03:36:35 +02:00
Linus Rath 96f0681ab5 feat: tell plugins when files are uploaded, downloaded, deleted, renamed, moved or copied, and let them stop it 2026-10-14 03:36:13 +02:00
Linus Rath e62553642f feat: tell plugins about sign-in, token renewal and account changes 2026-10-14 03:32:58 +02:00
Linus Rath 8ec7dc54ab feat: tell plugins when contacts are opened, selected, moved or imported and when groups change 2026-10-14 03:27:50 +02:00
Linus Rath c5dc263259 fix: stop plugins from blocking or stalling sign-out 2026-10-14 03:27:34 +02:00
Linus Rath 1ae73ceac1 feat: tell plugins when events are opened, created, changed, deleted, answered or imported, and let them stop changes 2026-10-14 03:26:39 +02:00
Linus Rath f530f5849d feat: tell plugins when preferences change, are imported, exported, reset or synced, and let them stop a change 2026-10-14 03:26:03 +02:00
Linus Rath 77088a6008 feat: tell plugins when toasts are shown and dismissed 2026-10-14 03:25:53 +02:00
Linus Rath 96f8aa6a63 feat: tell plugins when contacts are created, changed or deleted, and let them stop it 2026-10-14 03:24:19 +02:00
Linus Rath 02a7dfab16 feat: tell plugins when the colour scheme or theme changes 2026-10-14 03:24:00 +02:00
Linus Rath 480a1bb226 fix: clear a plugin's stored data when the admin removes it, not only on uninstall 2026-10-14 03:05:05 +02:00
Linus Rath f048db7b52 fix: count each plugin hook failure once and keep a plugin that kept failing turned off 2026-10-14 02:33:45 +02:00
Linus Rath 8f70951555 fix: give plugins their default settings and apply setting changes without a reload 2026-10-14 02:21: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