mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-02 16:15:39 +00:00
The review of offline mode found ways to send a message twice, to lose unsent mail without a word, and to send mail without its signing, encryption or check plugin. This fixes them and the smaller findings: - each outbox message is taken for sending in one database transaction under a Web Lock per account; only a failure before the submission request (SendNotStartedError from the client) puts it back, any other one marks it "may have gone out"; read-backs after the submission no longer fail a send; a send of a closed tab turns uncertain after a minute - every sign-out the user didn't confirm names the deleted messages on the sign-in page, or in a toast when another account stays signed in - nothing is queued while an enabled plugin isn't running (after a start without the network none can); the composer says why - the outbox waits for a fresh policy and holds messages the rules have since made stricter (a required label, a required send check) - another tab switching offline mode off sticks: only switching it on may create the database - only attachments of kept messages are kept, filed with their message, deleted with it and under the cap between syncs; file names and types are sealed; folders that went away leave the scope, and a folder that couldn't be asked keeps its mail without holding the others back - a group scope that forbids offline mode waits until the account's groups are known; one server down no longer holds another's mail - an offline start only when the server is really unreachable, and the real sign-in follows by itself once it answers - the service worker files pages and chunks under the build that served them, and the shell list of another build isn't kept under this one - a raw send counts as the composer's only from the plugin running its takeover, for that identity - errors and refusals are in all languages; the banner tells "offline" from "server can't be reached"; outbox buttons name their message; changes and messages go in the order they were made
42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
/**
|
|
* Whether a plugin's raw send (api.jmap.sendRaw / submitRaw) completes a
|
|
* send the composer handed it (onComposeSend: S/MIME, PGP). Such a send ran
|
|
* every step at Send, with the user present, so offline mode may keep the
|
|
* finished message in its outbox (#523). A plugin's own sends (a forward, a
|
|
* report) aren't covered and need the server.
|
|
*
|
|
* A raw send counts only when it comes from the plugin whose onComposeSend
|
|
* handler runs right now (lib/plugin-hooks.ts pluginRunsTakeOver) and is
|
|
* for the identity of a takeover the composer opened.
|
|
*/
|
|
|
|
import { generateUUID } from '@/lib/utils';
|
|
import { stripCrossAccountIdentityPrefix } from '@/hooks/use-pro-multi-account-identities';
|
|
import { pluginRunsTakeOver } from '@/lib/plugin-hooks';
|
|
|
|
const open = new Map<string, string>();
|
|
|
|
const rawId = (identityId: string) => stripCrossAccountIdentityPrefix(identityId).rawId ?? identityId;
|
|
|
|
/** Called by the composer right before it hands the send to the plugins; pass the token to endComposeTakeover. */
|
|
export function beginComposeTakeover(identityId: string): string {
|
|
const token = generateUUID();
|
|
open.set(token, rawId(identityId));
|
|
return token;
|
|
}
|
|
|
|
export function endComposeTakeover(token: string): void {
|
|
open.delete(token);
|
|
}
|
|
|
|
/** A raw send from `pluginId` for `identityId` completes an open composer send. */
|
|
export function completesComposeTakeover(pluginId: string, identityId: string): boolean {
|
|
if (!pluginRunsTakeOver(pluginId)) return false;
|
|
return [...open.values()].includes(rawId(identityId));
|
|
}
|
|
|
|
/** For tests. */
|
|
export function resetComposeTakeovers(): void {
|
|
open.clear();
|
|
}
|