@openreplay/tracker 16.1.0-beta.8 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/entry.js +227 -53
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +227 -53
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/main/app/index.d.ts +1 -0
- package/dist/cjs/main/app/sanitizer.d.ts +6 -1
- package/dist/lib/entry.js +227 -53
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +227 -53
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/main/app/index.d.ts +1 -0
- package/dist/lib/main/app/sanitizer.d.ts +6 -1
- package/dist/types/main/app/index.d.ts +1 -0
- package/dist/types/main/app/sanitizer.d.ts +6 -1
- package/package.json +2 -2
package/dist/cjs/entry.js
CHANGED
|
@@ -725,7 +725,9 @@ class StringDictionary {
|
|
|
725
725
|
this.backDict = {};
|
|
726
726
|
this.getKey = (str) => {
|
|
727
727
|
let isNew = false;
|
|
728
|
-
|
|
728
|
+
// avoiding potential native object properties
|
|
729
|
+
const safeKey = `__${str}`;
|
|
730
|
+
if (!this.backDict[safeKey]) {
|
|
729
731
|
isNew = true;
|
|
730
732
|
// shaving the first 2 digits of the timestamp (since they are irrelevant for next millennia)
|
|
731
733
|
const shavedTs = Date.now() % 10 ** (13 - 2);
|
|
@@ -737,20 +739,18 @@ class StringDictionary {
|
|
|
737
739
|
else {
|
|
738
740
|
this.lastSuffix = 1;
|
|
739
741
|
}
|
|
740
|
-
this.backDict[
|
|
742
|
+
this.backDict[safeKey] = id;
|
|
741
743
|
this.lastTs = shavedTs;
|
|
742
744
|
}
|
|
743
|
-
return [this.backDict[
|
|
745
|
+
return [this.backDict[safeKey], isNew];
|
|
744
746
|
};
|
|
745
747
|
}
|
|
746
748
|
}
|
|
747
749
|
class AttributeSender {
|
|
748
750
|
constructor(options) {
|
|
749
751
|
this.sendSetAttribute = (id, name, value) => {
|
|
750
|
-
// @ts-ignore
|
|
751
|
-
const attr = typeof value === 'string' ? value : (value.toString?.() ?? '');
|
|
752
752
|
if (this.isDictDisabled) {
|
|
753
|
-
const msg = [12 /* Type.SetNodeAttribute */, id, name,
|
|
753
|
+
const msg = [12 /* Type.SetNodeAttribute */, id, name, value];
|
|
754
754
|
return this.app.send(msg);
|
|
755
755
|
}
|
|
756
756
|
else {
|
|
@@ -758,7 +758,7 @@ class AttributeSender {
|
|
|
758
758
|
35 /* Type.SetNodeAttributeDictGlobal */,
|
|
759
759
|
id,
|
|
760
760
|
this.applyDict(name),
|
|
761
|
-
this.applyDict(
|
|
761
|
+
this.applyDict(value),
|
|
762
762
|
];
|
|
763
763
|
return this.app.send(message);
|
|
764
764
|
}
|
|
@@ -2204,7 +2204,7 @@ function Performance (app, opts) {
|
|
|
2204
2204
|
app.attachStopCallback(() => {
|
|
2205
2205
|
ticks = frames = undefined;
|
|
2206
2206
|
});
|
|
2207
|
-
app.ticker.attach(sendPerformanceTrack,
|
|
2207
|
+
app.ticker.attach(sendPerformanceTrack, 165, false);
|
|
2208
2208
|
if (document.hidden !== undefined) {
|
|
2209
2209
|
app.attachEventListener(document, 'visibilitychange', sendPerformanceTrack, false, false);
|
|
2210
2210
|
}
|
|
@@ -3711,9 +3711,26 @@ async function parseUseEl(useElement, mode, domParser) {
|
|
|
3711
3711
|
console.debug('Openreplay: xlink:href or href not found on <use>.');
|
|
3712
3712
|
return;
|
|
3713
3713
|
}
|
|
3714
|
-
|
|
3715
|
-
if
|
|
3716
|
-
|
|
3714
|
+
let [url, symbolId] = href.split('#');
|
|
3715
|
+
// happens if svg spritemap is local, fastest case for us
|
|
3716
|
+
if (!url && symbolId) {
|
|
3717
|
+
const symbol = document.querySelector(href);
|
|
3718
|
+
if (symbol) {
|
|
3719
|
+
const inlineSvg = `
|
|
3720
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="${symbol.getAttribute('viewBox') || '0 0 24 24'}">
|
|
3721
|
+
${symbol.innerHTML}
|
|
3722
|
+
</svg>
|
|
3723
|
+
`.trim();
|
|
3724
|
+
iconCache[symbolId] = inlineSvg;
|
|
3725
|
+
return inlineSvg;
|
|
3726
|
+
}
|
|
3727
|
+
else {
|
|
3728
|
+
console.warn('Openreplay: Sprite symbol not found in the document.');
|
|
3729
|
+
return;
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
if (!url && !symbolId) {
|
|
3733
|
+
console.warn('Openreplay: Invalid xlink:href or href found on <use>.');
|
|
3717
3734
|
return;
|
|
3718
3735
|
}
|
|
3719
3736
|
if (iconCache[symbolId]) {
|
|
@@ -3964,6 +3981,9 @@ class Observer {
|
|
|
3964
3981
|
if (name === 'href' || value.length > 1e5) {
|
|
3965
3982
|
value = '';
|
|
3966
3983
|
}
|
|
3984
|
+
if (['alt', 'placeholder'].includes(name) && this.app.sanitizer.privateMode) {
|
|
3985
|
+
value = value.replaceAll(/./g, '*');
|
|
3986
|
+
}
|
|
3967
3987
|
this.app.attributeSender.sendSetAttribute(id, name, value);
|
|
3968
3988
|
}
|
|
3969
3989
|
sendNodeData(id, parentElement, data) {
|
|
@@ -3991,7 +4011,7 @@ class Observer {
|
|
|
3991
4011
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
3992
4012
|
acceptNode: (node) => {
|
|
3993
4013
|
if (this.app.nodes.getID(node) !== undefined) {
|
|
3994
|
-
this.app.debug.
|
|
4014
|
+
this.app.debug.info('! Node is already bound', node);
|
|
3995
4015
|
}
|
|
3996
4016
|
return isIgnored(node) || this.app.nodes.getID(node) !== undefined
|
|
3997
4017
|
? NodeFilter.FILTER_REJECT
|
|
@@ -4404,18 +4424,30 @@ exports.SanitizeLevel = void 0;
|
|
|
4404
4424
|
})(exports.SanitizeLevel || (exports.SanitizeLevel = {}));
|
|
4405
4425
|
const stringWiper = (input) => input
|
|
4406
4426
|
.trim()
|
|
4407
|
-
.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/g, '
|
|
4427
|
+
.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\s]/g, '*');
|
|
4408
4428
|
class Sanitizer {
|
|
4409
4429
|
constructor(params) {
|
|
4410
4430
|
this.obscured = new Set();
|
|
4411
4431
|
this.hidden = new Set();
|
|
4412
4432
|
this.app = params.app;
|
|
4413
|
-
|
|
4433
|
+
const defaultOptions = {
|
|
4414
4434
|
obscureTextEmails: true,
|
|
4415
4435
|
obscureTextNumbers: false,
|
|
4416
|
-
|
|
4436
|
+
privateMode: false,
|
|
4437
|
+
domSanitizer: undefined,
|
|
4438
|
+
};
|
|
4439
|
+
this.privateMode = params.options?.privateMode ?? false;
|
|
4440
|
+
this.options = Object.assign(defaultOptions, params.options);
|
|
4417
4441
|
}
|
|
4418
4442
|
handleNode(id, parentID, node) {
|
|
4443
|
+
if (this.options.privateMode) {
|
|
4444
|
+
if (isElementNode(node) && !hasOpenreplayAttribute(node, 'unmask')) {
|
|
4445
|
+
return this.obscured.add(id);
|
|
4446
|
+
}
|
|
4447
|
+
if (isTextNode(node) && !hasOpenreplayAttribute(node.parentNode, 'unmask')) {
|
|
4448
|
+
return this.obscured.add(id);
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4419
4451
|
if (this.obscured.has(parentID) ||
|
|
4420
4452
|
(isElementNode(node) &&
|
|
4421
4453
|
(hasOpenreplayAttribute(node, 'masked') || hasOpenreplayAttribute(node, 'obscured')))) {
|
|
@@ -4658,7 +4690,7 @@ class Ticker {
|
|
|
4658
4690
|
* this value is injected during build time via rollup
|
|
4659
4691
|
* */
|
|
4660
4692
|
// @ts-ignore
|
|
4661
|
-
const workerBodyFn = "!function(){\"use strict\";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+\"/v1/web/i\",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){var e;const n=null==i?void 0:i.toString().replace(/^([^_]+)_([^_]+).*/,\"$1_$2_$3\");this.busy=!0;const h={Authorization:`Bearer ${this.token}`};s&&(h[\"Content-Encoding\"]=\"gzip\"),null!==this.token?fetch(`${this.ingestURL}?batch=${null!==(e=this.pageNo)&&void 0!==e?e:\"noPageNum\"}_${null!=n?n:\"noBatchNum\"}`,{body:t,method:\"POST\",headers:h,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn(\"OpenReplay:\",e),this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${null!=i?i:\"noBatchNum\"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s=\"function\"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 35:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 52:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 34:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 43:case 63:case 64:case 79:case 124:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.int(t[5]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 68:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 122:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 123:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn(\"OpenReplay: max message size overflow.\"),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(\"q_end\"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),122===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn(\"OpenReplay: beacon size overflow. Skipping large message.\",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]=\"NotActive\",t[t.Starting=1]=\"Starting\",t[t.Stopping=2]=\"Stopping\",t[t.Active=3]=\"Active\",t[t.Stopped=4]=\"Stopped\"}(h||(h={}));let r=null,a=null,u=h.NotActive;function o(){a&&a.finaliseBatch()}function c(){return new Promise((t=>{u=h.Stopping,null!==p&&(clearInterval(p),p=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive,t(null)}),100)}))}function l(){[h.Stopped,h.Stopping].includes(u)||(postMessage(\"a_stop\"),c().then((()=>{postMessage(\"a_start\")})))}let g,p=null;self.onmessage=({data:s})=>{if(null!=s){if(\"stop\"===s)return o(),void c().then((()=>{u=h.Stopped}));if(\"forceFlushBatch\"!==s){if(!Array.isArray(s)){if(\"compressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Compressed batch.\"),void l();s.batch&&r.sendCompressed(s.batch)}if(\"uncompressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Uncompressed batch.\"),void l();s.batch&&r.sendUncompressed(s.batch)}return\"start\"===s.type?(u=h.Starting,r=new t(s.ingestPoint,(()=>{l()}),(t=>{!function(t){postMessage({type:\"failure\",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:\"compress\",batch:t},[t.buffer])}),s.pageNo),a=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:\"queue_empty\"}))),null===p&&(p=setInterval(o,1e4)),u=h.Active):\"auth\"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug(\"OR WebWorker: writer not initialised. Received auth.\"),void l()):(console.debug(\"OR WebWorker: sender not initialised. Received auth.\"),void l()):void 0}if(a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?g=setTimeout((()=>l()),18e5):clearTimeout(g)),t.writeMessage(s)}))}else postMessage(\"not_init\"),l()}else o()}else o()}}();\n";
|
|
4693
|
+
const workerBodyFn = "!function(){\"use strict\";class t{constructor(t,s,i,e=10,n=250,h,r){this.onUnauthorised=s,this.onFailure=i,this.MAX_ATTEMPTS_COUNT=e,this.ATTEMPT_TIMEOUT=n,this.onCompress=h,this.pageNo=r,this.attemptsCount=0,this.busy=!1,this.queue=[],this.token=null,this.lastBatchNum=0,this.ingestURL=t+\"/v1/web/i\",this.isCompressing=void 0!==h}getQueueStatus(){return 0===this.queue.length&&!this.busy}authorise(t){this.token=t,this.busy||this.sendNext()}push(t){if(this.busy||!this.token)this.queue.push(t);else if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}}sendNext(){const t=this.queue.shift();if(t)if(this.busy=!0,this.isCompressing&&this.onCompress)this.onCompress(t);else{const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}else this.busy=!1}retry(t,s,i){this.attemptsCount>=this.MAX_ATTEMPTS_COUNT?this.onFailure(`Failed to send batch after ${this.attemptsCount} attempts.`):(this.attemptsCount++,setTimeout((()=>this.sendBatch(t,s,i)),this.ATTEMPT_TIMEOUT*this.attemptsCount))}sendBatch(t,s,i){var e;const n=null==i?void 0:i.toString().replace(/^([^_]+)_([^_]+).*/,\"$1_$2_$3\");this.busy=!0;const h={Authorization:`Bearer ${this.token}`};s&&(h[\"Content-Encoding\"]=\"gzip\"),null!==this.token?fetch(`${this.ingestURL}?batch=${null!==(e=this.pageNo)&&void 0!==e?e:\"noPageNum\"}_${null!=n?n:\"noBatchNum\"}`,{body:t,method:\"POST\",headers:h,keepalive:t.length<65536}).then((e=>{if(401===e.status)return this.busy=!1,void this.onUnauthorised();e.status>=400?this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_network:${e.status}`):(this.attemptsCount=0,this.sendNext())})).catch((e=>{console.warn(\"OpenReplay:\",e),this.retry(t,s,`${null!=i?i:\"noBatchNum\"}_reject:${e.message}`)})):setTimeout((()=>{this.sendBatch(t,s,`${null!=i?i:\"noBatchNum\"}_newToken`)}),500)}sendCompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!0,s)}sendUncompressed(t){const s=++this.lastBatchNum;this.sendBatch(t,!1,s)}clean(){this.sendNext(),setTimeout((()=>{this.token=null,this.queue.length=0}),10)}}const s=\"function\"==typeof TextEncoder?new TextEncoder:{encode(t){const s=t.length,i=new Uint8Array(3*s);let e=-1;for(let n=0,h=0,r=0;r!==s;){if(n=t.charCodeAt(r),r+=1,n>=55296&&n<=56319){if(r===s){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;break}if(h=t.charCodeAt(r),!(h>=56320&&h<=57343)){i[e+=1]=239,i[e+=1]=191,i[e+=1]=189;continue}if(n=1024*(n-55296)+h-56320+65536,r+=1,n>65535){i[e+=1]=240|n>>>18,i[e+=1]=128|n>>>12&63,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n;continue}}n<=127?i[e+=1]=0|n:n<=2047?(i[e+=1]=192|n>>>6,i[e+=1]=128|63&n):(i[e+=1]=224|n>>>12,i[e+=1]=128|n>>>6&63,i[e+=1]=128|63&n)}return i.subarray(0,e+1)}};class i{constructor(t){this.size=t,this.offset=0,this.checkpointOffset=0,this.data=new Uint8Array(t)}getCurrentOffset(){return this.offset}checkpoint(){this.checkpointOffset=this.offset}get isEmpty(){return 0===this.offset}skip(t){return this.offset+=t,this.offset<=this.size}set(t,s){this.data.set(t,s)}boolean(t){return this.data[this.offset++]=+t,this.offset<=this.size}uint(t){for((t<0||t>Number.MAX_SAFE_INTEGER)&&(t=0);t>=128;)this.data[this.offset++]=t%256|128,t=Math.floor(t/128);return this.data[this.offset++]=t,this.offset<=this.size}int(t){return t=Math.round(t),this.uint(t>=0?2*t:-2*t-1)}string(t){const i=s.encode(t),e=i.byteLength;return!(!this.uint(e)||this.offset+e>this.size)&&(this.data.set(i,this.offset),this.offset+=e,!0)}reset(){this.offset=0,this.checkpointOffset=0}flush(){const t=this.data.slice(0,this.checkpointOffset);return this.reset(),t}}class e extends i{encode(t){switch(t[0]){case 0:case 11:case 114:case 115:return this.uint(t[1]);case 4:case 44:case 47:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3]);case 5:case 20:case 70:case 75:case 76:case 77:case 82:return this.uint(t[1])&&this.uint(t[2]);case 6:return this.int(t[1])&&this.int(t[2]);case 7:return!0;case 8:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.string(t[4])&&this.boolean(t[5]);case 9:case 10:case 24:case 35:case 51:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3]);case 12:case 52:case 61:case 71:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3]);case 13:case 14:case 17:case 34:case 50:case 54:return this.uint(t[1])&&this.string(t[2]);case 16:return this.uint(t[1])&&this.int(t[2])&&this.int(t[3]);case 18:return this.uint(t[1])&&this.string(t[2])&&this.int(t[3]);case 19:return this.uint(t[1])&&this.boolean(t[2]);case 21:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8]);case 22:case 27:case 30:case 41:case 45:case 46:case 43:case 63:case 64:case 79:case 124:return this.string(t[1])&&this.string(t[2]);case 23:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 28:case 29:case 42:case 117:case 118:return this.string(t[1]);case 40:return this.string(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 48:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.int(t[5]);case 49:return this.int(t[1])&&this.int(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 53:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8]);case 55:return this.boolean(t[1]);case 57:case 60:return this.uint(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 58:case 120:return this.int(t[1]);case 68:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])&&this.uint(t[6]);case 69:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3])&&this.string(t[4]);case 73:return this.uint(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 78:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4]);case 81:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.int(t[4])&&this.string(t[5]);case 83:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.string(t[5])&&this.uint(t[6])&&this.uint(t[7])&&this.uint(t[8])&&this.uint(t[9]);case 84:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.uint(t[4])&&this.string(t[5])&&this.string(t[6]);case 112:return this.uint(t[1])&&this.string(t[2])&&this.boolean(t[3])&&this.string(t[4])&&this.int(t[5])&&this.int(t[6]);case 113:return this.uint(t[1])&&this.uint(t[2])&&this.string(t[3]);case 116:return this.uint(t[1])&&this.uint(t[2])&&this.uint(t[3])&&this.uint(t[4])&&this.uint(t[5])&&this.uint(t[6])&&this.string(t[7])&&this.string(t[8])&&this.uint(t[9])&&this.boolean(t[10]);case 119:return this.string(t[1])&&this.uint(t[2]);case 121:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.uint(t[4]);case 122:return this.string(t[1])&&this.string(t[2])&&this.uint(t[3])&&this.string(t[4]);case 123:return this.string(t[1])&&this.string(t[2])&&this.string(t[3])&&this.string(t[4])&&this.uint(t[5])}}}class n{constructor(t,s,i,n,h,r){this.pageNo=t,this.timestamp=s,this.url=i,this.onBatch=n,this.tabId=h,this.onOfflineEnd=r,this.nextIndex=0,this.beaconSize=2e5,this.encoder=new e(this.beaconSize),this.sizeBuffer=new Uint8Array(3),this.isEmpty=!0,this.beaconSizeLimit=1e6,this.prepare()}writeType(t){return this.encoder.uint(t[0])}writeFields(t){return this.encoder.encode(t)}writeSizeAt(t,s){for(let s=0;s<3;s++)this.sizeBuffer[s]=t>>8*s;this.encoder.set(this.sizeBuffer,s)}prepare(){if(!this.encoder.isEmpty)return;const t=[81,1,this.pageNo,this.nextIndex,this.timestamp,this.url],s=[0,this.timestamp],i=[118,this.tabId];this.writeType(t),this.writeFields(t),this.writeWithSize(s),this.writeWithSize(i),this.isEmpty=!0}writeWithSize(t){const s=this.encoder;if(!this.writeType(t)||!s.skip(3))return!1;const i=s.getCurrentOffset(),e=this.writeFields(t);if(e){const e=s.getCurrentOffset()-i;if(e>16777215)return console.warn(\"OpenReplay: max message size overflow.\"),!1;this.writeSizeAt(e,i-3),s.checkpoint(),this.isEmpty=this.isEmpty&&0===t[0],this.nextIndex++}return e}setBeaconSizeLimit(t){this.beaconSizeLimit=t}writeMessage(t){if(\"q_end\"===t[0])return this.finaliseBatch(),this.onOfflineEnd();0===t[0]&&(this.timestamp=t[1]),122===t[0]&&(this.url=t[1]),this.writeWithSize(t)||(this.finaliseBatch(),this.writeWithSize(t)||(this.encoder=new e(this.beaconSizeLimit),this.prepare(),this.writeWithSize(t)?this.finaliseBatch():console.warn(\"OpenReplay: beacon size overflow. Skipping large message.\",t,this),this.encoder=new e(this.beaconSize),this.prepare()))}finaliseBatch(){if(this.isEmpty)return;const t=this.encoder.flush();this.onBatch(t),this.prepare()}clean(){this.encoder.reset()}}var h;!function(t){t[t.NotActive=0]=\"NotActive\",t[t.Starting=1]=\"Starting\",t[t.Stopping=2]=\"Stopping\",t[t.Active=3]=\"Active\",t[t.Stopped=4]=\"Stopped\"}(h||(h={}));let r=null,a=null,u=h.NotActive;function o(){a&&a.finaliseBatch()}function c(){return new Promise((t=>{u=h.Stopping,null!==p&&(clearInterval(p),p=null),a&&(a.clean(),a=null),r&&(r.clean(),setTimeout((()=>{r=null}),20)),setTimeout((()=>{u=h.NotActive,t(null)}),100)}))}function l(){[h.Stopped,h.Stopping].includes(u)||(postMessage(\"a_stop\"),c().then((()=>{postMessage(\"a_start\")})))}let g,p=null;self.onmessage=({data:s})=>{if(null!=s){if(\"stop\"===s)return o(),void c().then((()=>{u=h.Stopped}));if(\"forceFlushBatch\"!==s){if(!Array.isArray(s)){if(\"compressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Compressed batch.\"),void l();s.batch&&r.sendCompressed(s.batch)}if(\"uncompressed\"===s.type){if(!r)return console.debug(\"OR WebWorker: sender not initialised. Uncompressed batch.\"),void l();s.batch&&r.sendUncompressed(s.batch)}return\"start\"===s.type?(u=h.Starting,r=new t(s.ingestPoint,(()=>{l()}),(t=>{!function(t){postMessage({type:\"failure\",reason:t}),c()}(t)}),s.connAttemptCount,s.connAttemptGap,(t=>{postMessage({type:\"compress\",batch:t},[t.buffer])}),s.pageNo),a=new n(s.pageNo,s.timestamp,s.url,(t=>{r&&r.push(t)}),s.tabId,(()=>postMessage({type:\"queue_empty\"}))),null===p&&(p=setInterval(o,1e4)),u=h.Active):\"auth\"===s.type?r?a?(r.authorise(s.token),void(s.beaconSizeLimit&&a.setBeaconSizeLimit(s.beaconSizeLimit))):(console.debug(\"OR WebWorker: writer not initialised. Received auth.\"),void l()):(console.debug(\"OR WebWorker: sender not initialised. Received auth.\"),void l()):void 0}if(a){const t=a;s.forEach((s=>{55===s[0]&&(s[1]?g=setTimeout((()=>l()),18e5):clearTimeout(g)),t.writeMessage(s)}))}else postMessage(\"not_init\"),l()}else o()}else o()}}();\n";
|
|
4662
4694
|
const CANCELED = 'canceled';
|
|
4663
4695
|
const uxtStorageKey = 'or_uxt_active';
|
|
4664
4696
|
const bufferStorageKey = 'or_buffer_1';
|
|
@@ -4712,7 +4744,7 @@ class App {
|
|
|
4712
4744
|
this.stopCallbacks = [];
|
|
4713
4745
|
this.commitCallbacks = [];
|
|
4714
4746
|
this.activityState = ActivityState.NotActive;
|
|
4715
|
-
this.version = '16.1.0
|
|
4747
|
+
this.version = '16.1.0'; // TODO: version compatability check inside each plugin.
|
|
4716
4748
|
this.socketMode = false;
|
|
4717
4749
|
this.compressionThreshold = 24 * 1000;
|
|
4718
4750
|
this.bc = null;
|
|
@@ -4726,6 +4758,7 @@ class App {
|
|
|
4726
4758
|
'feature-flags': true,
|
|
4727
4759
|
'usability-test': true,
|
|
4728
4760
|
};
|
|
4761
|
+
this.emptyBatchCounter = 0;
|
|
4729
4762
|
/** used by child iframes for crossdomain only */
|
|
4730
4763
|
this.parentActive = false;
|
|
4731
4764
|
this.checkStatus = () => {
|
|
@@ -5325,8 +5358,7 @@ class App {
|
|
|
5325
5358
|
* */
|
|
5326
5359
|
_nCommit() {
|
|
5327
5360
|
if (this.socketMode) {
|
|
5328
|
-
this.messages.unshift(TabData(this.session.getTabId()));
|
|
5329
|
-
this.messages.unshift(Timestamp(this.timestamp()));
|
|
5361
|
+
this.messages.unshift(Timestamp(this.timestamp()), TabData(this.session.getTabId()));
|
|
5330
5362
|
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
5331
5363
|
this.messages.length = 0;
|
|
5332
5364
|
return;
|
|
@@ -5343,25 +5375,19 @@ class App {
|
|
|
5343
5375
|
if (this.worker === undefined || !this.messages.length) {
|
|
5344
5376
|
return;
|
|
5345
5377
|
}
|
|
5378
|
+
if (!this.messages.length) {
|
|
5379
|
+
// Release empty batches every 30 secs (1000 * 30ms)
|
|
5380
|
+
if (this.emptyBatchCounter < 1000) {
|
|
5381
|
+
this.emptyBatchCounter++;
|
|
5382
|
+
return;
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
this.emptyBatchCounter = 0;
|
|
5386
|
+
console.log('messages', this.messages.join(', '));
|
|
5346
5387
|
try {
|
|
5347
5388
|
requestIdleCb(() => {
|
|
5348
|
-
this.messages.unshift(TabData(this.session.getTabId()));
|
|
5349
|
-
this.
|
|
5350
|
-
try {
|
|
5351
|
-
this.worker?.postMessage(this.messages);
|
|
5352
|
-
}
|
|
5353
|
-
catch (e) {
|
|
5354
|
-
console.log(this.messages.join('$___$'));
|
|
5355
|
-
console.error(e);
|
|
5356
|
-
this.messages.forEach(m => {
|
|
5357
|
-
try {
|
|
5358
|
-
this.worker?.postMessage([m]);
|
|
5359
|
-
}
|
|
5360
|
-
catch (e) {
|
|
5361
|
-
console.error(m, e);
|
|
5362
|
-
}
|
|
5363
|
-
});
|
|
5364
|
-
}
|
|
5389
|
+
this.messages.unshift(Timestamp(this.timestamp()), TabData(this.session.getTabId()));
|
|
5390
|
+
this.worker?.postMessage(this.messages);
|
|
5365
5391
|
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
5366
5392
|
this.messages.length = 0;
|
|
5367
5393
|
});
|
|
@@ -5383,10 +5409,9 @@ class App {
|
|
|
5383
5409
|
_cStartCommit() {
|
|
5384
5410
|
this.coldStartCommitN += 1;
|
|
5385
5411
|
if (this.coldStartCommitN === 2) {
|
|
5386
|
-
this.
|
|
5387
|
-
this.bufferedMessages1.push(
|
|
5388
|
-
this.bufferedMessages2.push(
|
|
5389
|
-
this.bufferedMessages2.push(TabData(this.session.getTabId()));
|
|
5412
|
+
const payload = [Timestamp(this.timestamp()), TabData(this.session.getTabId())];
|
|
5413
|
+
this.bufferedMessages1.push(...payload);
|
|
5414
|
+
this.bufferedMessages2.push(...payload);
|
|
5390
5415
|
this.coldStartCommitN = 0;
|
|
5391
5416
|
}
|
|
5392
5417
|
}
|
|
@@ -6192,7 +6217,13 @@ function Console (app, opts) {
|
|
|
6192
6217
|
if (!Array.isArray(options.consoleMethods) || options.consoleMethods.length === 0) {
|
|
6193
6218
|
return;
|
|
6194
6219
|
}
|
|
6195
|
-
const sendConsoleLog = app.safe((level, args) =>
|
|
6220
|
+
const sendConsoleLog = app.safe((level, args) => {
|
|
6221
|
+
let logMsg = printf(args);
|
|
6222
|
+
if (app.sanitizer.privateMode) {
|
|
6223
|
+
logMsg = logMsg.replaceAll(/./g, '*');
|
|
6224
|
+
}
|
|
6225
|
+
app.send(ConsoleLog(level, logMsg));
|
|
6226
|
+
});
|
|
6196
6227
|
let n = 0;
|
|
6197
6228
|
const reset = () => {
|
|
6198
6229
|
n = 0;
|
|
@@ -6716,7 +6747,10 @@ function Input (app, opts) {
|
|
|
6716
6747
|
}, 3);
|
|
6717
6748
|
function sendInputChange(id, node, hesitationTime, inputTime) {
|
|
6718
6749
|
const { value, mask } = getInputValue(id, node);
|
|
6719
|
-
|
|
6750
|
+
let label = getInputLabel(node);
|
|
6751
|
+
if (app.sanitizer.privateMode) {
|
|
6752
|
+
label = label.replaceAll(/./g, '*');
|
|
6753
|
+
}
|
|
6720
6754
|
app.send(InputChange(id, value, mask !== 0, label, hesitationTime, inputTime));
|
|
6721
6755
|
}
|
|
6722
6756
|
app.nodes.attachNodeCallback(app.safe((node) => {
|
|
@@ -7224,7 +7258,8 @@ function Mouse (app, options) {
|
|
|
7224
7258
|
const normalizedX = roundNumber(clickX / contentWidth);
|
|
7225
7259
|
const normalizedY = roundNumber(clickY / contentHeight);
|
|
7226
7260
|
sendMouseMove();
|
|
7227
|
-
|
|
7261
|
+
const label = getTargetLabel(target);
|
|
7262
|
+
app.send(MouseClick(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, app.sanitizer.privateMode ? label.replaceAll(/./g, '*') : label, isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : '', normalizedX, normalizedY), true);
|
|
7228
7263
|
}
|
|
7229
7264
|
mouseTarget = null;
|
|
7230
7265
|
});
|
|
@@ -7335,7 +7370,7 @@ function Timing (app, opts) {
|
|
|
7335
7370
|
if (failed) {
|
|
7336
7371
|
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), 0, 0, 0, 0, 0, entry.name, entry.initiatorType, 0, true));
|
|
7337
7372
|
}
|
|
7338
|
-
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), entry.duration, entry.responseStart && entry.startTime ? entry.responseStart - entry.startTime : 0, entry.transferSize > entry.encodedBodySize ? entry.transferSize - entry.encodedBodySize : 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, entry.name, entry.initiatorType, entry.transferSize,
|
|
7373
|
+
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), entry.duration, entry.responseStart && entry.startTime ? entry.responseStart - entry.startTime : 0, entry.transferSize > entry.encodedBodySize ? entry.transferSize - entry.encodedBodySize : 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, app.sanitizer.privateMode ? entry.name.replaceAll(/./g, '*') : entry.name, entry.initiatorType, entry.transferSize,
|
|
7339
7374
|
// @ts-ignore
|
|
7340
7375
|
(entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
|
|
7341
7376
|
}
|
|
@@ -7524,7 +7559,10 @@ function Viewport (app) {
|
|
|
7524
7559
|
const { URL } = document;
|
|
7525
7560
|
if (URL !== url) {
|
|
7526
7561
|
url = URL;
|
|
7527
|
-
app.
|
|
7562
|
+
const safeTitle = app.sanitizer.privateMode ? stringWiper(document.title) : document.title;
|
|
7563
|
+
const safeUrl = app.sanitizer.privateMode ? stringWiper(url) : url;
|
|
7564
|
+
const safeReferrer = app.sanitizer.privateMode ? stringWiper(referrer) : referrer;
|
|
7565
|
+
app.send(SetPageLocation(safeUrl, safeReferrer, navigationStart, safeTitle));
|
|
7528
7566
|
navigationStart = 0;
|
|
7529
7567
|
referrer = url;
|
|
7530
7568
|
}
|
|
@@ -7993,6 +8031,136 @@ function isObject(thing) {
|
|
|
7993
8031
|
return thing !== null && typeof thing === 'object';
|
|
7994
8032
|
}
|
|
7995
8033
|
|
|
8034
|
+
const sensitiveParams = new Set([
|
|
8035
|
+
"password",
|
|
8036
|
+
"pass",
|
|
8037
|
+
"pwd",
|
|
8038
|
+
"mdp",
|
|
8039
|
+
"token",
|
|
8040
|
+
"bearer",
|
|
8041
|
+
"jwt",
|
|
8042
|
+
"api_key",
|
|
8043
|
+
"api-key",
|
|
8044
|
+
"apiKey",
|
|
8045
|
+
"secret",
|
|
8046
|
+
"ssn",
|
|
8047
|
+
"zip",
|
|
8048
|
+
"zipcode",
|
|
8049
|
+
"x-api-key",
|
|
8050
|
+
"www-authenticate",
|
|
8051
|
+
"x-csrf-token",
|
|
8052
|
+
"x-requested-with",
|
|
8053
|
+
"x-forwarded-for",
|
|
8054
|
+
"x-real-ip",
|
|
8055
|
+
"cookie",
|
|
8056
|
+
"authorization",
|
|
8057
|
+
"auth",
|
|
8058
|
+
"proxy-authorization",
|
|
8059
|
+
"set-cookie",
|
|
8060
|
+
"account_key",
|
|
8061
|
+
]);
|
|
8062
|
+
function numDigits(x) {
|
|
8063
|
+
return (Math.log10((x ^ (x >> 31)) - (x >> 31)) | 0) + 1;
|
|
8064
|
+
}
|
|
8065
|
+
function obscure(value) {
|
|
8066
|
+
if (typeof value === "number") {
|
|
8067
|
+
const digits = numDigits(value);
|
|
8068
|
+
return "9".repeat(digits);
|
|
8069
|
+
}
|
|
8070
|
+
return value.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff\s]/g, '*');
|
|
8071
|
+
}
|
|
8072
|
+
function filterHeaders(headers) {
|
|
8073
|
+
const filteredHeaders = {};
|
|
8074
|
+
if (Array.isArray(headers)) {
|
|
8075
|
+
headers.forEach(({ name, value }) => {
|
|
8076
|
+
if (sensitiveParams.has(name.toLowerCase())) {
|
|
8077
|
+
filteredHeaders[name] = obscure(value);
|
|
8078
|
+
}
|
|
8079
|
+
else {
|
|
8080
|
+
filteredHeaders[name] = value;
|
|
8081
|
+
}
|
|
8082
|
+
});
|
|
8083
|
+
}
|
|
8084
|
+
else {
|
|
8085
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
8086
|
+
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8087
|
+
filteredHeaders[key] = obscure(value);
|
|
8088
|
+
}
|
|
8089
|
+
else {
|
|
8090
|
+
filteredHeaders[key] = value;
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
}
|
|
8094
|
+
return filteredHeaders;
|
|
8095
|
+
}
|
|
8096
|
+
function filterBody(body) {
|
|
8097
|
+
if (!body) {
|
|
8098
|
+
return body;
|
|
8099
|
+
}
|
|
8100
|
+
let parsedBody;
|
|
8101
|
+
let isJSON = false;
|
|
8102
|
+
try {
|
|
8103
|
+
parsedBody = JSON.parse(body);
|
|
8104
|
+
isJSON = true;
|
|
8105
|
+
}
|
|
8106
|
+
catch (e) {
|
|
8107
|
+
// not json
|
|
8108
|
+
}
|
|
8109
|
+
if (isJSON) {
|
|
8110
|
+
obscureSensitiveData(parsedBody);
|
|
8111
|
+
return JSON.stringify(parsedBody);
|
|
8112
|
+
}
|
|
8113
|
+
else {
|
|
8114
|
+
const params = new URLSearchParams(body);
|
|
8115
|
+
for (const key of params.keys()) {
|
|
8116
|
+
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8117
|
+
const value = obscure(params.get(key));
|
|
8118
|
+
params.set(key, value);
|
|
8119
|
+
}
|
|
8120
|
+
}
|
|
8121
|
+
return params.toString();
|
|
8122
|
+
}
|
|
8123
|
+
}
|
|
8124
|
+
function sanitizeObject(obj) {
|
|
8125
|
+
obscureSensitiveData(obj);
|
|
8126
|
+
return obj;
|
|
8127
|
+
}
|
|
8128
|
+
function obscureSensitiveData(obj) {
|
|
8129
|
+
if (Array.isArray(obj)) {
|
|
8130
|
+
obj.forEach(obscureSensitiveData);
|
|
8131
|
+
}
|
|
8132
|
+
else if (obj && typeof obj === "object") {
|
|
8133
|
+
for (const key in obj) {
|
|
8134
|
+
if (Object.hasOwn(obj, key)) {
|
|
8135
|
+
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8136
|
+
obj[key] = obscure(obj[key]);
|
|
8137
|
+
}
|
|
8138
|
+
else if (obj[key] !== null && typeof obj[key] === "object") {
|
|
8139
|
+
obscureSensitiveData(obj[key]);
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
}
|
|
8143
|
+
}
|
|
8144
|
+
}
|
|
8145
|
+
function tryFilterUrl(url) {
|
|
8146
|
+
if (!url)
|
|
8147
|
+
return "";
|
|
8148
|
+
try {
|
|
8149
|
+
const urlObj = new URL(url);
|
|
8150
|
+
if (urlObj.searchParams) {
|
|
8151
|
+
for (const key of urlObj.searchParams.keys()) {
|
|
8152
|
+
if (sensitiveParams.has(key.toLowerCase())) {
|
|
8153
|
+
urlObj.searchParams.set(key, "******");
|
|
8154
|
+
}
|
|
8155
|
+
}
|
|
8156
|
+
}
|
|
8157
|
+
return urlObj.toString();
|
|
8158
|
+
}
|
|
8159
|
+
catch (e) {
|
|
8160
|
+
return url;
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
|
|
7996
8164
|
/**
|
|
7997
8165
|
* I know we're not using most of the information from this class
|
|
7998
8166
|
* but it can be useful in the future if we will decide to display more stuff in our ui
|
|
@@ -8024,13 +8192,18 @@ class NetworkMessage {
|
|
|
8024
8192
|
}
|
|
8025
8193
|
getMessage() {
|
|
8026
8194
|
const { reqHs, resHs } = this.writeHeaders();
|
|
8195
|
+
const reqBody = this.method === 'GET'
|
|
8196
|
+
? JSON.stringify(sanitizeObject(this.getData)) : filterBody(this.requestData);
|
|
8027
8197
|
const request = {
|
|
8028
|
-
headers: reqHs,
|
|
8029
|
-
body:
|
|
8198
|
+
headers: filterHeaders(reqHs),
|
|
8199
|
+
body: reqBody,
|
|
8200
|
+
};
|
|
8201
|
+
const response = {
|
|
8202
|
+
headers: filterHeaders(resHs),
|
|
8203
|
+
body: filterBody(this.response)
|
|
8030
8204
|
};
|
|
8031
|
-
const response = { headers: resHs, body: this.response };
|
|
8032
8205
|
const messageInfo = this.sanitize({
|
|
8033
|
-
url: this.url,
|
|
8206
|
+
url: tryFilterUrl(this.url),
|
|
8034
8207
|
method: this.method,
|
|
8035
8208
|
status: this.status,
|
|
8036
8209
|
request,
|
|
@@ -8895,7 +9068,7 @@ function Network (app, opts = {}) {
|
|
|
8895
9068
|
}
|
|
8896
9069
|
}
|
|
8897
9070
|
function sanitize(reqResInfo) {
|
|
8898
|
-
if (!options.capturePayload) {
|
|
9071
|
+
if (!options.capturePayload || app.sanitizer.privateMode) {
|
|
8899
9072
|
// @ts-ignore
|
|
8900
9073
|
delete reqResInfo.request.body;
|
|
8901
9074
|
delete reqResInfo.response.body;
|
|
@@ -8928,11 +9101,12 @@ function Network (app, opts = {}) {
|
|
|
8928
9101
|
const patchWindow = (context) => {
|
|
8929
9102
|
/* ====== modern way ====== */
|
|
8930
9103
|
if (options.useProxy) {
|
|
8931
|
-
return createNetworkProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => {
|
|
9104
|
+
return createNetworkProxy(context, app.sanitizer.privateMode ? true : options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => {
|
|
8932
9105
|
if (options.failuresOnly && message.status < 400) {
|
|
8933
9106
|
return;
|
|
8934
9107
|
}
|
|
8935
|
-
|
|
9108
|
+
const url = app.sanitizer.privateMode ? '************' : message.url;
|
|
9109
|
+
app.send(NetworkRequest(message.requestType, message.method, url, message.request, message.response, message.status, message.startTime + getTimeOrigin(), message.duration, message.responseSize));
|
|
8936
9110
|
}, (url) => app.isServiceURL(url), { xhr: true, fetch: true, beacon: true }, options.tokenUrlMatcher);
|
|
8937
9111
|
}
|
|
8938
9112
|
/* ====== Fetch ====== */
|
|
@@ -9189,7 +9363,7 @@ class API {
|
|
|
9189
9363
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9190
9364
|
const doNotTrack = this.checkDoNotTrack();
|
|
9191
9365
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9192
|
-
trackerVersion: '16.1.0
|
|
9366
|
+
trackerVersion: '16.1.0',
|
|
9193
9367
|
projectKey: this.options.projectKey,
|
|
9194
9368
|
doNotTrack,
|
|
9195
9369
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|