/** * push.js — Web Push notification setup for Nexus POS * * Registers a service worker and subscribes to push notifications. * Only activates for owner/admin roles. */ (function() { 'use strict'; // Only set up push for owner/admin var employee = {}; try { employee = JSON.parse(localStorage.getItem('pos_employee') || '{}'); } catch(e) {} var role = employee.role || ''; if (role !== 'owner' && role !== 'admin') return; // Check browser support if (!('serviceWorker' in navigator) || !('PushManager' in window)) { console.log('[Push] Browser does not support push notifications'); return; } var token = localStorage.getItem('pos_token'); if (!token) return; function urlBase64ToUint8Array(base64String) { var padding = '='.repeat((4 - base64String.length % 4) % 4); var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); var rawData = window.atob(base64); var outputArray = new Uint8Array(rawData.length); for (var i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } async function setupPush() { try { // Register service worker var registration = await navigator.serviceWorker.register('/pos/static/sw-push.js', { scope: '/pos/' }); console.log('[Push] Service worker registered'); // Get VAPID key from server var resp = await fetch('/pos/api/push/vapid-key', { headers: { 'Authorization': 'Bearer ' + token } }); if (!resp.ok) { console.log('[Push] VAPID key not available:', resp.status); return; } var data = await resp.json(); var vapidKey = data.public_key; if (!vapidKey) return; // Request permission var permission = await Notification.requestPermission(); if (permission !== 'granted') { console.log('[Push] Permission denied'); return; } // Subscribe var subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(vapidKey) }); // Send subscription to server var subResp = await fetch('/pos/api/push/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify({ subscription: subscription.toJSON() }) }); if (subResp.ok) { console.log('[Push] Subscribed successfully'); } } catch(err) { console.log('[Push] Setup error:', err); } } // Delay push setup to not block page load if (document.readyState === 'complete') { setTimeout(setupPush, 2000); } else { window.addEventListener('load', function() { setTimeout(setupPush, 2000); }); } })();