Commit Graph
1456 Commits
Author SHA1 Message Date
Linus Rath d86aa1d12b refactor: group security into sign-in, other apps and devices, and encryption 2026-10-19 17:46:42 +02:00
Linus Rath b1fa88841d refactor: move identities, sub-addressing and multi-account options onto the account page 2026-10-19 17:44:11 +02:00
Linus Rath 5b1d056eef feat: split the message list out of reading and fold content and senders into it 2026-10-19 17:40:52 +02:00
Linus Rath 1025c1973d refactor: fold the layout and themes tabs into appearance as sections 2026-10-19 17:33:39 +02:00
Stefan Hildebrandt 04efcfc1f3 fix: save a group identity's drafts in the group account's Drafts (#1090)
Drafts were always created in the primary account, so a message composed as
a group identity sat in the member's own Drafts while its Sent copy (since the
previous commit) went to the group.

- createDraft takes { accountId, previousDraftAccountId }: the draft goes to
  the account that owns the From identity (resolveSendAccountId, now public
  and briefly caching the identity lists for autosave), and the replaced
  version is destroyed in the account it lives in.
- The composer tracks draftAccountId next to draftId (save, re-resolve of
  attachment blobs, send, discard, stashed state), since draft ids are only
  unique within one account.
- sendEmail destroys the sent draft in options.draftAccountId; discarding
  (inline and Pro tab) deletes it there, through the identity's login.
- Re-opening a draft from a group/shared Drafts folder (or a stamped
  aggregate row) keeps its account.
- resolveSendAccountId is optional on IJMAPClient; without it drafts stay in
  the primary account.
- Tests: client unit tests for draft placement / replacement / send cleanup,
  E2E spec 18 draft cases (autosave + send, discard).
2026-10-19 16:33:27 +02:00
Linus Rath 391ed6c018 Merge branch 'fix/security-audit-2026-10' 2026-10-19 12:58:50 +02:00
Linus Rath 7e1e2aabf8 test: use a sidecar path instead of the now-denied translate route in the plugin POST test 2026-10-19 01:44:29 +02:00
Linus Rath 29b33eb46c fix: show attachment names without directional override characters 2026-10-19 01:32:30 +02:00
Linus Rath 546f34f47e fix: cap concurrent upstream favicon fetches 2026-10-19 01:32:29 +02:00
Linus Rath d13aada077 fix: bound how many CalDAV probes one discovery request can make 2026-10-19 01:32:29 +02:00
Linus Rath f35ed6fb02 fix: give every upstream mail server request a deadline 2026-10-19 01:32:28 +02:00
Linus Rath 1f11cc7249 fix: stop talking to a plugin frame once it has navigated to another document 2026-10-19 01:32:27 +02:00
Linus Rath 1fd5d0558c fix: send HSTS on TLS requests and drop the X-Powered-By header 2026-10-19 01:32:27 +02:00
Linus Rath 703a15663f fix: keep the extension directory URL off private addresses 2026-10-19 01:32:25 +02:00
Linus Rath 735b37b812 fix: refuse an extension directory keyring older than the newest one seen 2026-10-19 01:32:25 +02:00
Linus Rath 71036c1812 fix: validate the marketplace version and refuse a silent downgrade on update 2026-10-19 01:32:24 +02:00
Linus Rath e4a9027b30 fix: stop OAuth discovery from reading a well-known document off another host 2026-10-19 01:32:24 +02:00
Linus Rath 5632097971 fix: type the capped feed reader and the invitation sender lookup 2026-10-19 01:32:23 +02:00
Linus Rath 0b01a2d066 fix: ask before handing a sign-in to the mobile app and only to its own callback link 2026-10-19 01:22:19 +02:00
Linus Rath 0f1fc2bb5d fix: sanitise imported and synced HTML templates before the composer previews them 2026-10-19 01:15:39 +02:00
Linus Rath 8ed621914e fix: only count an SPF or DKIM pass aligned with the From domain as sender verification 2026-10-19 01:15:05 +02:00
Linus Rath 044c98e6d2 fix: cap the size of a synced settings blob 2026-10-19 01:15:04 +02:00
Linus Rath c0b6519136 fix: stop reading a calendar feed at the size cap instead of buffering it whole 2026-10-19 01:15:04 +02:00
Linus Rath 9e64d9a026 fix: drop remote images from plugin-authored HTML so a plugin cannot beacon past its allowed origins 2026-10-19 01:15:04 +02:00
Linus Rath e6064f3476 fix: only connect and proxy plugin credentials that a plugin known to the server declares 2026-10-19 01:07:50 +02:00
Linus Rath 685ce7f469 fix: keep plugin POSTs off the plugin proxy, secrets, agenda, ical and translate routes 2026-10-19 01:04:45 +02:00
Linus Rath c02aadd6a9 fix: preview HTML attachments as sanitised text in a locked frame instead of a same-origin blob document 2026-10-19 00:58:31 +02:00
Linus Rath 29cb6b7f61 fix: keep a crafted style attribute or read-receipt header from freezing the message view 2026-10-19 00:54:24 +02:00
Linus Rath f8eee3b12d fix: keep a crafted mail body or subject from stalling the reader in the verification code search 2026-10-19 00:54:24 +02:00
Linus Rath 31326c7daf fix: keep OAuth client secrets and the session secret out of the admin audit log, config API and dashboard writes 2026-10-19 00:50:16 +02:00
Linus Rath f91b214719 fix: key synced settings on the account a token login resolves to, not on a bare claimed name 2026-10-19 00:45:11 +02:00
Linus Rath 89ef4d14f2 fix: budget failed sign-ins per client and forward the client address to the mail server 2026-10-19 00:43:00 +02:00
Linus Rath d4b5c4b5c2 fix: load demo portraits from the mount prefix so a Lite bundle under a subpath stays self-contained 2026-10-19 00:29:37 +02:00
Linus Rath 8da659fd8c feat: install any version from the marketplace and show updates, withdrawn versions and advisories
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.
2026-10-19 00:09:39 +02:00
Linus Rath dd0da783c6 feat: keep replaced plugin and theme versions and roll back to them 2026-10-19 00:08:10 +02:00
Linus Rath dc837c25f2 feat: let an install link name the extension version to offer in the marketplace 2026-10-19 00:07:04 +02:00
Linus Rath 47e89b678e fix: scope demo queries to the account they are asked for, so merged views and search list each message once 2026-10-18 20:06:39 +02:00
Linus Rath 4c0017d0c1 feat: rework the demo around one persona with two accounts and a shared mailbox
The demo user becomes Nora Lindqvist, engineering lead at Meridian Labs,
in the week of a product launch. The fixtures tell one story across mail,
contacts, calendar, tasks and files, and exercise the features the
screenshots and the public demo should show:

