Follow-ups to the review of the push, keyword and identity work:
- A send that names no sender, like the List-Unsubscribe mailto: of the
unified view, fell back to the first identity in server order, which
on Stalwart 1.0 is a group's. It now takes the login's own identity,
with addresses compared regardless of case.
- Re-register creates the replacement subscription before it destroys
the old one, so at Stalwart's limit (15 per account by default) it
failed with `overQuota`. It now frees the old record's place and
tries once more.
- On 1.0 the push settings note goes by the emailpush capability alone
and ignores refusals remembered under 0.16. On 0.16 a group the user
belongs to is recognised by its identity, so a member without
calendars, contacts or files keeps the group's junk filter and is no
longer told the group sends no notifications.
- Plugin imports can no longer set Stalwart 1.0's attachment keywords,
and `keywords.discover` leaves them out.
- Batch mark-as-read showed messages the server refused as read. It now
updates only what was written and reports the rest, and thread
expansion and category-tab moves keep what a partly refused batch
did write.
- Refused read and star changes from shortcuts, the list, the viewer
and Pro tabs show "Failed to update email" instead of an unhandled
rejection. The automatic mark-as-read on opening stays quiet.
- A tag whose id predates the 128-byte limit can have its colour
changed again.
- The state-regression guard notes that a multi-node 1.0 cluster can
trip it harmlessly, at the cost of one extra full fetch.
Stalwart 1.0 counts every EmailSubmission record of an account against
`maxSubmissions` (500 by default), whatever its status or age, and its
own purge of old records never runs. Bulwark never destroyed a
submission, so after about 500 JMAP sends an account could not send at
all: every send, read receipt and reschedule failed with a raw "There
are too many email submissions" error, and each failed attempt left one
more copy of the message in Drafts.
Bulwark now removes the records that can no longer be cancelled.
Destroying a record never stops its delivery, but a pending one could
no longer be cancelled, so pending records are never touched:
- an immediate send (no hold, no undo window) destroys its own record
right after the send, riding along with the old-draft cleanup; only
where `urn:stalwart:jmap` is advertised, and never decided by the
created `undoStatus`, which 0.16.10-0.16.16 report as final for held
sends
- a throttled background prune destroys canceled records and final
records whose `sendAt` has passed, going by `EmailSubmission/get`, in
every submission account; it runs at startup, after sends, after
undo and on EmailSubmission state changes
- a confirmed cancel (undo, cancel, reschedule) destroys the canceled
record in a request of its own
- an `overQuota` on a submission create prunes at once, on Stalwart
walks the change log for records older than the query's three-day
window, retries once, and otherwise throws `SubmissionQuotaError`,
shown as a translated explanation in the composer, quick reply, read
receipts and the scheduled-send actions
Failed sends now clean up after themselves and say so:
- a failed send removes the Drafts copy it created and keeps the
user's draft; the raw send paths remove their import the same way
- a read receipt that did not go out is taken back out of Sent, a
method-level error counts as a failure, `$MDNSent` is only set after
a sent receipt, and the automatic receipt no longer retries on every
refresh of the open message
- quick-reply failures, "Send now", "Reschedule" and a failed undo are
shown instead of only logged
- the scheduled list reads every page of `EmailSubmission/query`; it
stopped after the first because `total` needs `calculateTotal`