Add configurable UI extension slots#3622
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| taskQueue: workflow?.taskQueue, | ||
| workflowType: workflow?.name, | ||
| }, | ||
| }} |
There was a problem hiding this comment.
⚠️ Type 'WorkflowStatus | undefined' is not assignable to type 'string | undefined'.
|
| buildIframeSandbox({ | ||
| ...extension().sandbox, | ||
| allowForms: true, | ||
| allowPopupsToEscapeSandbox: true, |
There was a problem hiding this comment.
allowPopupsToEscapeSandbox This seems sus I feel like we shouldn't allow sandbox escaping?
| ).toBeNull(); | ||
| expect(safeNavigationPath('javascript:alert(1)', currentOrigin)).toBeNull(); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Can we have some tests around iframe allow headers on origin and remote and maybe an iFrame script to reach to the parent frame and a script from the parent frame trying to reach into the child frame?
| const minWidth = positiveOrUndefined(sizing.minWidth) ?? MIN_WIDTH; | ||
| const maxWidth = positiveOrUndefined(sizing.maxWidth) ?? MAX_WIDTH; | ||
| return clamp(defaultWidth, minWidth, maxWidth); | ||
| }; |
There was a problem hiding this comment.
It might be cool to have an @Attach on the parent html container with a ResizeObserver debounced by RAF that sends the height/width of the container to the iframe so you could have the iframe reactive to the size of the parent html contianer
|
|
||
| CustomUI struct { | ||
| Enabled bool `yaml:"enabled"` | ||
| IframeExtensions []IframeExtension `yaml:"iframeExtensions"` |
There was a problem hiding this comment.
I think static YAML is fine for now, but wondering if it might it be worth it to support getting extensions via a manifest URL?
Something that wouldn't require a redeploy every time something needed to be changed e.g.
extensionManifests:
- url: https://example.com/manifest.json
allowedOrigin: https://example.com
permissions: [context:workflow]
There was a problem hiding this comment.
Yes I think that's a great idea. Then that would also support Nexus endpoints - you could point the url to a Nexus endpoint and have it return a custom UI
Description & motivation 💭
Adds configurable iframe-based UI extensions so operators can mount customer-owned UI into stable Temporal UI slots without forking the main UI bundle.
This PR:
customUiserver configuration for enabling iframe extensions, including extension IDs, slot names, source URLs, allowed origins, route filters, sandbox options, sizing bounds, and permissions.settings.customUi.ExtensionSlotandIframeExtensioncomponents that render configured extensions only when the slot, route pattern, iframe URL, and allowed origin all match.postMessageprotocol:temporal-ui/contextandtemporal-ui/theme.temporal-extension/ready,temporal-extension/resize, and permittedtemporal-extension/navigate.src/lib/extensions/README.md.Screenshots (if applicable) 📸
Examples
Design Considerations 🎨
customUi.enabledis false.allow-scripts; additional capabilities are opt-in per extension.navigation:write.Testing 🧪
How was this tested 👻
Local test commands run:
Results:
github.com/temporalio/ui-server/v2/server/apipassed.Steps for others to test: 🚶🏽♂️🚶🏽♀️
customUi.enabled: truewith one or moreiframeExtensionsin the UI server config.srcwithallowedOrigin: self, or at an HTTPS origin with a matching explicitallowedOrigin.app.top-nav.actions.beforeapp.top-nav.actions.afterapp.top-nav.sub-navworkflow.header.after-detailsroutePatternsmatch.readyandresizemessages and verify the host responds with context/theme messages and clamps dimensions to configured bounds.permissions: [context:workflow], verify workflow context is delivered.permissions: [navigation:write], send a same-origin navigate message and verify the host navigates; verify off-origin URLs are ignored.Checklists
Draft Checklist
N/A
Merge Checklist
N/A
Issue(s) closed
N/A
Docs
Any docs updates needed?
Docs for the new extension framework are included in
src/lib/extensions/README.md.