Re_Figma_Code/src/utils/pushNotifications.ts

48 lines
1.8 KiB
TypeScript

const VAPID_PUBLIC_KEY = import.meta.env.VITE_PUBLIC_VAPID_KEY as string;
const VITE_BASE_URL = import.meta.env.VITE_BASE_URL as string;
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 async function registerServiceWorker() {
if (!('serviceWorker' in navigator)) throw new Error('Service workers not supported');
const register = await navigator.serviceWorker.register('/service-worker.js');
return register;
}
export async function subscribeUserToPush(register: ServiceWorkerRegistration) {
if (!VAPID_PUBLIC_KEY) throw new Error('Missing VAPID public key');
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
});
// Attach auth token if available
const token = (window as any)?.localStorage?.getItem?.('accessToken') || (document?.cookie || '').match(/accessToken=([^;]+)/)?.[1] || '';
await fetch(`${VITE_BASE_URL}/api/v1/workflows/notifications/subscribe`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
},
body: JSON.stringify(subscription)
});
return subscription;
}
export async function setupPushNotifications() {
const permission = await Notification.requestPermission();
if (permission !== 'granted') return;
const reg = await registerServiceWorker();
await subscribeUserToPush(reg);
}