PageSourceSearch

https://cavoraai.web.app/sw.js

js cavoraai.web.app collected 2026-10-03 12:19:55 UTC 2,238 bytes, 46 lines download raw bytes

1/*
2 * CavoraAI Service Worker: nur Push-Meldungen (Konzept Meldungen und Lernen, Paket N3).
3 * Kein Offline-Cache und keine abgefangenen Anfragen: Updates der App laufen weiter über /version.json
4 * (UpdateToast), die App verhält sich mit und ohne diesen Worker gleich.
5 *
6 * Die Nachricht kommt verschlüsselt vom Server (RFC 8291) und trägt nur Titel, Ziel und Dringlichkeit;
7 * Details zeigt die App nach der Anmeldung (Sperrbildschirm ohne Beträge, Namen oder Kundentexte).
8 */
9self.addEventListener('install', () => { self.skipWaiting(); });
10self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()); });
11
12self.addEventListener('push', (event) => {
13  let d = {};
14  try { d = event.data ? event.data.json() : {}; } catch (e) { d = {}; }
15  const urgent = d.severity === 'urgent';
16  const options = {
17    body: '',
18    icon: '/icons/icon-192.png',
19    badge: '/icons/icon-192.png',
20    tag: typeof d.tag === 'string' ? d.tag : undefined,
21    renotify: urgent && typeof d.tag === 'string',
22    requireInteraction: urgent,
23    timestamp: typeof d.at === 'number' ? d.at : Date.now(),
24    data: { link: typeof d.link === 'string' ? d.link : '/' },
25  };
26  // Jede Push-Nachricht zeigt eine Meldung (Safari und Chrome verlangen das, sonst entziehen sie das Recht).
27  event.waitUntil(self.registration.showNotification(typeof d.title === 'string' && d.title ? d.title : 'CavoraAI', options));
28});
29
30self.addEventListener('notificationclick', (event) => {
31  event.notification.close();
32  const target = new URL((event.notification.data && event.notification.data.link) || '/', self.location.origin);
33  // Nur Ziele innerhalb der App; alles andere öffnet die Startseite.
34  const url = target.origin === self.location.origin ? target.href : self.location.origin + '/';
35  event.waitUntil((async () => {
36    const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
37    for (const w of windows) {
38      if (new URL(w.url).origin === self.location.origin) {
39        await w.focus();
40        if ('navigate' in w) { try { await w.navigate(url); } catch (e) { /* fremder Zustand: nur fokussieren */ } }
41        return;
42      }
43    }
44    await self.clients.openWindow(url);
45  })());
46});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.