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
7 changes: 4 additions & 3 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,10 +614,13 @@ function serializeTextNode(
/* Start of Highlight */
// Randomizes the text content to a string of the same length.
const enableStrictPrivacy = privacySetting === 'strict';
const highlightOverwriteRecord =
n.parentElement?.getAttribute('data-hl-record');
const obfuscateDefaultPrivacy =
privacySetting === 'default' && shouldObfuscateTextByDefault(textContent);
if (
(enableStrictPrivacy || obfuscateDefaultPrivacy) &&
!highlightOverwriteRecord &&
!textContentHandled &&
parentTagName
) {
Expand Down Expand Up @@ -744,9 +747,7 @@ function serializeElementNode(
type,
tagName,
value,
inputId: (n as HTMLInputElement).id,
inputName: (n as HTMLInputElement).name,
autocomplete: (n as HTMLInputElement).autocomplete,
overwriteRecord: n.getAttribute('data-hl-record'),
maskInputOptions,
maskInputFn,
});
Expand Down
42 changes: 0 additions & 42 deletions packages/rrweb-snapshot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,48 +135,6 @@ export type MaskInputOptions = Partial<{
textarea: boolean;
select: boolean;
password: boolean;
// Highlight: added additonal fields to obfuscate
name: boolean;
'given-name': boolean;
'family-name': boolean;
'additional-name': boolean;
'one-time-code': boolean;
'street-address': boolean;
address: boolean;
'address-line1': boolean;
'address-line2': boolean;
'address-line3': boolean;
'address-level4': boolean;
'address-level3': boolean;
'address-level2': boolean;
'address-level1': boolean;
city: boolean;
state: boolean;
country: boolean;
zip: boolean;
'country-name': boolean;
'postal-code': boolean;
'cc-name': boolean;
'cc-given-name': boolean;
'cc-additional-name': boolean;
'cc-family-name': boolean;
'cc-number': boolean;
'cc-exp': boolean;
'cc-exp-month': boolean;
'cc-exp-year': boolean;
'cc-csc': boolean;
'cc-type': boolean;
bday: boolean;
'bday-day': boolean;
'bday-month': boolean;
'bday-year': boolean;
sex: boolean;
'tel-country-code': boolean;
'tel-national': boolean;
'tel-area-code': boolean;
'tel-local': boolean;
'tel-extension': boolean;
ssn: boolean;
}>;

export type SlimDOMOptions = Partial<{
Expand Down
36 changes: 12 additions & 24 deletions packages/rrweb-snapshot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,14 @@ const EMAIL_REGEX = new RegExp(
);
const LONG_NUMBER_REGEX = new RegExp('[0-9]{9,16}'); // unformatted ssn, phone numbers, or credit card numbers
const SSN_REGEX = new RegExp('[0-9]{3}-?[0-9]{2}-?[0-9]{4}');
// prettier-ignore
const PHONE_NUMBER_REGEX = new RegExp(
'[+]?[(]?[0-9]{3}[)]?[-s.]?[0-9]{3}[-s.]?[0-9]{4,6}',
'[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}',
);
const CREDIT_CARD_REGEX = new RegExp('[0-9]{4}-?[0-9]{4}-?[0-9]{4}-?[0-9]{4}');
// prettier-ignore
const ADDRESS_REGEX = new RegExp(
'[0-9]{1,5}.?[0-9]{0,3}s[a-zA-Z]{2,30}s[a-zA-Z]{2,15}',
'[0-9]{1,5}.?[0-9]{0,3}\s[a-zA-Z]{2,30}\s[a-zA-Z]{2,15}',
);
const IP_REGEX = new RegExp('(?:[0-9]{1,3}.){3}[0-9]{1,3}');

Expand All @@ -298,27 +300,19 @@ export const maskedInputType = ({
maskInputOptions,
tagName,
type,
inputId,
inputName,
autocomplete,
overwriteRecord,
}: {
maskInputOptions: MaskInputOptions;
tagName: string;
type: string | null;
inputId: string | null;
inputName: string | null;
autocomplete: boolean | string | null;
overwriteRecord: string | null;
}): boolean => {
const actualType = type && type.toLowerCase();

return (
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||
(actualType && maskInputOptions[actualType as keyof MaskInputOptions]) ||
(inputId && maskInputOptions[inputId as keyof MaskInputOptions]) ||
(inputName && maskInputOptions[inputName as keyof MaskInputOptions]) ||
(!!autocomplete &&
typeof autocomplete === 'string' &&
!!maskInputOptions[autocomplete as keyof MaskInputOptions])
overwriteRecord !== 'true' &&
(!!maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||
!!(actualType && maskInputOptions[actualType as keyof MaskInputOptions]))
);
};

Expand All @@ -327,19 +321,15 @@ export function maskInputValue({
maskInputOptions,
tagName,
type,
inputId,
inputName,
autocomplete,
value,
overwriteRecord,
maskInputFn,
}: {
maskInputOptions: MaskInputOptions;
tagName: string;
type: string | null;
inputId: string | null;
inputName: string | null;
autocomplete: boolean | string | null;
value: string | null;
overwriteRecord: string | null;
maskInputFn?: MaskInputFn;
}): string {
let text = value || '';
Expand All @@ -349,9 +339,7 @@ export function maskInputValue({
maskInputOptions,
tagName,
type,
inputId,
inputName,
autocomplete,
overwriteRecord,
})
) {
if (maskInputFn) {
Expand Down
12 changes: 8 additions & 4 deletions packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,13 @@ export default class MutationBuffer {
const obfuscateDefaultPrivacy =
this.privacySetting === 'default' &&
shouldObfuscateTextByDefault(value);
if ((enableStrictPrivacy || obfuscateDefaultPrivacy) && value) {
const highlightOverwriteRecord =
text.node?.parentElement?.getAttribute('data-hl-record');
if (
(enableStrictPrivacy || obfuscateDefaultPrivacy) &&
highlightOverwriteRecord &&
value
) {
value = obfuscateText(value);
}
return {
Expand Down Expand Up @@ -515,9 +521,7 @@ export default class MutationBuffer {
tagName: target.tagName,
type,
value,
inputId: target.id,
inputName: target.getAttribute('name'),
autocomplete: target.getAttribute('autocomplete'),
overwriteRecord: target.getAttribute('data-hl-record'),
maskInputFn: this.maskInputFn,
});
}
Expand Down
15 changes: 3 additions & 12 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,12 +394,7 @@ function initInputObserver({
let text = (target as HTMLInputElement).value;
let isChecked = false;
const type: Lowercase<string> = getInputType(target) || '';

const {
id: inputId,
name: inputName,
autocomplete,
} = target as HTMLInputElement;
const overwriteRecord = target.getAttribute('data-hl-record');

if (type === 'radio' || type === 'checkbox') {
isChecked = (target as HTMLInputElement).checked;
Expand All @@ -408,19 +403,15 @@ function initInputObserver({
maskInputOptions,
type,
tagName,
inputId,
inputName,
autocomplete,
overwriteRecord,
})
) {
text = maskInputValue({
maskInputOptions,
tagName,
type,
value: text,
inputId,
inputName,
autocomplete,
overwriteRecord,
maskInputFn,
});
}
Expand Down