Skip to content

Commit

Permalink
feat can unmask attributes, masks input type=button/submit (only with…
Browse files Browse the repository at this point in the history
… maskAllText enabled)
  • Loading branch information
billyvg committed Jul 31, 2023
1 parent 6607014 commit 2f26b27
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,21 @@
"textContent": "\n ",
"id": 20
},
{
"type": 2,
"tagName": "input",
"attributes": {
"data-sentry-unmask": "",
"placeholder": "Placeholder can be unmasked"
},
"childNodes": [],
"id": 21
},
{
"type": 3,
"textContent": "\n ",
"id": 22
},
{
"type": 2,
"tagName": "div",
Expand All @@ -141,15 +156,15 @@
{
"type": 3,
"textContent": "***** ****** ** ******",
"id": 22
"id": 24
}
],
"id": 21
"id": 23
},
{
"type": 3,
"textContent": "\n ",
"id": 23
"id": 25
},
{
"type": 2,
Expand All @@ -160,12 +175,12 @@
},
"childNodes": [],
"isSVG": true,
"id": 24
"id": 26
},
{
"type": 3,
"textContent": "\n ",
"id": 25
"id": 27
},
{
"type": 2,
Expand All @@ -184,32 +199,32 @@
},
"childNodes": [],
"isSVG": true,
"id": 27
"id": 29
},
{
"type": 2,
"tagName": "area",
"attributes": {},
"childNodes": [],
"isSVG": true,
"id": 28
"id": 30
},
{
"type": 2,
"tagName": "rect",
"attributes": {},
"childNodes": [],
"isSVG": true,
"id": 29
"id": 31
}
],
"isSVG": true,
"id": 26
"id": 28
},
{
"type": 3,
"textContent": "\n ",
"id": 30
"id": 32
},
{
"type": 2,
Expand All @@ -219,12 +234,12 @@
"rr_height": "[100-150]px"
},
"childNodes": [],
"id": 31
"id": 33
},
{
"type": 3,
"textContent": "\n ",
"id": 32
"id": 34
},
{
"type": 2,
Expand All @@ -235,12 +250,12 @@
"src": "file:///none.png"
},
"childNodes": [],
"id": 33
"id": 35
},
{
"type": 3,
"textContent": "\n ",
"id": 34
"id": 36
},
{
"type": 2,
Expand All @@ -250,17 +265,17 @@
"rr_height": "[0-50]px"
},
"childNodes": [],
"id": 35
"id": 37
},
{
"type": 3,
"textContent": "\n ",
"id": 36
"id": 38
},
{
"type": 3,
"textContent": "\n\n",
"id": 37
"id": 39
}
],
"id": 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { IncrementalSource } from '@sentry-internal/rrweb';

import { sentryTest } from '../../../utils/fixtures';
import type { IncrementalRecordingSnapshot } from '../../../utils/replayHelpers';
<<<<<<< HEAD
import {
getFullRecordingSnapshots,
=======
import { getFullRecordingSnapshots ,
>>>>>>> d495cdedf (feat can unmask attributes, masks input type=button/submit (only with maskAllText enabled))
getIncrementalRecordingSnapshots,
shouldSkipReplayTest,
waitForReplayRequest,
} from '../../../utils/replayHelpers';


function isInputMutation(
snap: IncrementalRecordingSnapshot,
): snap is IncrementalRecordingSnapshot & { data: inputData } {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { inputData } from '@sentry-internal/rrweb';
import { IncrementalSource } from '@sentry-internal/rrweb';

import { sentryTest } from '../../../utils/fixtures';
import type { IncrementalRecordingSnapshot } from '../../../utils/replayHelpers';
import { getFullRecordingSnapshots, IncrementalRecordingSnapshot } from '../../../utils/replayHelpers';
import {
getFullRecordingSnapshots,
getIncrementalRecordingSnapshots,
Expand Down
3 changes: 3 additions & 0 deletions packages/replay/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ export const REPLAY_MAX_EVENT_BUFFER_SIZE = 20_000_000; // ~20MB
export const MIN_REPLAY_DURATION = 4_999;
/* The max. allowed value that the minReplayDuration can be set to. */
export const MIN_REPLAY_DURATION_LIMIT = 15_000;

/** Default attributes to be ignored when `maskAllText` is enabled */
export const DEFAULT_IGNORED_ATTRIBUTES = ['title', 'placeholder'];
46 changes: 31 additions & 15 deletions packages/replay/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,33 +101,49 @@ export class Replay implements Integration {
// eslint-disable-next-line deprecation/deprecation
ignoreClass,
}: ReplayConfiguration = {}) {
const privacyOptions = getPrivacyOptions({
mask,
unmask,
block,
unblock,
ignore,
blockClass,
blockSelector,
maskTextClass,
maskTextSelector,
ignoreClass,
});

this._recordingOptions = {
maskAllInputs,
maskAllText,
maskInputOptions: { ...(maskInputOptions || {}), password: true },
maskTextFn: maskFn,
maskInputFn: maskFn,
maskAttributeFn: (key: string, value: string): string => {
// For now, always mask these attributes
if (maskAttributes.includes(key)) {
maskAttributeFn: (key: string, value: string, el: HTMLElement): string => {
// We only mask attributes if `maskAllText` is true
if (!maskAllText) {
return value;
}

// unmaskTextSelector takes precendence
if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {
return value;
}

if (
maskAttributes.includes(key) ||
// Need to mask `value` attribute for `<input>` if it's a button-like
// type
(key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))
) {
return value.replace(/[\S]/g, '*');
}

return value;
},

...getPrivacyOptions({
mask,
unmask,
block,
unblock,
ignore,
blockClass,
blockSelector,
maskTextClass,
maskTextSelector,
ignoreClass,
}),
...privacyOptions,

// Our defaults
slimDOMOptions: 'all',
Expand Down

0 comments on commit 2f26b27

Please sign in to comment.