@sailfish-ai/recorder 1.2.0 → 1.2.2
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/README.md +1 -1
- package/dist/index.js +54 -11
- package/dist/sailfish-recorder.cjs.js +1 -1
- package/dist/sailfish-recorder.cjs.js.br +0 -0
- package/dist/sailfish-recorder.cjs.js.gz +0 -0
- package/dist/sailfish-recorder.es.js +1 -1
- package/dist/sailfish-recorder.es.js.br +0 -0
- package/dist/sailfish-recorder.es.js.gz +0 -0
- package/dist/sailfish-recorder.umd.js +1 -1
- package/dist/sailfish-recorder.umd.js.br +0 -0
- package/dist/sailfish-recorder.umd.js.gz +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { fetchCaptureSettings, sendDomainsToNotPropagateHeaderTo, startRecording
|
|
|
6
6
|
import { initializeRecording } from "./recording";
|
|
7
7
|
// Default list of domains to ignore
|
|
8
8
|
const DOMAINS_TO_NOT_PROPAGATE_HEADER_TO_DEFAULT = [
|
|
9
|
+
"t.co",
|
|
9
10
|
"identitytoolkit.googleapis.com",
|
|
10
11
|
];
|
|
11
12
|
const DOMAINS_TO_NOT_RECORD_NETWORK_REQUESTS_TO = [];
|
|
@@ -92,7 +93,12 @@ function storeCredentialsAndConnection({ apiKey, backendApi, }) {
|
|
|
92
93
|
}
|
|
93
94
|
// Utility function to match domains or paths with wildcard support
|
|
94
95
|
export function matchUrlWithWildcard(url, patterns) {
|
|
95
|
-
|
|
96
|
+
if (!url || typeof url !== "string") {
|
|
97
|
+
throw new Error("Invalid URL input");
|
|
98
|
+
}
|
|
99
|
+
// Ensure the URL has a protocol. If not, prepend "http://"
|
|
100
|
+
const formattedUrl = url.match(/^[a-zA-Z]+:\/\//) ? url : `http://${url}`;
|
|
101
|
+
const strippedUrl = formattedUrl.replace(/^[a-zA-Z]+:\/\//, "");
|
|
96
102
|
const parsedUrl = new URL("http://" + strippedUrl); // Add a dummy protocol for URL parsing
|
|
97
103
|
const { hostname, pathname, port } = parsedUrl;
|
|
98
104
|
// Handle stripping 'www.' and port
|
|
@@ -151,26 +157,49 @@ export function matchUrlWithWildcard(url, patterns) {
|
|
|
151
157
|
});
|
|
152
158
|
}
|
|
153
159
|
// Updated XMLHttpRequest interceptor with single check function
|
|
160
|
+
// Updated XMLHttpRequest interceptor to bypass for CORS-sensitive domains
|
|
154
161
|
function setupXMLHttpRequestInterceptor(domainsToNotPropagateHeaderTo, domainsToPropagateHeadersTo = []) {
|
|
162
|
+
const originalOpen = XMLHttpRequest.prototype.open;
|
|
155
163
|
const originalSend = XMLHttpRequest.prototype.send;
|
|
156
164
|
const sessionId = getOrSetSessionId();
|
|
165
|
+
// Combine default and passed ignore domains
|
|
157
166
|
const combinedIgnoreDomains = [
|
|
158
167
|
...DOMAINS_TO_NOT_PROPAGATE_HEADER_TO_DEFAULT,
|
|
159
168
|
...domainsToNotPropagateHeaderTo,
|
|
160
169
|
];
|
|
170
|
+
// Store URL during open()
|
|
171
|
+
XMLHttpRequest.prototype.open = function (method, url, ...args) {
|
|
172
|
+
// Ensure the URL is a string, otherwise handle gracefully
|
|
173
|
+
if (typeof url === "string" && url.length > 0) {
|
|
174
|
+
this._requestUrl = url; // Capture the valid URL
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.warn("Invalid or non-string URL passed to XMLHttpRequest:", url);
|
|
178
|
+
this._requestUrl = null; // Handle invalid or non-string URL
|
|
179
|
+
}
|
|
180
|
+
return originalOpen.apply(this, [method, url, ...args]);
|
|
181
|
+
};
|
|
182
|
+
// Intercept send()
|
|
161
183
|
XMLHttpRequest.prototype.send = function (...args) {
|
|
162
|
-
const url = this.
|
|
163
|
-
//
|
|
164
|
-
|
|
184
|
+
const url = this._requestUrl;
|
|
185
|
+
// If no valid URL was captured, proceed without modification
|
|
186
|
+
if (!url) {
|
|
187
|
+
return originalSend.apply(this, args);
|
|
188
|
+
}
|
|
189
|
+
// Bypass logic for domains listed in the combinedIgnoreDomains
|
|
190
|
+
if (matchUrlWithWildcard(url, combinedIgnoreDomains)) {
|
|
191
|
+
return originalSend.apply(this, args);
|
|
192
|
+
}
|
|
193
|
+
// Check if the domain should propagate headers
|
|
165
194
|
const shouldPropagateHeader = domainsToPropagateHeadersTo.length === 0 ||
|
|
166
195
|
matchUrlWithWildcard(url, domainsToPropagateHeadersTo);
|
|
167
|
-
if (sessionId && shouldPropagateHeader
|
|
196
|
+
if (sessionId && shouldPropagateHeader) {
|
|
168
197
|
this.setRequestHeader("X-Sf3-Rid", sessionId);
|
|
169
198
|
}
|
|
170
|
-
originalSend.apply(this, args);
|
|
199
|
+
return originalSend.apply(this, args);
|
|
171
200
|
};
|
|
172
201
|
}
|
|
173
|
-
// Updated fetch interceptor
|
|
202
|
+
// Updated fetch interceptor to bypass for CORS-sensitive domains
|
|
174
203
|
function setupFetchInterceptor(domainsToNotPropagateHeaderTo, domainsToPropagateHeadersTo = []) {
|
|
175
204
|
const originalFetch = window.fetch;
|
|
176
205
|
const sessionId = getOrSetSessionId();
|
|
@@ -181,22 +210,35 @@ function setupFetchInterceptor(domainsToNotPropagateHeaderTo, domainsToPropagate
|
|
|
181
210
|
];
|
|
182
211
|
window.fetch = function (input, init) {
|
|
183
212
|
let url;
|
|
213
|
+
// Handle different types of `input` for fetch
|
|
184
214
|
if (typeof input === "string") {
|
|
215
|
+
// String URL
|
|
185
216
|
url = input;
|
|
186
217
|
}
|
|
187
218
|
else if (input instanceof Request) {
|
|
219
|
+
// Request object (we extract the URL)
|
|
188
220
|
url = input.url;
|
|
189
221
|
}
|
|
222
|
+
else if (input instanceof URL) {
|
|
223
|
+
// URL object
|
|
224
|
+
url = input.href;
|
|
225
|
+
}
|
|
190
226
|
else {
|
|
227
|
+
// Unsupported input type, skip interception
|
|
228
|
+
console.warn("Unsupported input type for fetch:", input);
|
|
191
229
|
return originalFetch.apply(this, arguments);
|
|
192
230
|
}
|
|
193
|
-
//
|
|
194
|
-
|
|
231
|
+
// Bypass logic for domains listed in the combinedIgnoreDomains
|
|
232
|
+
if (matchUrlWithWildcard(url, combinedIgnoreDomains)) {
|
|
233
|
+
return originalFetch.apply(this, arguments);
|
|
234
|
+
}
|
|
235
|
+
// Check if the domain should propagate headers
|
|
195
236
|
const shouldPropagateHeader = domainsToPropagateHeadersTo.length === 0 ||
|
|
196
237
|
matchUrlWithWildcard(url, domainsToPropagateHeadersTo);
|
|
197
238
|
// Proceed with fetch if header should propagate and not be excluded
|
|
198
|
-
if (sessionId && shouldPropagateHeader
|
|
239
|
+
if (sessionId && shouldPropagateHeader) {
|
|
199
240
|
if (input instanceof Request) {
|
|
241
|
+
// If input is a Request, clone it and modify the headers
|
|
200
242
|
const clonedRequest = input.clone();
|
|
201
243
|
const newHeaders = new Headers(clonedRequest.headers);
|
|
202
244
|
newHeaders.set("X-Sf3-Rid", sessionId);
|
|
@@ -206,6 +248,7 @@ function setupFetchInterceptor(domainsToNotPropagateHeaderTo, domainsToPropagate
|
|
|
206
248
|
return originalFetch.call(this, modifiedRequest);
|
|
207
249
|
}
|
|
208
250
|
else {
|
|
251
|
+
// For string or URL input, modify init to add headers
|
|
209
252
|
const modifiedInit = { ...init };
|
|
210
253
|
const newHeaders = new Headers(init?.headers || {});
|
|
211
254
|
newHeaders.set("X-Sf3-Rid", sessionId);
|
|
@@ -214,12 +257,12 @@ function setupFetchInterceptor(domainsToNotPropagateHeaderTo, domainsToPropagate
|
|
|
214
257
|
}
|
|
215
258
|
}
|
|
216
259
|
else {
|
|
260
|
+
// No header propagation required, proceed with original fetch
|
|
217
261
|
return originalFetch.apply(this, arguments);
|
|
218
262
|
}
|
|
219
263
|
};
|
|
220
264
|
}
|
|
221
265
|
// Main Recording Function
|
|
222
|
-
// Main Recording Function
|
|
223
266
|
export async function startRecording({ apiKey, backendApi, domainsToPropagateHeaderTo = [], domainsToNotPropagateHeaderTo = [], }) {
|
|
224
267
|
let sessionId = getOrSetSessionId();
|
|
225
268
|
storeCredentialsAndConnection({ apiKey, backendApi });
|