diff --git a/src/hooks/__tests__/use-logout.test.ts b/src/hooks/__tests__/use-logout.test.ts index b6d0483b9..49e14c26b 100644 --- a/src/hooks/__tests__/use-logout.test.ts +++ b/src/hooks/__tests__/use-logout.test.ts @@ -137,6 +137,8 @@ describe("useLogout", () => { expect(JSON.parse(String(deleteCall[1]?.body))).toEqual({ endpoint: subscription.endpoint, }); + // A connection that carries nothing must not hold the sign-out. + expect(deleteCall[1]?.signal).toBeInstanceOf(AbortSignal); expect(replace).toHaveBeenCalledWith("/auth/login"); }); diff --git a/src/lib/notifications/web-push-subscription.ts b/src/lib/notifications/web-push-subscription.ts index ace66218e..654075eeb 100644 --- a/src/lib/notifications/web-push-subscription.ts +++ b/src/lib/notifications/web-push-subscription.ts @@ -9,11 +9,16 @@ async function browserSubscription(): Promise { return (await registration?.pushManager.getSubscription()) ?? null; } +/** + * Bounded: on a connection that is up but carries nothing, sign-out would + * otherwise wait out the browser's own timeout before it even starts. + */ function deleteServerRow(subscription: PushSubscription): Promise { return apiFetchRaw("/api/notifications/web-push", { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ endpoint: subscription.endpoint }), + signal: AbortSignal.timeout(5_000), }); }