From 684f1598bc85e34856fc2c9dc3d9c788f69d0778 Mon Sep 17 00:00:00 2001 From: sylenien Date: Fri, 3 Jun 2022 17:17:23 +0200 Subject: [PATCH 1/2] feat(tracker): add option to hide dom nodes --- .../tracker/src/main/app/observer/observer.ts | 33 ++++++++++++++----- tracker/tracker/src/main/app/sanitizer.ts | 16 +++++++-- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/tracker/tracker/src/main/app/observer/observer.ts b/tracker/tracker/src/main/app/observer/observer.ts index dcbba6365..79c92cc47 100644 --- a/tracker/tracker/src/main/app/observer/observer.ts +++ b/tracker/tracker/src/main/app/observer/observer.ts @@ -1,5 +1,5 @@ -import { - RemoveNodeAttribute, +import { + RemoveNodeAttribute, SetNodeAttribute, SetNodeAttributeURLBased, SetCSSDataURLBased, @@ -220,9 +220,10 @@ export default abstract class Observer { } const parent = node.parentNode; let parentID: number | undefined; + // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before) // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though) - // TODO: Clean the logic (though now it workd fine) + // TODO: Clean the logic (though now it workd fine) if (!isInstance(node, HTMLHtmlElement) || !this.isTopContext) { if (parent === null) { this.unbindNode(node); @@ -239,6 +240,11 @@ export default abstract class Observer { } this.app.sanitizer.handleNode(id, parentID, node); } + if (parentID) { + if (this.app.sanitizer.isMaskedContainer(parentID)) { + return false; + } + } let sibling = node.previousSibling; while (sibling !== null) { const siblingID = this.app.nodes.getID(sibling); @@ -259,20 +265,31 @@ export default abstract class Observer { } if (isNew === true) { if (isInstance(node, Element)) { + let el: Element = node if (parentID !== undefined) { - this.app.send(new + if (this.app.sanitizer.isMaskedContainer(id)) { + const width = el.clientWidth; + const height = el.clientHeight; + console.log(width, height); + el = node.cloneNode() as Element; + (el as HTMLElement | SVGElement).style.width = width + 'px'; + (el as HTMLElement | SVGElement).style.height = height + 'px'; + console.log(el) + } + + this.app.send(new CreateElementNode( id, parentID, index, - node.tagName, + el.tagName, isSVGElement(node), ), ); } - for (let i = 0; i < node.attributes.length; i++) { - const attr = node.attributes[i]; - this.sendNodeAttribute(id, node, attr.nodeName, attr.value); + for (let i = 0; i < el.attributes.length; i++) { + const attr = el.attributes[i]; + this.sendNodeAttribute(id, el, attr.nodeName, attr.value); } } else if (isInstance(node, Text)) { // for text node id != 0, hence parentID !== undefined and parent is Element diff --git a/tracker/tracker/src/main/app/sanitizer.ts b/tracker/tracker/src/main/app/sanitizer.ts index 3e2e275ac..3b783041a 100644 --- a/tracker/tracker/src/main/app/sanitizer.ts +++ b/tracker/tracker/src/main/app/sanitizer.ts @@ -9,6 +9,7 @@ export interface Options { export default class Sanitizer { private readonly masked: Set = new Set(); + private readonly maskedContainers: Set = new Set(); private readonly options: Options; constructor(private readonly app: App, options: Partial) { @@ -21,10 +22,15 @@ export default class Sanitizer { handleNode(id: number, parentID: number, node: Node) { if ( this.masked.has(parentID) || - (isElementNode(node) && hasOpenreplayAttribute(node, 'masked')) + (isElementNode(node) && + (hasOpenreplayAttribute(node, 'masked'))) ) { this.masked.add(id); } + if (this.maskedContainers.has(parentID) || + (isElementNode(node) && hasOpenreplayAttribute(node, 'htmlmasked'))) { + this.maskedContainers.add(id); + } } sanitize(id: number, data: string): string { @@ -34,7 +40,7 @@ export default class Sanitizer { /[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/g, '█', ); - } + } if (this.options.obscureTextNumbers) { data = data.replace(/\d/g, '0'); } @@ -51,6 +57,9 @@ export default class Sanitizer { isMasked(id: number): boolean { return this.masked.has(id); } + isMaskedContainer(id: number) { + return this.maskedContainers.has(id); + } getInnerTextSecure(el: HTMLElement): string { const id = this.app.nodes.getID(el) @@ -61,6 +70,7 @@ export default class Sanitizer { clear(): void { this.masked.clear(); + this.maskedContainers.clear(); } -} \ No newline at end of file +} From 308ef872f402fa37e50fac78e7dd7e57e57944b8 Mon Sep 17 00:00:00 2001 From: sylenien Date: Wed, 22 Jun 2022 09:54:26 +0200 Subject: [PATCH 2/2] fix(tracker): code review --- tracker/tracker/src/main/app/observer/observer.ts | 4 ---- tracker/tracker/src/main/app/sanitizer.ts | 9 ++++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tracker/tracker/src/main/app/observer/observer.ts b/tracker/tracker/src/main/app/observer/observer.ts index 79c92cc47..ba6e46895 100644 --- a/tracker/tracker/src/main/app/observer/observer.ts +++ b/tracker/tracker/src/main/app/observer/observer.ts @@ -239,8 +239,6 @@ export default abstract class Observer { return false; } this.app.sanitizer.handleNode(id, parentID, node); - } - if (parentID) { if (this.app.sanitizer.isMaskedContainer(parentID)) { return false; } @@ -270,11 +268,9 @@ export default abstract class Observer { if (this.app.sanitizer.isMaskedContainer(id)) { const width = el.clientWidth; const height = el.clientHeight; - console.log(width, height); el = node.cloneNode() as Element; (el as HTMLElement | SVGElement).style.width = width + 'px'; (el as HTMLElement | SVGElement).style.height = height + 'px'; - console.log(el) } this.app.send(new diff --git a/tracker/tracker/src/main/app/sanitizer.ts b/tracker/tracker/src/main/app/sanitizer.ts index 3b783041a..d870cfaca 100644 --- a/tracker/tracker/src/main/app/sanitizer.ts +++ b/tracker/tracker/src/main/app/sanitizer.ts @@ -23,12 +23,15 @@ export default class Sanitizer { if ( this.masked.has(parentID) || (isElementNode(node) && - (hasOpenreplayAttribute(node, 'masked'))) + hasOpenreplayAttribute(node, 'masked')) ) { this.masked.add(id); } - if (this.maskedContainers.has(parentID) || - (isElementNode(node) && hasOpenreplayAttribute(node, 'htmlmasked'))) { + if ( + this.maskedContainers.has(parentID) || + (isElementNode(node) && + hasOpenreplayAttribute(node, 'htmlmasked')) + ) { this.maskedContainers.add(id); } }