Merge pull request #26914 from Classic298/srcdoc-embed-prompt-confirmation
fix: restore prompt confirmation for sandboxed tool result embeds
This commit is contained in:
@@ -113,6 +113,7 @@
|
||||
import FilesOverlay from './MessageInput/FilesOverlay.svelte';
|
||||
import NotificationToast from '../NotificationToast.svelte';
|
||||
import Spinner from '../common/Spinner.svelte';
|
||||
import { isEmbedWindow } from '../common/FullHeightIframe.svelte';
|
||||
import Tooltip from '../common/Tooltip.svelte';
|
||||
import Sidebar from '../icons/Sidebar.svelte';
|
||||
import Image from '../common/Image.svelte';
|
||||
@@ -795,18 +796,18 @@
|
||||
|
||||
const onMessageHandler = async (event: {
|
||||
origin: string;
|
||||
source: unknown;
|
||||
data: { type: string; text: string };
|
||||
}) => {
|
||||
const isSameOrigin = event.origin === window.origin;
|
||||
const type = event.data?.type;
|
||||
|
||||
// Prompt-driving message types let an embedding page control the chat
|
||||
// input / submission. Cross-origin sources are only trusted when the
|
||||
// user has explicitly opted in via the "iframe Sandbox Allow Same
|
||||
// Origin" interface setting (the same toggle that governs whether
|
||||
// rendered iframes receive `allow-same-origin`).
|
||||
// Prompt-driving types are trusted only same-origin, from our own embed iframes
|
||||
// (opaque srcdoc origin, submission still confirmed below) or via explicit opt-in.
|
||||
const promptTypes = ['input:prompt', 'input:prompt:submit', 'action:submit'];
|
||||
const isTrusted = isSameOrigin || ($settings?.iframeSandboxAllowSameOrigin ?? false);
|
||||
const isOwnEmbed = isEmbedWindow(event.source);
|
||||
const isTrusted =
|
||||
isSameOrigin || isOwnEmbed || ($settings?.iframeSandboxAllowSameOrigin ?? false);
|
||||
|
||||
// Non-prompt message types are always restricted to same-origin only.
|
||||
if (!isSameOrigin && !promptTypes.includes(type)) {
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<script context="module" lang="ts">
|
||||
// contentWindows of embeds rendered here; Chat.svelte trusts prompt messages from these
|
||||
const embedWindows = new Set<Window>();
|
||||
|
||||
export const isEmbedWindow = (source: unknown): boolean => embedWindows.has(source as Window);
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount, tick } from 'svelte';
|
||||
import { config } from '$lib/stores';
|
||||
@@ -28,6 +35,7 @@
|
||||
let iframe: HTMLIFrameElement | null = null;
|
||||
let iframeSrc: string | null = null;
|
||||
let iframeDoc: string | null = null;
|
||||
let registeredWindow: Window | null = null;
|
||||
|
||||
// Derived: build sandbox attribute from flags
|
||||
$: sandbox =
|
||||
@@ -175,6 +183,14 @@ window.Chart = parent.Chart; // Chart previously assigned on parent
|
||||
const onLoad = async () => {
|
||||
requestAnimationFrame(resizeSameOrigin);
|
||||
|
||||
if (iframe?.contentWindow && iframe.contentWindow !== registeredWindow) {
|
||||
if (registeredWindow) {
|
||||
embedWindows.delete(registeredWindow);
|
||||
}
|
||||
registeredWindow = iframe.contentWindow;
|
||||
embedWindows.add(registeredWindow);
|
||||
}
|
||||
|
||||
// if arguments are provided, inject them into the iframe window
|
||||
if (args && iframe?.contentWindow) {
|
||||
(iframe.contentWindow as any).args = args;
|
||||
@@ -188,6 +204,9 @@ window.Chart = parent.Chart; // Chart previously assigned on parent
|
||||
|
||||
onDestroy(() => {
|
||||
window.removeEventListener('message', onMessage);
|
||||
if (registeredWindow) {
|
||||
embedWindows.delete(registeredWindow);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user