diff --git a/resources/js/hooks/use-push-notification.ts b/resources/js/hooks/use-push-notification.ts index 320e9b4..fda0756 100644 --- a/resources/js/hooks/use-push-notification.ts +++ b/resources/js/hooks/use-push-notification.ts @@ -33,6 +33,38 @@ function getIsSupported(): boolean { ); } +async function sendSubscriptionToServer( + subscription: PushSubscription, +): Promise { + const { endpoint } = subscription; + const key = subscription.getKey('p256dh'); + const auth = subscription.getKey('auth'); + + const response = await fetch('/api/push/subscribe', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest', + 'X-XSRF-TOKEN': decodeURIComponent( + document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? '', + ), + }, + credentials: 'same-origin', + body: JSON.stringify({ + endpoint, + public_key: key + ? btoa(String.fromCharCode(...new Uint8Array(key))) + : null, + auth_token: auth + ? btoa(String.fromCharCode(...new Uint8Array(auth))) + : null, + content_encoding: 'aes128gcm', + }), + }); + + return response.ok; +} + export function usePushNotification() { const [permission, setPermission] = useState(getInitialPermission); @@ -54,40 +86,29 @@ export function usePushNotification() { async (vapidPublicKey: string): Promise => { try { const registration = await navigator.serviceWorker.ready; - const subscription = await registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array( - vapidPublicKey, - ) as BufferSource, - }); - const { endpoint } = subscription; - const key = subscription.getKey('p256dh'); - const auth = subscription.getKey('auth'); + const existingSubscription = + await registration.pushManager.getSubscription(); - const response = await fetch('/api/push/subscribe', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Requested-With': 'XMLHttpRequest', - 'X-XSRF-TOKEN': decodeURIComponent( - document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? - '', - ), - }, - body: JSON.stringify({ - endpoint, - public_key: key - ? btoa(String.fromCharCode(...new Uint8Array(key))) - : null, - auth_token: auth - ? btoa(String.fromCharCode(...new Uint8Array(auth))) - : null, - content_encoding: 'aes128gcm', - }), - }); + if (existingSubscription) { + const synced = await sendSubscriptionToServer( + existingSubscription, + ); - return response.ok; + return synced; + } + + const subscription = + await registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array( + vapidPublicKey, + ) as BufferSource, + }); + + const saved = await sendSubscriptionToServer(subscription); + + return saved; } catch (error) { console.error( 'Failed to subscribe to push notifications:', @@ -119,6 +140,7 @@ export function usePushNotification() { document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? '', ), }, + credentials: 'same-origin', body: JSON.stringify({ endpoint: subscription.endpoint, }), diff --git a/vite.config.ts b/vite.config.ts index 0f2810a..a18e2ab 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -37,7 +37,9 @@ export default defineConfig({ manifest: false, srcDir: 'resources/js', filename: 'sw.ts', - workbox: { + scope: '/', + strategies: 'injectManifest', + injectManifest: { globPatterns: ['**/*.{js,css,html,ico,png,svg,woff,woff2}'], }, devOptions: {