feat(push): Web Push notifications for backgrounded/closed/mobile tabs

Page-level Notifications can't fire when a tab is frozen/closed (and never on
mobile), which is why recipients on another tab/app got nothing. Adds a
notification-only service worker (sw.js, no caching) + Web Push:

- push.js: optional web-push wrapper (no-op unless web-push installed AND
  VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY set -> app unaffected if unconfigured).
- push_subscriptions table + R.pushSubs repo (upsert by endpoint, prune dead).
- /api/push/vapid|subscribe|unsubscribe; DM + group message routes also send a
  Web Push to recipients.
- Client registers /sw.js, subscribes when permission granted; hidden-tab popups
  are left to push to avoid double-notifying (pushActive flag); SW suppresses the
  OS popup when a tab is visible. Removes the old code that unregistered SWs.

Requires (prod, once): npm install + VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY/VAPID_SUBJECT env.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 21:58:49 +05:30
parent d50d4bde47
commit 1272b81cee
8 changed files with 356 additions and 13 deletions
+13 -4
View File
@@ -3,8 +3,17 @@
"version": "2.0.0",
"description": "BizGaze Support — remote screen sharing: public landing, agent console, sessions, SSO + webhook for BizGaze integration",
"main": "server.js",
"scripts": { "start": "node server.js" },
"engines": { "node": ">=22.5.0" },
"dependencies": { "ws": "^8.18.0" },
"optionalDependencies": { "nodemailer": "^6.9.14" }
"scripts": {
"start": "node server.js"
},
"engines": {
"node": ">=22.5.0"
},
"dependencies": {
"web-push": "^3.6.7",
"ws": "^8.18.0"
},
"optionalDependencies": {
"nodemailer": "^6.9.14"
}
}