feat(push): owner enrolment UI, service worker and VAPID keygen (T10)

EnableNotifications subscribes the owner's device with the public VAPID
key and stores it; sw.js receives pushes and opens /defects on click;
`pnpm vapid:keys` mints the key pair.
This commit is contained in:
Julien Calixte
2026-05-28 01:23:10 +02:00
parent ea7384591c
commit 0745ad14f0
7 changed files with 258 additions and 2 deletions

33
public/sw.js Normal file
View File

@@ -0,0 +1,33 @@
// Web Push service worker (T10). Registered from EnableNotifications.vue and
// served at the site root so it controls the whole origin. Its job is to
// receive pushes the server sends (T11) and surface them as OS notifications.
self.addEventListener('push', (event) => {
let payload = {}
try {
payload = event.data ? event.data.json() : {}
} catch {
payload = {}
}
const title = payload.title || 'New defect filed'
event.waitUntil(
self.registration.showNotification(title, {
body: payload.body || '',
tag: payload.tag,
data: { url: payload.url || '/defects' },
}),
)
})
self.addEventListener('notificationclick', (event) => {
event.notification.close()
const target = (event.notification.data && event.notification.data.url) || '/defects'
event.waitUntil(
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clients) => {
for (const client of clients) {
if (client.url.includes(target) && 'focus' in client) return client.focus()
}
return self.clients.openWindow(target)
}),
)
})