@@ -218,7 +218,7 @@ const processWithGlobalScopeExecutionEnv = (
218218}
219219
220220/**
221- * Sandbox that avoids CSP errors, but evaluates everything globally
221+ * Sandbox that invokes processSignal in the global scope (avoids all CSP errors)
222222 */
223223interface GlobalScopeSandboxSettings {
224224 edgeFnDownloadURL : string
@@ -246,35 +246,12 @@ export class NoopSandbox implements SignalSandbox {
246246}
247247
248248/**
249- * window.addEventListener('message', async (event) => {
250- const { type, payload } = event.data
251- if (type === 'execute') {
252- try {
253- const { signal, signals, analytics, SignalType, EventType, NavigationAction } = payload
254- await processSignal(signal, { analytics, signals, SignalType, EventType, NavigationAction })
255- event.source.postMessage({ type: 'result', payload: analytics.getCalls() }, '*')
256- } catch (err) {
257- event.source.postMessage({ type: 'error', error: err.message }, '*')
258- }
259- }
260- })
261-
262- window.parent.postMessage('iframe_ready', '*')
249+ * Sandbox that executes code in an iframe.
250+ * Pros:
251+ * - More secure
252+ * Cons:
253+ * - Can trigger CSP errors unless :blob directive is present
263254 */
264-
265- const noramizeMethodCallsWithArgResolver = (
266- methodCalls : AnalyticsMethodCalls
267- ) => {
268- const normalizedRuntime = new AnalyticsRuntime ( )
269- Object . entries ( methodCalls ) . forEach ( ( [ methodName , calls ] ) => {
270- calls . forEach ( ( args ) => {
271- // @ts -ignore
272- normalizedRuntime [ methodName ] ( ...args )
273- } )
274- } )
275- return normalizedRuntime . getCalls ( )
276- }
277-
278255export class IframeSandbox implements SignalSandbox {
279256 private iframe : HTMLIFrameElement
280257 private iframeReady : Promise < void >
@@ -339,7 +316,7 @@ export class IframeSandbox implements SignalSandbox {
339316 constructor() {
340317 this.calls = new Map();
341318 }
342- getFormattedCalls () {
319+ getCalls () {
343320 return Object.fromEntries(this.calls); // call in {track: [args]} format
344321 }
345322 createProxy() {
@@ -389,7 +366,7 @@ export class IframeSandbox implements SignalSandbox {
389366 });
390367 window.signals.signalBuffer = signalBuffer; // signals is exposed as part of get runtimeCode
391368 window.processSignal(signal, { signals, constants })
392- event.source.postMessage({ type: 'execution_result', payload: analyticsProxy.getFormattedCalls () }, '*');
369+ event.source.postMessage({ type: 'execution_result', payload: analyticsProxy.getCalls () }, '*');
393370 } catch(err) {
394371 event.source.postMessage({ type: 'execution_error', error: err }, '*');
395372 }
@@ -405,6 +382,19 @@ export class IframeSandbox implements SignalSandbox {
405382 doc . head . appendChild ( runtimeScript )
406383 }
407384
385+ private normalizeAnalyticsMethodCallsWithArgResolver = (
386+ methodCalls : AnalyticsMethodCalls
387+ ) => {
388+ const analytics = new AnalyticsRuntime ( )
389+ Object . entries ( methodCalls ) . forEach ( ( [ methodName , calls ] ) => {
390+ calls . forEach ( ( args ) => {
391+ // @ts -ignore
392+ analytics [ methodName ] ( ...args )
393+ } )
394+ } )
395+ return analytics . getCalls ( )
396+ }
397+
408398 async execute (
409399 signal : Signal ,
410400 signals : Signal [ ]
@@ -416,7 +406,10 @@ export class IframeSandbox implements SignalSandbox {
416406 if ( e . source !== this . iframe . contentWindow ) return
417407 if ( e . data ?. type === 'execution_result' ) {
418408 window . removeEventListener ( 'message' , handler )
419- resolve ( noramizeMethodCallsWithArgResolver ( e . data . payload ) )
409+ const methodCalls = this . normalizeAnalyticsMethodCallsWithArgResolver (
410+ e . data . payload
411+ )
412+ resolve ( methodCalls )
420413 }
421414 if ( e . data ?. type === 'execution_error' ) {
422415 window . removeEventListener ( 'message' , handler )
0 commit comments