From e1b8a05e883ea4f41a8ab615c130fedf54bd9e09 Mon Sep 17 00:00:00 2001 From: Akhilesh Airen Date: Wed, 11 Mar 2026 14:12:26 +0530 Subject: [PATCH 1/4] added service worket to set COOP AND COEP headers --- src/page_assets/index/js/main.js | 12 ++++++++ src/public/sw-coi.js | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/public/sw-coi.js diff --git a/src/page_assets/index/js/main.js b/src/page_assets/index/js/main.js index 3841777..bcbe96f 100644 --- a/src/page_assets/index/js/main.js +++ b/src/page_assets/index/js/main.js @@ -4,5 +4,17 @@ import '../../../scss/styles.scss'; import { init } from '../../../common/js/scl-app'; +async function registerCoiServiceWorker() { + if (!('serviceWorker' in navigator)) return; + + try { + await navigator.serviceWorker.register('/sw-coi.js', { scope: '/' }); + await navigator.serviceWorker.ready; + } catch { + // Ignore registration failures; app can still run without SW header shim. + } +} + // Start the app +registerCoiServiceWorker(); init(); diff --git a/src/public/sw-coi.js b/src/public/sw-coi.js new file mode 100644 index 0000000..9a44584 --- /dev/null +++ b/src/public/sw-coi.js @@ -0,0 +1,52 @@ +/* + Best-effort COI shim: adds missing COOP/COEP/CORP headers to same-origin GET responses. + Note: This only applies after the service worker controls the page. +*/ + +const REQUIRED_HEADERS = { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + 'Cross-Origin-Resource-Policy': 'same-origin', +}; + +self.addEventListener('install', (event) => { + event.waitUntil(self.skipWaiting()); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil(self.clients.claim()); +}); + +self.addEventListener('fetch', (event) => { + const { request } = event; + + // Only patch same-origin GET requests we can safely proxy. + if (request.method !== 'GET') return; + + const url = new URL(request.url); + if (url.origin !== self.location.origin) return; + + event.respondWith( + (async () => { + const networkResponse = await fetch(request); + + // Do not attempt to rewrite opaque or redirected responses. + if (networkResponse.type === 'opaque' || networkResponse.type === 'opaqueredirect') { + return networkResponse; + } + + const headers = new self.Headers(networkResponse.headers); + Object.entries(REQUIRED_HEADERS).forEach(([name, value]) => { + if (!headers.has(name)) { + headers.set(name, value); + } + }); + + return new self.Response(networkResponse.body, { + status: networkResponse.status, + statusText: networkResponse.statusText, + headers, + }); + })() + ); +}); From f2eb94090f99748453351c0cedb99ea500fafc14 Mon Sep 17 00:00:00 2001 From: Akhilesh Airen Date: Wed, 11 Mar 2026 14:29:40 +0530 Subject: [PATCH 2/4] run prettier and make changes in service worker --- eslint.config.js | 1 + src/page_assets/index/js/main.js | 18 +++++++++++------- src/public/sw-coi.js | 8 +++++++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 5404d7f..1c8b866 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -25,6 +25,7 @@ export default [ AbortController: "readonly", requestAnimationFrame: "readonly", setTimeout: "readonly", + Response: "readonly", }, }, rules: { diff --git a/src/page_assets/index/js/main.js b/src/page_assets/index/js/main.js index bcbe96f..ab86982 100644 --- a/src/page_assets/index/js/main.js +++ b/src/page_assets/index/js/main.js @@ -5,14 +5,18 @@ import '../../../scss/styles.scss'; import { init } from '../../../common/js/scl-app'; async function registerCoiServiceWorker() { - if (!('serviceWorker' in navigator)) return; + if (!('serviceWorker' in navigator)) return; + if (window.crossOriginIsolated) return; - try { - await navigator.serviceWorker.register('/sw-coi.js', { scope: '/' }); - await navigator.serviceWorker.ready; - } catch { - // Ignore registration failures; app can still run without SW header shim. - } + try { + await navigator.serviceWorker.register('/sw-coi.js', { scope: '/' }); + await navigator.serviceWorker.ready; + if (!window.crossOriginIsolated) { + window.location.reload(); + } + } catch { + // Ignore registration failures; app can still run without SW header shim. + } } // Start the app diff --git a/src/public/sw-coi.js b/src/public/sw-coi.js index 9a44584..93ba8cc 100644 --- a/src/public/sw-coi.js +++ b/src/public/sw-coi.js @@ -28,7 +28,13 @@ self.addEventListener('fetch', (event) => { event.respondWith( (async () => { - const networkResponse = await fetch(request); + let networkResponse; + try { + networkResponse = await fetch(request); + } catch (error) { + // If the network request fails (e.g. offline), just return the error response. + return new Response(error.message, { status: 503, statusText: 'Service Unavailable' }); + } // Do not attempt to rewrite opaque or redirected responses. if (networkResponse.type === 'opaque' || networkResponse.type === 'opaqueredirect') { From d68f2a7e827d4429a447f449a93c19aa68973f5c Mon Sep 17 00:00:00 2001 From: Akhilesh Airen Date: Wed, 11 Mar 2026 14:33:19 +0530 Subject: [PATCH 3/4] wait for register service worker before initialization --- src/page_assets/index/js/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page_assets/index/js/main.js b/src/page_assets/index/js/main.js index ab86982..70e34d7 100644 --- a/src/page_assets/index/js/main.js +++ b/src/page_assets/index/js/main.js @@ -20,5 +20,5 @@ async function registerCoiServiceWorker() { } // Start the app -registerCoiServiceWorker(); +await registerCoiServiceWorker(); init(); From e0f3e504289e76cf88ba67ade4711af1419972b5 Mon Sep 17 00:00:00 2001 From: Akhilesh Airen Date: Wed, 11 Mar 2026 14:36:51 +0530 Subject: [PATCH 4/4] add promise.then instead of await --- src/page_assets/index/js/main.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/page_assets/index/js/main.js b/src/page_assets/index/js/main.js index 70e34d7..883e5d2 100644 --- a/src/page_assets/index/js/main.js +++ b/src/page_assets/index/js/main.js @@ -20,5 +20,6 @@ async function registerCoiServiceWorker() { } // Start the app -await registerCoiServiceWorker(); -init(); +registerCoiServiceWorker().then(() => { + init(); +});