First-launch web setup wizard. New installs no longer need to hand-edit .env.local - point a browser at the container and the wizard probes the JMAP server(s), configures OAuth/OIDC, generates the session secret, accepts branding uploads, and provisions the initial admin password. Admin storage is now split into ADMIN_CONFIG_DIR (operator-authored, mountable read-only after setup) and ADMIN_STATE_DIR (runtime audit log and login timestamps); the legacy ADMIN_DATA_DIR keeps working for existing installs.
Features
Setup: Web setup wizard with multi-step flow: Server, Auth, Security, Logging, Branding, Review, Admin
Setup: Admin config/state directory split with optional ADMIN_CONFIG_READONLY for immutable deployments (#226)
Setup: File uploads on the wizard branding step
Setup: Redesigned review step with grouped summary and an advanced toggle for the full config
Setup: Require explicit confirmation when JMAP probe finds no session
Mail: Drag attachments out of the viewer to the local file system (#267)
Mail: Configurable signature position β above or below quoted text (#266)
Mail: Signature position is now searchable from the email behavior settings
Mail: Show avatar in Focused list for compact density and above
Mail: Align Focused list preview with other layout previews
Compose: From-header override in the composer with catch-all auto-reply, replies to an alias on a domain you own pre-fill the alias as the sender even when it isn't a configured identity (#246)
Performance
Mail: Prefetch initial email data on login
Auth: Parallelize login round-trips and drop redundant JMAP re-verify
Fixes
Auth: Skip upstream JMAP reverify for trusted URLs (#237)
Auth: Show account identity in the switcher header instead of the sending alias
Compose: Fall back to the primary identity signature on reply
Setup: Drop redundant first-login banner about removing ADMIN_PASSWORD (#222)
UI: Consistent notice cards for server probe results
New: Help shape Bulwark Webmail. Each instance now sends a lightweight daily heartbeat (version, platform, bucketed account counts, feature toggles - never message data or PII) so we can see which platforms and features actually get used and prioritize fixes where they matter most. You're in control: opt out any time from Admin β Telemetry or by setting BULWARK_TELEMETRY=off. Full schema in the privacy notice.
Features
Telemetry: Anonymous instance telemetry, on by default. Reports schema version, platform, bucketed account counts, and feature toggles only - disable from the admin UI, with BULWARK_TELEMETRY=off, or by clearing the endpoint
Telemetry: Track unique logins (HMAC'd per instance, 90-day retention) so the heartbeat can report bucketed account totals without storing usernames
Plugins: Theme API v2 with token compiler and skin slot
Plugins: Extension preview page and detailed extension info API
Calendar: Right-click context menu on empty calendar space
Docker: Persistent named volume for telemetry data so the instance id and admin's consent choice survive container upgrades
Fixes
Security: Block telemetry endpoint from pointing at internal/loopback hosts (validation + DNS-rebind re-check at fetch time)
Plugins: New composer-sidebar slot and ui:composer-sidebar permission β plugins can now render a panel on either side of the New Message dialog. See repos/subway-surfers for an example
Plugins: Manifests can declare frameOrigins β a strictly-validated list of https://host origins the plugin needs to embed. The proxy reads the union from enabled plugins and merges it into the host CSP frame-src, so the host CSP no longer needs to know about specific embed providers
Calendar/Contacts: JMAP sharing for calendars and address books
i18n: Czech language support
Fixes
Security: Validate URLs before outbound fetch
Calendar: Prevent drag creation on touch events in the time grid
Contacts: Emit RFC 9553 name kinds and decode QUOTED-PRINTABLE in vCard import (#224, #187)
Mail: Hide preview line in compact density to match settings preview (#223)
Proxy: Inline matcher for Next.js proxy and drop unnecessary Node.js runtime config
i18n: Portuguese fixes for "ficheiro" and "contactos" variants
Self-service portal now needs Stalwart 0.16+: Stalwart dropped its self-service HTTP API in 0.16.0 and replaced it with JMAP. Bulwark Webmail only talks to the new JMAP endpoint, so the self-service portal (account settings, app passwords, API keys) requires Stalwart 0.16 or newer. STALWART_API_URL is deprecated, these actions go through the normal JMAP session.
Features
Stalwart: Migrate Stalwart management API to JMAP x: methods for Stalwart 0.16
Admin: Add API Keys management and IP allowlist for App Passwords
Contacts: Revamp contact detail view with filters, photo, print, and duplicate actions
Logging: Add logging categories for better log management
Fixes
Security: Harden security with CSP enforcement, SSRF redirect validation, reenabled S/MIME chain verify, IP spoofing prevention, and PDF iframe sandbox
Security: Harden proxy authentication and SSRF defenses
Security: Block plugins with dangerous JS patterns and enforce strict session secret length validation
S/MIME: Add self-signed certificate detection and update status messages for S/MIME signatures
Email: Auto-focus input fields in email composer for improved user experience (#126)
Mailbox: Prevent orphaning of nested mailboxes by restricting deduplication to root-level folders
JMAP: Strip server-immutable fields from updates before sending to JMAP (#128)
Files: Update file feature disabled messages and add stability warnings
i18n: Add missing translation keys to all non-English locales