Commit Graph
2405 Commits
Author SHA1 Message Date
Linus Rath 94b9fe8803 fix: start out of office with real text and never switch on a blank reply
Out of office used grey placeholder text, so switching the reply on sent
an empty message. A reply never written now opens with an editable subject
and message in the user's language; the switch stays off while the message
is empty and says "Write a message first", and a reply that is on can't be
saved with its text deleted. Forwarding won't switch on without an address,
and the address field shows while it is off. The page puts the switch
first, then "Reply to" with plain choices, then "From/Until (optional)",
then one message editor with formatting instead of a text box plus a
second "Formatted message (HTML)" box. A message nobody edited is sent as
the server has it. A failed save is no longer retried once at once when
the last change was a click.

Test changes: the forward tests type the address before switching
forwarding on (it no longer switches on without one) and check the new
order and option labels; the HTML-body and template tests use the one
editor instead of the text box and HTML switch, which are gone. The
search index names the new rows.
2026-11-04 06:29:53 +01:00
Linus Rath 0f3d534246 test: give the app lock's tests time for two PBKDF2 runs on a busy machine 2026-11-04 05:24:11 +01:00
Linus Rath 0aa0f21955 Merge branch 'feat/desktop-offline' into feat/do-key-fixes
# Conflicts:
#	lib/desktop/types.ts
2026-11-04 04:53:26 +01:00
Linus Rath ce3e3b9db2 fix: let a remote wipe and a wipe from settings reach what only the desktop app's main process can delete 2026-11-04 04:47:38 +01:00
Linus Rath f9503570ca Merge branch 'feat/desktop-offline' into feat/do-key-fixes
# Conflicts:
#	components/settings/app-lock-settings.tsx
#	stores/auth-store.ts
2026-11-04 04:16:14 +01:00
Linus Rath 88d64b7f95 fix: protect the keys to the mail on this device for real
The review found the store key readable from a copy of the disk. The
desktop app only added its OS layer with the lock on, the record from
before a lock stayed in LevelDB and opened the mail with no PIN, any
frame could unwrap the PIN record and guess at it, a lock left the key
in the renderer's memory, and a store waiting after a refused login went
to whoever signed in next under the same username@host.

- The desktop app wraps the store key with safeStorage, lock or no lock.
  A record without the layer gets it at its next open. A refusal is said
  out loud, and only a computer with no key store goes without, which
  settings say. So do they for a browser, which has no such layer.
- A record that gained layers, and every record after a changed PIN, asks
  for a new key: `sqlite3_backup` into a new file under a new key while
  the store keeps working, one write to the record, then the old file
  goes. A changed PIN makes a new lock key, since the old PIN's record
  stays on disk too. The passkey and OS unlock go with the old key.
- `wrap` and `unwrap` come through `claim()`, and the key under the PIN
  takes a secret from main, one counted trip per guess.
- A lock on the desktop ends the renderer rather than reload in it.
- A sign-in compares the waiting store's JMAP account and server first,
  and wipes on a mismatch. The account id keeps its form: every store,
  setting and server record of an account is keyed by it.
- The 30 days also run in an app that stays open.

Changes an existing assertion: turning the lock off now keeps the
safeStorage layer, by decision, so that test expects it to stay.
2026-11-04 04:15:31 +01:00
Linus Rath c49c68ffbd Merge branch 'feat/desktop-offline' into feat/do-proxy-fixes 2026-11-04 04:12:23 +01:00
Linus Rath 8cd9d72558 Merge branch 'feat/desktop-offline' into feat/do-proxy-fixes 2026-11-04 03:55:52 +01:00
Linus Rath bce0c0b744 Merge branch 'feat/desktop-offline' into feat/do-keystore-fixes 2026-11-04 03:52:09 +01:00
Linus Rath 7443654459 Merge branch 'feat/do-package-fixes' into feat/desktop-offline 2026-11-04 03:43:04 +01:00
Linus Rath 92e6ee1bfa Merge branch 'feat/do-trust-fixes' into feat/desktop-offline 2026-11-04 03:43:04 +01:00
Linus Rath be8aba2ae7 Merge remote-tracking branch 'origin/main' into feat/desktop-offline
# Conflicts:
#	stores/auth-store.ts
2026-11-04 03:42:18 +01:00
Linus Rath d3308e7729 Merge branch 'feat/desktop-offline' into feat/do-keystore-fixes
# Conflicts:
#	lib/desktop/__tests__/policy-schema.test.ts
2026-11-04 03:31:22 +01:00
Linus Rath 66c6b61853 fix: keep downloaded mail out of the browser's HTTP cache 2026-11-04 03:31:16 +01:00
Linus Rath 2f846bb2da fix: list the browser sign-in budget as shared server state 2026-11-04 03:30:48 +01:00
Linus Rath 9b61b79d5c fix: sign only CMS signed attributes through api.keystore, and ask a user about a managed plugin's keystore
The shell now takes a message's signed attributes where it took a digest,
so a page can't get a login or TLS digest signed. A quiet option lets a
plugin answer from what's allowed, for anything the user didn't ask for.

An admin's install no longer covers the certificates on someone's own
computer: a managed plugin gets `keystore` when that person says yes, also
when an update adds it, and it's forgotten once everyone has signed out.

