import type { RpcMessage, RpcTransport } from '@dorfteich/plugin-sdk'; /** * RPC transport bound to one sandbox iframe (ADR 0008, issue #73). * * Outgoing messages go to the frame's window; `targetOrigin '*'` is the only * option for an opaque-origin sandbox (it has no origin to pin), and is safe * because the payload never contains secrets — capability *results* flow only * after the gate approved the call. * * Incoming messages are accepted **only** when `event.source` is this exact * frame's window: another plugin frame (or any other window) on the page must * not be able to spoof requests or responses on this channel. */ export function frameTransport(frame: HTMLIFrameElement): RpcTransport { return { post: (message) => { frame.contentWindow?.postMessage(message, '*'); }, listen: (onMessage) => { const listener = (event: MessageEvent): void => { if (event.source === null || event.source !== frame.contentWindow) return; onMessage(event.data as RpcMessage); }; window.addEventListener('message', listener); return () => window.removeEventListener('message', listener); }, }; }