Better network sanitizer (#2969)
* tracker: improve network sanitization * ui: fix hl image gen * tracker: rm sanitizer thing
This commit is contained in:
parent
c2878bacd4
commit
6882c62a32
9 changed files with 52 additions and 16 deletions
|
|
@ -111,7 +111,7 @@ function HighlightPanel({ onClose }: { onClose: () => void }) {
|
||||||
const onSave = async () => {
|
const onSave = async () => {
|
||||||
try {
|
try {
|
||||||
notesStore.setSaving(true)
|
notesStore.setSaving(true)
|
||||||
const playerContainer = document.querySelector('iframe')?.contentWindow?.document.body;
|
const playerContainer = document.querySelector('iframe')?.contentWindow?.document;
|
||||||
let thumbnail;
|
let thumbnail;
|
||||||
if (playerContainer) {
|
if (playerContainer) {
|
||||||
thumbnail = await elementToImage(playerContainer);
|
thumbnail = await elementToImage(playerContainer);
|
||||||
|
|
@ -125,8 +125,8 @@ function HighlightPanel({ onClose }: { onClose: () => void }) {
|
||||||
endAt: parseInt(uiPlayerStore.highlightSelection.endTs, 10),
|
endAt: parseInt(uiPlayerStore.highlightSelection.endTs, 10),
|
||||||
thumbnail,
|
thumbnail,
|
||||||
}
|
}
|
||||||
if (editNoteId) {
|
if (editNote) {
|
||||||
await notesStore.updateNote(editNoteId, note);
|
await notesStore.updateNote(editNote.noteId, note);
|
||||||
toast.success('Highlight updated');
|
toast.success('Highlight updated');
|
||||||
} else {
|
} else {
|
||||||
const sessionId = sessionStore.current.sessionId;
|
const sessionId = sessionStore.current.sessionId;
|
||||||
|
|
@ -239,16 +239,21 @@ window.__debugElementToImage = (el) => elementToImage(el).then(img => {
|
||||||
a.click();
|
a.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
function elementToImage(el) {
|
function elementToImage(doc: Document) {
|
||||||
|
const el = doc.body;
|
||||||
return import('html2canvas').then(({ default: html2canvas }) => {
|
return import('html2canvas').then(({ default: html2canvas }) => {
|
||||||
|
const images = doc.querySelectorAll('img');
|
||||||
|
images.forEach((img) => {
|
||||||
|
img.setAttribute('crossorigin', 'Anonymous');
|
||||||
|
})
|
||||||
return html2canvas(
|
return html2canvas(
|
||||||
el,
|
el,
|
||||||
{
|
{
|
||||||
scale: 1,
|
scale: 1,
|
||||||
allowTaint: true,
|
allowTaint: true,
|
||||||
useCORS: false,
|
foreignObjectRendering: true,
|
||||||
|
useCORS: true,
|
||||||
logging: true,
|
logging: true,
|
||||||
foreignObjectRendering: false,
|
|
||||||
height: 900,
|
height: 900,
|
||||||
width: 1200,
|
width: 1200,
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|
@ -263,4 +268,36 @@ function elementToImage(el) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const convertAllImagesToBase64 = (proxyURL, cloned) => {
|
||||||
|
const pendingImagesPromises = [];
|
||||||
|
const pendingPromisesData = [];
|
||||||
|
|
||||||
|
const images = cloned.getElementsByTagName('img');
|
||||||
|
|
||||||
|
for (let i = 0; i < images.length; i += 1) {
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
pendingPromisesData.push({
|
||||||
|
index: i, resolve, reject,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
pendingImagesPromises.push(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < images.length; i += 1) {
|
||||||
|
fetch(`${proxyURL}?url=${images[i].src}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
const pending = pendingPromisesData.find((p) => p.index === i);
|
||||||
|
images[i].src = data;
|
||||||
|
pending.resolve(data);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
const pending = pendingPromisesData.find((p) => p.index === i);
|
||||||
|
pending.reject(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(pendingImagesPromises);
|
||||||
|
};
|
||||||
|
|
||||||
export default observer(HighlightPanel);
|
export default observer(HighlightPanel);
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -55,5 +55,5 @@
|
||||||
"eslint --fix --quiet"
|
"eslint --fix --quiet"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.1"
|
"packageManager": "yarn@4.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@openreplay/tracker",
|
"name": "@openreplay/tracker",
|
||||||
"description": "The OpenReplay tracker main package",
|
"description": "The OpenReplay tracker main package",
|
||||||
"version": "15.0.5",
|
"version": "15.0.6",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"logging",
|
"logging",
|
||||||
"replay"
|
"replay"
|
||||||
|
|
@ -80,5 +80,5 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0"
|
"node": ">=14.0"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.1"
|
"packageManager": "yarn@4.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ function _getSelector(target: Element, document: Document, options?: MouseHandle
|
||||||
root: document.body,
|
root: document.body,
|
||||||
seedMinLength: 3,
|
seedMinLength: 3,
|
||||||
optimizedMinLength: options?.minSelectorDepth || 2,
|
optimizedMinLength: options?.minSelectorDepth || 2,
|
||||||
threshold: options?.nthThreshold || 1000,
|
maxNumberOfPathChecks: options?.maxOptimiseTries || 10_000,
|
||||||
maxNumberOfTries: options?.maxOptimiseTries || 10_000,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return selector
|
return selector
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,8 @@ export default function (app: App, opts: Partial<Options> = {}) {
|
||||||
|
|
||||||
const ignoreHeaders = options.ignoreHeaders
|
const ignoreHeaders = options.ignoreHeaders
|
||||||
const isHIgnored = Array.isArray(ignoreHeaders)
|
const isHIgnored = Array.isArray(ignoreHeaders)
|
||||||
? (name: string) => ignoreHeaders.includes(name)
|
? (name: string) => ignoreHeaders.includes(name)
|
||||||
: () => ignoreHeaders
|
: () => ignoreHeaders
|
||||||
|
|
||||||
const stHeader =
|
const stHeader =
|
||||||
options.sessionTokenHeader === true ? 'X-OpenReplay-SessionToken' : options.sessionTokenHeader
|
options.sessionTokenHeader === true ? 'X-OpenReplay-SessionToken' : options.sessionTokenHeader
|
||||||
|
|
@ -361,4 +361,4 @@ export default function (app: App, opts: Partial<Options> = {}) {
|
||||||
if (options.captureInIframes) {
|
if (options.captureInIframes) {
|
||||||
app.observer.attachContextCallback(app.safe(patchWindow))
|
app.observer.attachContextCallback(app.safe(patchWindow))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"extends": "../../tsconfig-base.json",
|
"extends": "../../tsconfig-base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"lib": ["es2020", "dom"],
|
"lib": ["es2022", "dom"],
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"declarationDir": "../../dist/types",
|
"declarationDir": "../../dist/types",
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"alwaysStrict": false,
|
"alwaysStrict": false,
|
||||||
"target": "es2020",
|
"target": "es2020",
|
||||||
"lib": ["DOM", "ES2020"],
|
"lib": ["DOM", "ES2022"],
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue