Skip to content

Commit

Permalink
Fix for rrweb-io#1596 - we missed a path where masking could be skipped
Browse files Browse the repository at this point in the history
  • Loading branch information
eoghanmurray committed Nov 29, 2024
1 parent 53b83bb commit 6419132
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/textarea-inner-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'rrweb': patch
---

#1596 Add masking for innerText mutations on textarea elements
10 changes: 9 additions & 1 deletion packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,18 @@ export default class MutationBuffer {
this.attributes.push(item);
this.attributeMap.set(textarea, item);
}
item.attributes.value = Array.from(
let value = Array.from(

Check failure on line 536 in packages/rrweb/src/record/mutation.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

'value' is never reassigned. Use 'const' instead
dom.childNodes(textarea),
(cn) => dom.textContent(cn) || '',
).join('');
item.attributes.value = maskInputValue({
element: textarea,
maskInputOptions: this.maskInputOptions,
tagName: textarea.tagName,
type: getInputType(textarea),
value,
maskInputFn: this.maskInputFn,
});
};

private processMutation = (m: mutationRecord) => {
Expand Down
133 changes: 129 additions & 4 deletions packages/rrweb/test/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9964,6 +9964,21 @@ exports[`record integration tests > should not record input values if dynamicall
{
\\"parentId\\": 14,
\\"nextId\\": 16,
\\"node\\": {
\\"type\\": 2,
\\"tagName\\": \\"textarea\\",
\\"attributes\\": {
\\"id\\": \\"textarea\\",
\\"size\\": \\"50\\",
\\"value\\": \\"*************************\\"
},
\\"childNodes\\": [],
\\"id\\": 21
}
},
{
\\"parentId\\": 14,
\\"nextId\\": 21,
\\"node\\": {
\\"type\\": 2,
\\"tagName\\": \\"input\\",
Expand All @@ -9973,7 +9988,7 @@ exports[`record integration tests > should not record input values if dynamicall
\\"value\\": \\"**********************\\"
},
\\"childNodes\\": [],
\\"id\\": 21
\\"id\\": 22
}
}
]
Expand All @@ -9985,6 +10000,15 @@ exports[`record integration tests > should not record input values if dynamicall
\\"source\\": 5,
\\"text\\": \\"**********************\\",
\\"isChecked\\": false,
\\"id\\": 22
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"*************************\\",
\\"isChecked\\": false,
\\"id\\": 21
}
},
Expand All @@ -9993,7 +10017,7 @@ exports[`record integration tests > should not record input values if dynamicall
\\"data\\": {
\\"source\\": 2,
\\"type\\": 5,
\\"id\\": 21
\\"id\\": 22
}
},
{
Expand All @@ -10002,7 +10026,7 @@ exports[`record integration tests > should not record input values if dynamicall
\\"source\\": 5,
\\"text\\": \\"***********************\\",
\\"isChecked\\": false,
\\"id\\": 21
\\"id\\": 22
}
},
{
Expand All @@ -10011,7 +10035,7 @@ exports[`record integration tests > should not record input values if dynamicall
\\"source\\": 5,
\\"text\\": \\"************************\\",
\\"isChecked\\": false,
\\"id\\": 21
\\"id\\": 22
}
},
{
Expand All @@ -10020,8 +10044,109 @@ exports[`record integration tests > should not record input values if dynamicall
\\"source\\": 5,
\\"text\\": \\"*************************\\",
\\"isChecked\\": false,
\\"id\\": 22
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 2,
\\"type\\": 6,
\\"id\\": 22
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 2,
\\"type\\": 5,
\\"id\\": 21
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"**************************\\",
\\"isChecked\\": false,
\\"id\\": 21
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"***************************\\",
\\"isChecked\\": false,
\\"id\\": 21
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"****************************\\",
\\"isChecked\\": false,
\\"id\\": 21
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"**********************************************\\",
\\"isChecked\\": false,
\\"id\\": 22
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 5,
\\"text\\": \\"*************************************************\\",
\\"isChecked\\": false,
\\"id\\": 21
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 22,
\\"attributes\\": {
\\"value\\": \\"**********************************************************************************************\\"
}
},
{
\\"id\\": 21,
\\"attributes\\": {
\\"value\\": \\"*************************************************************************************************\\"
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 21,
\\"attributes\\": {
\\"value\\": \\"****************************************************************\\"
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
}
]"
`;
Expand Down
37 changes: 37 additions & 0 deletions packages/rrweb/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,9 +783,46 @@ describe('record integration tests', function (this: ISuite) {

const nextElement = document.querySelector('#one')!;
nextElement.parentNode!.insertBefore(el, nextElement);

const ta = document.createElement('textarea');
ta.size = 50;
ta.id = 'textarea';
ta.setAttribute('size', '50');
ta.value = 'textarea should be masked';

nextElement.parentNode!.insertBefore(ta, nextElement);
});

await page.type('#input', 'moo');
await page.type('#textarea', 'boo');

await page.evaluate(() => {
const el = document.querySelector('input');
el.value = 'input attribute mutation should also be masked';

const ta = document.querySelector('textarea');
ta.value = 'textarea attribute mutation should also be masked';
});

await page.evaluate(() => {
const el = document.querySelector('input');
el.setAttribute(
'value',
"input attribute mutation should also be masked (even though the new value doesn't take effect)",
);

const ta = document.querySelector('textarea');
ta.setAttribute(
'value',
"textarea attribute mutation should also be masked (even though the new value doesn't take effect)",
);
});

await page.evaluate(() => {
const ta = document.querySelector('textarea');
ta.innerText =
'textarea attribute mutation via innerText should also be masked ';
});

await assertSnapshot(page);
});
Expand Down

0 comments on commit 6419132

Please sign in to comment.