A persisted account id with no subject yet read as decided: Everyone's
noOffline wiped mail a group scope allowed, and a wider scope went out at
every reload. A public, partial policy counted as the organisation's word,
and turned on the desktop default in a forbidding organisation.
- an organisation's cap on one file now binds a pin
- Clear and the off switch read what would be lost when asked, messages,
changes and drafts, and Clear waits for a connection
- turning one account off survives the last one going off, and off then on
no longer warns of an eviction
- a tab that takes over the store sends no scope until it has heard the policy
- a dropped account is judged by what applies to anyone
- a choice reaches the store once it settles; progress announces phases only
- restored Pro tabs ask for their titles
The offline section of Settings > Backup & reset now shows, per account, the
space each part takes, the last sync, a first sync's progress with the time
left, the window and attachment choices, and clearing the account. All
conflicts, calendar and contacts too, are listed there and counted in the
banner.
- the organisation's caps beat the user's choice and the desktop default, and
every path that takes a scope goes through `effectiveScope`
- the desktop app keeps mail without asking, says so once, and stays off for
an account where the user turned it off
- `navigator.storage.persist()` is asked on turning it on, and a refusal
warns with a way to ask again; Safari gets the 7-day hint when not installed
- a store the browser deleted is noticed, says what was lost and syncs again
- a full disk says so, with what to do
- those who had offline mode keep it, with the 30 days they had
- Keep offline in the Files app's menu
A security and an accessibility review of the proofreading hook found
gaps, fixed here.
What leaves the browser:
- A checker gets a name for each composer of its own, not the composer's
id, so it can't reach the message through the other api.composer calls
after proofreading stops.
- Checking pauses while a plugin that can sign or encrypt is turned on but
still starting, and while the policy couldn't be fetched (the built-in
defaults could undo an admin's lock).
- No plugin can hold up turning proofreading off (onBeforeSettingChange).
- Suggestions can't carry zero-width, bidi or line-separator characters;
messages lose bidi overrides; a flood of annotations is cut off early.
- The notices name the plugin as installed, not a label it chose, and say
that text written before signing or encryption was turned on may
already have been checked.
- A checker registered during start-up no longer fails its first check.
Keyboard and screen readers:
- Escape in the issue panel closes the panel, not the message.
- Underlines carry aria-invalid, as the browser's own markers do.
- The focus goes somewhere sensible when a button or an issue goes away,
Tab past the popup's edges goes back to the text, and the shortcuts work
in the popup and the panel.
- Ctrl+' and Ctrl+; follow the character typed, so other layouts keep
their own keys (Ctrl+S on Dvorak), with Ä and Ö on German keyboards.
- The popup is described by its message, sits inside a modal composer,
fits narrow screens, and the panel fits a phone.
- The banner judged its start and end by the time it was mounted, so an
announcement fetched later than its start never showed in that tab.
- The Pro shell shows it once above its panes; email and folder tabs had
none and split panes showed it twice.
- Screen readers get it from a live region that fills a moment after it
is in the page; text present when a live region appears isn't read out
reliably. The tests that checked the strip's role now check that region.
- Moving the start or end no longer shows a closed announcement again;
the lib test that expected a new end time to reset it now expects the
opposite.
Organisation > Devices now sets policy.json `organisation.devices`, each
switch off by default and scoped per domain or group:
- No downloads: attachments and files only preview (reader, conversation
view, Pro tab, list chips, .eml previews, the Files app). Download,
Download all, Open in new tab, Save to Files, drag-out, the browser's
PDF viewer (pdf.js instead) and media download controls go away.
- No export: no .eml export, View source, message drag-out, or folder and
account export; a running export stops and its file is deleted when
the switch turns on. Import stays.
- No printing: no Print buttons in mail, calendar and contacts; Ctrl+P
prints a note; the reader frame prints blank.
- No install prompt: no card, and the browser's own banner is held back.
- Watermark: the user's address and the date over the reader,
previews and every printout (mail, calendar, contacts, plugins).
A message follows its own account's policy; what isn't about one message
follows the strictest signed-in account. Every user path hides its
button, and the anchor and new-tab helpers refuse as a backstop
(lib/download-guard.ts), never the blob readers. The plugin APIs
`ui.downloadFile` and `ui.print` refuse too, and the office editor frame
loses `allow-downloads`.
Two assertions in components/mail/__tests__/blob-routing.test.tsx now
expect `{ kind: 'export' }` as the fifth argument of downloadBlob for an
.eml export: the export says what it is, so the backstop checks "No
export" rather than "No downloads" for it.
The first version wrote the whole tag list on every change, guessed a
group when the server wouldn't say, and treated a failed read like a
server without metadata. Now:
- Definitions are a map by tag id under `tags`, and each change patches
one tag (`metadata/org.bulwarkmail.tags/tags/<id>`), so two members
adding tags at once both keep theirs. Fields and colors this version
doesn't know survive. The `{ list }` and bare-array shapes are still
read and converted by the first save.
- Shared tags appear only for confirmed group principals. A failed
principal lookup keeps the user's own tags and asks again later.
- "No metadata advertised" (0.16) and "the read failed" are separate.
A failed read keeps the last good tags; a failed save keeps the change,
says so, and sends it with the next good read after the client's
pause.
- Push reloads wait for 5 s of quiet and skip the echo of our own save;
a returning tab reloads definitions only, and the scan for unnamed tags
runs once per sign-in and then at most every 30 minutes.
- The editor names its buttons after the tag, shows the delete warning
and 44 px buttons on phones, returns focus to the edit button, and
asks for Inbox rights only for confirmed groups.