diff --git a/src/lib/push/client.ts b/src/lib/push/client.ts index 534677d..bc62e46 100644 --- a/src/lib/push/client.ts +++ b/src/lib/push/client.ts @@ -13,24 +13,36 @@ function urlBase64ToUint8Array(base64String: string): Uint8Array { /** * Registers the service worker and makes sure a push subscription exists - * and is saved server-side. Best-effort only: quietly no-ops if push isn't - * supported, permission isn't granted, or anything in the chain fails — - * this is an enhancement on top of the in-page toast, never something a - * page load should be blocked or broken by. + * and is saved server-side. Never throws or blocks the page on failure — + * this is an enhancement on top of the in-page toast — but every step logs + * to the console (visible in DevTools) since a silent no-op is otherwise + * impossible to tell apart from "it worked" when diagnosing remotely. */ export async function ensurePushSubscribed(): Promise { if (typeof window === "undefined") return; - if (!("serviceWorker" in navigator) || !("PushManager" in window)) return; - if (Notification.permission !== "granted") return; + if (!("serviceWorker" in navigator) || !("PushManager" in window)) { + console.warn("[push] not supported in this browser"); + return; + } + if (Notification.permission !== "granted") { + console.warn("[push] Notification permission is", Notification.permission, "- skipping subscribe"); + return; + } try { const registration = await navigator.serviceWorker.register("/sw.js"); await navigator.serviceWorker.ready; + console.log("[push] service worker registered:", registration.scope); let subscription = await registration.pushManager.getSubscription(); - if (!subscription) { + if (subscription) { + console.log("[push] reusing existing subscription:", subscription.endpoint); + } else { const keyRes = await fetch("/api/push/vapid-public-key"); - if (!keyRes.ok) return; // push not configured server-side yet + if (!keyRes.ok) { + console.error("[push] /api/push/vapid-public-key returned", keyRes.status, "- is VAPID configured server-side?"); + return; + } const { publicKey } = await keyRes.json(); subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, @@ -39,14 +51,20 @@ export async function ensurePushSubscribed(): Promise { // plain (non-shared) ArrayBuffer. applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource, }); + console.log("[push] created new subscription:", subscription.endpoint); } - await fetch("/api/push/subscribe", { + const saveRes = await fetch("/api/push/subscribe", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(subscription.toJSON()), }); - } catch { - // best-effort — a failure here must never disrupt the page + if (saveRes.ok) { + console.log("[push] subscription saved server-side — done"); + } else { + console.error("[push] failed to save subscription server-side:", saveRes.status, await saveRes.text()); + } + } catch (err) { + console.error("[push] ensurePushSubscribed failed:", err); } }