Linus Rath
8bf4df4513
feat: add a notifications panel for plugin notifications and app errors
2026-10-14 05:25:16 +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
1ba53655e5
fix: let identity hooks stop a plugin's change, send notification clicks to plugins that show notifications, and mark reading mail as high risk
2026-10-14 04:37:24 +02:00
Linus Rath
8ad8f44e78
Merge branch 'feat/plugin-host-apis' into feat/plugin-system-audit
...
# Conflicts:
# lib/plugin-sandbox/permission-text.ts
# lib/plugin-sandbox/permissions.ts
# lib/protocol-handlers/mailto.ts
# locales/en/common.json
2026-10-14 04:34:14 +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
3a83c00e00
feat: describe every place a plugin can show UI in one catalogue, with a permission for each area
2026-10-14 04:31:43 +02:00
Linus Rath
437bb1d11a
test: require every plugin permission to gate a method, hook or slot
2026-10-14 04:28:24 +02:00
Linus Rath
3a65964d26
feat: let plugins show notifications that name the plugin
2026-10-14 04:26:16 +02:00
Linus Rath
ead925c1b8
feat: let plugins open a filled-in composer and save drafts
2026-10-14 04:23:17 +02:00
Linus Rath
31205e44d8
fix: stop cutting off uploads over 10 MB that pass through the server, such as office documents saved from the editor
2026-10-14 04:17:51 +02:00
Linus Rath
08e2d65944
feat: let untrusted plugins save attachments and message sources of a given message
2026-10-14 04:16:31 +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
8fd6bc42c3
feat: let plugins read any message, list a folder and see the folders
2026-10-14 04:13:33 +02:00
Linus Rath
3aec045163
test: require a call site for every plugin hook
2026-10-14 04:06:37 +02:00
Linus Rath
121d8ba30c
feat: let plugins manage templates, sender signatures and the out-of-office reply
2026-10-14 04:06:06 +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
3df031edd1
feat: let plugins read and change calendar events and tasks
2026-10-14 04:02:47 +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
2fe865f108
feat: tell plugins when the server accepted a sent or scheduled message, but not an undone one
2026-10-14 03:58:58 +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
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
adf5ad6c16
test: require every calendar and task hook to have a call site
2026-10-14 03:46:11 +02:00
Linus Rath
348ec1d399
feat: let plugins stop app shortcuts and hear when one ran
2026-10-14 03:44:09 +02:00
Linus Rath
e16e8946a8
test: require every contact and file hook to have a call site
2026-10-14 03:42:34 +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
69dbc1b661
feat: tell plugins when a message body is on screen or a conversation unfolds, and let them rewrite links
2026-10-14 03:39: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
77088a6008
feat: tell plugins when toasts are shown and dismissed
2026-10-14 03:25:53 +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
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
af53675191
feat: add plain-data views of messages, events, contacts, tasks and files for plugin hooks
2026-10-14 03:16:25 +02:00
Linus Rath
a3cb9e630e
refactor: describe every plugin hook in one catalogue
...
The hook buses, the permission each hook needs and the docs were three
separate lists that had drifted: 145 of 198 hooks were never fired and
nothing noticed. `lib/plugin-hook-catalog.ts` now names each hook with
its kind, permission, payload and when it fires; the permission check
reads it, and a test fails for any catalogued hook without a call site.
Groups still being wired in this branch are listed in that test.
Also:
- new before-hooks for archive, spam, read state, star, keywords, folder
changes, RSVP, event import, tasks, file moves, settings, identities,
filters and out-of-office, plus onComposerClose and onSyncStateChange
- removed hooks that can never fire: the S/MIME group (S/MIME is a
plugin now), onMobileViewSwitch, onSidebarAppChange and the
registerShortcut pseudo-hook
- smime:read no longer grants anything; manifests that name it still
install, with a warning
2026-10-14 03:14:29 +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
8ef7ec022f
fix: deliver a plugin OAuth callback only to the plugin that started the flow
2026-10-14 03:04:17 +02:00
Linus Rath
bf1d8fd2c3
fix: stop keeping unanswered plugin hook calls and old slot callbacks around
2026-10-14 03:02:12 +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
3bfc0e69d0
fix: check attachments a plugin adds to the composer and keep callbacks out of shouldShow
2026-10-14 02:58:47 +02:00
Linus Rath
2adb1e2b12
fix: size toolbar plugin slots to their content and give composer plugin buttons their own row
2026-10-14 02:53:46 +02:00
Linus Rath
cef2438c33
fix: let untrusted plugins upload attachments for the composer again
2026-10-14 02:34:31 +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
a491eab317
fix: hash WKD names with WebCrypto instead of shipping a Node crypto polyfill to the browser
2026-10-14 02:31:39 +02:00
Linus Rath
23c4c654d7
fix: limit what a plugin can store, download, toast and send to a WKD lookup, and report refused admin config writes
2026-10-14 02:30:54 +02:00
Linus Rath
22846b4a9b
fix: keep blob uploads privileged-only and derive the WebAuthn salt from the calling plugin
2026-10-14 02:28:11 +02:00
Linus Rath
c4853a4bba
fix: check dev-directory plugins like uploads and keep their files inside the plugin folder
2026-10-14 02:26:56 +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
bb562362b8
fix: lay out plugin slots right-to-left in Arabic, Hebrew and Persian and use the app font size
2026-10-14 02:24:45 +02:00