@openreplay/tracker 16.1.0-beta.9 → 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 -57
- package/dist/cjs/entry.js.map +1 -1
- package/dist/cjs/index.js +227 -57
- 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/cjs/main/modules/attributeSender.d.ts +2 -2
- package/dist/lib/entry.js +227 -57
- package/dist/lib/entry.js.map +1 -1
- package/dist/lib/index.js +227 -57
- 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/lib/main/modules/attributeSender.d.ts +2 -2
- package/dist/types/main/app/index.d.ts +1 -0
- package/dist/types/main/app/sanitizer.d.ts +6 -1
- package/dist/types/main/modules/attributeSender.d.ts +2 -2
- 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,31 +739,26 @@ 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 {
|
|
757
|
-
if (typeof this.applyDict(attr) !== 'number') {
|
|
758
|
-
console.log(id, name, value, this.app.nodes.getNode(id));
|
|
759
|
-
}
|
|
760
757
|
const message = [
|
|
761
758
|
35 /* Type.SetNodeAttributeDictGlobal */,
|
|
762
759
|
id,
|
|
763
760
|
this.applyDict(name),
|
|
764
|
-
this.applyDict(
|
|
761
|
+
this.applyDict(value),
|
|
765
762
|
];
|
|
766
763
|
return this.app.send(message);
|
|
767
764
|
}
|
|
@@ -2207,7 +2204,7 @@ function Performance (app, opts) {
|
|
|
2207
2204
|
app.attachStopCallback(() => {
|
|
2208
2205
|
ticks = frames = undefined;
|
|
2209
2206
|
});
|
|
2210
|
-
app.ticker.attach(sendPerformanceTrack,
|
|
2207
|
+
app.ticker.attach(sendPerformanceTrack, 165, false);
|
|
2211
2208
|
if (document.hidden !== undefined) {
|
|
2212
2209
|
app.attachEventListener(document, 'visibilitychange', sendPerformanceTrack, false, false);
|
|
2213
2210
|
}
|
|
@@ -3714,9 +3711,26 @@ async function parseUseEl(useElement, mode, domParser) {
|
|
|
3714
3711
|
console.debug('Openreplay: xlink:href or href not found on <use>.');
|
|
3715
3712
|
return;
|
|
3716
3713
|
}
|
|
3717
|
-
|
|
3718
|
-
if
|
|
3719
|
-
|
|
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>.');
|
|
3720
3734
|
return;
|
|
3721
3735
|
}
|
|
3722
3736
|
if (iconCache[symbolId]) {
|
|
@@ -3967,6 +3981,9 @@ class Observer {
|
|
|
3967
3981
|
if (name === 'href' || value.length > 1e5) {
|
|
3968
3982
|
value = '';
|
|
3969
3983
|
}
|
|
3984
|
+
if (['alt', 'placeholder'].includes(name) && this.app.sanitizer.privateMode) {
|
|
3985
|
+
value = value.replaceAll(/./g, '*');
|
|
3986
|
+
}
|
|
3970
3987
|
this.app.attributeSender.sendSetAttribute(id, name, value);
|
|
3971
3988
|
}
|
|
3972
3989
|
sendNodeData(id, parentElement, data) {
|
|
@@ -3994,7 +4011,7 @@ class Observer {
|
|
|
3994
4011
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
|
|
3995
4012
|
acceptNode: (node) => {
|
|
3996
4013
|
if (this.app.nodes.getID(node) !== undefined) {
|
|
3997
|
-
this.app.debug.
|
|
4014
|
+
this.app.debug.info('! Node is already bound', node);
|
|
3998
4015
|
}
|
|
3999
4016
|
return isIgnored(node) || this.app.nodes.getID(node) !== undefined
|
|
4000
4017
|
? NodeFilter.FILTER_REJECT
|
|
@@ -4407,18 +4424,30 @@ exports.SanitizeLevel = void 0;
|
|
|
4407
4424
|
})(exports.SanitizeLevel || (exports.SanitizeLevel = {}));
|
|
4408
4425
|
const stringWiper = (input) => input
|
|
4409
4426
|
.trim()
|
|
4410
|
-
.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, '*');
|
|
4411
4428
|
class Sanitizer {
|
|
4412
4429
|
constructor(params) {
|
|
4413
4430
|
this.obscured = new Set();
|
|
4414
4431
|
this.hidden = new Set();
|
|
4415
4432
|
this.app = params.app;
|
|
4416
|
-
|
|
4433
|
+
const defaultOptions = {
|
|
4417
4434
|
obscureTextEmails: true,
|
|
4418
4435
|
obscureTextNumbers: false,
|
|
4419
|
-
|
|
4436
|
+
privateMode: false,
|
|
4437
|
+
domSanitizer: undefined,
|
|
4438
|
+
};
|
|
4439
|
+
this.privateMode = params.options?.privateMode ?? false;
|
|
4440
|
+
this.options = Object.assign(defaultOptions, params.options);
|
|
4420
4441
|
}
|
|
4421
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
|
+
}
|
|
4422
4451
|
if (this.obscured.has(parentID) ||
|
|
4423
4452
|
(isElementNode(node) &&
|
|
4424
4453
|
(hasOpenreplayAttribute(node, 'masked') || hasOpenreplayAttribute(node, 'obscured')))) {
|
|
@@ -4661,7 +4690,7 @@ class Ticker {
|
|
|
4661
4690
|
* this value is injected during build time via rollup
|
|
4662
4691
|
* */
|
|
4663
4692
|
// @ts-ignore
|
|
4664
|
-
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";
|
|
4665
4694
|
const CANCELED = 'canceled';
|
|
4666
4695
|
const uxtStorageKey = 'or_uxt_active';
|
|
4667
4696
|
const bufferStorageKey = 'or_buffer_1';
|
|
@@ -4715,7 +4744,7 @@ class App {
|
|
|
4715
4744
|
this.stopCallbacks = [];
|
|
4716
4745
|
this.commitCallbacks = [];
|
|
4717
4746
|
this.activityState = ActivityState.NotActive;
|
|
4718
|
-
this.version = '16.1.0
|
|
4747
|
+
this.version = '16.1.0'; // TODO: version compatability check inside each plugin.
|
|
4719
4748
|
this.socketMode = false;
|
|
4720
4749
|
this.compressionThreshold = 24 * 1000;
|
|
4721
4750
|
this.bc = null;
|
|
@@ -4729,6 +4758,7 @@ class App {
|
|
|
4729
4758
|
'feature-flags': true,
|
|
4730
4759
|
'usability-test': true,
|
|
4731
4760
|
};
|
|
4761
|
+
this.emptyBatchCounter = 0;
|
|
4732
4762
|
/** used by child iframes for crossdomain only */
|
|
4733
4763
|
this.parentActive = false;
|
|
4734
4764
|
this.checkStatus = () => {
|
|
@@ -5328,8 +5358,7 @@ class App {
|
|
|
5328
5358
|
* */
|
|
5329
5359
|
_nCommit() {
|
|
5330
5360
|
if (this.socketMode) {
|
|
5331
|
-
this.messages.unshift(TabData(this.session.getTabId()));
|
|
5332
|
-
this.messages.unshift(Timestamp(this.timestamp()));
|
|
5361
|
+
this.messages.unshift(Timestamp(this.timestamp()), TabData(this.session.getTabId()));
|
|
5333
5362
|
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
5334
5363
|
this.messages.length = 0;
|
|
5335
5364
|
return;
|
|
@@ -5346,26 +5375,19 @@ class App {
|
|
|
5346
5375
|
if (this.worker === undefined || !this.messages.length) {
|
|
5347
5376
|
return;
|
|
5348
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(', '));
|
|
5349
5387
|
try {
|
|
5350
5388
|
requestIdleCb(() => {
|
|
5351
|
-
this.messages.unshift(TabData(this.session.getTabId()));
|
|
5352
|
-
this.
|
|
5353
|
-
try {
|
|
5354
|
-
this.worker?.postMessage(this.messages);
|
|
5355
|
-
}
|
|
5356
|
-
catch (e) {
|
|
5357
|
-
console.log(this.messages.join('$___$'));
|
|
5358
|
-
console.log(this.attributeSender.dict);
|
|
5359
|
-
console.error(e);
|
|
5360
|
-
this.messages.forEach(m => {
|
|
5361
|
-
try {
|
|
5362
|
-
this.worker?.postMessage([m]);
|
|
5363
|
-
}
|
|
5364
|
-
catch (e) {
|
|
5365
|
-
console.error(m, e);
|
|
5366
|
-
}
|
|
5367
|
-
});
|
|
5368
|
-
}
|
|
5389
|
+
this.messages.unshift(Timestamp(this.timestamp()), TabData(this.session.getTabId()));
|
|
5390
|
+
this.worker?.postMessage(this.messages);
|
|
5369
5391
|
this.commitCallbacks.forEach((cb) => cb(this.messages));
|
|
5370
5392
|
this.messages.length = 0;
|
|
5371
5393
|
});
|
|
@@ -5387,10 +5409,9 @@ class App {
|
|
|
5387
5409
|
_cStartCommit() {
|
|
5388
5410
|
this.coldStartCommitN += 1;
|
|
5389
5411
|
if (this.coldStartCommitN === 2) {
|
|
5390
|
-
this.
|
|
5391
|
-
this.bufferedMessages1.push(
|
|
5392
|
-
this.bufferedMessages2.push(
|
|
5393
|
-
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);
|
|
5394
5415
|
this.coldStartCommitN = 0;
|
|
5395
5416
|
}
|
|
5396
5417
|
}
|
|
@@ -6196,7 +6217,13 @@ function Console (app, opts) {
|
|
|
6196
6217
|
if (!Array.isArray(options.consoleMethods) || options.consoleMethods.length === 0) {
|
|
6197
6218
|
return;
|
|
6198
6219
|
}
|
|
6199
|
-
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
|
+
});
|
|
6200
6227
|
let n = 0;
|
|
6201
6228
|
const reset = () => {
|
|
6202
6229
|
n = 0;
|
|
@@ -6720,7 +6747,10 @@ function Input (app, opts) {
|
|
|
6720
6747
|
}, 3);
|
|
6721
6748
|
function sendInputChange(id, node, hesitationTime, inputTime) {
|
|
6722
6749
|
const { value, mask } = getInputValue(id, node);
|
|
6723
|
-
|
|
6750
|
+
let label = getInputLabel(node);
|
|
6751
|
+
if (app.sanitizer.privateMode) {
|
|
6752
|
+
label = label.replaceAll(/./g, '*');
|
|
6753
|
+
}
|
|
6724
6754
|
app.send(InputChange(id, value, mask !== 0, label, hesitationTime, inputTime));
|
|
6725
6755
|
}
|
|
6726
6756
|
app.nodes.attachNodeCallback(app.safe((node) => {
|
|
@@ -7228,7 +7258,8 @@ function Mouse (app, options) {
|
|
|
7228
7258
|
const normalizedX = roundNumber(clickX / contentWidth);
|
|
7229
7259
|
const normalizedY = roundNumber(clickY / contentHeight);
|
|
7230
7260
|
sendMouseMove();
|
|
7231
|
-
|
|
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);
|
|
7232
7263
|
}
|
|
7233
7264
|
mouseTarget = null;
|
|
7234
7265
|
});
|
|
@@ -7339,7 +7370,7 @@ function Timing (app, opts) {
|
|
|
7339
7370
|
if (failed) {
|
|
7340
7371
|
app.send(ResourceTiming(entry.startTime + getTimeOrigin(), 0, 0, 0, 0, 0, entry.name, entry.initiatorType, 0, true));
|
|
7341
7372
|
}
|
|
7342
|
-
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,
|
|
7343
7374
|
// @ts-ignore
|
|
7344
7375
|
(entry.responseStatus && entry.responseStatus === 304) || entry.transferSize === 0));
|
|
7345
7376
|
}
|
|
@@ -7528,7 +7559,10 @@ function Viewport (app) {
|
|
|
7528
7559
|
const { URL } = document;
|
|
7529
7560
|
if (URL !== url) {
|
|
7530
7561
|
url = URL;
|
|
7531
|
-
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));
|
|
7532
7566
|
navigationStart = 0;
|
|
7533
7567
|
referrer = url;
|
|
7534
7568
|
}
|
|
@@ -7997,6 +8031,136 @@ function isObject(thing) {
|
|
|
7997
8031
|
return thing !== null && typeof thing === 'object';
|
|
7998
8032
|
}
|
|
7999
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
|
+
|
|
8000
8164
|
/**
|
|
8001
8165
|
* I know we're not using most of the information from this class
|
|
8002
8166
|
* but it can be useful in the future if we will decide to display more stuff in our ui
|
|
@@ -8028,13 +8192,18 @@ class NetworkMessage {
|
|
|
8028
8192
|
}
|
|
8029
8193
|
getMessage() {
|
|
8030
8194
|
const { reqHs, resHs } = this.writeHeaders();
|
|
8195
|
+
const reqBody = this.method === 'GET'
|
|
8196
|
+
? JSON.stringify(sanitizeObject(this.getData)) : filterBody(this.requestData);
|
|
8031
8197
|
const request = {
|
|
8032
|
-
headers: reqHs,
|
|
8033
|
-
body:
|
|
8198
|
+
headers: filterHeaders(reqHs),
|
|
8199
|
+
body: reqBody,
|
|
8200
|
+
};
|
|
8201
|
+
const response = {
|
|
8202
|
+
headers: filterHeaders(resHs),
|
|
8203
|
+
body: filterBody(this.response)
|
|
8034
8204
|
};
|
|
8035
|
-
const response = { headers: resHs, body: this.response };
|
|
8036
8205
|
const messageInfo = this.sanitize({
|
|
8037
|
-
url: this.url,
|
|
8206
|
+
url: tryFilterUrl(this.url),
|
|
8038
8207
|
method: this.method,
|
|
8039
8208
|
status: this.status,
|
|
8040
8209
|
request,
|
|
@@ -8899,7 +9068,7 @@ function Network (app, opts = {}) {
|
|
|
8899
9068
|
}
|
|
8900
9069
|
}
|
|
8901
9070
|
function sanitize(reqResInfo) {
|
|
8902
|
-
if (!options.capturePayload) {
|
|
9071
|
+
if (!options.capturePayload || app.sanitizer.privateMode) {
|
|
8903
9072
|
// @ts-ignore
|
|
8904
9073
|
delete reqResInfo.request.body;
|
|
8905
9074
|
delete reqResInfo.response.body;
|
|
@@ -8932,11 +9101,12 @@ function Network (app, opts = {}) {
|
|
|
8932
9101
|
const patchWindow = (context) => {
|
|
8933
9102
|
/* ====== modern way ====== */
|
|
8934
9103
|
if (options.useProxy) {
|
|
8935
|
-
return createNetworkProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => {
|
|
9104
|
+
return createNetworkProxy(context, app.sanitizer.privateMode ? true : options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => {
|
|
8936
9105
|
if (options.failuresOnly && message.status < 400) {
|
|
8937
9106
|
return;
|
|
8938
9107
|
}
|
|
8939
|
-
|
|
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));
|
|
8940
9110
|
}, (url) => app.isServiceURL(url), { xhr: true, fetch: true, beacon: true }, options.tokenUrlMatcher);
|
|
8941
9111
|
}
|
|
8942
9112
|
/* ====== Fetch ====== */
|
|
@@ -9193,7 +9363,7 @@ class API {
|
|
|
9193
9363
|
this.signalStartIssue = (reason, missingApi) => {
|
|
9194
9364
|
const doNotTrack = this.checkDoNotTrack();
|
|
9195
9365
|
console.log("Tracker couldn't start due to:", JSON.stringify({
|
|
9196
|
-
trackerVersion: '16.1.0
|
|
9366
|
+
trackerVersion: '16.1.0',
|
|
9197
9367
|
projectKey: this.options.projectKey,
|
|
9198
9368
|
doNotTrack,
|
|
9199
9369
|
reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,
|