Repository navigation
[iFrame] Add the WebAppFrameUrl and WebAppFrameSrcdoc universal components - #2798
josemontespg wants to merge 1 commit into
Conversation
96104b7 to
2fe370d
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces the iframeCatalog along with the WebAppFrameUrl and WebAppFrameSrcdoc universal components, which render sandboxed iframe content and connect it to the host via WebAppFrameBridge. It also adds base classes and host adapters (SandboxedFrameElement and ComponentContextFrameHost) to support custom sandboxed frame components, alongside comprehensive unit and integration tests. The feedback highlights a potential security vulnerability in injectContentSecurityPolicy where regular expressions are used to parse and inject elements into HTML, and suggests using DOMParser for a more robust and secure implementation.
2fe370d to
5264f2a
Compare
5264f2a to
5d0ea7d
Compare
8fc76cb to
b6c8505
Compare
b6c8505 to
e1c127e
Compare
e1c127e to
ba0f9ad
Compare
ba0f9ad to
b75ff80
Compare
f7242a5 to
d5cac41
Compare
d5cac41 to
4c12b8a
Compare
c89212a to
676109f
Compare
676109f to
1c0f3bd
Compare
1c0f3bd to
ca70f69
Compare
ca70f69 to
0bac791
Compare
a70f9a3 to
7f30e5f
Compare
86eda65 to
56cc3e2
Compare
56cc3e2 to
61f98ee
Compare
| frameHeightFromProp, | ||
| frameTitleFromProps, | ||
| SandboxedFrameElement, | ||
| } from './shared/sandbox/sandboxed_frame_element.js'; |
There was a problem hiding this comment.
Agent: Do we really need to export these symbols as part of the public API of this package? Are consumers expected to use frameHeightFromProp,
frameTitleFromProps,
SandboxedFrameElement, ?, or is this an internal implementation detail of the package?
Summary
This change adds the two components of the iframe catalog to
@a2ui/catalog-iframeas universal components:WebAppFrameUrl, which loads an external web application from an http or https URL, andWebAppFrameSrcdoc, which renders inline HTML. Both render the sandbox proxy in their light DOM, hand it the content once it reports ready, and connect the frame to the surface throughWebAppFrameBridge, so the application gets the bound data paths, the allowlists and aMessagePortin the handshake, and its actions, data changes, function calls and resize requests go through the validated host bridge.iframeCatalogexposes them to aMessageProcessor.The components target A2UI v1.0: they import from
@a2ui/web_core/v1_0, the bridge uses the v1.0ActionPayloadandAgentToRendererMessagetypes, andiframeCatalogis aCatalogfor protocol1.0.The pieces the components are made of are shared:
SandboxedFrameElement(proxy frame rendering, height, proxy handshake, bridge lifecycle across context and content changes, cleanup on removal) andComponentContextFrameHost(theFrameHostover a universal component'sComponentContext) live intypescript/catalogs/shared/sandbox/and are exported, so a catalog that adds another sandboxed frame component can build on them.Changes
WebAppFrameUrl(a2ui-web-app-frame-url) andWebAppFrameSrcdoc(a2ui-web-app-frame-srcdoc) with zod APIs that match the catalog schema,iframeCatalog, and the exports insrc/index.ts.WebAppFrameUrlonly loads http and https URLs and appends the host origin as theoriginquery parameter; other schemes load nothing and are reported once.WebAppFrameSrcdocdecodes theurl_encoded:form, keeps author CSP meta tags (they can only narrow the policy), injects the strict policy and the link interceptor, and loads nothing for empty content.SandboxedFrameElement: one<iframe>in the light DOM pointing at the sandbox proxy, nosandboxattribute on the proxy frame (the inner frame the proxy creates runs withallow-scripts allow-forms allow-modalsand neverallow-same-origin),titlefromaccessibility.label,heightapplied to the element with app-driven resizing throughFrameSizing, proxy-ready listening and resource sending, bridge reconnection when the context or the content changes, teardown on disconnect and a new session on re-attach. Styling through--a2ui-sandboxed-frame-*custom properties.ComponentContextFrameHost: data paths through the component's data context, functions through the surface catalog invoker with signal results unwrapped, actions dispatched as events of the component.@a2ui/web_coreandlitbecome peer dependencies (and dev dependencies); the wireitbuild,test:typesandlintscripts depend ontypescript/web_core:build.catalog.json; component tests that process small inlinev1.0message fixtures with a realMessageProcessor, render the elements and play the proxy and the application over an inert same-origin page and the real transferred port; tests of the base class and the host adapter; real-frame scenarios undertests/that load the real proxy fromdist/sandbox/(served by Karma at/a2ui-sandbox/) and a fixture application in both modes, covering the double-iframe bootstrap and handshake, action, two-way data, function call and resize round trips, and the negative cases (undeclared actions, invalid payloads and unbound data dropped, ambient protocol messages ignored, foreign-origin handshakes ignored, top navigation blocked, noallow-same-originon the inner frame).catalogIdto use the frames in a basic surface), the component properties with an example message, styling, and how to write another sandboxed frame component. The CHANGELOG entry extends the package bullet from [iFrame] Add the @a2ui/catalog-iframe package and frame bridge #2797.Verification
yarn workspaces foreach -R --from @a2ui/catalog-iframe --topological-dev run build: passes from a clean tree.yarn workspace @a2ui/catalog-iframe test: 258 of 258 Karma specs pass in headless Chrome, including the real-frame scenarios.yarn workspace @a2ui/catalog-iframe lint,yarn lint:deps,./scripts/fix_format.sh --checkandpython3 scripts/fix_licenses.py --check: pass.yarn pack --dry-runin the package: the components ship underdist/; no tests, test support or fixtures are included.Pre-launch Checklist
Related to #3157