fix: extend timeout for PushVerification and clean up leftover subscriptions
This commit is contained in:
+18
-3
@@ -168,7 +168,11 @@ async function pollVerificationCode(
|
|||||||
relayBaseUrl: string,
|
relayBaseUrl: string,
|
||||||
subscriptionId: string,
|
subscriptionId: string,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const timeoutAt = Date.now() + 20_000;
|
// Stalwart per-account rate-limits PushVerification posts (default 60s).
|
||||||
|
// If there are leftover unverified subscriptions on the account, our new
|
||||||
|
// one queues up behind them - so we wait long enough to clear one verify
|
||||||
|
// window even in the unlucky case.
|
||||||
|
const timeoutAt = Date.now() + 75_000;
|
||||||
let delay = 400;
|
let delay = 400;
|
||||||
while (Date.now() < timeoutAt) {
|
while (Date.now() < timeoutAt) {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
@@ -254,10 +258,10 @@ export async function enableWebPush(
|
|||||||
|
|
||||||
// Reuse the JMAP-side PushSubscription if the server still has it, just
|
// Reuse the JMAP-side PushSubscription if the server still has it, just
|
||||||
// refreshing the expiry so it doesn't time out between sessions.
|
// refreshing the expiry so it doesn't time out between sessions.
|
||||||
|
const existingSubs = await params.client.listPushSubscriptions().catch(() => []);
|
||||||
const storedServerId = localStorage.getItem(SUBSCRIPTION_ID_KEY);
|
const storedServerId = localStorage.getItem(SUBSCRIPTION_ID_KEY);
|
||||||
if (storedServerId) {
|
if (storedServerId) {
|
||||||
const existing = await params.client.listPushSubscriptions().catch(() => []);
|
const match = existingSubs.find((s) => s.id === storedServerId);
|
||||||
const match = existing.find((s) => s.id === storedServerId);
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const refreshed = await refreshSubscriptionExpires(params.client, match);
|
const refreshed = await refreshSubscriptionExpires(params.client, match);
|
||||||
if (refreshed) return { subscriptionId: storedServerId };
|
if (refreshed) return { subscriptionId: storedServerId };
|
||||||
@@ -266,6 +270,17 @@ export async function enableWebPush(
|
|||||||
localStorage.removeItem(SUBSCRIPTION_ID_KEY);
|
localStorage.removeItem(SUBSCRIPTION_ID_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reap any leftover subscriptions still bound to this device. These pile
|
||||||
|
// up when a previous enable attempt failed mid-flow (verification timed
|
||||||
|
// out, browser tab closed, etc). Stalwart per-account rate-limits
|
||||||
|
// verification posts, so leaving stragglers around blocks the new one.
|
||||||
|
const stragglers = existingSubs.filter(
|
||||||
|
(s) => s.deviceClientId === deviceClientId && s.id !== storedServerId,
|
||||||
|
);
|
||||||
|
for (const s of stragglers) {
|
||||||
|
await params.client.destroyPushSubscription(s.id).catch(() => undefined);
|
||||||
|
}
|
||||||
|
|
||||||
const serverAssignedId = await params.client.createPushSubscription({
|
const serverAssignedId = await params.client.createPushSubscription({
|
||||||
deviceClientId,
|
deviceClientId,
|
||||||
url: buildRelayUrl(relayBaseUrl, `/api/push/jmap/${encodeURIComponent(deviceClientId)}`),
|
url: buildRelayUrl(relayBaseUrl, `/api/push/jmap/${encodeURIComponent(deviceClientId)}`),
|
||||||
|
|||||||
Reference in New Issue
Block a user