|
57 | 57 | inner.setAttribute('sandbox', 'allow-scripts allow-same-origin'); |
58 | 58 | document.body.appendChild(inner); |
59 | 59 |
|
| 60 | + // Build iframe allow attribute from permissions |
| 61 | + function buildAllowAttribute(permissions) { |
| 62 | + if (!permissions) return ''; |
| 63 | + const allowList = []; |
| 64 | + if (permissions.camera) allowList.push('camera'); |
| 65 | + if (permissions.microphone) allowList.push('microphone'); |
| 66 | + if (permissions.geolocation) allowList.push('geolocation'); |
| 67 | + return allowList.join('; '); |
| 68 | + } |
| 69 | + |
60 | 70 | window.addEventListener('message', async (event) => { |
61 | 71 | if (event.source === window.parent) { |
62 | 72 | if (event.data && event.data.method === 'ui/notifications/sandbox-resource-ready') { |
63 | | - const { html, sandbox } = event.data.params || {}; |
| 73 | + const { html, sandbox, permissions } = event.data.params || {}; |
| 74 | + // Note: csp is not extracted here - CSP is set via HTTP response headers in serve.ts |
64 | 75 | if (typeof sandbox === 'string') { |
65 | 76 | // Ensure allow-same-origin is present for document.write to work |
66 | 77 | let finalSandbox = sandbox; |
|
69 | 80 | } |
70 | 81 | inner.setAttribute('sandbox', finalSandbox); |
71 | 82 | } |
| 83 | + // Set Permission Policy allow attribute if permissions are provided |
| 84 | + const allowAttribute = buildAllowAttribute(permissions); |
| 85 | + if (allowAttribute) { |
| 86 | + inner.setAttribute('allow', allowAttribute); |
| 87 | + } |
72 | 88 | if (typeof html === 'string') { |
73 | 89 | // Use document.write instead of srcdoc to avoid CSP base-uri issues |
74 | 90 | // document.write allows the browser to resolve relative URLs correctly |
|
0 commit comments