Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | import type { WebPushSubscriptionJson } from '@/db/schema' /** * Convert a base64url-encoded VAPID public key to a Uint8Array * for use with pushManager.subscribe(). */ function urlBase64ToUint8Array(base64String: string): Uint8Array { const padding = '='.repeat((4 - (base64String.length % 4)) % 4) const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/') const rawData = atob(base64) const outputArray = new Uint8Array(rawData.length) for (let i = 0; i < rawData.length; i++) { outputArray[i] = rawData.charCodeAt(i) } return outputArray } /** * Register the push notification service worker. * Returns null if service workers are not supported. */ export async function registerServiceWorker(): Promise<ServiceWorkerRegistration | null> { if (!('serviceWorker' in navigator)) return null return navigator.serviceWorker.register('/sw.js') } /** * Subscribe to push notifications using the browser Push API. * The VAPID public key must be fetched from the server and passed in. */ export async function subscribeToPush( registration: ServiceWorkerRegistration, vapidPublicKey: string ): Promise<PushSubscription> { if (!vapidPublicKey) { throw new Error('[register-sw] vapidPublicKey is required') } return registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(vapidPublicKey) as BufferSource, }) } /** * Convert a browser PushSubscription to the JSON shape stored in the database. */ export function pushSubscriptionToJson(sub: PushSubscription): WebPushSubscriptionJson { const json = sub.toJSON() if (!json.endpoint || !json.keys?.p256dh || !json.keys?.auth) { throw new Error('[register-sw] PushSubscription is missing required fields') } return { endpoint: json.endpoint, keys: { p256dh: json.keys.p256dh, auth: json.keys.auth, }, } } |