'use strict'; // Guards the boundary added on top of #254 (org-level widget sandbox toggle). // // #254 let an org opt out of widget iframe isolation so PLAYERS can embed // origin-strict third-party sites. As merged it applied the same opt-out to the // widget editor's Preview — which is framed by the DASHBOARD, from the dashboard's // own origin, where the admin's session JWT lives in localStorage. That turned // "my kiosks are less isolated" into "anyone who can author a widget can lift the // session of whichever admin clicks Preview" (workspace_editor and up; viewers are // refused at the create route). // // These tests fail if the preview path ever consults the org setting again. const { test } = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const WIDGETS_ROUTE = fs.readFileSync(path.join(__dirname, '..', 'routes', 'widgets.js'), 'utf8'); const WIDGETS_VIEW = fs.readFileSync( path.join(__dirname, '..', '..', 'frontend', 'js', 'views', 'widgets.js'), 'utf8' ); // Body of a router handler, from its `router.(''` to the next `router.` function handlerBody(source, verb, route) { const start = source.indexOf(`router.${verb}('${route}'`); assert.notEqual(start, -1, `could not find router.${verb}('${route}') — test needs updating`); const rest = source.slice(start + 1); const end = rest.indexOf('\nrouter.'); return end === -1 ? rest : rest.slice(0, end); } test('preview sandbox constant is the isolating one', () => { assert.match( WIDGETS_ROUTE, /const PREVIEW_IFRAME_SANDBOX = 'allow-scripts';/, 'PREVIEW_IFRAME_SANDBOX must be exactly allow-scripts (no allow-same-origin)' ); }); for (const [verb, route] of [['post', '/preview'], ['post', '/preview-session']]) { test(`${verb.toUpperCase()} ${route} pins the isolating sandbox and ignores the org setting`, () => { const body = handlerBody(WIDGETS_ROUTE, verb, route); assert.match(body, /PREVIEW_IFRAME_SANDBOX/, `${route} must render with PREVIEW_IFRAME_SANDBOX`); assert.doesNotMatch( body, /widgetIframeSandboxForWorkspace/, `${route} must NOT consult the org widget-sandbox setting — it renders in the dashboard origin` ); }); } test('player render path still honours the org setting (the feature itself)', () => { const body = handlerBody(WIDGETS_ROUTE, 'get', '/:id/render'); assert.match( body, /widgetIframeSandboxForWorkspace\(widget\.workspace_id\)/, 'the /render path is what #254 is for — it must keep consulting the org setting' ); }); test('dashboard preview iframe is hard-coded to allow-scripts', () => { const iframeTag = WIDGETS_VIEW.match(/