@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 +8 -0
- package/cjs/app/index.js +3 -3
- package/cjs/app/nodes.js +2 -0
- package/cjs/index.js +1 -1
- package/cjs/modules/Network/fetchProxy.d.ts +3 -2
- package/cjs/modules/Network/fetchProxy.js +9 -3
- package/cjs/modules/Network/index.d.ts +1 -1
- package/cjs/modules/Network/index.js +3 -3
- package/cjs/modules/Network/xhrProxy.d.ts +3 -2
- package/cjs/modules/Network/xhrProxy.js +9 -3
- package/cjs/modules/network.d.ts +1 -0
- package/cjs/modules/network.js +1 -1
- package/lib/app/index.js +3 -3
- package/lib/app/nodes.js +2 -0
- package/lib/index.js +1 -1
- package/lib/modules/Network/fetchProxy.d.ts +3 -2
- package/lib/modules/Network/fetchProxy.js +9 -3
- package/lib/modules/Network/index.d.ts +1 -1
- package/lib/modules/Network/index.js +3 -3
- package/lib/modules/Network/xhrProxy.d.ts +3 -2
- package/lib/modules/Network/xhrProxy.js +9 -3
- package/lib/modules/network.d.ts +1 -0
- package/lib/modules/network.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
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.
|
|
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
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.
|
|
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
|
-
|
|
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
|
}
|
package/cjs/modules/network.d.ts
CHANGED
package/cjs/modules/network.js
CHANGED
|
@@ -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.
|
|
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
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.
|
|
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
|
-
|
|
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
|
}
|
package/lib/modules/network.d.ts
CHANGED
package/lib/modules/network.js
CHANGED
|
@@ -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);
|