@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 CHANGED
@@ -725,7 +725,9 @@ class StringDictionary {
725
725
  this.backDict = {};
726
726
  this.getKey = (str) => {
727
727
  let isNew = false;
728
- if (!this.backDict[str]) {
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[str] = id;
742
+ this.backDict[safeKey] = id;
741
743
  this.lastTs = shavedTs;
742
744
  }
743
- return [this.backDict[str], isNew];
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, attr];
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(attr),
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, 40, false);
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
- const [url, symbolId] = href.split('#');
3715
- if (!url || !symbolId) {
3716
- console.debug('Openreplay: Invalid xlink:href or href found on <use>.');
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.warn('! Node is already bound', node);
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
- this.options = Object.assign({
4433
+ const defaultOptions = {
4414
4434
  obscureTextEmails: true,
4415
4435
  obscureTextNumbers: false,
4416
- }, params.options);
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-beta.8'; // TODO: version compatability check inside each plugin.
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.messages.unshift(Timestamp(this.timestamp()));
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.bufferedMessages1.push(Timestamp(this.timestamp()));
5387
- this.bufferedMessages1.push(TabData(this.session.getTabId()));
5388
- this.bufferedMessages2.push(Timestamp(this.timestamp()));
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) => app.send(ConsoleLog(level, printf(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
- const label = getInputLabel(node);
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
- app.send(MouseClick(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : '', normalizedX, normalizedY), true);
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.send(SetPageLocation(url, referrer, navigationStart, document.title));
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: this.method === 'GET' ? JSON.stringify(this.getData) : this.requestData,
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
- app.send(NetworkRequest(message.requestType, message.method, message.url, message.request, message.response, message.status, message.startTime + getTimeOrigin(), message.duration, message.responseSize));
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-beta.8',
9366
+ trackerVersion: '16.1.0',
9193
9367
  projectKey: this.options.projectKey,
9194
9368
  doNotTrack,
9195
9369
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,