Skip to content

Commit 6483541

Browse files
authored
Add signals strategy configuration for customers with restrictive CSPs (#1284)
1 parent 4e0cb63 commit 6483541

35 files changed

+348
-97
lines changed

.changeset/eight-adults-type.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-signals': minor
3+
---
4+
5+
Fix CSP errors with sandboxStrategy: global

.changeset/empty-eagles-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-signals': minor
3+
---
4+
5+
Update max signals in buffer to 100

packages/signals/signals-example/public/index.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
<title>React TypeScript App</title>
8+
<!---
9+
10+
1. Requres 'unsafe-inline'
11+
- Refused to execute inline script because it violates the following Content Security Policy directive: [directive] Either the 'unsafe-inline' keyword, a hash ('sha256-XDT/UwTV/dYYXFad1cmKD+q1zZNK8KGVRYvIdvkmo7I='), or a nonce ('nonce-...') is required to enable inline execution.
12+
2. Requires 'unsafe-eval'
13+
processSignal() error in sandbox Error: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive
14+
-->
15+
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://*.segment.com https://*.googletagmanager.com blob:">
816
</head>
9-
1017
<body>
1118
<div id="root"></div>
1219
</body>
1320

14-
</html>
21+
</html>

packages/signals/signals-example/src/lib/analytics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const isStage = process.env.STAGE === 'true'
3333

3434
const signalsPlugin = new SignalsPlugin({
3535
...(isStage ? { apiHost: 'signals.segment.build/v1' } : {}),
36-
// enableDebugLogging: true,
36+
sandboxStrategy: 'global',
3737
// processSignal: processSignalExample,
3838
})
3939

packages/signals/signals-integration-tests/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
"scripts": {
99
".": "yarn run -T turbo run --filter=@internal/signals-integration-tests...",
1010
"build": "webpack",
11-
"test:int": "playwright test",
11+
"test:int": "playwright test && SKIP_BUILD=true yarn test:global-sandbox",
1212
"test:vanilla": "playwright test src/tests/signals-vanilla",
1313
"test:perf": "playwright test src/tests/performance",
1414
"test:custom": "playwright test src/tests/custom",
15+
"test:global-sandbox": "SANDBOX_STRATEGY=global playwright test src/tests/signals-vanilla src/tests/custom",
1516
"watch": "webpack -w",
1617
"lint": "yarn concurrently 'yarn:eslint .' 'yarn:tsc --noEmit'",
1718
"concurrently": "yarn run -T concurrently",
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import type { FullConfig } from '@playwright/test'
22
import { execSync } from 'child_process'
3+
import { envConfig } from './src/helpers/env-config'
34

45
export default function globalSetup(_cfg: FullConfig) {
5-
console.log('Executing global setup...')
6-
execSync('yarn build', { stdio: 'inherit' })
7-
console.log('Finished global setup.')
6+
console.log(`Executing playwright.global-setup.ts...\n`)
7+
console.log(`Using envConfig: ${JSON.stringify(envConfig, undefined, 2)}\n`)
8+
if (process.env.SKIP_BUILD !== 'true') {
9+
console.log(`Executing yarn build:\n`)
10+
execSync('yarn build', { stdio: 'inherit' })
11+
}
12+
console.log('Finished global setup. Should start running tests.\n')
813
}

packages/signals/signals-integration-tests/src/helpers/base-page-object.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
SignalAPIRequestBuffer,
88
TrackingAPIRequestBuffer,
99
} from './network-utils'
10+
import { envConfig } from './env-config'
1011

1112
export class BasePage {
1213
protected page!: Page
@@ -63,6 +64,7 @@ export class BasePage {
6364
await this.page.goto(url, { waitUntil: 'domcontentloaded' })
6465
if (!options.skipSignalsPluginInit) {
6566
void this.invokeAnalyticsLoad({
67+
sandboxStrategy: envConfig.SANDBOX_STRATEGY,
6668
flushInterval: 500,
6769
...signalSettings,
6870
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { SignalsPluginSettingsConfig } from '@segment/analytics-signals'
2+
3+
// This is for testing with the global sandbox strategy with an npm script, that executes processSignal in the global scope
4+
// If we change this to be the default, this can be rejiggered
5+
const SANDBOX_STRATEGY = (process.env.SANDBOX_STRATEGY ??
6+
'iframe') as SignalsPluginSettingsConfig['sandboxStrategy']
7+
8+
export const envConfig = {
9+
SANDBOX_STRATEGY,
10+
}

packages/signals/signals-integration-tests/src/tests/custom-elements/custom-select.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { waitForCondition } from '../../helpers/playwright-utils'
33
import { IndexPage } from './index-page'
44
import type { SegmentEvent } from '@segment/analytics-next'
55

6-
const basicEdgeFn = `const processSignal = (signal) => {}`
6+
const basicEdgeFn = `globalThis.processSignal = (signal) => {}`
77

88
test('Collecting signals whenever a user selects an item', async ({ page }) => {
99
const indexPage = await new IndexPage().loadAndWait(page, basicEdgeFn, {

packages/signals/signals-integration-tests/src/tests/custom-elements/custom-textfield.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'
22
import { waitForCondition } from '../../helpers/playwright-utils'
33
import { IndexPage } from './index-page'
44

5-
const basicEdgeFn = `const processSignal = (signal) => {}`
5+
const basicEdgeFn = `globalThis.processSignal = (signal) => {}`
66

77
test('Collecting signals whenever a user enters text input and focuses out', async ({
88
page,

0 commit comments

Comments
 (0)