- a second, mail-only login (her personal domain) and the shared Support
  mailbox delegated to the work account, so the account switcher, the
  shared section and the merged inbox have real content
- raw headers the way Stalwart writes them: the sender check fails on
  the phishing mail, newsletters carry a one-click unsubscribe, one mail
  asks for a read receipt, and spam scores show in the details
- an iMIP invitation with a served .ics, an event waiting for the answer
  on the calendar, and RSVP patches applied in the demo client
- @mentions as mailto links in a received mail, a verification code
  twelve minutes old, nested folders, named tags on the mail, contact
  groups, a scheduled message and tasks switched on
- every attachment and file backed by real bytes under public/demo,
  generated by `scripts/demo-assets/generate.mjs`; contact photos are
  bundled portraits instead of requests to randomuser.me
- folder counts computed from the mail instead of hand-kept numbers

Demo login seeds the tags, templates and merged-inbox settings once per
device and switches the cross-account gate on for the session; "Reset"
restores them. `bulwark-demo-simulate=off` in localStorage stops the
simulated incoming mail for screenshot runs.
2026-10-18 19:48:11 +02:00
Linus Rath eb18a13878 feat: show the contact card for @mentions in the composer and in received mail 2026-10-18 18:23:45 +02:00
Linus Rath fbae8acfb8 feat: turn @mentions into chips with a hover card 2026-10-18 17:52:11 +02:00
Linus Rath 0ac7bcb385 feat: show the message list as columns with one-line conversation rows #262 2026-10-18 17:37:21 +02:00
Linus Rath 8791fa5176 feat: offer contacts in @ mentions and add the picked one as a recipient 2026-10-18 16:36:28 +02:00
Linus Rath 0e6733d5e6 fix: drop plain-text emphasis markers from message previews #1260 2026-10-18 16:23:54 +02:00
Linus Rath 45840e722a Merge pull request #854 from dev-hive-kazniisa/fix/keyword-rename-sieve-sync
fix: renaming a tag leaves filter rules tagging under the old id
2026-10-18 15:02:15 +02:00
Linus Rath 99cf78a280 fix: keep shared folders from other servers when they reuse an account id #1108 2026-10-18 14:58:53 +02:00
Linus Rath 4f9271e25b Merge pull request #1108 from hildebrandttk/fix/cross-view-shared-folder-dedup
fix: list a shared folder reachable through two logins only once in c…
2026-10-18 14:57:30 +02:00
Linus Rath f3482ce020 fix: remember restored sign-ins only when the restoring account is remembered 2026-10-18 14:39:59 +02:00
Linus Rath 1e992e6c7f fix: check plugin dropdown messages before the host draws them 2026-10-18 14:39:59 +02:00
Linus Rath 7573471544 fix: keep plugins from reading mail of other connected logins #1273 2026-10-18 14:39:58 +02:00
Linus Rath 811e175cd0 fix: tell today's mail by the time zone setting in the sender line #1259 2026-10-18 14:39:58 +02:00