diff --git a/docker-compose.yml b/docker-compose.yml index eb0ec4c..f157ab8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,7 +37,7 @@ services: # Router 1: Público (assets, manifest, icons) - SIN autenticación - ALTA PRIORIDAD # NOTA: /outpost.goauthentik.io NO debe estar aquí, lo maneja el middleware de Authentik - - "traefik.http.routers.wifi-nucleoriofrio-public.rule=Host(`wifi.nucleoriofrio.com`) && (PathPrefix(`/assets`) || PathPrefix(`/.well-known`) || PathPrefix(`/icons`) || Path(`/manifest.webmanifest`) || Path(`/favicon.ico`) || Path(`/vite.svg`) || Path(`/sw.js`))" + - "traefik.http.routers.wifi-nucleoriofrio-public.rule=Host(`wifi.nucleoriofrio.com`) && (PathPrefix(`/assets`) || PathPrefix(`/.well-known`) || PathPrefix(`/icons`) || Path(`/manifest.webmanifest`) || Path(`/manifest.json`) || Path(`/favicon.ico`) || Path(`/vite.svg`) || Path(`/sw.js`))" - "traefik.http.routers.wifi-nucleoriofrio-public.entrypoints=websecure" - "traefik.http.routers.wifi-nucleoriofrio-public.tls.certresolver=letsencrypt" - "traefik.http.routers.wifi-nucleoriofrio-public.service=wifi-nucleoriofrio-service" diff --git a/frontend/public/sw.js b/frontend/public/sw.js index 317e2b3..cfe1c27 100644 --- a/frontend/public/sw.js +++ b/frontend/public/sw.js @@ -1,5 +1,5 @@ // Nombre del caché para la aplicación -const CACHE_NAME = 'radius-nucleo-cache-v2'; +const CACHE_NAME = 'radius-nucleo-cache-v3'; // Archivos que se almacenarán en caché durante la instalación const URLS_TO_CACHE = [ @@ -42,21 +42,67 @@ self.addEventListener('activate', (event) => { ); }); -// Evento de recuperación (fetch): responde desde la caché si existe, si no, recupera de la red +// Evento de recuperación (fetch): estrategia inteligente según el tipo de recurso self.addEventListener('fetch', (event) => { + const url = new URL(event.request.url); + // Excluir las peticiones a /api/* del Service Worker // Estas peticiones requieren autenticación y no deben ser cacheadas - const url = new URL(event.request.url); if (url.pathname.startsWith('/api/')) { - // Dejar que el navegador maneje las peticiones de API normalmente return; } + // Para archivos de build (JS/CSS en /assets/): Network-first con cache fallback + // Esto asegura que siempre se intente obtener la versión más reciente + if (url.pathname.startsWith('/assets/')) { + event.respondWith( + fetch(event.request) + .then((response) => { + // Guardar en cache la nueva versión + const responseClone = response.clone(); + caches.open(CACHE_NAME).then((cache) => { + cache.put(event.request, responseClone); + }); + return response; + }) + .catch(() => { + // Si falla la red, usar cache + return caches.match(event.request); + }) + ); + return; + } + + // Para HTML: Network-first siempre + if (url.pathname.endsWith('.html') || url.pathname === '/') { + event.respondWith( + fetch(event.request) + .catch(() => { + // Solo si falla la red, usar cache + return caches.match(event.request); + }) + ); + return; + } + + // Para recursos estáticos (iconos, manifest, etc.): Cache-first + // Estos archivos rara vez cambian event.respondWith( caches.match(event.request) .then((response) => { - // Devuelve la respuesta en caché o realiza la solicitud a la red - return response || fetch(event.request); + if (response) { + return response; + } + return fetch(event.request).then((response) => { + // Guardar en cache si es exitoso + if (response.status === 200) { + const responseClone = response.clone(); + caches.open(CACHE_NAME).then((cache) => { + cache.put(event.request, responseClone); + }); + } + return response; + }); }) ); }); \ No newline at end of file