diff --git a/dev-packages/browser-integration-tests/suites/feedback/attachTo/test.ts b/dev-packages/browser-integration-tests/suites/feedback/attachTo/test.ts index 177d8cc2994f..a9888ad6edf6 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/attachTo/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/attachTo/test.ts @@ -57,9 +57,6 @@ sentryTest('should capture feedback with custom button', async ({ getLocalTestUr event_id: expect.stringMatching(/\w{32}/), environment: 'production', tags: {}, - user: { - ip_address: '{{auto}}', - }, sdk: { integrations: expect.arrayContaining(['Feedback']), version: expect.any(String), diff --git a/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts b/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts index 68c45e2c2f2f..138e7225a7c8 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts @@ -69,9 +69,6 @@ sentryTest('should capture feedback', async ({ getLocalTestUrl, page }) => { 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); }); diff --git a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/hasSampling/test.ts b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/hasSampling/test.ts index c91be3511d0a..51374ac81947 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/hasSampling/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/hasSampling/test.ts @@ -103,9 +103,6 @@ sentryTest('should capture feedback', async ({ forceFlushReplay, getLocalTestUrl 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); }); diff --git a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackCsp/test.ts b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackCsp/test.ts index 56ba6606c724..77eadb71173a 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackCsp/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackCsp/test.ts @@ -69,9 +69,6 @@ sentryTest('should capture feedback', async ({ getLocalTestUrl, page }) => { 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); const cspViolation = await page.evaluate('window.__CSPVIOLATION__'); diff --git a/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts b/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts index a220ba2923d6..642006f4c2fc 100644 --- a/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts +++ b/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts @@ -34,9 +34,6 @@ sentryTest('allows to setup a client manually & capture exceptions', async ({ ge 'User-Agent': expect.any(String), }), }, - user: { - ip_address: '{{auto}}', - }, timestamp: expect.any(Number), environment: 'local', release: '0.0.1', diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/subject.js b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/subject.js new file mode 100644 index 000000000000..1b632e0a9289 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/subject.js @@ -0,0 +1 @@ +Sentry.captureException(new Error('woot')); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/test.ts new file mode 100644 index 000000000000..310085607b09 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/errors/test.ts @@ -0,0 +1,11 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/core'; + +import { sentryTest } from '../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; + +sentryTest('should default user to {{auto}} on errors when sendDefaultPii: true', async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + const eventData = await getFirstSentryEnvelopeRequest(page, url); + expect(eventData.user?.ip_address).toBe('{{auto}}'); +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/init.js b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/init.js new file mode 100644 index 000000000000..b876cb8a3288 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/init.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + tracesSampleRate: 1, + sendDefaultPii: true, +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/subject.js b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/subject.js new file mode 100644 index 000000000000..8a509ca1d99d --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/subject.js @@ -0,0 +1 @@ +Sentry.startSpan({ name: 'woot' }, () => undefined); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/test.ts b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/test.ts new file mode 100644 index 000000000000..6e1f20826548 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/performance/test.ts @@ -0,0 +1,21 @@ +import { expect } from '@playwright/test'; +import { sentryTest } from '../../../../utils/fixtures'; +import { + envelopeRequestParser, + shouldSkipTracingTest, + waitForTransactionRequestOnUrl, +} from '../../../../utils/helpers'; + +sentryTest( + 'should default user to {{auto}} on transactions when sendDefaultPii: true', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + const req = await waitForTransactionRequestOnUrl(page, url); + const transaction = envelopeRequestParser(req); + expect(transaction.user?.ip_address).toBe('{{auto}}'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/init.js b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/init.js new file mode 100644 index 000000000000..b40eb0542e6b --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/init.js @@ -0,0 +1,20 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +window.Replay = Sentry.replayIntegration({ + flushMinDelay: 200, + flushMaxDelay: 200, + minReplayDuration: 0, + useCompression: false, + blockAllMedia: false, + unmask: ['.sentry-unmask, [data-sentry-unmask]'], +}); + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 0.0, + integrations: [window.Replay], + sendDefaultPii: true, +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/test.ts b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/test.ts new file mode 100644 index 000000000000..4f4ad6e3003a --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/replay/test.ts @@ -0,0 +1,24 @@ +import { expect } from '@playwright/test'; + +import { sentryTest } from '../../../../utils/fixtures'; +import { getReplayEvent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers'; + +sentryTest( + 'replay recording should contain default performance spans', + async ({ getLocalTestUrl, page, browserName }) => { + // We only test this against the NPM package and replay bundles + // and only on chromium as most performance entries are only available in chromium + if (shouldSkipReplayTest() || browserName !== 'chromium') { + sentryTest.skip(); + } + + const reqPromise0 = waitForReplayRequest(page, 0); + + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.goto(url); + const replayEvent = getReplayEvent(await reqPromise0); + + expect(replayEvent.user?.ip_address).toBe('{{auto}}'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/init.js b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/init.js new file mode 100644 index 000000000000..2003a9cf82eb --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/init.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + sendDefaultPii: true, + release: '1.0', +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/test.ts b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/test.ts new file mode 100644 index 000000000000..898e1cd9dbec --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/sendDefaultPii/sessions/test.ts @@ -0,0 +1,13 @@ +import { expect } from '@playwright/test'; + +import { sentryTest } from '../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; + +sentryTest( + 'should default user to {{auto}} on sessions when sendDefaultPii: true', + async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + const session = await getFirstSentryEnvelopeRequest(page, url); + expect((session as any).attrs.ip_address).toBe('{{auto}}'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/public-api/setUser/init.js b/dev-packages/browser-integration-tests/suites/public-api/setUser/init.js index d8c94f36fdd0..1f66b52852eb 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setUser/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/setUser/init.js @@ -4,4 +4,5 @@ window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', + sendDefaultPii: true, }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts index 43bc03bfb4d1..6fbdf6491d69 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts @@ -10,6 +10,8 @@ sentryTest('should unset user', async ({ getLocalTestUrl, page }) => { const eventData = await getMultipleSentryEnvelopeRequests(page, 3, { url }); expect(eventData[0].message).toBe('no_user'); + + // because sendDefaultPii: true expect(eventData[0].user).toEqual({ ip_address: '{{auto}}' }); expect(eventData[1].message).toBe('user'); @@ -20,6 +22,8 @@ sentryTest('should unset user', async ({ getLocalTestUrl, page }) => { }); expect(eventData[2].message).toBe('unset_user'); + + // because sendDefaultPii: true expect(eventData[2].user).toEqual({ ip_address: '{{auto}}', }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts index 9c4c83bf6764..0663d16b6995 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts @@ -103,9 +103,6 @@ sentryTest( headers: expect.any(Object), url: expect.any(String), }, - user: { - ip_address: '{{auto}}', - }, sdk: expect.any(Object), spans: [ { diff --git a/dev-packages/browser-integration-tests/suites/public-api/withScope/init.js b/dev-packages/browser-integration-tests/suites/public-api/withScope/init.js index d8c94f36fdd0..1f66b52852eb 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/withScope/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/withScope/init.js @@ -4,4 +4,5 @@ window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', + sendDefaultPii: true, }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts b/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts index d75b0248bd4f..bf10eed2b504 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts @@ -10,22 +10,36 @@ sentryTest('should allow nested scoping', async ({ getLocalTestUrl, page }) => { const eventData = await getMultipleSentryEnvelopeRequests(page, 5, { url }); expect(eventData[0].message).toBe('root_before'); - expect(eventData[0].user).toEqual({ id: 'qux', ip_address: '{{auto}}' }); + expect(eventData[0].user).toEqual({ + id: 'qux', + ip_address: '{{auto}}', // because sendDefaultPii: true + }); expect(eventData[0].tags).toBeUndefined(); expect(eventData[1].message).toBe('outer_before'); - expect(eventData[1].user).toEqual({ id: 'qux', ip_address: '{{auto}}' }); + expect(eventData[1].user).toEqual({ + id: 'qux', + ip_address: '{{auto}}', // because sendDefaultPii: true + }); expect(eventData[1].tags).toMatchObject({ foo: false }); expect(eventData[2].message).toBe('inner'); - expect(eventData[2].user).toEqual({ ip_address: '{{auto}}' }); + expect(eventData[2].user).toEqual({ + ip_address: '{{auto}}', // because sendDefaultPii: true + }); expect(eventData[2].tags).toMatchObject({ foo: false, bar: 10 }); expect(eventData[3].message).toBe('outer_after'); - expect(eventData[3].user).toEqual({ id: 'baz', ip_address: '{{auto}}' }); + expect(eventData[3].user).toEqual({ + id: 'baz', + ip_address: '{{auto}}', // because sendDefaultPii: true + }); expect(eventData[3].tags).toMatchObject({ foo: false }); expect(eventData[4].message).toBe('root_after'); - expect(eventData[4].user).toEqual({ id: 'qux', ip_address: '{{auto}}' }); + expect(eventData[4].user).toEqual({ + id: 'qux', + ip_address: '{{auto}}', // because sendDefaultPii: true + }); expect(eventData[4].tags).toBeUndefined(); }); diff --git a/dev-packages/browser-integration-tests/suites/replay/captureReplay/test.ts b/dev-packages/browser-integration-tests/suites/replay/captureReplay/test.ts index 9737a3908247..e581a8eacd57 100644 --- a/dev-packages/browser-integration-tests/suites/replay/captureReplay/test.ts +++ b/dev-packages/browser-integration-tests/suites/replay/captureReplay/test.ts @@ -55,9 +55,6 @@ sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalT 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); @@ -96,9 +93,6 @@ sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalT 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); }); diff --git a/dev-packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts b/dev-packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts index 1c7fe09e3c33..3a10ea72e18c 100644 --- a/dev-packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts +++ b/dev-packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts @@ -55,9 +55,6 @@ sentryTest('should capture replays (@sentry-internal/replay export)', async ({ g 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); @@ -96,9 +93,6 @@ sentryTest('should capture replays (@sentry-internal/replay export)', async ({ g 'User-Agent': expect.stringContaining(''), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }); }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts index 9018252f37cb..02431dae3b79 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts @@ -69,7 +69,6 @@ sentryTest('captures a "GOOD" CLS vital with its source as a standalone span', a transaction: expect.stringContaining('index.html'), 'user_agent.original': expect.stringContaining('Chrome'), 'sentry.pageload.span_id': expect.stringMatching(/[a-f0-9]{16}/), - 'client.address': '{{auto}}', }, description: expect.stringContaining('body > div#content > p'), exclusive_time: 0, @@ -138,7 +137,6 @@ sentryTest('captures a "MEH" CLS vital with its source as a standalone span', as transaction: expect.stringContaining('index.html'), 'user_agent.original': expect.stringContaining('Chrome'), 'sentry.pageload.span_id': expect.stringMatching(/[a-f0-9]{16}/), - 'client.address': '{{auto}}', }, description: expect.stringContaining('body > div#content > p'), exclusive_time: 0, @@ -205,7 +203,6 @@ sentryTest('captures a "POOR" CLS vital with its source as a standalone span.', transaction: expect.stringContaining('index.html'), 'user_agent.original': expect.stringContaining('Chrome'), 'sentry.pageload.span_id': expect.stringMatching(/[a-f0-9]{16}/), - 'client.address': '{{auto}}', }, description: expect.stringContaining('body > div#content > p'), exclusive_time: 0, @@ -273,7 +270,6 @@ sentryTest( transaction: expect.stringContaining('index.html'), 'user_agent.original': expect.stringContaining('Chrome'), 'sentry.pageload.span_id': expect.stringMatching(/[a-f0-9]{16}/), - 'client.address': '{{auto}}', }, description: 'Layout shift', exclusive_time: 0, diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts index d151772439a1..fffa85b89ae2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts @@ -71,7 +71,6 @@ sentryTest('should capture an INP click event span after pageload', async ({ bro 'sentry.source': 'custom', transaction: 'test-url', 'user_agent.original': expect.stringContaining('Chrome'), - 'client.address': '{{auto}}', }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts index 961f98518049..65852c734c98 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts @@ -74,7 +74,6 @@ sentryTest( 'sentry.source': 'custom', transaction: 'test-route', 'user_agent.original': expect.stringContaining('Chrome'), - 'client.address': '{{auto}}', }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts index 911929471ea4..5705fe6863b5 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts @@ -70,7 +70,6 @@ sentryTest( 'sentry.origin': 'auto.http.browser.inp', transaction: 'test-route', 'user_agent.original': expect.stringContaining('Chrome'), - 'client.address': '{{auto}}', }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts index 1be97e2446dc..b3435a49b002 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts @@ -69,7 +69,6 @@ sentryTest('should capture an INP click event span during pageload', async ({ br 'sentry.origin': 'auto.http.browser.inp', transaction: 'test-url', 'user_agent.original': expect.stringContaining('Chrome'), - 'client.address': '{{auto}}', }, measurements: { inp: { diff --git a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts index 8455bcc34600..52dbbca1c086 100644 --- a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts +++ b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts @@ -37,9 +37,6 @@ const DEFAULT_REPLAY_EVENT = { 'User-Agent': expect.any(String), }, }, - user: { - ip_address: '{{auto}}', - }, platform: 'javascript', }; diff --git a/dev-packages/e2e-tests/test-applications/react-17/src/index.tsx b/dev-packages/e2e-tests/test-applications/react-17/src/index.tsx index 49609a988202..aab492c7388b 100644 --- a/dev-packages/e2e-tests/test-applications/react-17/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-17/src/index.tsx @@ -38,6 +38,7 @@ Sentry.init({ replaysOnErrorSampleRate: 0.0, tunnel: 'http://localhost:3031', + sendDefaultPii: true, }); const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes); diff --git a/dev-packages/e2e-tests/test-applications/react-router-6/src/index.tsx b/dev-packages/e2e-tests/test-applications/react-router-6/src/index.tsx index 8c219563e5a4..76884645c4c0 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/react-router-6/src/index.tsx @@ -40,6 +40,7 @@ Sentry.init({ replaysOnErrorSampleRate: 0.0, tunnel: 'http://localhost:3031', + sendDefaultPii: true, }); const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes); diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx index a49c2c35de9d..baf12f7ff574 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx @@ -39,6 +39,7 @@ Sentry.init({ replaysSessionSampleRate: 1.0, replaysOnErrorSampleRate: 0.0, tunnel: 'http://localhost:3031', + sendDefaultPii: true, }); const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes); diff --git a/docs/migration/v8-to-v9.md b/docs/migration/v8-to-v9.md index 7eaf78ed81d4..7c6c0153e05d 100644 --- a/docs/migration/v8-to-v9.md +++ b/docs/migration/v8-to-v9.md @@ -106,6 +106,7 @@ Older Typescript versions _may_ still work, but we will not test them anymore an ### `@sentry/browser` +- The SDK no longer instructs the Sentry backend to automatically infer IP addresses by default. This means that places where you previously saw IP addresses in Sentry may now be grouped to anonymous users. Set the `sendDefaultPii` option in `Sentry.init()` to true to instruct the Sentry backend to infer IP addresses. - The `captureUserFeedback` method has been removed. Use the `captureFeedback` method instead and update the `comments` field to `message`. ### `@sentry/nextjs` diff --git a/packages/browser-utils/src/metrics/utils.ts b/packages/browser-utils/src/metrics/utils.ts index 2bc97d588395..91aefa8a8918 100644 --- a/packages/browser-utils/src/metrics/utils.ts +++ b/packages/browser-utils/src/metrics/utils.ts @@ -74,7 +74,7 @@ export function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptio const { name, transaction, attributes: passedAttributes, startTime } = options; - const { release, environment } = client.getOptions(); + const { release, environment, sendDefaultPii } = client.getOptions(); // We need to get the replay, user, and activeTransaction from the current scope // so that we can associate replay id, profile id, and a user display to the span const replay = client.getIntegrationByName string }>('Replay'); @@ -109,7 +109,7 @@ export function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptio 'user_agent.original': WINDOW.navigator?.userAgent, // This tells Sentry to infer the IP address from the request - 'client.address': '{{auto}}', + 'client.address': sendDefaultPii ? '{{auto}}' : undefined, ...passedAttributes, }; diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 801a1bffbd2e..20b43ca6ddac 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -8,7 +8,6 @@ import type { ParameterizedString, Scope, SeverityLevel, - User, } from '@sentry/core'; import { Client, applySdkMetadata, getSDKSource } from '@sentry/core'; import { eventFromException, eventFromMessage } from './eventbuilder'; @@ -84,22 +83,31 @@ export class BrowserClient extends Client { }); } - this.on('postprocessEvent', event => { - addAutoIpAddressToUser(event); - }); - - this.on('beforeSendSession', session => { - if ('aggregates' in session) { - if (session.attrs?.['ip_address'] === undefined) { - session.attrs = { - ...session.attrs, + if (this._options.sendDefaultPii) { + this.on('postprocessEvent', event => { + if (event.user?.ip_address === undefined) { + event.user = { + ...event.user, ip_address: '{{auto}}', }; } - } else { - addAutoIpAddressToUser(session); - } - }); + }); + + this.on('beforeSendSession', session => { + if ('aggregates' in session) { + if (session.attrs?.['ip_address'] === undefined) { + session.attrs = { + ...session.attrs, + ip_address: '{{auto}}', + }; + } + } else { + if (session.ipAddress === undefined) { + session.ipAddress = '{{auto}}'; + } + } + }); + } } /** @@ -134,15 +142,3 @@ export class BrowserClient extends Client { return super._prepareEvent(event, hint, currentScope, isolationScope); } } - -// By default, we want to infer the IP address, unless this is explicitly set to `null` -// We do this after all other processing is done -// If `ip_address` is explicitly set to `null` or a value, we leave it as is -function addAutoIpAddressToUser(objWithMaybeUser: { user?: User | null }): void { - if (objWithMaybeUser.user?.ip_address === undefined) { - objWithMaybeUser.user = { - ...objWithMaybeUser.user, - ip_address: '{{auto}}', - }; - } -} diff --git a/packages/core/src/integrations/requestdata.ts b/packages/core/src/integrations/requestdata.ts index 72bd02c199fb..eea701be09f3 100644 --- a/packages/core/src/integrations/requestdata.ts +++ b/packages/core/src/integrations/requestdata.ts @@ -38,12 +38,17 @@ const _requestDataIntegration = ((options: RequestDataIntegrationOptions = {}) = return { name: INTEGRATION_NAME, - processEvent(event) { + processEvent(event, _hint, client) { const { sdkProcessingMetadata = {} } = event; const { normalizedRequest, ipAddress } = sdkProcessingMetadata; + const includeWithDefaultPiiApplied: RequestDataIncludeOptions = { + ...include, + ip: include.ip || client.getOptions().sendDefaultPii, + }; + if (normalizedRequest) { - addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, include); + addNormalizedRequestDataToEvent(event, normalizedRequest, { ipAddress }, includeWithDefaultPiiApplied); } return event;