@openreplay/tracker 9.0.5 → 9.0.7

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 9.0.7
2
+
3
+ - fix for `getSessionURL` method
4
+
5
+ # 9.0.6
6
+
7
+ - added `tokenUrlMatcher` option to network settings, allowing to ingest session token header to custom allowed urls
8
+
1
9
  # 9.0.5
2
10
 
3
11
  - same fixes but for fetch proxy
package/cjs/app/index.js CHANGED
@@ -42,7 +42,7 @@ class App {
42
42
  this.stopCallbacks = [];
43
43
  this.commitCallbacks = [];
44
44
  this.activityState = ActivityState.NotActive;
45
- this.version = '9.0.5'; // TODO: version compatability check inside each plugin.
45
+ this.version = '9.0.7'; // TODO: version compatability check inside each plugin.
46
46
  this.compressionThreshold = 24 * 1000;
47
47
  this.restartAttempts = 0;
48
48
  this.bc = null;
@@ -307,7 +307,7 @@ class App {
307
307
  }
308
308
  const ingest = this.options.ingestPoint;
309
309
  const isSaas = /api\.openreplay\.com/.test(ingest);
310
- const projectPath = isSaas ? 'https://openreplay.com/ingest' : ingest;
310
+ const projectPath = isSaas ? 'https://app.openreplay.com/ingest' : ingest;
311
311
  const url = projectPath.replace(/ingest$/, `${projectID}/session/${sessionID}`);
312
312
  if (options === null || options === void 0 ? void 0 : options.withCurrentTime) {
313
313
  const jumpTo = (0, utils_js_1.now)() - timestamp;
@@ -401,7 +401,7 @@ class App {
401
401
  'Content-Type': 'application/json',
402
402
  },
403
403
  body: JSON.stringify(Object.assign(Object.assign({}, this.getTrackerInfo()), { timestamp, userID: this.session.getInfo().userID, token: isNewSession ? undefined : sessionToken, deviceMemory: performance_js_1.deviceMemory,
404
- jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit })),
404
+ jsHeapSizeLimit: performance_js_1.jsHeapSizeLimit, timezone: getTimezone() })),
405
405
  })
