@rogatio/cli 6.21.0 → 6.21.1
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/node/index.js +148 -96
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -2318,18 +2318,19 @@ import { isAbsolute as isAbsolute3 } from "node:path";
|
|
|
2318
2318
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
2319
2319
|
import { existsSync as existsSync2 } from "node:fs";
|
|
2320
2320
|
import { join as join6 } from "node:path";
|
|
2321
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2321
2322
|
import { lookup as dnsLookup2 } from "node:dns/promises";
|
|
2322
2323
|
import {
|
|
2323
2324
|
createServer as createServer2
|
|
2324
2325
|
} from "node:http";
|
|
2325
2326
|
import { connect } from "node:net";
|
|
2326
2327
|
import { Worker } from "node:worker_threads";
|
|
2328
|
+
import { randomBytes } from "node:crypto";
|
|
2327
2329
|
import { lookup as dnsLookup } from "node:dns/promises";
|
|
2328
2330
|
import { request as httpRequest2 } from "node:http";
|
|
2329
2331
|
import { request as httpsRequest } from "node:https";
|
|
2330
|
-
import { createHash as createHash2, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2332
|
+
import { createHash as createHash2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
2331
2333
|
import { spawn as spawn4 } from "node:child_process";
|
|
2332
|
-
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
2333
2334
|
import { createHash as createHash3 } from "node:crypto";
|
|
2334
2335
|
import { createHash as createHash4 } from "node:crypto";
|
|
2335
2336
|
var __create = Object.create;
|
|
@@ -25024,6 +25025,74 @@ async function sourceMatchesWithinDeadline(source, url) {
|
|
|
25024
25025
|
function matchUrlCapturesWithinDeadline(urlRegex, url) {
|
|
25025
25026
|
return runRegexExec(url, urlRegex, RUNTIME_LIMITS.maxRegexDeadlineMs);
|
|
25026
25027
|
}
|
|
25028
|
+
async function readMockFile(root, logicalPath, signal) {
|
|
25029
|
+
return readConfinedPathBytes(root, logicalPath, signal);
|
|
25030
|
+
}
|
|
25031
|
+
function mintToken() {
|
|
25032
|
+
return randomBytes(32).toString("hex");
|
|
25033
|
+
}
|
|
25034
|
+
function headerName(name) {
|
|
25035
|
+
return name.toLowerCase();
|
|
25036
|
+
}
|
|
25037
|
+
function waitForDelay(delayMs, signal) {
|
|
25038
|
+
if (signal?.aborted) return Promise.resolve(failure("runtime.timeout"));
|
|
25039
|
+
if (delayMs === void 0 || delayMs <= 0) {
|
|
25040
|
+
return Promise.resolve({ ok: true, value: void 0 });
|
|
25041
|
+
}
|
|
25042
|
+
return new Promise((resolve12) => {
|
|
25043
|
+
const onAbort = () => {
|
|
25044
|
+
clearTimeout(timer);
|
|
25045
|
+
resolve12(failure("runtime.timeout"));
|
|
25046
|
+
};
|
|
25047
|
+
const timer = setTimeout(() => {
|
|
25048
|
+
signal?.removeEventListener("abort", onAbort);
|
|
25049
|
+
resolve12({ ok: true, value: void 0 });
|
|
25050
|
+
}, delayMs);
|
|
25051
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
25052
|
+
});
|
|
25053
|
+
}
|
|
25054
|
+
async function renderMockResponse(options) {
|
|
25055
|
+
const { mock, fileRoot, method, signal } = options;
|
|
25056
|
+
const waited = await waitForDelay(mock.delayMs, signal);
|
|
25057
|
+
if (!waited.ok) return waited;
|
|
25058
|
+
let fullBytes;
|
|
25059
|
+
if (mock.body !== void 0) {
|
|
25060
|
+
fullBytes = new TextEncoder().encode(mock.body);
|
|
25061
|
+
} else if (mock.file !== void 0) {
|
|
25062
|
+
if (fileRoot === void 0) return failure("runtime.file-denied");
|
|
25063
|
+
if (!isConfinedFileSupported()) {
|
|
25064
|
+
return failure("runtime.platform-unsupported");
|
|
25065
|
+
}
|
|
25066
|
+
const read2 = await readMockFile(fileRoot, mock.file, signal);
|
|
25067
|
+
if (!read2.ok) return read2;
|
|
25068
|
+
fullBytes = read2.value;
|
|
25069
|
+
} else {
|
|
25070
|
+
return failure("runtime.file-denied");
|
|
25071
|
+
}
|
|
25072
|
+
const headers = [];
|
|
25073
|
+
let hasContentType = false;
|
|
25074
|
+
let hasCacheControl = false;
|
|
25075
|
+
for (const header of mock.headers ?? []) {
|
|
25076
|
+
const name = headerName(header.name);
|
|
25077
|
+
if (name === "content-length") continue;
|
|
25078
|
+
if (name === "content-type") hasContentType = true;
|
|
25079
|
+
if (name === "cache-control") hasCacheControl = true;
|
|
25080
|
+
headers.push([header.name, header.value]);
|
|
25081
|
+
}
|
|
25082
|
+
if (!hasContentType) {
|
|
25083
|
+
headers.push(["Content-Type", "application/octet-stream"]);
|
|
25084
|
+
}
|
|
25085
|
+
headers.push(["Content-Length", String(fullBytes.byteLength)]);
|
|
25086
|
+
if (!hasCacheControl) headers.push(["Cache-Control", "no-store"]);
|
|
25087
|
+
return {
|
|
25088
|
+
ok: true,
|
|
25089
|
+
value: {
|
|
25090
|
+
status: mock.status,
|
|
25091
|
+
headers,
|
|
25092
|
+
bodyBytes: method === "HEAD" ? new Uint8Array() : fullBytes
|
|
25093
|
+
}
|
|
25094
|
+
};
|
|
25095
|
+
}
|
|
25027
25096
|
var MOCK_LISTENER_PREFIX = "/.rogatio/mock/";
|
|
25028
25097
|
function isSingleSegment(value) {
|
|
25029
25098
|
return value.length > 0 && value.length <= 2048 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\") && !value.includes("?") && !hasControl(value);
|
|
@@ -25402,6 +25471,9 @@ async function fetchAndRewriteAuthorizedResponse(operation, action, options = {}
|
|
|
25402
25471
|
};
|
|
25403
25472
|
}
|
|
25404
25473
|
var RESPONSE_BODY_LISTENER_PREFIX = "/.rogatio/body/";
|
|
25474
|
+
function isSingleSegment2(value) {
|
|
25475
|
+
return value.length > 0 && value.length <= 2048 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\") && !value.includes("?") && !hasControl(value);
|
|
25476
|
+
}
|
|
25405
25477
|
function parseResponseBodyRedirect(rawUrl) {
|
|
25406
25478
|
const queryAt = rawUrl.indexOf("?");
|
|
25407
25479
|
const path2 = queryAt === -1 ? rawUrl : rawUrl.slice(0, queryAt);
|
|
@@ -25412,18 +25484,24 @@ function parseResponseBodyRedirect(rawUrl) {
|
|
|
25412
25484
|
if (slash1 <= 0) return null;
|
|
25413
25485
|
const slash2 = rest.indexOf("/", slash1 + 1);
|
|
25414
25486
|
if (slash2 <= slash1 + 1) return null;
|
|
25487
|
+
const slash3 = rest.indexOf("/", slash2 + 1);
|
|
25488
|
+
if (slash3 <= slash2 + 1) return null;
|
|
25489
|
+
let token;
|
|
25415
25490
|
let ruleId;
|
|
25416
25491
|
let digest;
|
|
25417
25492
|
try {
|
|
25418
|
-
|
|
25419
|
-
|
|
25493
|
+
token = decodeURIComponent(rest.slice(0, slash1));
|
|
25494
|
+
ruleId = decodeURIComponent(rest.slice(slash1 + 1, slash2));
|
|
25495
|
+
digest = decodeURIComponent(rest.slice(slash2 + 1, slash3));
|
|
25420
25496
|
} catch {
|
|
25421
25497
|
return null;
|
|
25422
25498
|
}
|
|
25423
|
-
if (
|
|
25424
|
-
|
|
25499
|
+
if (!isSingleSegment2(token) || !isSingleSegment2(ruleId) || !isSingleSegment2(digest)) {
|
|
25500
|
+
return null;
|
|
25501
|
+
}
|
|
25502
|
+
const original = rest.slice(slash3 + 1) + search;
|
|
25425
25503
|
if (!/^https?:\/\//i.test(original)) return null;
|
|
25426
|
-
return { ruleId, digest, originalUrl: original };
|
|
25504
|
+
return { token, ruleId, digest, originalUrl: original };
|
|
25427
25505
|
}
|
|
25428
25506
|
function originOf(value) {
|
|
25429
25507
|
const direct = normalizeSiteOrigin(value);
|
|
@@ -25492,8 +25570,12 @@ async function revalidateAuthority(project, operations, request) {
|
|
|
25492
25570
|
}
|
|
25493
25571
|
}
|
|
25494
25572
|
if (matcher.resourceTypes.length > 0) {
|
|
25495
|
-
const
|
|
25496
|
-
if (
|
|
25573
|
+
const supplied = request.resourceType;
|
|
25574
|
+
if (supplied === void 0) {
|
|
25575
|
+
if (operation.kind !== "response-body") {
|
|
25576
|
+
return { allowed: false, reason: "resource-type-unauthorized" };
|
|
25577
|
+
}
|
|
25578
|
+
} else if (typeof supplied !== "string" || !matcher.resourceTypes.includes(supplied)) {
|
|
25497
25579
|
return { allowed: false, reason: "resource-type-unauthorized" };
|
|
25498
25580
|
}
|
|
25499
25581
|
}
|
|
@@ -25504,6 +25586,24 @@ async function revalidateAuthority(project, operations, request) {
|
|
|
25504
25586
|
operation
|
|
25505
25587
|
};
|
|
25506
25588
|
}
|
|
25589
|
+
var PROXY_DOCUMENT_CSP = "sandbox; default-src 'none'; script-src 'none'; connect-src 'none'; form-action 'none'; frame-src 'none'";
|
|
25590
|
+
var DROPPED_DOCUMENT_HEADERS = /* @__PURE__ */ new Set([
|
|
25591
|
+
"content-security-policy",
|
|
25592
|
+
"content-security-policy-report-only",
|
|
25593
|
+
"x-content-type-options"
|
|
25594
|
+
]);
|
|
25595
|
+
function sameToken(supplied, expected) {
|
|
25596
|
+
const left = Buffer.from(supplied);
|
|
25597
|
+
const right = Buffer.from(expected);
|
|
25598
|
+
if (left.byteLength !== right.byteLength) return false;
|
|
25599
|
+
return timingSafeEqual(left, right);
|
|
25600
|
+
}
|
|
25601
|
+
function proxyDocumentHeaders() {
|
|
25602
|
+
return [
|
|
25603
|
+
["content-security-policy", PROXY_DOCUMENT_CSP],
|
|
25604
|
+
["x-content-type-options", "nosniff"]
|
|
25605
|
+
];
|
|
25606
|
+
}
|
|
25507
25607
|
function isBodyOp(op) {
|
|
25508
25608
|
return op.kind === "request-body" || op.kind === "response-body";
|
|
25509
25609
|
}
|
|
@@ -25906,6 +26006,8 @@ async function authorizeOp(policy, op, url, method, headers) {
|
|
|
25906
26006
|
return decision.allowed;
|
|
25907
26007
|
}
|
|
25908
26008
|
async function startInterceptProxy(options = {}) {
|
|
26009
|
+
const responseBodyToken = mintToken();
|
|
26010
|
+
const outbound = options.outbound;
|
|
25909
26011
|
let policy = options.policy ?? null;
|
|
25910
26012
|
const serveMock = options.serveMock;
|
|
25911
26013
|
const resolver = options.resolver ?? defaultResolver2;
|
|
@@ -26126,10 +26228,11 @@ async function startInterceptProxy(options = {}) {
|
|
|
26126
26228
|
endEmpty(res, status);
|
|
26127
26229
|
return;
|
|
26128
26230
|
}
|
|
26129
|
-
|
|
26130
|
-
|
|
26131
|
-
rendered.value.headers.map(([name, value]) => [name, value])
|
|
26231
|
+
const mockHeaders = rendered.value.headers.flatMap(
|
|
26232
|
+
([name, value]) => DROPPED_DOCUMENT_HEADERS.has(name.toLowerCase()) ? [] : [[name, value]]
|
|
26132
26233
|
);
|
|
26234
|
+
mockHeaders.push(...proxyDocumentHeaders());
|
|
26235
|
+
res.writeHead(rendered.value.status, mockHeaders);
|
|
26133
26236
|
res.end(Buffer.from(rendered.value.bodyBytes));
|
|
26134
26237
|
} catch {
|
|
26135
26238
|
endEmpty(res, 502);
|
|
@@ -26146,9 +26249,19 @@ async function startInterceptProxy(options = {}) {
|
|
|
26146
26249
|
return;
|
|
26147
26250
|
}
|
|
26148
26251
|
const parsed = parseResponseBodyRedirect(rawUrl);
|
|
26252
|
+
if (parsed === null) {
|
|
26253
|
+
res.writeHead(400);
|
|
26254
|
+
res.end();
|
|
26255
|
+
return;
|
|
26256
|
+
}
|
|
26257
|
+
if (!sameToken(parsed.token, responseBodyToken)) {
|
|
26258
|
+
res.writeHead(403);
|
|
26259
|
+
res.end();
|
|
26260
|
+
return;
|
|
26261
|
+
}
|
|
26149
26262
|
const active = policy;
|
|
26150
|
-
if (
|
|
26151
|
-
res.writeHead(
|
|
26263
|
+
if (active === null || active.presetDigest === void 0) {
|
|
26264
|
+
res.writeHead(403);
|
|
26152
26265
|
res.end();
|
|
26153
26266
|
return;
|
|
26154
26267
|
}
|
|
@@ -26189,8 +26302,7 @@ async function startInterceptProxy(options = {}) {
|
|
|
26189
26302
|
url: parsed.originalUrl,
|
|
26190
26303
|
target,
|
|
26191
26304
|
method: "GET",
|
|
26192
|
-
initiator: initiatorFromHeaders(req.headers, parsed.originalUrl) ?? new URL(target).origin
|
|
26193
|
-
resourceType: operation.matcher.resourceTypes[0]
|
|
26305
|
+
initiator: initiatorFromHeaders(req.headers, parsed.originalUrl) ?? new URL(target).origin
|
|
26194
26306
|
}
|
|
26195
26307
|
);
|
|
26196
26308
|
if (!allowed.allowed) {
|
|
@@ -26209,7 +26321,8 @@ async function startInterceptProxy(options = {}) {
|
|
|
26209
26321
|
sourceValue: operation.matcher.source.value,
|
|
26210
26322
|
presetDigest
|
|
26211
26323
|
},
|
|
26212
|
-
operation.responseBody
|
|
26324
|
+
operation.responseBody,
|
|
26325
|
+
outbound ?? {}
|
|
26213
26326
|
);
|
|
26214
26327
|
if (!fetched.ok) {
|
|
26215
26328
|
res.writeHead(502);
|
|
@@ -26219,7 +26332,7 @@ async function startInterceptProxy(options = {}) {
|
|
|
26219
26332
|
const headers = {};
|
|
26220
26333
|
for (const [name, value] of fetched.value.headers) {
|
|
26221
26334
|
const lower = name.toLowerCase();
|
|
26222
|
-
if (lower === "set-cookie" || lower === "cookie" || lower === "authorization" || lower === "proxy-authorization") {
|
|
26335
|
+
if (lower === "set-cookie" || lower === "cookie" || lower === "authorization" || lower === "proxy-authorization" || DROPPED_DOCUMENT_HEADERS.has(lower)) {
|
|
26223
26336
|
continue;
|
|
26224
26337
|
}
|
|
26225
26338
|
const existing = headers[lower];
|
|
@@ -26227,6 +26340,9 @@ async function startInterceptProxy(options = {}) {
|
|
|
26227
26340
|
else if (Array.isArray(existing)) existing.push(value);
|
|
26228
26341
|
else headers[lower] = [existing, value];
|
|
26229
26342
|
}
|
|
26343
|
+
for (const [name, value] of proxyDocumentHeaders()) {
|
|
26344
|
+
headers[name] = value;
|
|
26345
|
+
}
|
|
26230
26346
|
writeResponse(
|
|
26231
26347
|
res,
|
|
26232
26348
|
fetched.value.status,
|
|
@@ -26296,6 +26412,7 @@ async function startInterceptProxy(options = {}) {
|
|
|
26296
26412
|
});
|
|
26297
26413
|
return {
|
|
26298
26414
|
endpoint,
|
|
26415
|
+
responseBodyToken,
|
|
26299
26416
|
setPolicy(next) {
|
|
26300
26417
|
policy = next;
|
|
26301
26418
|
},
|
|
@@ -26462,7 +26579,7 @@ function createPlatformInterceptionProvider(adapter) {
|
|
|
26462
26579
|
var TOKEN_BYTES = 32;
|
|
26463
26580
|
var TOKEN_LENGTH = 43;
|
|
26464
26581
|
function createCapabilityState(preset, now) {
|
|
26465
|
-
const bootstrap =
|
|
26582
|
+
const bootstrap = randomBytes2(TOKEN_BYTES).toString("base64url");
|
|
26466
26583
|
return {
|
|
26467
26584
|
presetDigest: preset.digest,
|
|
26468
26585
|
bootstrap,
|
|
@@ -26485,15 +26602,15 @@ function isToken(value) {
|
|
|
26485
26602
|
return false;
|
|
26486
26603
|
}
|
|
26487
26604
|
}
|
|
26488
|
-
function
|
|
26605
|
+
function sameToken2(value, expectedDigest) {
|
|
26489
26606
|
const actual = digestToken(value);
|
|
26490
|
-
return actual.length === expectedDigest.length &&
|
|
26607
|
+
return actual.length === expectedDigest.length && timingSafeEqual2(actual, expectedDigest);
|
|
26491
26608
|
}
|
|
26492
26609
|
function sameDigest(value, expected) {
|
|
26493
26610
|
if (!isSha256Digest(value) || value.length !== expected.length) return false;
|
|
26494
26611
|
const actual = Buffer.from(value, "ascii");
|
|
26495
26612
|
const wanted = Buffer.from(expected, "ascii");
|
|
26496
|
-
return
|
|
26613
|
+
return timingSafeEqual2(actual, wanted);
|
|
26497
26614
|
}
|
|
26498
26615
|
function cleanSessions(state, now) {
|
|
26499
26616
|
for (let index = state.sessions.length - 1; index >= 0; index -= 1) {
|
|
@@ -26503,14 +26620,14 @@ function cleanSessions(state, now) {
|
|
|
26503
26620
|
}
|
|
26504
26621
|
function pairCapability(state, capability, digest, now) {
|
|
26505
26622
|
cleanSessions(state, now);
|
|
26506
|
-
if (state.closed || state.consumed || !isToken(capability) || typeof digest !== "string" || !sameDigest(digest, state.presetDigest) || now >= state.bootstrapExpiresAt || !
|
|
26623
|
+
if (state.closed || state.consumed || !isToken(capability) || typeof digest !== "string" || !sameDigest(digest, state.presetDigest) || now >= state.bootstrapExpiresAt || !sameToken2(capability, state.bootstrapDigest)) {
|
|
26507
26624
|
return failure("runtime.pairing-denied");
|
|
26508
26625
|
}
|
|
26509
26626
|
if (state.sessions.length >= RUNTIME_LIMITS.maxConcurrentSessions) {
|
|
26510
26627
|
return failure("runtime.overloaded");
|
|
26511
26628
|
}
|
|
26512
26629
|
state.consumed = true;
|
|
26513
|
-
const sessionCapability =
|
|
26630
|
+
const sessionCapability = randomBytes2(TOKEN_BYTES).toString("base64url");
|
|
26514
26631
|
const expiresAt = now + RUNTIME_LIMITS.sessionLifetimeMs;
|
|
26515
26632
|
state.sessions.push({
|
|
26516
26633
|
digest: Buffer.from(state.presetDigest, "ascii"),
|
|
@@ -26533,7 +26650,7 @@ function findSession(state, capability, digest, now) {
|
|
|
26533
26650
|
if (!sameDigest(digest, state.presetDigest)) return null;
|
|
26534
26651
|
const candidate = digestToken(capability);
|
|
26535
26652
|
for (const session of state.sessions) {
|
|
26536
|
-
if (candidate.length === session.tokenDigest.length &&
|
|
26653
|
+
if (candidate.length === session.tokenDigest.length && timingSafeEqual2(candidate, session.tokenDigest) && sameDigest(digest, session.digest.toString("ascii"))) {
|
|
26537
26654
|
return session;
|
|
26538
26655
|
}
|
|
26539
26656
|
}
|
|
@@ -26649,74 +26766,6 @@ async function pickDirectory(run = runDialog, platform = process.platform) {
|
|
|
26649
26766
|
}
|
|
26650
26767
|
return { ok: false, code: "runtime.picker-unavailable" };
|
|
26651
26768
|
}
|
|
26652
|
-
async function readMockFile(root, logicalPath, signal) {
|
|
26653
|
-
return readConfinedPathBytes(root, logicalPath, signal);
|
|
26654
|
-
}
|
|
26655
|
-
function mintToken() {
|
|
26656
|
-
return randomBytes2(32).toString("hex");
|
|
26657
|
-
}
|
|
26658
|
-
function headerName(name) {
|
|
26659
|
-
return name.toLowerCase();
|
|
26660
|
-
}
|
|
26661
|
-
function waitForDelay(delayMs, signal) {
|
|
26662
|
-
if (signal?.aborted) return Promise.resolve(failure("runtime.timeout"));
|
|
26663
|
-
if (delayMs === void 0 || delayMs <= 0) {
|
|
26664
|
-
return Promise.resolve({ ok: true, value: void 0 });
|
|
26665
|
-
}
|
|
26666
|
-
return new Promise((resolve12) => {
|
|
26667
|
-
const onAbort = () => {
|
|
26668
|
-
clearTimeout(timer);
|
|
26669
|
-
resolve12(failure("runtime.timeout"));
|
|
26670
|
-
};
|
|
26671
|
-
const timer = setTimeout(() => {
|
|
26672
|
-
signal?.removeEventListener("abort", onAbort);
|
|
26673
|
-
resolve12({ ok: true, value: void 0 });
|
|
26674
|
-
}, delayMs);
|
|
26675
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
26676
|
-
});
|
|
26677
|
-
}
|
|
26678
|
-
async function renderMockResponse(options) {
|
|
26679
|
-
const { mock, fileRoot, method, signal } = options;
|
|
26680
|
-
const waited = await waitForDelay(mock.delayMs, signal);
|
|
26681
|
-
if (!waited.ok) return waited;
|
|
26682
|
-
let fullBytes;
|
|
26683
|
-
if (mock.body !== void 0) {
|
|
26684
|
-
fullBytes = new TextEncoder().encode(mock.body);
|
|
26685
|
-
} else if (mock.file !== void 0) {
|
|
26686
|
-
if (fileRoot === void 0) return failure("runtime.file-denied");
|
|
26687
|
-
if (!isConfinedFileSupported()) {
|
|
26688
|
-
return failure("runtime.platform-unsupported");
|
|
26689
|
-
}
|
|
26690
|
-
const read2 = await readMockFile(fileRoot, mock.file, signal);
|
|
26691
|
-
if (!read2.ok) return read2;
|
|
26692
|
-
fullBytes = read2.value;
|
|
26693
|
-
} else {
|
|
26694
|
-
return failure("runtime.file-denied");
|
|
26695
|
-
}
|
|
26696
|
-
const headers = [];
|
|
26697
|
-
let hasContentType = false;
|
|
26698
|
-
let hasCacheControl = false;
|
|
26699
|
-
for (const header of mock.headers ?? []) {
|
|
26700
|
-
const name = headerName(header.name);
|
|
26701
|
-
if (name === "content-length") continue;
|
|
26702
|
-
if (name === "content-type") hasContentType = true;
|
|
26703
|
-
if (name === "cache-control") hasCacheControl = true;
|
|
26704
|
-
headers.push([header.name, header.value]);
|
|
26705
|
-
}
|
|
26706
|
-
if (!hasContentType) {
|
|
26707
|
-
headers.push(["Content-Type", "application/octet-stream"]);
|
|
26708
|
-
}
|
|
26709
|
-
headers.push(["Content-Length", String(fullBytes.byteLength)]);
|
|
26710
|
-
if (!hasCacheControl) headers.push(["Cache-Control", "no-store"]);
|
|
26711
|
-
return {
|
|
26712
|
-
ok: true,
|
|
26713
|
-
value: {
|
|
26714
|
-
status: mock.status,
|
|
26715
|
-
headers,
|
|
26716
|
-
bodyBytes: method === "HEAD" ? new Uint8Array() : fullBytes
|
|
26717
|
-
}
|
|
26718
|
-
};
|
|
26719
|
-
}
|
|
26720
26769
|
var MAX_MOCK_FILE_ERRORS = 64;
|
|
26721
26770
|
var FILE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
26722
26771
|
"runtime.file-denied",
|
|
@@ -28171,7 +28220,10 @@ function createNativeHost(options) {
|
|
|
28171
28220
|
signal: request.signal
|
|
28172
28221
|
})
|
|
28173
28222
|
});
|
|
28174
|
-
return
|
|
28223
|
+
return {
|
|
28224
|
+
...interceptProxy.endpoint,
|
|
28225
|
+
responseBodyToken: interceptProxy.responseBodyToken
|
|
28226
|
+
};
|
|
28175
28227
|
},
|
|
28176
28228
|
async stopTlsProxy() {
|
|
28177
28229
|
if (interceptProxy) {
|
|
@@ -29792,7 +29844,7 @@ function createServer3(handler, options = {}) {
|
|
|
29792
29844
|
}
|
|
29793
29845
|
|
|
29794
29846
|
// packages/cli/src/server/routes.ts
|
|
29795
|
-
import { randomBytes as randomBytes4, timingSafeEqual as
|
|
29847
|
+
import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
|
|
29796
29848
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
29797
29849
|
import { dirname as dirname9, isAbsolute as isAbsolute5, resolve as resolve5 } from "node:path";
|
|
29798
29850
|
|
|
@@ -30261,7 +30313,7 @@ function tokensEqual(provided, expected) {
|
|
|
30261
30313
|
const providedBytes = Buffer.from(provided);
|
|
30262
30314
|
const expectedBytes = Buffer.from(expected);
|
|
30263
30315
|
if (providedBytes.length !== expectedBytes.length) return false;
|
|
30264
|
-
return
|
|
30316
|
+
return timingSafeEqual3(providedBytes, expectedBytes);
|
|
30265
30317
|
}
|
|
30266
30318
|
function scopedPathname(pathname, sessionToken) {
|
|
30267
30319
|
const marker = "/e/";
|
package/package.json
CHANGED