@replayio-app-building/netlify-recorder 0.20.0 → 0.22.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/index.d.ts +0 -18
- package/dist/index.js +15 -21
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -205,24 +205,6 @@ interface CreateRecordingRequestHandlerOptions extends FinishRequestOptions {
|
|
|
205
205
|
*/
|
|
206
206
|
declare function createRecordingRequestHandler(handler: (event: NetlifyEvent | NetlifyV2Request, context?: unknown) => Promise<HandlerResponse>, options: CreateRecordingRequestHandlerOptions): (event: NetlifyEvent | NetlifyV2Request, context?: unknown) => Promise<HandlerResponse>;
|
|
207
207
|
|
|
208
|
-
/**
|
|
209
|
-
* Redacts sensitive environment variable values from blob data.
|
|
210
|
-
*
|
|
211
|
-
* This function performs two passes:
|
|
212
|
-
*
|
|
213
|
-
* Pass 1 — Redact env reads:
|
|
214
|
-
* For each captured EnvRead whose value should be redacted,
|
|
215
|
-
* replace the value with a "*"-repeated string of the same length.
|
|
216
|
-
*
|
|
217
|
-
* Pass 2 — Scrub the rest of the blob:
|
|
218
|
-
* Any redacted value that appears elsewhere in the blob data
|
|
219
|
-
* (network call headers, bodies, request info headers/body) is
|
|
220
|
-
* also replaced with the same mask. This prevents secrets from
|
|
221
|
-
* leaking through, e.g., an Authorization header that embeds
|
|
222
|
-
* an API key captured via process.env.
|
|
223
|
-
*
|
|
224
|
-
* The function returns a new BlobData object; the input is not mutated.
|
|
225
|
-
*/
|
|
226
208
|
declare function redactBlobData(blobData: BlobData): BlobData;
|
|
227
209
|
|
|
228
210
|
interface RecordingResult {
|
package/dist/index.js
CHANGED
|
@@ -417,25 +417,28 @@ function shouldRedact(key, value) {
|
|
|
417
417
|
if (value === void 0 || value.length <= 8) return false;
|
|
418
418
|
return true;
|
|
419
419
|
}
|
|
420
|
-
function replaceAll(text, searchValue,
|
|
421
|
-
return text.split(searchValue).join(
|
|
420
|
+
function replaceAll(text, searchValue, replacement) {
|
|
421
|
+
return text.split(searchValue).join(replacement);
|
|
422
422
|
}
|
|
423
|
-
function
|
|
424
|
-
|
|
423
|
+
function buildPlaceholder(key) {
|
|
424
|
+
if (key === "DATABASE_URL" || key.endsWith("_DATABASE_URL")) {
|
|
425
|
+
return "postgresql://replay:replay@localhost:5432/replay";
|
|
426
|
+
}
|
|
427
|
+
return `placeholder_${key.toLowerCase()}`;
|
|
425
428
|
}
|
|
426
429
|
function redactBlobData(blobData) {
|
|
427
|
-
const
|
|
430
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
428
431
|
const redactedEnvReads = blobData.capturedData.envReads.map(
|
|
429
432
|
(read) => {
|
|
430
433
|
if (shouldRedact(read.key, read.value) && read.value !== void 0) {
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
return { ...read, value:
|
|
434
|
+
const placeholder = buildPlaceholder(read.key);
|
|
435
|
+
replacements.set(read.value, placeholder);
|
|
436
|
+
return { ...read, value: placeholder };
|
|
434
437
|
}
|
|
435
438
|
return { ...read };
|
|
436
439
|
}
|
|
437
440
|
);
|
|
438
|
-
if (
|
|
441
|
+
if (replacements.size === 0) {
|
|
439
442
|
return {
|
|
440
443
|
...blobData,
|
|
441
444
|
capturedData: {
|
|
@@ -444,14 +447,14 @@ function redactBlobData(blobData) {
|
|
|
444
447
|
}
|
|
445
448
|
};
|
|
446
449
|
}
|
|
447
|
-
const
|
|
450
|
+
const sorted = [...replacements.entries()].sort(
|
|
448
451
|
(a, b) => b[0].length - a[0].length
|
|
449
452
|
);
|
|
450
453
|
function scrub(text) {
|
|
451
454
|
if (text === void 0) return void 0;
|
|
452
455
|
let result = text;
|
|
453
|
-
for (const [original,
|
|
454
|
-
result = replaceAll(result, original,
|
|
456
|
+
for (const [original, placeholder] of sorted) {
|
|
457
|
+
result = replaceAll(result, original, placeholder);
|
|
455
458
|
}
|
|
456
459
|
return result;
|
|
457
460
|
}
|
|
@@ -617,15 +620,6 @@ async function createRequestRecording(blobUrlOrData, handlerPath, requestInfo) {
|
|
|
617
620
|
} else {
|
|
618
621
|
blobData = blobUrlOrData;
|
|
619
622
|
}
|
|
620
|
-
for (const read of blobData.capturedData.envReads) {
|
|
621
|
-
if (read.value && read.value.length > 8 && /^\*+$/.test(read.value)) {
|
|
622
|
-
if (read.key === "DATABASE_URL" || read.key.endsWith("_DATABASE_URL")) {
|
|
623
|
-
read.value = "postgresql://replay:replay@localhost:5432/replay";
|
|
624
|
-
} else {
|
|
625
|
-
read.value = `placeholder_${read.key.toLowerCase()}`;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
623
|
const networkHandle = installNetworkInterceptor(
|
|
630
624
|
"replay",
|
|
631
625
|
blobData.capturedData.networkCalls
|