| |
| |
| |
| import { logError, logWarn } from './logger'; |
|
|
| function urlBase64ToUint8Array(base64String: string) { |
| 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; |
| } |
|
|
| export const setupNotifications = async (token: string, orgId: string) => { |
| if (!('serviceWorker' in navigator) || !('PushManager' in window)) { |
| logWarn('Push notifications are not supported in this browser.'); |
| return; |
| } |
|
|
| try { |
| |
| if (Notification.permission === 'denied') { |
| return; |
| } |
|
|
| |
| const registration = await navigator.serviceWorker.register('/sw.js'); |
|
|
| |
| const permission = Notification.permission === 'granted' |
| ? 'granted' |
| : await Notification.requestPermission(); |
| if (permission !== 'granted') { |
| return; |
| } |
|
|
| |
| const keyRes = await fetch(`${import.meta.env.VITE_API_URL}/v1/notifications/vapid-key`, { |
| headers: { 'Authorization': `Bearer ${token}`, 'x-organization-id': orgId } |
| }); |
| const { publicKey } = await keyRes.json(); |
|
|
| if (!publicKey) { |
| logWarn('VAPID public key missing from server'); |
| return; |
| } |
|
|
| |
| const subscription = await registration.pushManager.subscribe({ |
| userVisibleOnly: true, |
| applicationServerKey: urlBase64ToUint8Array(publicKey) |
| }); |
|
|
| |
| await fetch(`${import.meta.env.VITE_API_URL}/v1/notifications/subscribe`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'Authorization': `Bearer ${token}`, |
| 'x-organization-id': orgId |
| }, |
| body: JSON.stringify({ subscription }) |
| }); |
|
|
| } catch (err) { |
| logError('Failed to setup push notifications', err); |
| } |
| }; |
|
|