|
1 | 1 | import { useEffect, useRef, useState } from "react"; |
2 | 2 |
|
3 | | -const IFramePermissionKeys = set(['downloads', 'forms', 'modals', 'popups', 'fullscreen', 'camera', 'microphone', 'geolocation', 'payment', 'topNavigation', 'sameOrigin']) |
| 3 | +const MINIMUM_SANDBOX_PERMISSIONS = 'allow-scripts allow-same-origin' |
4 | 4 |
|
5 | | -const constructPermissionStrings = (permissions) => { |
6 | | - if (!permissions || permissions.length === 0) { |
7 | | - return { allowString: undefined, sandboxString: undefined } |
8 | | - } |
9 | | - |
10 | | - const allowArray = [] |
11 | | - const sandboxArray = [] |
12 | | - |
13 | | - permissions.filter(permission => IFramePermissionKeys.has(permission)).forEach(permission => { |
14 | | - switch (permission) { |
15 | | - case 'downloads': |
16 | | - sandboxArray.push('allow-downloads') |
17 | | - break |
18 | | - case 'forms': |
19 | | - sandboxArray.push('allow-forms') |
20 | | - break |
21 | | - case 'modals': |
22 | | - sandboxArray.push('allow-modals') |
23 | | - break |
24 | | - case 'popups': |
25 | | - sandboxArray.push('allow-popups', 'allow-popups-to-escape-sandbox') |
26 | | - break |
27 | | - case 'fullscreen': |
28 | | - allowArray.push('fullscreen') |
29 | | - break |
30 | | - case 'camera': |
31 | | - allowArray.push('camera') |
32 | | - break |
33 | | - case 'microphone': |
34 | | - allowArray.push('microphone') |
35 | | - break |
36 | | - case 'geolocation': |
37 | | - allowArray.push('geolocation') |
38 | | - break |
39 | | - case 'payment': |
40 | | - allowArray.push('payment') |
41 | | - break |
42 | | - case 'topNavigation': |
43 | | - sandboxArray.push('allow-top-navigation', 'allow-top-navigation-by-user-activation') |
44 | | - break |
45 | | - case 'sameOrigin': |
46 | | - sandboxArray.push('allow-same-origin') |
47 | | - break |
48 | | - } |
49 | | - }) |
50 | | - |
51 | | - const allowString = allowArray.length > 0 ? allowArray.join(';') : undefined |
52 | | - const sandboxString = sandboxArray.length > 0 ? sandboxArray.join(' ') : undefined |
53 | | - |
54 | | - return { allowString, sandboxString } |
55 | | -} |
56 | | - |
57 | | -const Retool = ({ data, url, height, width, onData, permissions }) => { |
| 5 | +const Retool = ({ data, url, height, width, onData, sandbox, allow }) => { |
58 | 6 | const embeddedIframe = useRef(null); |
59 | 7 | const [elementWatchers, setElementWatchers] = useState({}); |
60 | 8 |
|
61 | | - const { allowString, sandboxString } = constructPermissionStrings(permissions) |
62 | | - |
63 | 9 | /* Retool passes up the list of elements to watch on page load */ |
64 | 10 | useEffect(() => { |
65 | 11 | for (const key in elementWatchers) { |
@@ -141,17 +87,19 @@ const Retool = ({ data, url, height, width, onData, permissions }) => { |
141 | 87 | } |
142 | 88 | }; |
143 | 89 |
|
| 90 | + const sandboxAttrib = typeof sandbox === 'string' ? `${MINIMUM_SANDBOX_PERMISSIONS} ${sandbox}` : sandbox === true ? MINIMUM_SANDBOX_PERMISSIONS : sandbox |
| 91 | + |
144 | 92 | return ( |
145 | 93 | <iframe |
146 | | - allow={allowString} |
147 | | - sandbox={sandboxString} |
| 94 | + allow={allow} |
| 95 | + sandbox={sandboxAttrib} |
148 | 96 | height={height ?? "100%"} |
149 | 97 | width={width ?? "100%"} |
150 | 98 | frameBorder="none" |
151 | 99 | src={url} |
152 | 100 | ref={embeddedIframe} |
153 | 101 | title="retool" |
154 | | - ></iframe> |
| 102 | + /> |
155 | 103 | ); |
156 | 104 | }; |
157 | 105 |
|
|
0 commit comments