async function registerPush() { try { console.log("Registering for push notifications"); if (!('serviceWorker' in navigator)) { console.error("ServiceWorker not supported"); return; } const permission = await Notification.requestPermission(); console.log("Permission:", permission); if (permission !== 'granted') { console.warn("Notification permission denied"); return; } const registration = await navigator.serviceWorker.register('/sw.js'); console.log("SW registered:", registration); // const subscription = await registration.pushManager.subscribe({ // userVisibleOnly: true, // applicationServerKey: vapidKey // }); const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(vapidKey), }); console.log('VAPID key:', vapidKey); console.log("Subscription created:", subscription); const res = await fetch('/push/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify(subscription) }); console.log("Server response:", await res.text()); alert("Push enabled ✅"); } catch (e) { console.error("Push registration failed ❌", e); } } function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) .replace(/-/g, '+') .replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; }