opencode-secrets-obfuscation 0.1.5 → 0.1.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/README.md +1 -1
- package/package.json +1 -1
- package/plugin.mjs +11 -52
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ This plugin keeps configured dotenv values private and substitutes opaque secret
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
-
Install with: opencode plugin add opencode-secrets-obfuscation@0.1.
|
|
13
|
+
Install with: opencode plugin add opencode-secrets-obfuscation@0.1.7
|
|
14
14
|
|
|
15
15
|
Configure the published package in opencode.jsonc with the options documented at https://github.com/jfomhhover/opencode-secrets-obfuscation/blob/main/INSTALL.md.
|
|
16
16
|
|
package/package.json
CHANGED
package/plugin.mjs
CHANGED
|
@@ -3359,7 +3359,6 @@ function verifyCeilingBytes(patterns) {
|
|
|
3359
3359
|
var WITHHELD = "SANITIZATION_UNAVAILABLE";
|
|
3360
3360
|
var encoder2 = new TextEncoder();
|
|
3361
3361
|
var decoder = new TextDecoder();
|
|
3362
|
-
var AUTH_CHANNEL = /* @__PURE__ */ new Set(["authorization", "api-key", "x-api-key", "proxy-authorization"]);
|
|
3363
3362
|
var NULL_BODY_STATUS = /* @__PURE__ */ new Set([101, 204, 205, 304]);
|
|
3364
3363
|
var hasSecrets = (state) => state.patterns.length > 0;
|
|
3365
3364
|
function redactNode(current, depth, state, counters) {
|
|
@@ -3419,30 +3418,6 @@ function containsSecret(value, state) {
|
|
|
3419
3418
|
if (!hasSecrets(state)) return false;
|
|
3420
3419
|
return scanForSecrets(value, state.patterns, state.budget) !== "clean";
|
|
3421
3420
|
}
|
|
3422
|
-
function redactHeaders(headers, state, options2) {
|
|
3423
|
-
if (!hasSecrets(state)) return;
|
|
3424
|
-
for (const name of Object.keys(headers)) {
|
|
3425
|
-
if (options2.skipAuth && AUTH_CHANNEL.has(name.toLowerCase())) continue;
|
|
3426
|
-
const value = headers[name];
|
|
3427
|
-
if (typeof value !== "string") {
|
|
3428
|
-
if (options2.strict) return "withheld";
|
|
3429
|
-
delete headers[name];
|
|
3430
|
-
continue;
|
|
3431
|
-
}
|
|
3432
|
-
const safeValue = redactString(value, state);
|
|
3433
|
-
const safeName = redactString(name, state);
|
|
3434
|
-
if (safeValue === null || safeName === null) {
|
|
3435
|
-
if (options2.strict) return "withheld";
|
|
3436
|
-
delete headers[name];
|
|
3437
|
-
continue;
|
|
3438
|
-
}
|
|
3439
|
-
if (safeValue !== value) headers[name] = safeValue;
|
|
3440
|
-
if (safeName !== name) {
|
|
3441
|
-
delete headers[name];
|
|
3442
|
-
headers[safeName] = safeValue;
|
|
3443
|
-
}
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
3421
|
function redactBody(text, state) {
|
|
3447
3422
|
if (!hasSecrets(state)) return text;
|
|
3448
3423
|
if (scanForSecrets(text, state.patterns, state.budget) === "clean") return text;
|
|
@@ -3511,12 +3486,6 @@ async function redactRequest(request, state) {
|
|
|
3511
3486
|
const verifyCeiling = verifyCeilingBytes(state.patterns);
|
|
3512
3487
|
const declared = Number(request.headers.get("content-length") ?? Number.NaN);
|
|
3513
3488
|
if (Number.isFinite(declared) && declared > verifyCeiling) return "withheld";
|
|
3514
|
-
const record = {};
|
|
3515
|
-
request.headers.forEach((value, name) => {
|
|
3516
|
-
record[name] = value;
|
|
3517
|
-
});
|
|
3518
|
-
const originalHeaders = { ...record };
|
|
3519
|
-
if (redactHeaders(record, state, { skipAuth: true, strict: true }) === "withheld") return "withheld";
|
|
3520
3489
|
let body;
|
|
3521
3490
|
if (request.body !== null) {
|
|
3522
3491
|
const read = await readBoundedBody(request.clone().body, verifyCeiling);
|
|
@@ -3529,34 +3498,25 @@ async function redactRequest(request, state) {
|
|
|
3529
3498
|
if (safe !== read.text) body = safe;
|
|
3530
3499
|
}
|
|
3531
3500
|
}
|
|
3532
|
-
|
|
3533
|
-
if (body === void 0 && !headersChanged) return request;
|
|
3534
|
-
if (body !== void 0) {
|
|
3535
|
-
delete record["content-length"];
|
|
3536
|
-
record["content-length"] = String(encoder2.encode(body).byteLength);
|
|
3537
|
-
}
|
|
3501
|
+
if (body === void 0) return request;
|
|
3538
3502
|
try {
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
signal: request.signal
|
|
3503
|
+
const headers = {};
|
|
3504
|
+
request.headers.forEach((value, name) => {
|
|
3505
|
+
headers[name] = value;
|
|
3543
3506
|
});
|
|
3507
|
+
headers["content-length"] = String(encoder2.encode(body).byteLength);
|
|
3508
|
+
return new Request(request, { headers, body, signal: request.signal });
|
|
3544
3509
|
} catch {
|
|
3545
3510
|
return "withheld";
|
|
3546
3511
|
}
|
|
3547
3512
|
}
|
|
3548
3513
|
async function redactResponse(response2, state) {
|
|
3549
3514
|
if (!hasSecrets(state)) return response2;
|
|
3550
|
-
const headers = {};
|
|
3551
|
-
response2.headers.forEach((value, name) => {
|
|
3552
|
-
headers[name] = value;
|
|
3553
|
-
});
|
|
3554
|
-
redactHeaders(headers, state, { skipAuth: false, strict: false });
|
|
3555
3515
|
const status = response2.status;
|
|
3556
3516
|
const nullBody = NULL_BODY_STATUS.has(status);
|
|
3557
3517
|
if (nullBody) {
|
|
3558
3518
|
try {
|
|
3559
|
-
return new Response(null, { status, headers });
|
|
3519
|
+
return new Response(null, { status, headers: response2.headers });
|
|
3560
3520
|
} catch {
|
|
3561
3521
|
return new Response(null, { status: 502 });
|
|
3562
3522
|
}
|
|
@@ -3565,7 +3525,7 @@ async function redactResponse(response2, state) {
|
|
|
3565
3525
|
const declared = Number(response2.headers.get("content-length") ?? Number.NaN);
|
|
3566
3526
|
if (Number.isFinite(declared) && declared > verifyCeiling) {
|
|
3567
3527
|
try {
|
|
3568
|
-
return new Response(null, { status, headers });
|
|
3528
|
+
return new Response(null, { status, headers: response2.headers });
|
|
3569
3529
|
} catch {
|
|
3570
3530
|
return new Response(null, { status: 502 });
|
|
3571
3531
|
}
|
|
@@ -3573,7 +3533,7 @@ async function redactResponse(response2, state) {
|
|
|
3573
3533
|
const read = await readBoundedBody(response2.clone().body, verifyCeiling);
|
|
3574
3534
|
if (read === null) {
|
|
3575
3535
|
try {
|
|
3576
|
-
return new Response(null, { status, headers });
|
|
3536
|
+
return new Response(null, { status, headers: response2.headers });
|
|
3577
3537
|
} catch {
|
|
3578
3538
|
return new Response(null, { status: 502 });
|
|
3579
3539
|
}
|
|
@@ -3581,14 +3541,14 @@ async function redactResponse(response2, state) {
|
|
|
3581
3541
|
let body;
|
|
3582
3542
|
if (read.bytes > state.maxInputBytes) {
|
|
3583
3543
|
body = scanForSecrets(read.text, state.patterns, state.budget) === "clean" ? read.text : "";
|
|
3584
|
-
} else if ((headers
|
|
3544
|
+
} else if ((response2.headers.get("content-type") ?? "").toLowerCase().includes("text/event-stream")) {
|
|
3585
3545
|
body = redactEventStream(read.text, state) ?? "";
|
|
3586
3546
|
} else {
|
|
3587
3547
|
const safe = redactBody(read.text, state);
|
|
3588
3548
|
body = safe === null ? "" : safe;
|
|
3589
3549
|
}
|
|
3590
3550
|
try {
|
|
3591
|
-
return new Response(body, { status, headers });
|
|
3551
|
+
return new Response(body, { status, headers: response2.headers });
|
|
3592
3552
|
} catch {
|
|
3593
3553
|
return new Response(null, { status: 502 });
|
|
3594
3554
|
}
|
|
@@ -3771,7 +3731,6 @@ var realRuntimeFactory = (options2, location) => {
|
|
|
3771
3731
|
}),
|
|
3772
3732
|
modelRequest: (event) => Effect4.gen(function* () {
|
|
3773
3733
|
if (!hasSecrets(filter)) return;
|
|
3774
|
-
if (redactHeaders(event.headers, filter, { skipAuth: true, strict: true }) === "withheld") yield* Effect4.die(new Error(WITHHELD));
|
|
3775
3734
|
if (event.baseURL !== void 0) event.baseURL = redactString(event.baseURL, filter) ?? WITHHELD;
|
|
3776
3735
|
}),
|
|
3777
3736
|
httpRequest: (event) => Effect4.promise(async () => {
|