Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion developer-extension/src/content-scripts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ function overrideInitConfiguration(global: GlobalInstrumentation, configurationO
if ('init' in sdkInstance) {
const originalInit = sdkInstance.init
sdkInstance.init = (config: any) => {
originalInit({ ...config, ...configurationOverride })
originalInit({
...config,
...configurationOverride,
allowedTrackingOrigins: [location.origin],
})
}
}
})
Expand Down
16 changes: 4 additions & 12 deletions packages/core/src/domain/allowedTrackingOrigins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { STACK_WITH_INIT_IN_EXTENSION, STACK_WITH_INIT_IN_PAGE } from '../../tes
import { display } from '../tools/display'
import {
isAllowedTrackingOrigins,
WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN,
ERROR_NOT_ALLOWED_TRACKING_ORIGIN,
ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN,
} from './allowedTrackingOrigins'

const DEFAULT_CONFIG = {
Expand All @@ -13,17 +13,14 @@ const DEFAULT_CONFIG = {
}

describe('checkForAllowedTrackingOrigins', () => {
let displayWarnSpy: jasmine.Spy
let displayErrorSpy: jasmine.Spy

beforeEach(() => {
displayWarnSpy = spyOn(display, 'warn')
displayErrorSpy = spyOn(display, 'error')
})

it('should not warn if not in extension environment', () => {
const result = isAllowedTrackingOrigins(DEFAULT_CONFIG, STACK_WITH_INIT_IN_PAGE, 'https://app.example.com')
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand All @@ -38,7 +35,6 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_PAGE,
'https://app.example.com'
)
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand All @@ -52,7 +48,6 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_PAGE,
'https://app.example.com'
)
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand All @@ -66,7 +61,6 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_PAGE,
'https://app.example.com'
)
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand All @@ -84,7 +78,6 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_PAGE,
'https://app.example.com'
)
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand Down Expand Up @@ -175,7 +168,7 @@ describe('checkForAllowedTrackingOrigins', () => {
})

describe('when configuration does not have allowedTrackingOrigins', () => {
it('should warn when in extension environment and allowedTrackingOrigins is undefined', () => {
it('should log an error when in extension environment and allowedTrackingOrigins is undefined', () => {
const result = isAllowedTrackingOrigins(
{
...DEFAULT_CONFIG,
Expand All @@ -184,8 +177,8 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_EXTENSION,
'https://example.com'
)
expect(displayWarnSpy).toHaveBeenCalledWith(WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN)
expect(result).toBe(true)
expect(displayErrorSpy).toHaveBeenCalledWith(ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN)
expect(result).toBe(false)
})

it('should error when in extension environment and allowedTrackingOrigins is an empty array', () => {
Expand All @@ -210,7 +203,6 @@ describe('checkForAllowedTrackingOrigins', () => {
STACK_WITH_INIT_IN_PAGE,
'https://example.com'
)
expect(displayWarnSpy).not.toHaveBeenCalled()
expect(displayErrorSpy).not.toHaveBeenCalled()
expect(result).toBe(true)
})
Expand Down
16 changes: 5 additions & 11 deletions packages/core/src/domain/allowedTrackingOrigins.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { display } from '../tools/display'
import { matchList } from '../tools/matchOption'
import type { InitConfiguration } from './configuration'
import { extractExtensionUrlFromStack, isUnsupportedExtensionEnvironment } from './extension/extensionUtils'
import { addTelemetryDebug } from './telemetry'
import { isUnsupportedExtensionEnvironment } from './extension/extensionUtils'

export const WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN =
'Running the Browser SDK in a Web extension content script is discouraged and will be forbidden in a future major release unless the `allowedTrackingOrigins` option is provided.'
export const ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN =
'Running the Browser SDK in a Web extension content script is forbidden unless the `allowedTrackingOrigins` option is provided.'
export const ERROR_NOT_ALLOWED_TRACKING_ORIGIN = 'SDK initialized on a non-allowed domain.'

export function isAllowedTrackingOrigins(
Expand All @@ -16,14 +15,9 @@ export function isAllowedTrackingOrigins(
const allowedTrackingOrigins = configuration.allowedTrackingOrigins
if (!allowedTrackingOrigins) {
if (isUnsupportedExtensionEnvironment(windowOrigin, errorStack)) {
display.warn(WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN)
display.error(ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN)

const extensionUrl = extractExtensionUrlFromStack(errorStack)
// monitor-until: 2026-01-01
addTelemetryDebug(WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN, {
extensionUrl: extensionUrl || 'unknown',
})
// TODO(next major): make `allowedTrackingOrigins` required in unsupported extension environments
return false
}
return true
}
Expand Down
22 changes: 1 addition & 21 deletions packages/core/src/domain/extension/extensionUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import {
STACK_WITH_INIT_IN_EXTENSION_FIREFOX,
STACK_WITH_INIT_IN_PAGE,
} from '../../../test'
import {
containsExtensionUrl,
EXTENSION_PREFIXES,
extractExtensionUrlFromStack,
isUnsupportedExtensionEnvironment,
} from './extensionUtils'
import { containsExtensionUrl, EXTENSION_PREFIXES, isUnsupportedExtensionEnvironment } from './extensionUtils'

describe('extensionUtils', () => {
describe('containsExtensionUrl', () => {
Expand Down Expand Up @@ -49,19 +44,4 @@ describe('extensionUtils', () => {
expect(isUnsupportedExtensionEnvironment('https://example.com', STACK_WITH_INIT_IN_EXTENSION)).toBe(true)
})
})

describe('extract init caller', () => {
it('should extract extension URL from stack trace', () => {
const stack = `Error
at foo (<anonymous>:549:44)
at bar (<anonymous>:701:91)
at e.init (chrome-extension://abcd/content-script-main.js:1:1009)`
expect(extractExtensionUrlFromStack(stack)).toBe('chrome-extension://abcd')
})

it('should return undefined when no extension URL found', () => {
const stack = 'Error at https://example.com/script.js:10:15'
expect(extractExtensionUrlFromStack(stack)).toBeUndefined()
})
})
})
10 changes: 0 additions & 10 deletions packages/core/src/domain/extension/extensionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,3 @@ export function isUnsupportedExtensionEnvironment(windowLocation: string, stack:

return containsExtensionUrl(target)
}

export function extractExtensionUrlFromStack(stack: string = ''): string | undefined {
for (const prefix of EXTENSION_PREFIXES) {
const match = stack.match(new RegExp(`${prefix}[^/]+`))

if (match) {
return match[0]
}
}
}
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,3 @@ export * from './domain/connectivity'
export * from './tools/stackTrace/handlingStack'
export * from './tools/abstractHooks'
export * from './domain/tags'
export { WARN_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN } from './domain/allowedTrackingOrigins'
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { test, expect } from '@playwright/test'
import type { BrowserLog } from '../../lib/framework'
import { createTest, createExtension, createCrossOriginScriptUrls, formatConfiguration } from '../../lib/framework'

const WARNING_MESSAGE =
'Datadog Browser SDK: Running the Browser SDK in a Web extension content script is discouraged and will be forbidden in a future major release unless the `allowedTrackingOrigins` option is provided.'
const ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN =
'Datadog Browser SDK: Running the Browser SDK in a Web extension content script is forbidden unless the `allowedTrackingOrigins` option is provided.'
const ERROR_MESSAGE = 'Datadog Browser SDK: SDK initialized on a non-allowed domain.'

const BASE_PATH = path.join(process.cwd(), 'test/apps')
Expand All @@ -18,22 +18,22 @@ const isNotSdkLoadedMoreThanOnce = (log: BrowserLog) => !log.message.includes('S
test.describe('browser extensions', () => {
for (const name of EXTENSIONS) {
test.describe(`with ${name} extension`, () => {
createTest('should warn and start tracking when SDK is initialized in an unsupported environment')
createTest('should not start tracking and log an error when SDK is initialized in an unsupported environment')
.withExtension(createExtension(path.join(BASE_PATH, name)).withRum().withLogs())
.run(async ({ withBrowserLogs, flushEvents, intakeRegistry }) => {
await flushEvents()

expect(intakeRegistry.rumViewEvents).toHaveLength(1)
expect(intakeRegistry.rumViewEvents).toHaveLength(0)

withBrowserLogs((logs) => {
const filteredLogs = logs.filter(isNotSdkLoadedMoreThanOnce)

// Two warnings, one for RUM and one for LOGS SDK
// Two errors, one for RUM and one for LOGS SDK
expect(filteredLogs).toHaveLength(2)
filteredLogs.forEach((log) => {
expect(log).toMatchObject({
level: 'warning',
message: WARNING_MESSAGE,
level: 'error',
message: ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN,
})
})
})
Expand All @@ -53,8 +53,8 @@ test.describe('browser extensions', () => {
withBrowserLogs((logs) =>
expect(logs).not.toContainEqual(
expect.objectContaining({
level: 'warning',
message: WARNING_MESSAGE,
level: 'error',
message: ERROR_DOES_NOT_HAVE_ALLOWED_TRACKING_ORIGIN,
})
)
)
Expand Down