diff --git a/app.js b/app.js index a5f78d82..77abf024 100644 --- a/app.js +++ b/app.js @@ -522,7 +522,24 @@ function addCorsHeaders(req, res) { res.setHeader('Access-Control-Allow-Private-Network', 'true'); } // if (!crossOrigin) { - res.setHeader("Cross-Origin-Opener-Policy", 'same-origin'); + // COOP describes a top-level document's opener relationship - it has + // no defined meaning for a nested document, and setting it there is + // an architecture mismatch for a host like CMMS that only ever loads + // Kiri:Moto/Mesh:Tool inside an iframe: browsers apparently still act + // on a nested COOP header in ways that block postMessage delivery + // into the frame, even though messages are otherwise well-formed + // (same-origin, correct explicit targetOrigin) - CMMS integration bug, + // 2026-08-27: a postMessage-driven `load` command silently never + // reached this app at all when run/kiri/mesh was iframed, despite + // working perfectly when visited directly (top-level). Both Chrome + // and Firefox send Sec-Fetch-Dest: iframe on a request for an embed, + // so skip COOP only for that case - a direct top-level visit (this + // app's other real use, e.g. as an installable PWA) keeps full + // cross-origin isolation, COEP (which is what SharedArrayBuffer + // actually needs) stays on unconditionally either way. + if (req.headers['sec-fetch-dest'] !== 'iframe') { + res.setHeader("Cross-Origin-Opener-Policy", 'same-origin'); + } res.setHeader("Cross-Origin-Embedder-Policy", 'require-corp'); // } res.setHeader("Allow", "GET,POST,OPTIONS");