edtech / apps /admin /src /lib /notifications.ts
CognxSafeTrack
fix(notifications): skip permission request if already denied by browser
84fb6f6
/**
* Push Notification Helper
*/
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 {
// 1. Check existing permission — ne pas re-demander si déjà refusé
if (Notification.permission === 'denied') {
return; // silencieux : l'utilisateur a déjà dit non
}
// 2. Register Service Worker
const registration = await navigator.serviceWorker.register('/sw.js');
// 3. Request Permission (seulement si 'default', pas 'denied')
const permission = Notification.permission === 'granted'
? 'granted'
: await Notification.requestPermission();
if (permission !== 'granted') {
return; // silencieux
}
// 3. Get VAPID public key from server
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;
}
// 4. Subscribe to Push
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicKey)
});
// 5. Send subscription to server
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);
}
};