feat(editor): allow embedding any iframes (#12895)

fix BS-3606




#### PR Dependency Tree


* **PR #12892**
  * **PR #12895** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced support for embedding generic iframes with customizable
dimensions and permissions, while ensuring only secure, non-AFFiNE URLs
are allowed.
* Enhanced embedding options by prioritizing custom embed blocks over
iframe blocks for a richer embedding experience across toolbars and link
actions.
* Added URL validation to support secure and flexible embedding
configurations.

* **Bug Fixes**
* Improved iframe embedding reliability by removing restrictive HTTP
headers and certain Content Security Policy directives that could block
iframe usage in the Electron app.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Peng Xiao
2025-06-27 12:49:54 +08:00
committed by GitHub
parent ec66b6d660
commit f80b69273f
6 changed files with 171 additions and 52 deletions

View File

@@ -160,6 +160,48 @@ export function registerProtocol() {
delete responseHeaders['Access-Control-Allow-Origin'];
delete responseHeaders['Access-Control-Allow-Headers'];
}
// to allow url embedding, remove "x-frame-options",
// if response header contains "content-security-policy", remove "frame-ancestors/frame-src"
delete responseHeaders['x-frame-options'];
delete responseHeaders['X-Frame-Options'];
// Handle Content Security Policy headers
const cspHeaders = [
'content-security-policy',
'Content-Security-Policy',
];
for (const cspHeader of cspHeaders) {
const cspValues = responseHeaders[cspHeader];
if (cspValues) {
// Remove frame-ancestors and frame-src directives from CSP
const modifiedCspValues = cspValues
.map(cspValue => {
if (typeof cspValue === 'string') {
return cspValue
.split(';')
.filter(directive => {
const trimmed = directive.trim().toLowerCase();
return (
!trimmed.startsWith('frame-ancestors') &&
!trimmed.startsWith('frame-src')
);
})
.join(';');
}
return cspValue;
})
.filter(
value => value && typeof value === 'string' && value.trim()
);
if (modifiedCspValues.length > 0) {
responseHeaders[cspHeader] = modifiedCspValues;
} else {
delete responseHeaders[cspHeader];
}
}
}
}
})()
.catch(err => {