406
406
  .then((r) => {
407
407
  if (r.status === 200) {
package/cjs/app/nodes.js CHANGED
@@ -66,6 +66,8 @@ class Nodes {
66
66
  this.nodeCallbacks.forEach((cb) => cb(node, isStart));
67
67
  }
68
68
  getID(node) {
69
+ if (!node)
70
+ return undefined;
69
71
  return node[this.node_id];
70
72
  }
71
73
  getNode(id) {
package/cjs/index.js CHANGED
@@ -153,7 +153,7 @@ class API {
153
153
  // no-cors issue only with text/plain or not-set Content-Type
154
154
  // req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
155
155
  req.send(JSON.stringify({
156
- trackerVersion: '9.0.5',
156
+ trackerVersion: '9.0.7',
157
157
  projectKey: options.projectKey,
158
158
  doNotTrack,
159
159
  // TODO: add precise reason (an exact API missing)
@@ -22,7 +22,8 @@ export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyH
22
22
  private readonly sanitize;
23
23
  private readonly sendMessage;
24
24
  private readonly isServiceUrl;
25
- constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
25
+ private readonly tokenUrlMatcher?;
26
+ constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
26
27
  apply(target: T, _: typeof window, argsList: [RequestInfo | URL, RequestInit]): any;
27
28
  protected beforeFetch(item: NetworkMessage, input: RequestInfo, init?: RequestInit): void;
28
29
  protected afterFetch(item: NetworkMessage): (resp: Response) => Response;
@@ -30,5 +31,5 @@ export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyH
30
31
  }
31
32
  export default class FetchProxy {
32
33
  static origFetch: typeof fetch;
33
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): typeof fetch;
34
+ static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): typeof fetch;
34
35
  }
@@ -106,12 +106,13 @@ class ResponseProxyHandler {
106
106
  }
107
107
  exports.ResponseProxyHandler = ResponseProxyHandler;
108
108
  class FetchProxyHandler {
109
- constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
109
+ constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
110
110
  this.ignoredHeaders = ignoredHeaders;
111
111
  this.setSessionTokenHeader = setSessionTokenHeader;
112
112
  this.sanitize = sanitize;
113
113
  this.sendMessage = sendMessage;
114
114
  this.isServiceUrl = isServiceUrl;
115
+ this.tokenUrlMatcher = tokenUrlMatcher;
115
116
  }
116
117
  apply(target, _, argsList) {
117
118
  const input = argsList[0];
@@ -125,6 +126,11 @@ class FetchProxyHandler {
125
126
  const item = new networkMessage_js_1.default(this.ignoredHeaders, this.setSessionTokenHeader, this.sanitize);
126
127
  this.beforeFetch(item, input, init);
127
128
  this.setSessionTokenHeader((name, value) => {
129
+ if (this.tokenUrlMatcher !== undefined) {
130
+ if (!this.tokenUrlMatcher(item.url)) {
131
+ return;
132
+ }
133
+ }
128
134
  if (argsList[1] === undefined && argsList[0] instanceof Request) {
129
135
  return argsList[0].headers.append(name, value);
130
136
  }
@@ -256,8 +262,8 @@ class FetchProxyHandler {
256
262
  }
257
263
  exports.FetchProxyHandler = FetchProxyHandler;
258
264
  class FetchProxy {
259
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
260
- return new Proxy(fetch, new FetchProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
265
+ static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
266
+ return new Proxy(fetch, new FetchProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher));
261
267
  }
262
268
  }
263
269
  exports.default = FetchProxy;
@@ -1,3 +1,3 @@
1
1
  import { RequestResponseData } from './types.js';
2
2
  import { NetworkRequest } from '../../common/messages.gen.js';
3
- export default function setProxy(context: typeof globalThis, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): void;
3
+ export default function setProxy(context: typeof globalThis, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): void;
@@ -4,15 +4,15 @@ const fetchProxy_js_1 = require("./fetchProxy.js");
4
4
  const xhrProxy_js_1 = require("./xhrProxy.js");
5
5
  const getWarning = (api) => console.warn(`Openreplay: Can't find ${api} in global context.
6
6
  If you're using serverside rendering in your app, make sure that tracker is loaded dynamically, otherwise ${api} won't be tracked.`);
7
- function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
7
+ function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
8
8
  if (context.XMLHttpRequest) {
9
- context.XMLHttpRequest = xhrProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
9
+ context.XMLHttpRequest = xhrProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
10
10
  }
11
11
  else {
12
12
  getWarning('XMLHttpRequest');
13
13
  }
14
14
  if (context.fetch) {
15
- context.fetch = fetchProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
15
+ context.fetch = fetchProxy_js_1.default.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
16
16
  }
17
17
  else {
18
18
  getWarning('fetch');
@@ -14,9 +14,10 @@ export declare class XHRProxyHandler<T extends XMLHttpRequest> implements ProxyH
14
14
  private readonly sanitize;
15
15
  private readonly sendMessage;
16
16
  private readonly isServiceUrl;
17
+ private readonly tokenUrlMatcher?;
17
18
  XMLReq: XMLHttpRequest;
18
19
  item: NetworkMessage;
19
- constructor(XMLReq: XMLHttpRequest, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
20
+ constructor(XMLReq: XMLHttpRequest, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
20
21
  get(target: T, key: string): any;
21
22
  set(target: T, key: string, value: (args: any[]) => any): boolean;
22
23
  onReadyStateChange(): void;
@@ -43,5 +44,5 @@ export default class XHRProxy {
43
44
  readonly OPENED: number;
44
45
  readonly UNSENT: number;
45
46
  };
46
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): any;
47
+ static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): any;
47
48
  }
@@ -11,12 +11,13 @@ exports.XHRProxyHandler = void 0;
11
11
  const networkMessage_js_1 = require("./networkMessage.js");
12
12
  const utils_js_1 = require("./utils.js");
13
13
  class XHRProxyHandler {
14
- constructor(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
14
+ constructor(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
15
15
  this.ignoredHeaders = ignoredHeaders;
16
16
  this.setSessionTokenHeader = setSessionTokenHeader;
17
17
  this.sanitize = sanitize;
18
18
  this.sendMessage = sendMessage;
19
19
  this.isServiceUrl = isServiceUrl;
20
+ this.tokenUrlMatcher = tokenUrlMatcher;
20
21
  this.XMLReq = XMLReq;
21
22
  this.XMLReq.onreadystatechange = () => {
22
23
  this.onReadyStateChange();
@@ -36,6 +37,11 @@ class XHRProxyHandler {
36
37
  return this.getOpen(target);
37
38
  case 'send':
38
39
  this.setSessionTokenHeader((name, value) => {
40
+ if (this.tokenUrlMatcher !== undefined) {
41
+ if (!this.tokenUrlMatcher(this.item.url)) {
42
+ return;
43
+ }
44
+ }
39
45
  target.setRequestHeader(name, value);
40
46
  });
41
47
  return this.getSend(target);
@@ -199,11 +205,11 @@ class XHRProxyHandler {
199
205
  }
200
206
  exports.XHRProxyHandler = XHRProxyHandler;
201
207
  class XHRProxy {
202
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
208
+ static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
203
209
  return new Proxy(XMLHttpRequest, {
204
210
  construct(original) {
205
211
  const XMLReq = new original();
206
- return new Proxy(XMLReq, new XHRProxyHandler(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
212
+ return new Proxy(XMLReq, new XHRProxyHandler(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher));
207
213
  },
208
214
  });
209
215
  }
@@ -25,6 +25,7 @@ export interface Options {
25
25
  sanitizer?: Sanitizer;
26
26
  axiosInstances?: Array<AxiosInstance>;
27
27
  useProxy?: boolean;
28
+ tokenUrlMatcher?: (url: string) => boolean;
28
29
  }
29
30
  export default function (app: App, opts?: Partial<Options>): void;
30
31
  export {};
@@ -76,7 +76,7 @@ function default_1(app, opts = {}) {
76
76
  const patchWindow = (context) => {
77
77
  /* ====== modern way ====== */
78
78
  if (options.useProxy) {
79
- return (0, index_js_1.default)(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url));
79
+ return (0, index_js_1.default)(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url), options.tokenUrlMatcher);
80
80
  }
81
81
  /* ====== Fetch ====== */
82
82
  const origFetch = context.fetch.bind(context);
package/lib/app/index.js CHANGED
@@ -39,7 +39,7 @@ export default class App {
39
39
  this.stopCallbacks = [];
40
40
  this.commitCallbacks = [];
41
41
  this.activityState = ActivityState.NotActive;
42
- this.version = '9.0.5'; // TODO: version compatability check inside each plugin.
42
+ this.version = '9.0.7'; // TODO: version compatability check inside each plugin.
43
43
  this.compressionThreshold = 24 * 1000;
44
44
  this.restartAttempts = 0;
45
45
  this.bc = null;
@@ -304,7 +304,7 @@ export default class App {
304
304
  }
305
305
  const ingest = this.options.ingestPoint;
306
306
  const isSaas = /api\.openreplay\.com/.test(ingest);
307
- const projectPath = isSaas ? 'https://openreplay.com/ingest' : ingest;
307
+ const projectPath = isSaas ? 'https://app.openreplay.com/ingest' : ingest;
308
308
  const url = projectPath.replace(/ingest$/, `${projectID}/session/${sessionID}`);
309
309
  if (options === null || options === void 0 ? void 0 : options.withCurrentTime) {
310
310
  const jumpTo = now() - timestamp;
@@ -398,7 +398,7 @@ export default class App {
398
398
  'Content-Type': 'application/json',
399
399
  },
400
400
  body: JSON.stringify(Object.assign(Object.assign({}, this.getTrackerInfo()), { timestamp, userID: this.session.getInfo().userID, token: isNewSession ? undefined : sessionToken, deviceMemory,
401
- jsHeapSizeLimit })),
401
+ jsHeapSizeLimit, timezone: getTimezone() })),
402
402
  })
403
403
  .then((r) => {
404
404
  if (r.status === 200) {
package/lib/app/nodes.js CHANGED
@@ -64,6 +64,8 @@ export default class Nodes {
64
64
  this.nodeCallbacks.forEach((cb) => cb(node, isStart));
65
65
  }
66
66
  getID(node) {
67
+ if (!node)
68
+ return undefined;
67
69
  return node[this.node_id];
68
70
  }
69
71
  getNode(id) {
package/lib/index.js CHANGED
@@ -148,7 +148,7 @@ export default class API {
148
148
  // no-cors issue only with text/plain or not-set Content-Type
149
149
  // req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
150
150
  req.send(JSON.stringify({
151
- trackerVersion: '9.0.5',
151
+ trackerVersion: '9.0.7',
152
152
  projectKey: options.projectKey,
153
153
  doNotTrack,
154
154
  // TODO: add precise reason (an exact API missing)
@@ -22,7 +22,8 @@ export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyH
22
22
  private readonly sanitize;
23
23
  private readonly sendMessage;
24
24
  private readonly isServiceUrl;
25
- constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
25
+ private readonly tokenUrlMatcher?;
26
+ constructor(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
26
27
  apply(target: T, _: typeof window, argsList: [RequestInfo | URL, RequestInit]): any;
27
28
  protected beforeFetch(item: NetworkMessage, input: RequestInfo, init?: RequestInit): void;
28
29
  protected afterFetch(item: NetworkMessage): (resp: Response) => Response;
@@ -30,5 +31,5 @@ export declare class FetchProxyHandler<T extends typeof fetch> implements ProxyH
30
31
  }
31
32
  export default class FetchProxy {
32
33
  static origFetch: typeof fetch;
33
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): typeof fetch;
34
+ static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (item: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): typeof fetch;
34
35
  }
@@ -102,12 +102,13 @@ export class ResponseProxyHandler {
102
102
  }
103
103
  }
104
104
  export class FetchProxyHandler {
105
- constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
105
+ constructor(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
106
106
  this.ignoredHeaders = ignoredHeaders;
107
107
  this.setSessionTokenHeader = setSessionTokenHeader;
108
108
  this.sanitize = sanitize;
109
109
  this.sendMessage = sendMessage;
110
110
  this.isServiceUrl = isServiceUrl;
111
+ this.tokenUrlMatcher = tokenUrlMatcher;
111
112
  }
112
113
  apply(target, _, argsList) {
113
114
  const input = argsList[0];
@@ -121,6 +122,11 @@ export class FetchProxyHandler {
121
122
  const item = new NetworkMessage(this.ignoredHeaders, this.setSessionTokenHeader, this.sanitize);
122
123
  this.beforeFetch(item, input, init);
123
124
  this.setSessionTokenHeader((name, value) => {
125
+ if (this.tokenUrlMatcher !== undefined) {
126
+ if (!this.tokenUrlMatcher(item.url)) {
127
+ return;
128
+ }
129
+ }
124
130
  if (argsList[1] === undefined && argsList[0] instanceof Request) {
125
131
  return argsList[0].headers.append(name, value);
126
132
  }
@@ -251,8 +257,8 @@ export class FetchProxyHandler {
251
257
  }
252
258
  }
253
259
  export default class FetchProxy {
254
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
255
- return new Proxy(fetch, new FetchProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
260
+ static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
261
+ return new Proxy(fetch, new FetchProxyHandler(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher));
256
262
  }
257
263
  }
258
264
  FetchProxy.origFetch = fetch;
@@ -1,3 +1,3 @@
1
1
  import { RequestResponseData } from './types.js';
2
2
  import { NetworkRequest } from '../../common/messages.gen.js';
3
- export default function setProxy(context: typeof globalThis, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): void;
3
+ export default function setProxy(context: typeof globalThis, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): void;
@@ -2,15 +2,15 @@ import FetchProxy from './fetchProxy.js';
2
2
  import XHRProxy from './xhrProxy.js';
3
3
  const getWarning = (api) => console.warn(`Openreplay: Can't find ${api} in global context.
4
4
  If you're using serverside rendering in your app, make sure that tracker is loaded dynamically, otherwise ${api} won't be tracked.`);
5
- export default function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
5
+ export default function setProxy(context, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
6
6
  if (context.XMLHttpRequest) {
7
- context.XMLHttpRequest = XHRProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
7
+ context.XMLHttpRequest = XHRProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
8
8
  }
9
9
  else {
10
10
  getWarning('XMLHttpRequest');
11
11
  }
12
12
  if (context.fetch) {
13
- context.fetch = FetchProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl);
13
+ context.fetch = FetchProxy.create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher);
14
14
  }
15
15
  else {
16
16
  getWarning('fetch');
@@ -14,9 +14,10 @@ export declare class XHRProxyHandler<T extends XMLHttpRequest> implements ProxyH
14
14
  private readonly sanitize;
15
15
  private readonly sendMessage;
16
16
  private readonly isServiceUrl;
17
+ private readonly tokenUrlMatcher?;
17
18
  XMLReq: XMLHttpRequest;
18
19
  item: NetworkMessage;
19
- constructor(XMLReq: XMLHttpRequest, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean);
20
+ constructor(XMLReq: XMLHttpRequest, ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (message: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: ((url: string) => boolean) | undefined);
20
21
  get(target: T, key: string): any;
21
22
  set(target: T, key: string, value: (args: any[]) => any): boolean;
22
23
  onReadyStateChange(): void;
@@ -43,5 +44,5 @@ export default class XHRProxy {
43
44
  readonly OPENED: number;
44
45
  readonly UNSENT: number;
45
46
  };
46
- static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean): any;
47
+ static create(ignoredHeaders: boolean | string[], setSessionTokenHeader: (cb: (name: string, value: string) => void) => void, sanitize: (data: RequestResponseData) => RequestResponseData, sendMessage: (data: NetworkRequest) => void, isServiceUrl: (url: string) => boolean, tokenUrlMatcher?: (url: string) => boolean): any;
47
48
  }
@@ -8,12 +8,13 @@
8
8
  import NetworkMessage, { RequestState } from './networkMessage.js';
9
9
  import { genGetDataByUrl, formatByteSize, genStringBody, getStringResponseByType } from './utils.js';
10
10
  export class XHRProxyHandler {
11
- constructor(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
11
+ constructor(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
12
12
  this.ignoredHeaders = ignoredHeaders;
13
13
  this.setSessionTokenHeader = setSessionTokenHeader;
14
14
  this.sanitize = sanitize;
15
15
  this.sendMessage = sendMessage;
16
16
  this.isServiceUrl = isServiceUrl;
17
+ this.tokenUrlMatcher = tokenUrlMatcher;
17
18
  this.XMLReq = XMLReq;
18
19
  this.XMLReq.onreadystatechange = () => {
19
20
  this.onReadyStateChange();
@@ -33,6 +34,11 @@ export class XHRProxyHandler {
33
34
  return this.getOpen(target);
34
35
  case 'send':
35
36
  this.setSessionTokenHeader((name, value) => {
37
+ if (this.tokenUrlMatcher !== undefined) {
38
+ if (!this.tokenUrlMatcher(this.item.url)) {
39
+ return;
40
+ }
41
+ }
36
42
  target.setRequestHeader(name, value);
37
43
  });
38
44
  return this.getSend(target);
@@ -195,11 +201,11 @@ export class XHRProxyHandler {
195
201
  }
196
202
  }
197
203
  export default class XHRProxy {
198
- static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl) {
204
+ static create(ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher) {
199
205
  return new Proxy(XMLHttpRequest, {
200
206
  construct(original) {
201
207
  const XMLReq = new original();
202
- return new Proxy(XMLReq, new XHRProxyHandler(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl));
208
+ return new Proxy(XMLReq, new XHRProxyHandler(XMLReq, ignoredHeaders, setSessionTokenHeader, sanitize, sendMessage, isServiceUrl, tokenUrlMatcher));
203
209
  },
204
210
  });
205
211
  }
@@ -25,6 +25,7 @@ export interface Options {
25
25
  sanitizer?: Sanitizer;
26
26
  axiosInstances?: Array<AxiosInstance>;
27
27
  useProxy?: boolean;
28
+ tokenUrlMatcher?: (url: string) => boolean;
28
29
  }
29
30
  export default function (app: App, opts?: Partial<Options>): void;
30
31
  export {};
@@ -74,7 +74,7 @@ export default function (app, opts = {}) {
74
74
  const patchWindow = (context) => {
75
75
  /* ====== modern way ====== */
76
76
  if (options.useProxy) {
77
- return setProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url));
77
+ return setProxy(context, options.ignoreHeaders, setSessionTokenHeader, sanitize, (message) => app.send(message), (url) => app.isServiceURL(url), options.tokenUrlMatcher);
78
78
  }
79
79
  /* ====== Fetch ====== */
80
80
  const origFetch = context.fetch.bind(context);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openreplay/tracker",
3
3
  "description": "The OpenReplay tracker main package",
4
- "version": "9.0.5",
4
+ "version": "9.0.7",
5
5
  "keywords": [
6
6
  "logging",
7
7
  "replay"