Changed test assertions: the fixture plugin needs a grant now, as managed
alone is no longer enough, and the bridge gets an options argument.
2026-11-04 03:23:45 +01:00
Linus Rath b1f26a93bf feat: let an organisation turn the system certificate store off by policy 2026-11-04 03:23:44 +01:00
Linus Rath 484ce34f5d Merge branch 'feat/do-browser-signin' into feat/desktop-offline 2026-11-04 03:19:32 +01:00
Linus Rath cb9a5ac810 Merge branch 'feat/do-edit-attachments' into feat/desktop-offline 2026-11-04 03:16:35 +01:00
Linus Rath 466fa7f974 fix: keep the desktop app's session secret and admin password out of its server's environment 2026-11-04 03:15:42 +01:00
Linus Rath a9e33ec2d6 fix: stop a page wiping another account's plugin secrets by naming it in the desktop app
A wipe by name took any username and server with no session behind it. It
now needs a sealed cookie the account got while it was signed in, since a
dropped account has no session cookie left. The old wipe test asserted that
a name alone was enough, which is the behaviour being removed.
2026-11-04 03:15:35 +01:00
Linus Rath 149d08d87b test: load the preview route once before its cases, so a slow import can't spill into them 2026-11-04 03:13:59 +01:00
Linus Rath f39cff2377 fix: call no relay from the worker in no-third-party mode, and handle several accounts in one push side by side 2026-11-04 03:13:59 +01:00
Linus Rath d8e2a4f42c fix: keep a waiting re-sync from undoing what another tab turned off, and note the relay on refresh 2026-11-04 03:13:59 +01:00
Linus Rath 9432345440 fix: keep a nothing-new notification from closing or replacing a real one 2026-11-04 03:13:59 +01:00
Linus Rath 8cb218ce3c fix: apply email notifications off and do not disturb per login, not to every login's mail 2026-11-04 03:13:59 +01:00
Linus Rath 248f9c261b fix: take down push for logins with no connection when signing out of everything 2026-11-04 03:13:59 +01:00
Linus Rath 9bc31b54ab fix: keep notifications generic after the browser closed when the organisation has idle limits 2026-11-04 03:13:59 +01:00
Linus Rath 6dbda4424e fix: stop a stuck push setup from holding up every tab and login 2026-11-04 03:13:58 +01:00
Linus Rath bc8653de8b fix: only replace a browser subscription on the relay's own answer, and move the other logins along 2026-11-04 03:13:58 +01:00
Linus Rath 226b9383ce fix: show a generic notification instead of guessing which login a push is for 2026-11-04 03:13:58 +01:00
Linus Rath f0617a61b1 fix: only treat a server subscription as this browser's when its device id matches 2026-11-04 03:13:58 +01:00
Linus Rath 6ffa0a3715 fix: show the real sender and subject for a push after the browser was closed 2026-11-04 03:13:57 +01:00
Linus Rath 5c62c57657 fix: replace a browser subscription the push service gave up on 2026-11-04 03:13:57 +01:00
Linus Rath a6ef818149 fix: end a login's push registration when it signs out, is removed or wiped 2026-11-04 03:13:57 +01:00
Linus Rath 8b4fb72357 fix: say in plain words why push could not be turned on or off 2026-11-04 03:13:57 +01:00
Linus Rath d520af51b2 fix: restore push when the browser replaces its subscription with no tab open 2026-11-04 03:13:56 +01:00
Linus Rath 8a69c35206 fix: open a notification in the app window, not a pop-out or a frame 2026-11-04 03:13:56 +01:00
Linus Rath 33249ca57a fix: show a notification even if building it fails 2026-11-04 03:13:56 +01:00
Linus Rath 2c462c304e fix: show the right preview when an account id is in more than one login 2026-11-04 03:13:56 +01:00
Linus Rath fc6a209727 fix: keep push notifications off screen with email notifications off or do not disturb on 2026-11-04 03:13:56 +01:00
Linus Rath 7fb0242a7b fix: open the new message from its notification however much older mail is unread 2026-11-04 03:13:56 +01:00
Linus Rath 376465ed80 fix: notify for every account a state-change push names 2026-11-04 03:13:56 +01:00
Linus Rath 6ca6448b5e fix: remove the record from the old relay when push moves to another one 2026-11-04 03:13:56 +01:00
Linus Rath 2551823006 fix: let tabs take turns setting up push so two can't race into two subscriptions 2026-11-04 03:13:55 +01:00
Linus Rath 4586f16c2e fix: remove the unverified subscription when push verification fails, and poll through a network blip 2026-11-04 03:13:55 +01:00
Linus Rath 3a805d1631 fix: restart push verification when the mail server skipped it after a quick off and on 2026-11-04 03:13:55 +01:00
Linus Rath c844f2a5f3 fix: finish a wipe in the desktop app, which never answers about shown notifications 2026-11-04 03:12:43 +01:00
Linus Rath 37d0200e43 Merge branch 'feat/desktop-offline' into feat/do-browser-signin 2026-11-04 03:11:34 +01:00
Linus Rath a048cb3553 fix: stop an approved mail server sending the desktop app to a server nobody approved 2026-11-04 03:10:26 +01:00