Linus Rath efd31de051 fix: never send an account's offline edits to another account
Adding an account put the new account's session in the JMAP client as
soon as it was up, while the queue of offline edits (outbox) stayed on
the account in use, and ready to replay, until the new account's server
was checked. A retry, a network flip or the return from the OAuth
browser in that window replayed the queue through the new account, and
edits to the user's own mail took its JMAP account id. Stalwart's ids
repeat across accounts, so a queued move or delete of one account's
message "x" hit the other account's "x". An edit made in that window ran
the same way, and so did the rest of a replay already under way.

Account switches could overlap too: tapping B, then C before B's session
was up, left the mail list on C while B's switch, finishing last, put B
in the client and its queue in the outbox, so edits in C's list went to
B under C's ids. An older switch that failed last put back the account
it had left, under the newer one.

- the outbox replays and runs edits only while the client serves the
  account the queue belongs to, checked before every op, and holds the
  queue while another account signs in; a failed sign-in gives the
  client and the queue back to the account in use
- the outbox resumes only for the account the mail list shows
- every account change (a switch, a sign-in, a sign-out) takes a
  generation, and one a newer change overtook touches neither the client
  nor the stores; the client no longer installs the session of a load or
  sign-in that a newer one overtook
- a failed switch puts back the account the first of overlapping
  switches left, and tapping that account while they are under way goes
  straight back to it
- a session retry gives way to a switch or sign-in under way
- tokens refreshed for an account being left stay with that account;
  they were saved into the credentials of the account loaded meanwhile,
  which then signed in as the other one
2026-09-26 01:42:35 +02:00
2026-09-24 22:18:42 +02:00

Bulwark Webmail

Bulwark Mobile

Beta - work in progress. Many features are unfinished or rough. Expect bugs, missing functionality, and breaking changes between releases. Do not rely on this for primary email yet.

React Native (Expo SDK 54) client for Bulwark Webmail - a JMAP-based mail, calendar, and contacts app.

What works today

  • Sign in to any JMAP server (e.g. Stalwart)
  • Multiple accounts
  • Email list, threads, compose
  • Calendar (basic)
  • Contacts (basic)
  • Push notifications via the Bulwark relay - FCM by default, or UnifiedPush (e.g. ntfy) for devices without Google Play services
  • In-app sideload updates from GitHub Releases

What's missing or rough

  • iOS builds, but push notifications and client certificates are Android-only so far
  • S/MIME, plugins, themes - UI stubs only (filters & rules, the vacation responder and file storage are real implementations)
  • Calendar editing is partial; contacts editing is basic
  • No Play Store distribution yet (sideload APK from Releases); iOS ships via TestFlight

Run locally

npm install
npx expo start

Then press a for Android, i for iOS, or scan the QR with Expo Go.

For release APK builds and signing see docs/android-release.md. For iOS builds and TestFlight distribution see docs/ios-release.md.

License

AGPL-3.0-only. See LICENSE.

S
Description
Bulwark Mobile: React Native client for iOS and Android. Mail, calendar and contacts over JMAP. Beta.
Readme AGPL-3.0
30 MiB
Languages
TypeScript 95.9%
Kotlin 2.1%
JavaScript 0.9%
Swift 0.4%
HTML 0.4%
Other 0.2%