Admins write an HTML and a plain-text signature with placeholders on
Organisation > Signatures, per scope. Users fill in the details it asks
for once, under Settings > Account. Without a lock it is the default for
addresses without a signature of their own; locked or hidden, it
replaces every signature.
- `lib/org-signature.ts` fills the templates: values escaped, lines whose
placeholders are all empty dropped
- the composer applies it right before the plugin signature, so new mail,
replies, forwards, re-opened drafts, plain text and identity swaps all
take it the way they take an identity signature; quick reply too
- a send finaliser puts a locked signature back once when it was deleted
- the identity editor shows the filled-in signature read-only with "Set
by your organisation" when locked, and no editor when hidden
- `signatureDetails` is a synced setting
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>
The old panel kept its active tab in a store, so every page sat at
/admin, the sidebar duplicated the webmail rail by hand, and each page
was a stack of boxed cards with their own save buttons. Plugin settings
were only reachable through a gear icon in a row of five.
- one catch-all route for the whole panel; pages switch through
history.pushState, so `/admin/plugins/<id>`, the back button, bookmarks
and connector links all work without a route transition
- sidebar laid out like the user settings: back to mail, search over
pages and their sections, two group headings, change password and
sign out at the bottom; the phone shows a list, then the page
- pages use SettingsSection rows instead of nested cards, with one page
header, one flash message and one save bar at the bottom (Discard,
Save, Ctrl+S); the unsaved-changes prompt still guards leaving
- plugins and themes are lists of rows with a toggle each; a row opens
the extension's own page with its settings, force-on, permissions,
kept versions and removal
- overview shows stat tiles, server facts and recent activity
- old `/admin?tab=x` links redirect; the tab store is gone and the
connector registry resolves admin links to the page URL
- `NEXT_TURBOPACK_ROOT` overrides the Turbopack root so `next dev` runs
from a worktree with a junctioned node_modules
The marketplace now talks to the extension directory's v2 API only. The
detail page lists every version, previews the one picked, installs it,
and refuses a version the publisher withdrew unless the admin confirms,
or one outside the Bulwark range it supports. The listing gains sort, an
Installed view and an updates strip fed by the directory's updates check,
with notices for advisories, deprecations and suspensions.
A self-hosted directory older than 2026-10-14 has no v2 API and no
longer works with the marketplace.
A new feature gate, archiveActionEnabled (default on), lets the admin turn the
Archive action off for installations that archive mail elsewhere, such as a
mail gateway. With it off, Bulwark offers no Archive anywhere: the viewer's
button and its overflow entry, the context menu for one or several messages,
Mountain View's selection bar, the hover and swipe actions, the E shortcut and
its help row, archiving after an export, and the archive mode setting (also in
the settings search). With it off nothing creates an Archive folder:
ensureArchiveMailbox returns null. Existing Archive folders stay ordinary
folders, moving mail into them by hand still works, and the plugin API is
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part 2 of 3 of the account archive agreed in #1198. When the admin turns on
"Account List Backup: Passwords" (off by default), saving the list offers to
include the passwords of the accounts signed in here with a plain password.
They are encrypted in the browser together with the list. On restore, those
accounts are signed in to in the background, one by one, without leaving the
active account; a refused password leaves the account waiting for a sign-in by
hand, as before. OAuth and TOTP accounts are saved without a password.
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