feat: implement tenant OAuth flow and guest achievements

This commit is contained in:
2025-09-25 08:32:37 +02:00
parent ef6203c603
commit b22d91ed32
84 changed files with 5984 additions and 1399 deletions

View File

@@ -7,25 +7,52 @@ self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim());
});
const ASSETS_CACHE = 'guest-assets-v1';
const IMAGES_CACHE = 'guest-images-v1';
self.addEventListener('fetch', (event) => {
const req = event.request;
if (req.method !== 'GET' || !req.url.startsWith(self.location.origin)) return;
event.respondWith((async () => {
const cache = await caches.open('guest-runtime');
const cached = await cache.match(req);
if (cached) return cached;
try {
const res = await fetch(req);
// Cache static assets and images
const ct = res.headers.get('content-type') || '';
if (res.ok && (ct.includes('text/css') || ct.includes('javascript') || ct.startsWith('image/'))) {
cache.put(req, res.clone());
if (req.method !== 'GET') return;
const url = new URL(req.url);
// Only handle same-origin requests
if (url.origin !== self.location.origin) return;
// Never cache API calls; let them hit network directly
if (url.pathname.startsWith('/api/')) return;
// Cache-first for images
if (req.destination === 'image' || /\.(png|jpg|jpeg|webp|avif|gif|svg)(\?.*)?$/i.test(url.pathname)) {
event.respondWith((async () => {
const cache = await caches.open(IMAGES_CACHE);
const cached = await cache.match(req);
if (cached) return cached;
try {
const res = await fetch(req, { credentials: 'same-origin' });
if (res.ok) cache.put(req, res.clone());
return res;
} catch (e) {
return cached || Response.error();
}
return res;
} catch (e) {
return cached || new Response('Offline', { status: 503 });
}
})());
})());
return;
}
// Stale-while-revalidate for CSS/JS assets
if (req.destination === 'style' || req.destination === 'script') {
event.respondWith((async () => {
const cache = await caches.open(ASSETS_CACHE);
const cached = await cache.match(req);
const networkPromise = fetch(req, { credentials: 'same-origin' })
.then((res) => {
if (res.ok) cache.put(req, res.clone());
return res;
})
.catch(() => null);
return cached || (await networkPromise) || Response.error();
})());
return;
}
});
self.addEventListener('sync', (event) => {