| 52 | // Listen to messages coming from the webframe |
| 53 | React.useEffect(() => { |
| 54 | const callback = (event: MessageEvent) => { |
| 55 | if (!iframeRef.current) { |
| 56 | return; |
| 57 | } |
| 58 | |
| 59 | const message = event.data; |
| 60 | |
| 61 | if (!URL.canParse(event.origin)) { |
| 62 | return; |
| 63 | } |
| 64 | |
| 65 | const origin = new URL(event.origin); |
| 66 | |
| 67 | // For security reasons, only iframe from our integrations domains are allowed |
| 68 | // to send and receive messages |
| 69 | if (!renderer.security.firstPartyDomains.includes(origin.host)) { |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | const contentWindow = iframeRef.current.contentWindow; |
| 74 | |
| 75 | // Discard any messages coming other potential webframes on the page. |
| 76 | if (!contentWindow || event.source !== contentWindow) { |
| 77 | return; |
| 78 | } |
| 79 | |
| 80 | if (typeof message === 'string') { |
| 81 | try { |
| 82 | // We support the default oembed iframe protocol |
| 83 | // https://docs.embed.ly/reference/provider-height-resizing |
| 84 | const parsed = JSON.parse(message); |
| 85 | if (parsed.context === 'iframe.resize' && typeof parsed.height === 'number') { |
| 86 | const width = iframeRef.current.clientWidth; |
| 87 | const height = parsed.height; |
| 88 | |
| 89 | setSize({ |
| 90 | aspectRatio: width / height, |
| 91 | height: height, |
| 92 | }); |
| 93 | } |
| 94 | } catch (_err) { |
| 95 | return; |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | if (message.action) { |
| 100 | switch (message.action.action) { |
| 101 | case '@webframe.ready': |
| 102 | readyRef.current = true; |
| 103 | messagesQueueRef.current.forEach((message) => { |
| 104 | sendMessage(message); |
| 105 | }); |
| 106 | messagesQueueRef.current = []; |
| 107 | break; |
| 108 | case '@webframe.resize': |
| 109 | setSize((size) => ({ |
| 110 | aspectRatio: |
| 111 | typeof message.action.size.aspectRatio !== 'undefined' |