diff --git a/packages/integration-tests/suites/replay/privacy/test.ts b/packages/integration-tests/suites/replay/privacy/test.ts index 3ad8ee5684fb..aed810f7c002 100644 --- a/packages/integration-tests/suites/replay/privacy/test.ts +++ b/packages/integration-tests/suites/replay/privacy/test.ts @@ -80,7 +80,7 @@ sentryTest('should have the correct default privacy settings', async ({ getLocal type: 2, tagName: 'button', attributes: { - 'aria-label': 'Click me', + 'aria-label': '***** **', onclick: "console.log('Test log')", }, childNodes: [ @@ -139,7 +139,7 @@ sentryTest('should have the correct default privacy settings', async ({ getLocal type: 2, tagName: 'input', attributes: { - placeholder: 'Placeholder should be masked', + placeholder: '*********** ****** ** ******', }, childNodes: [], id: 18, @@ -153,7 +153,7 @@ sentryTest('should have the correct default privacy settings', async ({ getLocal type: 2, tagName: 'div', attributes: { - title: 'Title should be masked', + title: '***** ****** ** ******', }, childNodes: [ { diff --git a/packages/replay/package.json b/packages/replay/package.json index 058457ae576c..0f02b3181997 100644 --- a/packages/replay/package.json +++ b/packages/replay/package.json @@ -46,7 +46,7 @@ "homepage": "https://docs.sentry.io/platforms/javascript/session-replay/", "devDependencies": { "@babel/core": "^7.17.5", - "@sentry-internal/rrweb": "1.101.2", + "@sentry-internal/rrweb": "1.102.0", "@types/pako": "^2.0.0", "jsdom-worker": "^0.2.1", "pako": "^2.0.4", diff --git a/packages/replay/src/constants.ts b/packages/replay/src/constants.ts index 434c64158cb4..87bf1823b056 100644 --- a/packages/replay/src/constants.ts +++ b/packages/replay/src/constants.ts @@ -20,9 +20,6 @@ export const VISIBILITY_CHANGE_TIMEOUT = SESSION_IDLE_DURATION; // The maximum length of a session export const MAX_SESSION_LIFE = 3_600_000; // 60 minutes -/** The select to use for the `maskAllText` option */ -export const MASK_ALL_TEXT_SELECTOR = 'body *:not(style), body *:not(script)'; - /** Default flush delays */ export const DEFAULT_FLUSH_MIN_DELAY = 5_000; export const DEFAULT_FLUSH_MAX_DELAY = 5_000; diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts index d7c67b403f77..14dc260099f9 100644 --- a/packages/replay/src/integration.ts +++ b/packages/replay/src/integration.ts @@ -2,7 +2,7 @@ import { getCurrentHub } from '@sentry/core'; import type { BrowserClientReplayOptions, Integration } from '@sentry/types'; import { dropUndefinedKeys } from '@sentry/utils'; -import { DEFAULT_FLUSH_MAX_DELAY, DEFAULT_FLUSH_MIN_DELAY, MASK_ALL_TEXT_SELECTOR } from './constants'; +import { DEFAULT_FLUSH_MAX_DELAY, DEFAULT_FLUSH_MIN_DELAY } from './constants'; import { ReplayContainer } from './replay'; import type { RecordingOptions, ReplayConfiguration, ReplayPluginOptions } from './types'; import { getPrivacyOptions } from './util/getPrivacyOptions'; @@ -53,7 +53,7 @@ export class Replay implements Integration { _experiments = {}, sessionSampleRate, errorSampleRate, - maskAllText, + maskAllText = true, maskAllInputs = true, blockAllMedia = true, @@ -79,6 +79,7 @@ export class Replay implements Integration { }: ReplayConfiguration = {}) { this._recordingOptions = { maskAllInputs, + maskAllText, maskInputOptions: { ...(maskInputOptions || {}), password: true }, maskTextFn: maskFn, maskInputFn: maskFn, @@ -113,7 +114,6 @@ export class Replay implements Integration { sessionSampleRate, errorSampleRate, useCompression, - maskAllText: typeof maskAllText === 'boolean' ? maskAllText : !maskTextSelector, blockAllMedia, _experiments, }; @@ -142,13 +142,6 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`, this._initialOptions.errorSampleRate = errorSampleRate; } - if (this._initialOptions.maskAllText) { - // `maskAllText` is a more user friendly option to configure - // `maskTextSelector`. This means that all nodes will have their text - // content masked. - this._recordingOptions.maskTextSelector = MASK_ALL_TEXT_SELECTOR; - } - if (this._initialOptions.blockAllMedia) { // `blockAllMedia` is a more user friendly option to configure blocking // embedded media elements diff --git a/packages/replay/src/types.ts b/packages/replay/src/types.ts index 136ce1e526a3..27c878a3edba 100644 --- a/packages/replay/src/types.ts +++ b/packages/replay/src/types.ts @@ -90,11 +90,6 @@ export interface ReplayPluginOptions extends SessionOptions { */ useCompression: boolean; - /** - * Mask all text in recordings. All text will be replaced with asterisks by default. - */ - maskAllText: boolean; - /** * Block all media (e.g. images, svg, video) in recordings. */ @@ -180,7 +175,7 @@ export interface ReplayConfiguration extends ReplayIntegrationPrivacyOptions, OptionalReplayPluginOptions, DeprecatedPrivacyOptions, - Pick {} + Pick {} interface CommonEventContext { /** diff --git a/packages/replay/src/types/rrweb.ts b/packages/replay/src/types/rrweb.ts index 3628d45ef9ab..7a794face4cb 100644 --- a/packages/replay/src/types/rrweb.ts +++ b/packages/replay/src/types/rrweb.ts @@ -30,6 +30,7 @@ export type eventWithTime = { * Record union type. */ export type recordOptions = { + maskAllText?: boolean; maskAllInputs?: boolean; blockClass?: blockClass; ignoreClass?: string; diff --git a/packages/replay/test/integration/integrationSettings.test.ts b/packages/replay/test/integration/integrationSettings.test.ts index dd23b1a4cfdb..35f9245a9880 100644 --- a/packages/replay/test/integration/integrationSettings.test.ts +++ b/packages/replay/test/integration/integrationSettings.test.ts @@ -1,4 +1,3 @@ -import { MASK_ALL_TEXT_SELECTOR } from '../../src/constants'; import { mockSdk } from '../index'; describe('Integration | integrationSettings', () => { @@ -191,33 +190,28 @@ describe('Integration | integrationSettings', () => { it('works with default value', async () => { const { replay } = await mockSdk({ replayOptions: {} }); - // Default is true - expect(replay['_recordingOptions'].maskTextSelector).toBe(MASK_ALL_TEXT_SELECTOR); + expect(replay['_recordingOptions'].maskAllText).toBe(true); }); it('works with true', async () => { const { replay } = await mockSdk({ replayOptions: { maskAllText: true } }); - expect(replay['_recordingOptions'].maskTextSelector).toBe(MASK_ALL_TEXT_SELECTOR); + expect(replay['_recordingOptions'].maskAllText).toBe(true); }); it('works with false', async () => { const { replay } = await mockSdk({ replayOptions: { maskAllText: false } }); - expect(replay['_recordingOptions'].maskTextSelector).toBe('.sentry-mask,[data-sentry-mask]'); + expect(replay['_recordingOptions'].maskAllText).toBe(false); }); + }); - it('maskTextSelector takes precedence over maskAllText when not specifiying maskAllText:true', async () => { + describe('maskTextSelector', () => { + it('can have custom mask selector', async () => { const { replay } = await mockSdk({ replayOptions: { maskTextSelector: '[custom]' } }); expect(replay['_recordingOptions'].maskTextSelector).toBe('[custom],.sentry-mask,[data-sentry-mask]'); }); - - it('maskAllText takes precedence over maskTextSelector when specifiying maskAllText:true', async () => { - const { replay } = await mockSdk({ replayOptions: { maskAllText: true, maskTextSelector: '[custom]' } }); - - expect(replay['_recordingOptions'].maskTextSelector).toBe(MASK_ALL_TEXT_SELECTOR); - }); }); describe('_experiments', () => { diff --git a/packages/replay/test/integration/rrweb.test.ts b/packages/replay/test/integration/rrweb.test.ts index 00e1fb09af97..e3b00d55271a 100644 --- a/packages/replay/test/integration/rrweb.test.ts +++ b/packages/replay/test/integration/rrweb.test.ts @@ -24,13 +24,14 @@ describe('Integration | rrweb', () => { "inlineImages": false, "inlineStylesheet": true, "maskAllInputs": true, + "maskAllText": true, "maskInputFn": undefined, "maskInputOptions": Object { "password": true, }, "maskInputSelector": ".sentry-mask,[data-sentry-mask]", "maskTextFn": undefined, - "maskTextSelector": "body *:not(style), body *:not(script)", + "maskTextSelector": ".sentry-mask,[data-sentry-mask]", "slimDOMOptions": "all", "unblockSelector": ".sentry-unblock,[data-sentry-unblock]", "unmaskInputSelector": ".sentry-unmask,[data-sentry-unmask]", diff --git a/packages/replay/test/utils/setupReplayContainer.ts b/packages/replay/test/utils/setupReplayContainer.ts index fd6a5baa40e0..15eaa47d5736 100644 --- a/packages/replay/test/utils/setupReplayContainer.ts +++ b/packages/replay/test/utils/setupReplayContainer.ts @@ -16,12 +16,12 @@ export function setupReplayContainer({ sessionSampleRate: 0, errorSampleRate: 1, useCompression: false, - maskAllText: true, blockAllMedia: true, _experiments: {}, ...options, }, recordingOptions: { + maskAllText: true, ...recordingOptions, }, }); diff --git a/yarn.lock b/yarn.lock index 8fb259ed02e0..1b9a0ca3018a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3158,17 +3158,17 @@ semver "7.3.2" semver-intersect "1.4.0" -"@sentry-internal/rrweb-snapshot@1.101.2": - version "1.101.2" - resolved "https://registry.yarnpkg.com/@sentry-internal/rrweb-snapshot/-/rrweb-snapshot-1.101.2.tgz#cf73629374812f110ab7271f9da65f1afc6c08c3" - integrity sha512-wbc/lQ4ta7zXZGFU3sFfTz8PVcfOTeI2H2l2bo4BehZiQEEDTrqhGSFe5Nzq6Noi38CZyPT0kweGI4fUk1u0KQ== +"@sentry-internal/rrweb-snapshot@1.102.0": + version "1.102.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/rrweb-snapshot/-/rrweb-snapshot-1.102.0.tgz#d9a68fe89a51feda1fe1a5385ef3ae84c773dbac" + integrity sha512-DLAKilL1/xr3OlC9VYBF5p1YbmU4WgKv4j9NBsUw/dM8qLcLLxZaS6oBKunoSQrMvZn4BtvTn7REzBb8lUt9Vw== -"@sentry-internal/rrweb@1.101.2": - version "1.101.2" - resolved "https://registry.yarnpkg.com/@sentry-internal/rrweb/-/rrweb-1.101.2.tgz#65e5d80745e1c01c2f66031fb807b36837283944" - integrity sha512-IaDgoo9kxnwC6xn25yLU0ymKLVBAWGEH90iMdweTC7Izhza6k4oTy01t4/wy7ORCnfCeHZYJ4gkNJJyi4J1XHQ== +"@sentry-internal/rrweb@1.102.0": + version "1.102.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/rrweb/-/rrweb-1.102.0.tgz#85bbd35594c4ef25427502be6e34c994b66559bc" + integrity sha512-GyU6UPN8RLlDQFyW0CRL30Gv+q02Qk01C83wSDuwnMRUeFufU5Ybj2zqlnh4HCali/JMaKmQlLT+C0EVPpwmwA== dependencies: - "@sentry-internal/rrweb-snapshot" "1.101.2" + "@sentry-internal/rrweb-snapshot" "1.102.0" "@types/css-font-loading-module" "0.0.7" "@xstate/fsm" "^1.4.0" base64-arraybuffer "^1.0.1"