Files
BizGaze_Remote/server/push.js
T

46 lines
2.0 KiB
JavaScript
Raw Normal View History

// Web Push (background / closed-tab / mobile notifications). Fully optional:
// - if the `web-push` package isn't installed, or VAPID env keys aren't set,
// isEnabled() is false and every call is a silent no-op (the app is unaffected).
// Configure in production by setting:
// VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT (e.g. mailto:admin@bizgaze.com)
// Generate a key pair once with: npx web-push generate-vapid-keys
const R = require('./repos');
let webpush = null;
try { webpush = require('web-push'); } catch (_) { /* package not installed -> push disabled */ }
const PUBLIC = process.env.VAPID_PUBLIC_KEY || '';
const PRIVATE = process.env.VAPID_PRIVATE_KEY || '';
const SUBJECT = process.env.VAPID_SUBJECT || 'mailto:support@bizgaze.com';
let ready = false;
if (webpush && PUBLIC && PRIVATE) {
try { webpush.setVapidDetails(SUBJECT, PUBLIC, PRIVATE); ready = true; }
catch (e) { console.warn('[push] invalid VAPID config:', e.message); }
}
if (!ready) console.log('[push] Web Push disabled (set web-push + VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY to enable).');
function isEnabled() { return ready; }
function publicKey() { return ready ? PUBLIC : ''; }
// Fire-and-forget push to every device the user has subscribed. Dead subscriptions
// (410 Gone / 404) are pruned. Never throws.
async function sendToUser(userId, payload) {
if (!ready) return;
let subs = [];
try { subs = R.pushSubs.byUser(userId); } catch (_) { return; }
const data = JSON.stringify(payload || {});
for (const s of subs) {
const sub = { endpoint: s.endpoint, keys: { p256dh: s.p256dh, auth: s.auth } };
try {
await webpush.sendNotification(sub, data, { TTL: 600 });
} catch (err) {
const code = err && err.statusCode;
if (code === 404 || code === 410) { try { R.pushSubs.removeByEndpoint(s.endpoint); } catch (_) {} }
// other errors (network, 4xx) are ignored — push is best-effort
}
}
}
module.exports = { isEnabled, publicKey, sendToUser };