File tree Expand file tree Collapse file tree 5 files changed +72
-33
lines changed
browser-integration-tests/suites/replay
privacyDefault/test.ts-snapshots Expand file tree Collapse file tree 5 files changed +72
-33
lines changed Original file line number Diff line number Diff line change 131
131
"textContent" : " \n " ,
132
132
"id" : 20
133
133
},
134
+ {
135
+ "type" : 2 ,
136
+ "tagName" : " input" ,
137
+ "attributes" : {
138
+ "data-sentry-unmask" : " " ,
139
+ "placeholder" : " Placeholder can be unmasked"
140
+ },
141
+ "childNodes" : [],
142
+ "id" : 21
143
+ },
144
+ {
145
+ "type" : 3 ,
146
+ "textContent" : " \n " ,
147
+ "id" : 22
148
+ },
134
149
{
135
150
"type" : 2 ,
136
151
"tagName" : " div" ,
141
156
{
142
157
"type" : 3 ,
143
158
"textContent" : " ***** ****** ** ******" ,
144
- "id" : 22
159
+ "id" : 24
145
160
}
146
161
],
147
- "id" : 21
162
+ "id" : 23
148
163
},
149
164
{
150
165
"type" : 3 ,
151
166
"textContent" : " \n " ,
152
- "id" : 23
167
+ "id" : 25
153
168
},
154
169
{
155
170
"type" : 2 ,
160
175
},
161
176
"childNodes" : [],
162
177
"isSVG" : true ,
163
- "id" : 24
178
+ "id" : 26
164
179
},
165
180
{
166
181
"type" : 3 ,
167
182
"textContent" : " \n " ,
168
- "id" : 25
183
+ "id" : 27
169
184
},
170
185
{
171
186
"type" : 2 ,
184
199
},
185
200
"childNodes" : [],
186
201
"isSVG" : true ,
187
- "id" : 27
202
+ "id" : 29
188
203
},
189
204
{
190
205
"type" : 2 ,
191
206
"tagName" : " area" ,
192
207
"attributes" : {},
193
208
"childNodes" : [],
194
209
"isSVG" : true ,
195
- "id" : 28
210
+ "id" : 30
196
211
},
197
212
{
198
213
"type" : 2 ,
199
214
"tagName" : " rect" ,
200
215
"attributes" : {},
201
216
"childNodes" : [],
202
217
"isSVG" : true ,
203
- "id" : 29
218
+ "id" : 31
204
219
}
205
220
],
206
221
"isSVG" : true ,
207
- "id" : 26
222
+ "id" : 28
208
223
},
209
224
{
210
225
"type" : 3 ,
211
226
"textContent" : " \n " ,
212
- "id" : 30
227
+ "id" : 32
213
228
},
214
229
{
215
230
"type" : 2 ,
219
234
"rr_height" : " [100-150]px"
220
235
},
221
236
"childNodes" : [],
222
- "id" : 31
237
+ "id" : 33
223
238
},
224
239
{
225
240
"type" : 3 ,
226
241
"textContent" : " \n " ,
227
- "id" : 32
242
+ "id" : 34
228
243
},
229
244
{
230
245
"type" : 2 ,
235
250
"src" : " file:///none.png"
236
251
},
237
252
"childNodes" : [],
238
- "id" : 33
253
+ "id" : 35
239
254
},
240
255
{
241
256
"type" : 3 ,
242
257
"textContent" : " \n " ,
243
- "id" : 34
258
+ "id" : 36
244
259
},
245
260
{
246
261
"type" : 2 ,
250
265
"rr_height" : " [0-50]px"
251
266
},
252
267
"childNodes" : [],
253
- "id" : 35
268
+ "id" : 37
254
269
},
255
270
{
256
271
"type" : 3 ,
257
272
"textContent" : " \n " ,
258
- "id" : 36
273
+ "id" : 38
259
274
},
260
275
{
261
276
"type" : 3 ,
262
277
"textContent" : " \n\n " ,
263
- "id" : 37
278
+ "id" : 39
264
279
}
265
280
],
266
281
"id" : 8
Original file line number Diff line number Diff line change @@ -4,13 +4,18 @@ import { IncrementalSource } from '@sentry-internal/rrweb';
4
4
5
5
import { sentryTest } from '../../../utils/fixtures' ;
6
6
import type { IncrementalRecordingSnapshot } from '../../../utils/replayHelpers' ;
7
+ < < < << << HEAD
7
8
import {
8
9
getFullRecordingSnapshots ,
10
+ = === ===
11
+ import { getFullRecordingSnapshots ,
12
+ > > >>> >> d495cdedf ( feat can unmask attributes , masks input type = button / submit ( only with maskAllText enabled ) )
9
13
getIncrementalRecordingSnapshots ,
10
14
shouldSkipReplayTest ,
11
15
waitForReplayRequest ,
12
16
} from '../../../utils/replayHelpers' ;
13
17
18
+
14
19
function isInputMutation (
15
20
snap : IncrementalRecordingSnapshot ,
16
21
) : snap is IncrementalRecordingSnapshot & { data : inputData } {
Original file line number Diff line number Diff line change @@ -3,7 +3,7 @@ import type { inputData } from '@sentry-internal/rrweb';
3
3
import { IncrementalSource } from '@sentry-internal/rrweb' ;
4
4
5
5
import { sentryTest } from '../../../utils/fixtures' ;
6
- import type { IncrementalRecordingSnapshot } from '../../../utils/replayHelpers' ;
6
+ import { getFullRecordingSnapshots , IncrementalRecordingSnapshot } from '../../../utils/replayHelpers' ;
7
7
import {
8
8
getFullRecordingSnapshots ,
9
9
getIncrementalRecordingSnapshots ,
Original file line number Diff line number Diff line change @@ -50,3 +50,6 @@ export const MIN_REPLAY_DURATION_LIMIT = 15_000;
50
50
51
51
/** The max. length of a replay. */
52
52
export const MAX_REPLAY_DURATION = 3_600_000 ; // 60 minutes in ms;
53
+
54
+ /** Default attributes to be ignored when `maskAllText` is enabled */
55
+ export const DEFAULT_IGNORED_ATTRIBUTES = [ 'title' , 'placeholder' ] ;
Original file line number Diff line number Diff line change @@ -105,33 +105,49 @@ export class Replay implements Integration {
105
105
} : ReplayConfiguration = { } ) {
106
106
this . name = Replay . id ;
107
107
108
+ const privacyOptions = getPrivacyOptions ( {
109
+ mask,
110
+ unmask,
111
+ block,
112
+ unblock,
113
+ ignore,
114
+ blockClass,
115
+ blockSelector,
116
+ maskTextClass,
117
+ maskTextSelector,
118
+ ignoreClass,
119
+ } ) ;
120
+
108
121
this . _recordingOptions = {
109
122
maskAllInputs,
110
123
maskAllText,
111
124
maskInputOptions : { ...( maskInputOptions || { } ) , password : true } ,
112
125
maskTextFn : maskFn ,
113
126
maskInputFn : maskFn ,
114
- maskAttributeFn : ( key : string , value : string ) : string => {
115
- // For now, always mask these attributes
116
- if ( maskAttributes . includes ( key ) ) {
127
+ maskAttributeFn : ( key : string , value : string , el : HTMLElement ) : string => {
128
+ // We only mask attributes if `maskAllText` is true
129
+ if ( ! maskAllText ) {
130
+ return value ;
131
+ }
132
+
133
+ // unmaskTextSelector takes precendence
134
+ if ( privacyOptions . unmaskTextSelector && el . matches ( privacyOptions . unmaskTextSelector ) ) {
135
+ return value ;
136
+ }
137
+
138
+ if (
139
+ maskAttributes . includes ( key ) ||
140
+ // Need to mask `value` attribute for `<input>` if it's a button-like
141
+ // type
142
+ ( key === 'value' && el . tagName === 'INPUT' && [ 'submit' , 'button' ] . includes ( el . getAttribute ( 'type' ) || '' ) )
143
+ ) {
117
144
return value . replace ( / [ \S ] / g, '*' ) ;
118
145
}
119
146
120
147
return value ;
121
148
} ,
122
149
123
- ...getPrivacyOptions ( {
124
- mask,
125
- unmask,
126
- block,
127
- unblock,
128
- ignore,
129
- blockClass,
130
- blockSelector,
131
- maskTextClass,
132
- maskTextSelector,
133
- ignoreClass,
134
- } ) ,
150
+ ...privacyOptions ,
135
151
136
152
// Our defaults
137
153
slimDOMOptions : 'all' ,
You can’t perform that action at this time.
0 commit comments