mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
fix: keep a waiting re-sync from undoing what another tab turned off, and note the relay on refresh
This commit is contained in:
@@ -958,6 +958,50 @@ describe('a setup that gets stuck', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('a re-sync waiting its turn', () => {
|
||||
afterEach(() => { delete (navigator as unknown as { locks?: unknown }).locks; });
|
||||
|
||||
it('does not bring back what another tab turned off meanwhile', async () => {
|
||||
localStorage.setItem(DEVICE_KEY, THIS_DEVICE);
|
||||
localStorage.setItem(SUB_KEY, 'push-mine');
|
||||
localStorage.setItem(RELAY_BASE_KEY, RELAY);
|
||||
const client = makeClient([sub('push-mine', THIS_DEVICE)]);
|
||||
installFetch({ [THIS_DEVICE]: true });
|
||||
let turn: Promise<unknown> = Promise.resolve();
|
||||
let release = () => {};
|
||||
turn = new Promise<void>((resolve) => { release = resolve; });
|
||||
Object.defineProperty(navigator, 'locks', {
|
||||
configurable: true,
|
||||
value: { request: (_n: string, run: () => Promise<unknown>) => { const next = turn.then(run, run); turn = next.catch(() => undefined); return next; } },
|
||||
});
|
||||
|
||||
const resync = resyncWebPush({ client, relayBaseUrl: RELAY, inboxOnly: false });
|
||||
await vi.waitFor(() => expect((navigator as unknown as { locks: unknown }).locks).toBeTruthy());
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
localStorage.removeItem(SUB_KEY); // The other tab, holding the lock.
|
||||
release();
|
||||
await resync;
|
||||
|
||||
expect(client.updatePushSubscription).not.toHaveBeenCalled();
|
||||
expect(client.createPushSubscription).not.toHaveBeenCalled();
|
||||
expect(localStorage.getItem(SUB_KEY)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('a registration from before the relay was remembered', () => {
|
||||
it('gets the relay noted when it is refreshed', async () => {
|
||||
localStorage.setItem(DEVICE_KEY, THIS_DEVICE);
|
||||
localStorage.setItem(SUB_KEY, 'push-mine');
|
||||
const client = makeClient([sub('push-mine', THIS_DEVICE)]);
|
||||
installFetch({ [THIS_DEVICE]: true });
|
||||
|
||||
await resyncWebPush({ client, relayBaseUrl: RELAY, inboxOnly: false });
|
||||
|
||||
expect(localStorage.getItem(RELAY_BASE_KEY)).toBe(RELAY);
|
||||
expect(client.createPushSubscription).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('resyncWebPush when the relay changed (#903)', () => {
|
||||
afterEach(() => setNoThirdPartyTraffic(false));
|
||||
|
||||
|
||||
@@ -428,6 +428,8 @@ export interface EnableWebPushParams {
|
||||
// that outlives a permission change keeps pushing for mailboxes the user can
|
||||
// no longer read - recreating is the only client-side remedy (#841).
|
||||
forceRecreate?: boolean;
|
||||
// For a re-sync: stop if another tab turned push off while this waited its turn.
|
||||
onlyIfStillOn?: boolean;
|
||||
// Scope OS push notifications to Inbox-only mail. Mirrors settings-store's
|
||||
// pushNotifyInboxOnly. Required, not optional: it changes the server-side
|
||||
// delivery filter, so every caller must decide explicitly.
|
||||
@@ -813,6 +815,9 @@ async function enableWebPushForThisTab(
|
||||
params: EnableWebPushParams,
|
||||
relayBaseUrl: string,
|
||||
): Promise<EnableWebPushResult> {
|
||||
if (params.onlyIfStillOn && !localStorage.getItem(subscriptionIdKey(params.client.getAccountId()))) {
|
||||
return { subscriptionId: '' };
|
||||
}
|
||||
const registration = await ensureServiceWorker();
|
||||
|
||||
const vapidPublicKey = await fetchVapidPublicKey(relayBaseUrl);
|
||||
@@ -914,6 +919,8 @@ async function enableWebPushForThisTab(
|
||||
const refreshed = await refreshSubscriptionExpires(params.client, match, emailPush);
|
||||
if (refreshed) {
|
||||
rememberRefusedEmailPushAccounts(accountId, refusedBefore, emailPush, refreshed.emailPush);
|
||||
// Unless it moved, which goes the other way, this is where it lives.
|
||||
if (!localStorage.getItem(relayBaseKey(accountId))) localStorage.setItem(relayBaseKey(accountId), relayBaseUrl);
|
||||
return { subscriptionId: storedServerId };
|
||||
}
|
||||
}
|
||||
@@ -1317,6 +1324,7 @@ async function runResync(accountId: string, params: ResyncWebPushParams): Promis
|
||||
if (!moved && !params.force && !(await resyncDue(accountId))) return false;
|
||||
await enableWebPush({
|
||||
client: params.client,
|
||||
onlyIfStillOn: true,
|
||||
forceRecreate: moved,
|
||||
relayBaseUrl: params.relayBaseUrl,
|
||||
accountLabel: params.accountLabel,
|
||||
|
||||
Reference in New Issue
Block a user