apitestcenter 0.7.0 → 0.8.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/THIRD-PARTY-NOTICES-UI.txt +1 -1
- package/dist/THIRD-PARTY-NOTICES.txt +1 -1
- package/dist/cli.mjs +949 -352
- package/dist/ui/404/index.html +1 -1
- package/dist/ui/404.html +1 -1
- package/dist/ui/__next.__PAGE__.txt +9 -9
- package/dist/ui/__next._full.txt +10 -10
- package/dist/ui/__next._tree.txt +1 -1
- package/dist/ui/_next/static/chunks/0e1nwxi9i1ag7.js +1 -0
- package/dist/ui/_next/static/chunks/{0txpfp028djv6.js → 11nxnz4doxir5.js} +64 -64
- package/dist/ui/_next/static/chunks/2xls_z5abvl-5.js +1 -0
- package/dist/ui/_not-found/__next._full.txt +9 -9
- package/dist/ui/_not-found/__next._not-found.__PAGE__.txt +8 -8
- package/dist/ui/_not-found/__next._tree.txt +1 -1
- package/dist/ui/_not-found/index.html +1 -1
- package/dist/ui/_not-found/index.txt +9 -9
- package/dist/ui/compare/__next._full.txt +10 -10
- package/dist/ui/compare/__next._tree.txt +1 -1
- package/dist/ui/compare/__next.compare.__PAGE__.txt +9 -9
- package/dist/ui/compare/index.html +1 -1
- package/dist/ui/compare/index.txt +10 -10
- package/dist/ui/history/__next._full.txt +11 -11
- package/dist/ui/history/__next._tree.txt +1 -1
- package/dist/ui/history/__next.history.__PAGE__.txt +10 -10
- package/dist/ui/history/index.html +1 -1
- package/dist/ui/history/index.txt +11 -11
- package/dist/ui/index.html +1 -1
- package/dist/ui/index.txt +10 -10
- package/dist/ui/preview/__next._full.txt +11 -11
- package/dist/ui/preview/__next._tree.txt +1 -1
- package/dist/ui/preview/__next.preview.__PAGE__.txt +10 -10
- package/dist/ui/preview/index.html +1 -1
- package/dist/ui/preview/index.txt +11 -11
- package/dist/ui/suite/__next._full.txt +10 -10
- package/dist/ui/suite/__next._tree.txt +1 -1
- package/dist/ui/suite/__next.suite.__PAGE__.txt +9 -9
- package/dist/ui/suite/index.html +1 -1
- package/dist/ui/suite/index.txt +10 -10
- package/dist/ui/tests/__next._full.txt +9 -9
- package/dist/ui/tests/__next._tree.txt +1 -1
- package/dist/ui/tests/__next.tests.__PAGE__.txt +8 -8
- package/dist/ui/tests/index.html +1 -1
- package/dist/ui/tests/index.txt +9 -9
- package/package.json +1 -1
- package/dist/ui/_next/static/chunks/0kfr8kv4cj_kv.js +0 -1
- package/dist/ui/_next/static/chunks/1w_q4qvvuinj2.js +0 -1
- /package/dist/ui/_next/static/{lBYayPKoT6YJhgfHFuw6O → BJz1RrA7HqZwUV22DBTCg}/_buildManifest.js +0 -0
- /package/dist/ui/_next/static/{lBYayPKoT6YJhgfHFuw6O → BJz1RrA7HqZwUV22DBTCg}/_clientMiddlewareManifest.js +0 -0
- /package/dist/ui/_next/static/{lBYayPKoT6YJhgfHFuw6O → BJz1RrA7HqZwUV22DBTCg}/_ssgManifest.js +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -804,14 +804,41 @@ function safeSegment(text, fallback = "untitled") {
|
|
|
804
804
|
return s || fallback;
|
|
805
805
|
}
|
|
806
806
|
function defaultOAuth() {
|
|
807
|
-
return {
|
|
807
|
+
return {
|
|
808
|
+
grant: "client_credentials",
|
|
809
|
+
tokenUrl: "",
|
|
810
|
+
authUrl: "",
|
|
811
|
+
redirectUri: DEFAULT_REDIRECT_URI,
|
|
812
|
+
clientId: "",
|
|
813
|
+
clientSecret: "",
|
|
814
|
+
scope: "",
|
|
815
|
+
username: "",
|
|
816
|
+
password: "",
|
|
817
|
+
clientAuth: "basic",
|
|
818
|
+
pkce: true,
|
|
819
|
+
extra: [],
|
|
820
|
+
privateKey: "",
|
|
821
|
+
assertionAlgorithm: "RS256",
|
|
822
|
+
issuer: "",
|
|
823
|
+
subject: "",
|
|
824
|
+
audience: "",
|
|
825
|
+
kid: "",
|
|
826
|
+
certificate: "",
|
|
827
|
+
extraClaims: "",
|
|
828
|
+
samlSource: "idp",
|
|
829
|
+
idpUrl: "",
|
|
830
|
+
userId: "",
|
|
831
|
+
companyId: "",
|
|
832
|
+
assertion: ""
|
|
833
|
+
};
|
|
808
834
|
}
|
|
809
835
|
function oauthFromUnknown(value) {
|
|
810
836
|
const base = defaultOAuth();
|
|
811
837
|
if (!value || typeof value !== "object") return base;
|
|
812
838
|
const v = value;
|
|
813
839
|
const s = (x, d) => typeof x === "string" ? x : d;
|
|
814
|
-
const grants = ["client_credentials", "password", "authorization_code"];
|
|
840
|
+
const grants = ["client_credentials", "password", "authorization_code", "jwt_bearer", "saml_bearer"];
|
|
841
|
+
const algs = ["RS256", "RS384", "RS512", "PS256", "ES256", "ES384"];
|
|
815
842
|
return {
|
|
816
843
|
grant: grants.includes(v.grant) ? v.grant : base.grant,
|
|
817
844
|
tokenUrl: s(v.tokenUrl, ""),
|
|
@@ -822,8 +849,21 @@ function oauthFromUnknown(value) {
|
|
|
822
849
|
scope: s(v.scope, ""),
|
|
823
850
|
username: s(v.username, ""),
|
|
824
851
|
password: s(v.password, ""),
|
|
825
|
-
clientAuth: v.clientAuth === "body" ? "body" : "basic",
|
|
852
|
+
clientAuth: v.clientAuth === "body" ? "body" : v.clientAuth === "private_key_jwt" ? "private_key_jwt" : "basic",
|
|
826
853
|
pkce: v.pkce !== false,
|
|
854
|
+
privateKey: s(v.privateKey, ""),
|
|
855
|
+
assertionAlgorithm: algs.includes(v.assertionAlgorithm) ? v.assertionAlgorithm : "RS256",
|
|
856
|
+
issuer: s(v.issuer, ""),
|
|
857
|
+
subject: s(v.subject, ""),
|
|
858
|
+
audience: s(v.audience, ""),
|
|
859
|
+
kid: s(v.kid, ""),
|
|
860
|
+
certificate: s(v.certificate, ""),
|
|
861
|
+
extraClaims: s(v.extraClaims, ""),
|
|
862
|
+
samlSource: v.samlSource === "assertion" ? "assertion" : "idp",
|
|
863
|
+
idpUrl: s(v.idpUrl, ""),
|
|
864
|
+
userId: s(v.userId, ""),
|
|
865
|
+
companyId: s(v.companyId, ""),
|
|
866
|
+
assertion: s(v.assertion, ""),
|
|
827
867
|
extra: (Array.isArray(v.extra) ? v.extra : []).flatMap((e) => e && typeof e.key === "string" ? [{ key: e.key, value: s(e.value, "") }] : [])
|
|
828
868
|
};
|
|
829
869
|
}
|
|
@@ -858,9 +898,28 @@ function jwtFromUnknown(value) {
|
|
|
858
898
|
prefix: s(v.prefix, base.prefix)
|
|
859
899
|
};
|
|
860
900
|
}
|
|
901
|
+
function defaultOAuth1() {
|
|
902
|
+
return { consumerKey: "", consumerSecret: "", token: "", tokenSecret: "", signatureMethod: "HMAC-SHA256", realm: "", addTo: "header" };
|
|
903
|
+
}
|
|
904
|
+
function oauth1FromUnknown(value) {
|
|
905
|
+
const base = defaultOAuth1();
|
|
906
|
+
if (!value || typeof value !== "object") return base;
|
|
907
|
+
const v = value;
|
|
908
|
+
const s = (x, d) => typeof x === "string" ? x : d;
|
|
909
|
+
const methods = ["HMAC-SHA256", "HMAC-SHA1", "PLAINTEXT"];
|
|
910
|
+
return {
|
|
911
|
+
consumerKey: s(v.consumerKey, ""),
|
|
912
|
+
consumerSecret: s(v.consumerSecret, ""),
|
|
913
|
+
token: s(v.token, ""),
|
|
914
|
+
tokenSecret: s(v.tokenSecret, ""),
|
|
915
|
+
signatureMethod: methods.includes(v.signatureMethod) ? v.signatureMethod : base.signatureMethod,
|
|
916
|
+
realm: s(v.realm, ""),
|
|
917
|
+
addTo: v.addTo === "query" ? "query" : "header"
|
|
918
|
+
};
|
|
919
|
+
}
|
|
861
920
|
function emptyFolderSettings() {
|
|
862
921
|
return {
|
|
863
|
-
auth: { authMode: "inherit", oauth: defaultOAuth(), aws: defaultAws(), jwt: defaultJwt(), domain: "", token: "", username: "", password: "", apiName: "X-API-Key", apiValue: "", apiIn: "header" },
|
|
922
|
+
auth: { authMode: "inherit", oauth: defaultOAuth(), oauth1: defaultOAuth1(), aws: defaultAws(), jwt: defaultJwt(), domain: "", token: "", username: "", password: "", apiName: "X-API-Key", apiValue: "", apiIn: "header" },
|
|
864
923
|
headers: [],
|
|
865
924
|
variables: []
|
|
866
925
|
};
|
|
@@ -871,7 +930,7 @@ function folderFromUnknown(value) {
|
|
|
871
930
|
const v = value;
|
|
872
931
|
const a = v.auth ?? {};
|
|
873
932
|
const s = (x, d) => typeof x === "string" ? x : d;
|
|
874
|
-
const modes = ["inherit", "none", "bearer", "basic", "api_key", "oauth2", "digest", "ntlm", "aws_sigv4", "jwt"];
|
|
933
|
+
const modes = ["inherit", "none", "bearer", "basic", "api_key", "oauth2", "digest", "ntlm", "aws_sigv4", "jwt", "oauth1"];
|
|
875
934
|
const authMode2 = modes.includes(a.authMode) ? a.authMode : "inherit";
|
|
876
935
|
const headers = (Array.isArray(v.headers) ? v.headers : []).flatMap(
|
|
877
936
|
(h) => h && typeof h.key === "string" ? [{ key: h.key, value: s(h.value, "") }] : []
|
|
@@ -881,6 +940,7 @@ function folderFromUnknown(value) {
|
|
|
881
940
|
auth: {
|
|
882
941
|
authMode: authMode2,
|
|
883
942
|
oauth: oauthFromUnknown(a.oauth),
|
|
943
|
+
oauth1: oauth1FromUnknown(a.oauth1),
|
|
884
944
|
aws: awsFromUnknown(a.aws),
|
|
885
945
|
jwt: jwtFromUnknown(a.jwt),
|
|
886
946
|
domain: s(a.domain, ""),
|
|
@@ -917,7 +977,7 @@ var init_workspace = __esm({
|
|
|
917
977
|
FOLDER_FILE = "_folder.json";
|
|
918
978
|
MAX_FOLDER_DEPTH = 6;
|
|
919
979
|
DEFAULT_REDIRECT_URI = "http://127.0.0.1:53682/callback";
|
|
920
|
-
NESTED_SECRET_FIELDS = { oauth: ["clientSecret", "password"], aws: ["secretAccessKey", "sessionToken"], jwt: ["secret", "privateKey"] };
|
|
980
|
+
NESTED_SECRET_FIELDS = { oauth: ["clientSecret", "password", "privateKey", "assertion"], aws: ["secretAccessKey", "sessionToken"], jwt: ["secret", "privateKey"], oauth1: ["consumerSecret", "tokenSecret"] };
|
|
921
981
|
}
|
|
922
982
|
});
|
|
923
983
|
|
|
@@ -16307,18 +16367,18 @@ var init_definition = __esm({
|
|
|
16307
16367
|
thinkTimeMs: external_exports.number().min(0).default(0),
|
|
16308
16368
|
thinkJitterMs: external_exports.number().min(0).default(0),
|
|
16309
16369
|
gracefulStop: durationSchema.default("10s")
|
|
16310
|
-
}).strict().superRefine((
|
|
16311
|
-
if ((
|
|
16370
|
+
}).strict().superRefine((load3, ctx) => {
|
|
16371
|
+
if ((load3.executor === "ramping-vus" || load3.executor === "ramping-arrival-rate") && load3.stages.length === 0) {
|
|
16312
16372
|
ctx.addIssue({
|
|
16313
16373
|
code: external_exports.ZodIssueCode.custom,
|
|
16314
|
-
message: `${
|
|
16374
|
+
message: `${load3.executor} requires at least one stage`,
|
|
16315
16375
|
path: ["stages"]
|
|
16316
16376
|
});
|
|
16317
16377
|
}
|
|
16318
|
-
if (
|
|
16378
|
+
if (load3.executor === "constant-arrival-rate" && !load3.rate) {
|
|
16319
16379
|
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "constant-arrival-rate needs a rate", path: ["rate"] });
|
|
16320
16380
|
}
|
|
16321
|
-
if (!isArrivalRate(
|
|
16381
|
+
if (!isArrivalRate(load3.executor) && load3.stages.some((s) => s.target > 500)) {
|
|
16322
16382
|
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, message: "A stage can use at most 500 virtual users", path: ["stages"] });
|
|
16323
16383
|
}
|
|
16324
16384
|
});
|
|
@@ -16341,9 +16401,11 @@ var init_definition = __esm({
|
|
|
16341
16401
|
maxRedirects: external_exports.number().int().min(0).max(20).default(5),
|
|
16342
16402
|
httpVersion: external_exports.enum(["1.1", "2"]).default("1.1"),
|
|
16343
16403
|
tlsSkipVerify: external_exports.boolean().default(false),
|
|
16344
|
-
connectionReuse: external_exports.boolean().default(true)
|
|
16404
|
+
connectionReuse: external_exports.boolean().default(true),
|
|
16405
|
+
/** Send cookies from the jar and keep the ones the API sets (like a browser). */
|
|
16406
|
+
cookies: external_exports.boolean().default(true)
|
|
16345
16407
|
}).strict();
|
|
16346
|
-
oauthGrants = ["client_credentials", "password", "authorization_code"];
|
|
16408
|
+
oauthGrants = ["client_credentials", "password", "authorization_code", "jwt_bearer", "saml_bearer"];
|
|
16347
16409
|
oauthConfigSchema = external_exports.object({
|
|
16348
16410
|
grant: external_exports.enum(oauthGrants),
|
|
16349
16411
|
tokenUrl: external_exports.string().url(),
|
|
@@ -16355,7 +16417,25 @@ var init_definition = __esm({
|
|
|
16355
16417
|
username: external_exports.string().default(""),
|
|
16356
16418
|
password: external_exports.string().default(""),
|
|
16357
16419
|
/** How the client id and secret go to the token endpoint. */
|
|
16358
|
-
|
|
16420
|
+
/** basic / body: the client secret; private_key_jwt: a JWT signed with the private key (client assertion). */
|
|
16421
|
+
clientAuth: external_exports.enum(["basic", "body", "private_key_jwt"]).default("basic"),
|
|
16422
|
+
// Signed assertions (JWT bearer grant, client assertion).
|
|
16423
|
+
privateKey: external_exports.string().default(""),
|
|
16424
|
+
assertionAlgorithm: external_exports.enum(["RS256", "RS384", "RS512", "PS256", "ES256", "ES384"]).default("RS256"),
|
|
16425
|
+
issuer: external_exports.string().default(""),
|
|
16426
|
+
subject: external_exports.string().default(""),
|
|
16427
|
+
audience: external_exports.string().default(""),
|
|
16428
|
+
kid: external_exports.string().default(""),
|
|
16429
|
+
/** The certificate (PEM) of the key: its thumbprint goes in the JWT header (x5t), as Azure AD wants. */
|
|
16430
|
+
certificate: external_exports.string().default(""),
|
|
16431
|
+
/** More claims for the JWT bearer assertion, as JSON. */
|
|
16432
|
+
extraClaims: external_exports.string().default(""),
|
|
16433
|
+
// SAML 2.0 bearer (SAP SuccessFactors).
|
|
16434
|
+
samlSource: external_exports.enum(["idp", "assertion"]).default("idp"),
|
|
16435
|
+
idpUrl: external_exports.string().default(""),
|
|
16436
|
+
userId: external_exports.string().default(""),
|
|
16437
|
+
companyId: external_exports.string().default(""),
|
|
16438
|
+
assertion: external_exports.string().default(""),
|
|
16359
16439
|
pkce: external_exports.boolean().default(true),
|
|
16360
16440
|
/** Extra token-request fields, e.g. audience or resource. */
|
|
16361
16441
|
extra: external_exports.array(keyValueSchema).max(20).default([])
|
|
@@ -16376,6 +16456,17 @@ var init_definition = __esm({
|
|
|
16376
16456
|
headerName: external_exports.string().min(1).default("Authorization"),
|
|
16377
16457
|
prefix: external_exports.string().default("Bearer")
|
|
16378
16458
|
}).strict(),
|
|
16459
|
+
// OAuth 1.0 (RFC 5849): every request signed with the consumer and token secrets (NetSuite TBA…).
|
|
16460
|
+
external_exports.object({
|
|
16461
|
+
mode: external_exports.literal("oauth1"),
|
|
16462
|
+
consumerKey: external_exports.string().min(1),
|
|
16463
|
+
consumerSecret: external_exports.string(),
|
|
16464
|
+
token: external_exports.string().default(""),
|
|
16465
|
+
tokenSecret: external_exports.string().default(""),
|
|
16466
|
+
signatureMethod: external_exports.enum(["HMAC-SHA256", "HMAC-SHA1", "PLAINTEXT"]).default("HMAC-SHA256"),
|
|
16467
|
+
realm: external_exports.string().default(""),
|
|
16468
|
+
addTo: external_exports.enum(["header", "query"]).default("header")
|
|
16469
|
+
}).strict(),
|
|
16379
16470
|
// AWS Signature Version 4: every request is signed (API Gateway, S3, Lambda function URLs…).
|
|
16380
16471
|
external_exports.object({
|
|
16381
16472
|
mode: external_exports.literal("aws_sigv4"),
|
|
@@ -24010,6 +24101,7 @@ function defaultRequestDraft() {
|
|
|
24010
24101
|
bodyText: "",
|
|
24011
24102
|
authMode: "inherit",
|
|
24012
24103
|
oauth: defaultOAuth(),
|
|
24104
|
+
oauth1: defaultOAuth1(),
|
|
24013
24105
|
aws: defaultAws(),
|
|
24014
24106
|
jwt: defaultJwt(),
|
|
24015
24107
|
domain: "",
|
|
@@ -24022,6 +24114,7 @@ function defaultRequestDraft() {
|
|
|
24022
24114
|
timeout: "60s",
|
|
24023
24115
|
maxRedirects: 5,
|
|
24024
24116
|
connectionReuse: true,
|
|
24117
|
+
useCookies: true,
|
|
24025
24118
|
tlsSkip: false,
|
|
24026
24119
|
checks: [],
|
|
24027
24120
|
before: null,
|
|
@@ -24065,7 +24158,7 @@ function requestFromUnknown(value) {
|
|
|
24065
24158
|
if (!value || typeof value !== "object") return base;
|
|
24066
24159
|
const item = value;
|
|
24067
24160
|
const bodyMode = item.bodyMode === "json" || item.bodyMode === "text" ? item.bodyMode : "none";
|
|
24068
|
-
const authMode2 = item.authMode === "bearer" || item.authMode === "basic" || item.authMode === "api_key" || item.authMode === "inherit" || item.authMode === "oauth2" || item.authMode === "digest" || item.authMode === "ntlm" || item.authMode === "aws_sigv4" || item.authMode === "jwt" ? item.authMode : item.authMode === void 0 ? "inherit" : "none";
|
|
24161
|
+
const authMode2 = item.authMode === "bearer" || item.authMode === "basic" || item.authMode === "api_key" || item.authMode === "inherit" || item.authMode === "oauth2" || item.authMode === "digest" || item.authMode === "ntlm" || item.authMode === "aws_sigv4" || item.authMode === "jwt" || item.authMode === "oauth1" ? item.authMode : item.authMode === void 0 ? "inherit" : "none";
|
|
24069
24162
|
return {
|
|
24070
24163
|
method: METHODS.includes(item.method) ? item.method : "GET",
|
|
24071
24164
|
url: str(item.url, ""),
|
|
@@ -24077,6 +24170,7 @@ function requestFromUnknown(value) {
|
|
|
24077
24170
|
bodyText: str(item.bodyText, ""),
|
|
24078
24171
|
authMode: authMode2,
|
|
24079
24172
|
oauth: oauthFromUnknown(item.oauth),
|
|
24173
|
+
oauth1: oauth1FromUnknown(item.oauth1),
|
|
24080
24174
|
aws: awsFromUnknown(item.aws),
|
|
24081
24175
|
jwt: jwtFromUnknown(item.jwt),
|
|
24082
24176
|
domain: str(item.domain, ""),
|
|
@@ -24089,6 +24183,7 @@ function requestFromUnknown(value) {
|
|
|
24089
24183
|
timeout: str(item.timeout, base.timeout),
|
|
24090
24184
|
maxRedirects: num(item.maxRedirects, base.maxRedirects),
|
|
24091
24185
|
connectionReuse: item.connectionReuse !== false,
|
|
24186
|
+
useCookies: item.useCookies !== false,
|
|
24092
24187
|
tlsSkip: item.tlsSkip === true,
|
|
24093
24188
|
checks: checksFrom(item.checks),
|
|
24094
24189
|
before: beforeFrom(item.before),
|
|
@@ -24099,12 +24194,12 @@ function requestFromUnknown(value) {
|
|
|
24099
24194
|
})
|
|
24100
24195
|
};
|
|
24101
24196
|
}
|
|
24102
|
-
function applyPreset(
|
|
24103
|
-
if (preset === "custom") return { ...
|
|
24104
|
-
return { preset, mode: "users", rps:
|
|
24197
|
+
function applyPreset(load3, preset) {
|
|
24198
|
+
if (preset === "custom") return { ...load3, preset };
|
|
24199
|
+
return { preset, mode: "users", rps: load3.rps, maxVus: load3.maxVus, stages: null, ...LOAD_KNOB_PRESETS[preset] };
|
|
24105
24200
|
}
|
|
24106
|
-
function toLoadConfig(
|
|
24107
|
-
const { preset: _preset, ...knobs } =
|
|
24201
|
+
function toLoadConfig(load3) {
|
|
24202
|
+
const { preset: _preset, ...knobs } = load3;
|
|
24108
24203
|
return loadFromLabKnobs(knobs);
|
|
24109
24204
|
}
|
|
24110
24205
|
function withUrl(draft, value) {
|
|
@@ -24119,12 +24214,12 @@ function hasBody(method) {
|
|
|
24119
24214
|
function draftRuntimeNames(draft) {
|
|
24120
24215
|
return runtimeVariableNames({ setup: draft.before, data: draft.testData });
|
|
24121
24216
|
}
|
|
24122
|
-
function buildPayload(draft,
|
|
24217
|
+
function buildPayload(draft, load3, name, targets) {
|
|
24123
24218
|
const parts = requestParts(draft);
|
|
24124
24219
|
return {
|
|
24125
24220
|
name: name.slice(0, 120),
|
|
24126
24221
|
...parts,
|
|
24127
|
-
load:
|
|
24222
|
+
load: load3,
|
|
24128
24223
|
targets,
|
|
24129
24224
|
setup: void 0,
|
|
24130
24225
|
data: draft.testData && draft.testData.rows.length ? draft.testData : void 0,
|
|
@@ -24178,6 +24273,11 @@ function requestParts(draft) {
|
|
|
24178
24273
|
if (!a.accessKeyId.trim() || !a.secretAccessKey) throw new Error("AWS signing needs the access key ID and the secret access key");
|
|
24179
24274
|
if (!a.region.trim() || !a.service.trim()) throw new Error("AWS signing needs the region (like eu-west-1) and the service (like execute-api or s3)");
|
|
24180
24275
|
auth = { mode: "aws_sigv4", accessKeyId: a.accessKeyId.trim(), secretAccessKey: a.secretAccessKey, sessionToken: a.sessionToken.trim(), region: a.region.trim(), service: a.service.trim() };
|
|
24276
|
+
} else if (draft.authMode === "oauth1") {
|
|
24277
|
+
const o = draft.oauth1;
|
|
24278
|
+
if (!o.consumerKey.trim()) throw new Error("OAuth 1.0 needs the consumer key");
|
|
24279
|
+
if (o.token.trim() && !o.tokenSecret) throw new Error("OAuth 1.0: the token needs its token secret");
|
|
24280
|
+
auth = { mode: "oauth1", consumerKey: o.consumerKey.trim(), consumerSecret: o.consumerSecret, token: o.token.trim(), tokenSecret: o.tokenSecret, signatureMethod: o.signatureMethod, realm: o.realm.trim(), addTo: o.addTo };
|
|
24181
24281
|
} else if (draft.authMode === "jwt") {
|
|
24182
24282
|
const j = draft.jwt;
|
|
24183
24283
|
const hmac3 = j.algorithm.startsWith("HS");
|
|
@@ -24219,7 +24319,8 @@ function requestParts(draft) {
|
|
|
24219
24319
|
maxRedirects: draft.maxRedirects,
|
|
24220
24320
|
httpVersion: "1.1",
|
|
24221
24321
|
tlsSkipVerify: draft.tlsSkip,
|
|
24222
|
-
connectionReuse: draft.connectionReuse
|
|
24322
|
+
connectionReuse: draft.connectionReuse,
|
|
24323
|
+
cookies: draft.useCookies
|
|
24223
24324
|
}
|
|
24224
24325
|
};
|
|
24225
24326
|
}
|
|
@@ -24250,22 +24351,22 @@ function durationError(value, allowZero = true) {
|
|
|
24250
24351
|
if (!allowZero && /^0+(\.0+)?(ms|s|m|h)$/.test(value.trim())) return "Must be longer than 0";
|
|
24251
24352
|
return void 0;
|
|
24252
24353
|
}
|
|
24253
|
-
function loadProblem(
|
|
24254
|
-
if (
|
|
24255
|
-
for (const [i, stage] of
|
|
24354
|
+
function loadProblem(load3) {
|
|
24355
|
+
if (load3.stages && load3.stages.length) {
|
|
24356
|
+
for (const [i, stage] of load3.stages.entries()) {
|
|
24256
24357
|
const bad = durationError(stage.duration, false);
|
|
24257
24358
|
if (bad) return `Stage ${i + 1}: ${bad}`;
|
|
24258
24359
|
if (!(stage.target >= 0)) return `Stage ${i + 1}: target must be 0 or more`;
|
|
24259
|
-
if (
|
|
24360
|
+
if (load3.mode !== "rate" && stage.target > 500) return `Stage ${i + 1}: at most 500 virtual users`;
|
|
24260
24361
|
}
|
|
24261
|
-
if (!
|
|
24262
|
-
return durationError(
|
|
24362
|
+
if (!load3.stages.some((s) => s.target > 0)) return "At least one stage needs a target above 0";
|
|
24363
|
+
return durationError(load3.gracefulStop) ?? null;
|
|
24263
24364
|
}
|
|
24264
|
-
if (
|
|
24265
|
-
if (!(
|
|
24266
|
-
if (!(
|
|
24267
|
-
} else if (!(
|
|
24268
|
-
return durationError(
|
|
24365
|
+
if (load3.mode === "rate") {
|
|
24366
|
+
if (!(load3.rps >= 1 && load3.rps <= 1e5)) return "Requests per second must be 1\u2013100,000";
|
|
24367
|
+
if (!(load3.maxVus >= 1 && load3.maxVus <= 2e3)) return "Max virtual users must be 1\u20132,000";
|
|
24368
|
+
} else if (!(load3.vus >= 1 && load3.vus <= 500)) return "Virtual users must be 1\u2013500";
|
|
24369
|
+
return durationError(load3.duration, false) ?? durationError(load3.rampUp) ?? durationError(load3.rampDown) ?? durationError(load3.gracefulStop) ?? null;
|
|
24269
24370
|
}
|
|
24270
24371
|
function applyFolders(draft, folders) {
|
|
24271
24372
|
let next = draft;
|
|
@@ -24275,7 +24376,7 @@ function applyFolders(draft, folders) {
|
|
|
24275
24376
|
const a = from?.settings.auth;
|
|
24276
24377
|
if (from && a && a.authMode !== "none") {
|
|
24277
24378
|
authFrom = from.path;
|
|
24278
|
-
next = { ...next, authMode: a.authMode, oauth: a.oauth, aws: a.aws, jwt: a.jwt, domain: a.domain, token: a.token, username: a.username, password: a.password, apiName: a.apiName, apiValue: a.apiValue, apiIn: a.apiIn };
|
|
24379
|
+
next = { ...next, authMode: a.authMode, oauth: a.oauth, oauth1: a.oauth1, aws: a.aws, jwt: a.jwt, domain: a.domain, token: a.token, username: a.username, password: a.password, apiName: a.apiName, apiValue: a.apiValue, apiIn: a.apiIn };
|
|
24279
24380
|
} else {
|
|
24280
24381
|
next = { ...next, authMode: "none" };
|
|
24281
24382
|
}
|
|
@@ -24298,6 +24399,20 @@ function oauthWire(o) {
|
|
|
24298
24399
|
throw new Error("The redirect URL must be on this computer, like http://127.0.0.1:53682/callback \u2014 add the same one in your OAuth app");
|
|
24299
24400
|
}
|
|
24300
24401
|
if (!o.clientId.trim()) throw new Error("OAuth 2.0 needs a client ID");
|
|
24402
|
+
const needsKey = o.grant === "jwt_bearer" || o.clientAuth === "private_key_jwt" || o.grant === "saml_bearer" && o.samlSource === "idp";
|
|
24403
|
+
if (needsKey && !o.privateKey.trim()) throw new Error("OAuth 2.0: this sign-in needs the private key (PEM)");
|
|
24404
|
+
if (o.grant === "jwt_bearer" && o.extraClaims.trim()) {
|
|
24405
|
+
try {
|
|
24406
|
+
const c = JSON.parse(o.extraClaims);
|
|
24407
|
+
if (!c || typeof c !== "object" || Array.isArray(c)) throw new Error("x");
|
|
24408
|
+
} catch {
|
|
24409
|
+
throw new Error("OAuth 2.0: the extra claims must be a JSON object");
|
|
24410
|
+
}
|
|
24411
|
+
}
|
|
24412
|
+
if (o.grant === "saml_bearer" && o.samlSource === "idp" && (!/^https?:\/\//i.test(o.idpUrl.trim()) || !o.userId.trim())) {
|
|
24413
|
+
throw new Error("SAML bearer needs the assertion URL (SuccessFactors: https://<api-server>/oauth/idp) and the user ID");
|
|
24414
|
+
}
|
|
24415
|
+
if (o.grant === "saml_bearer" && o.samlSource === "assertion" && !o.assertion.trim()) throw new Error("SAML bearer needs the assertion (base64)");
|
|
24301
24416
|
return {
|
|
24302
24417
|
grant: o.grant,
|
|
24303
24418
|
tokenUrl,
|
|
@@ -24310,7 +24425,20 @@ function oauthWire(o) {
|
|
|
24310
24425
|
password: o.password,
|
|
24311
24426
|
clientAuth: o.clientAuth,
|
|
24312
24427
|
pkce: o.pkce,
|
|
24313
|
-
extra: o.extra.filter((e) => e.key.trim())
|
|
24428
|
+
extra: o.extra.filter((e) => e.key.trim()),
|
|
24429
|
+
privateKey: o.privateKey.trim(),
|
|
24430
|
+
assertionAlgorithm: o.assertionAlgorithm,
|
|
24431
|
+
issuer: o.issuer.trim(),
|
|
24432
|
+
subject: o.subject.trim(),
|
|
24433
|
+
audience: o.audience.trim(),
|
|
24434
|
+
kid: o.kid.trim(),
|
|
24435
|
+
certificate: o.certificate.trim(),
|
|
24436
|
+
extraClaims: o.extraClaims.trim(),
|
|
24437
|
+
samlSource: o.samlSource,
|
|
24438
|
+
idpUrl: o.idpUrl.trim(),
|
|
24439
|
+
userId: o.userId.trim(),
|
|
24440
|
+
companyId: o.companyId.trim(),
|
|
24441
|
+
assertion: o.assertion.trim()
|
|
24314
24442
|
};
|
|
24315
24443
|
}
|
|
24316
24444
|
var METHODS, DEFAULT_LOAD, str, num, TEMPLATED, DURATION;
|
|
@@ -24340,6 +24468,7 @@ var init_draft = __esm({
|
|
|
24340
24468
|
"apiName",
|
|
24341
24469
|
"apiValue",
|
|
24342
24470
|
"oauth",
|
|
24471
|
+
"oauth1",
|
|
24343
24472
|
"aws",
|
|
24344
24473
|
"jwt",
|
|
24345
24474
|
"domain"
|
|
@@ -25189,10 +25318,10 @@ function checksRate(r) {
|
|
|
25189
25318
|
return passes + fails ? passes / (passes + fails) : null;
|
|
25190
25319
|
}
|
|
25191
25320
|
function plannedLoad(r) {
|
|
25192
|
-
const
|
|
25193
|
-
const rate =
|
|
25194
|
-
const peak = rate ?
|
|
25195
|
-
const ms3 =
|
|
25321
|
+
const load3 = r.definition.load;
|
|
25322
|
+
const rate = load3.executor.endsWith("arrival-rate");
|
|
25323
|
+
const peak = rate ? load3.rate ?? Math.max(0, ...load3.stages.map((s) => s.target)) : Math.max(0, ...load3.stages.map((s) => s.target));
|
|
25324
|
+
const ms3 = load3.stages.reduce((n, s) => n + durationToMs(s.duration), 0);
|
|
25196
25325
|
return { rate, peak, ms: ms3 };
|
|
25197
25326
|
}
|
|
25198
25327
|
function fairness(before, after) {
|
|
@@ -25473,6 +25602,83 @@ function __atcSign(method, url, headers, body) {
|
|
|
25473
25602
|
}
|
|
25474
25603
|
});
|
|
25475
25604
|
|
|
25605
|
+
// ../shared/src/oauth1.ts
|
|
25606
|
+
function pctEncode(s) {
|
|
25607
|
+
return encodeURIComponent(s).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
25608
|
+
}
|
|
25609
|
+
function decodeForm(s) {
|
|
25610
|
+
try {
|
|
25611
|
+
return decodeURIComponent(s.replace(/\+/g, " "));
|
|
25612
|
+
} catch {
|
|
25613
|
+
return s;
|
|
25614
|
+
}
|
|
25615
|
+
}
|
|
25616
|
+
function formPairs(text) {
|
|
25617
|
+
return text.replace(/^\?/, "").split("&").filter(Boolean).map((p) => {
|
|
25618
|
+
const i = p.indexOf("=");
|
|
25619
|
+
return [decodeForm(i < 0 ? p : p.slice(0, i)), decodeForm(i < 0 ? "" : p.slice(i + 1))];
|
|
25620
|
+
});
|
|
25621
|
+
}
|
|
25622
|
+
function oauth1BaseString(method, url2, params) {
|
|
25623
|
+
const m = /^(https?):\/\/([^/?#]+)([^?#]*)/i.exec(url2);
|
|
25624
|
+
if (!m) throw new Error("OAuth 1.0 needs a full http(s) address");
|
|
25625
|
+
const scheme = m[1].toLowerCase();
|
|
25626
|
+
let host2 = m[2].toLowerCase();
|
|
25627
|
+
if (scheme === "https" && host2.endsWith(":443") || scheme === "http" && host2.endsWith(":80")) host2 = host2.replace(/:\d+$/, "");
|
|
25628
|
+
const base = `${scheme}://${host2}${m[3] || "/"}`;
|
|
25629
|
+
const normalized = params.map(([k, v]) => [pctEncode(k), pctEncode(v)]).sort(([a, av], [b, bv]) => a < b ? -1 : a > b ? 1 : av < bv ? -1 : av > bv ? 1 : 0).map(([k, v]) => `${k}=${v}`).join("&");
|
|
25630
|
+
return [method.toUpperCase(), pctEncode(base), pctEncode(normalized)].join("&");
|
|
25631
|
+
}
|
|
25632
|
+
function oauth1Params(c, nonce, timestamp) {
|
|
25633
|
+
const p = [
|
|
25634
|
+
["oauth_consumer_key", c.consumerKey],
|
|
25635
|
+
["oauth_nonce", nonce],
|
|
25636
|
+
["oauth_signature_method", c.signatureMethod],
|
|
25637
|
+
["oauth_timestamp", String(timestamp)],
|
|
25638
|
+
["oauth_version", "1.0"]
|
|
25639
|
+
];
|
|
25640
|
+
if (c.token) p.push(["oauth_token", c.token]);
|
|
25641
|
+
return p;
|
|
25642
|
+
}
|
|
25643
|
+
function oauth1SigningKey(c) {
|
|
25644
|
+
return `${pctEncode(c.consumerSecret)}&${pctEncode(c.tokenSecret)}`;
|
|
25645
|
+
}
|
|
25646
|
+
function oauth1Header(c, oauth) {
|
|
25647
|
+
const parts = oauth.map(([k, v]) => `${pctEncode(k)}="${pctEncode(v)}"`);
|
|
25648
|
+
return `OAuth ${c.realm ? `realm="${c.realm.replace(/"/g, "")}", ` : ""}${parts.join(", ")}`;
|
|
25649
|
+
}
|
|
25650
|
+
var OAUTH1_JS;
|
|
25651
|
+
var init_oauth1 = __esm({
|
|
25652
|
+
"../shared/src/oauth1.ts"() {
|
|
25653
|
+
"use strict";
|
|
25654
|
+
OAUTH1_JS = `
|
|
25655
|
+
function __atcPct(s) { return encodeURIComponent(s).replace(/[!'()*]/g, function (c) { return "%" + c.charCodeAt(0).toString(16).toUpperCase(); }); }
|
|
25656
|
+
function __atcForm(t) { return t.replace(/^\\?/, "").split("&").filter(Boolean).map(function (p) { var i = p.indexOf("="); var d = function (x) { try { return decodeURIComponent(x.replace(/\\+/g, " ")); } catch (e) { return x; } }; return [d(i < 0 ? p : p.slice(0, i)), d(i < 0 ? "" : p.slice(i + 1))]; }); }
|
|
25657
|
+
function __atcOAuth1(method, url, headers, body) {
|
|
25658
|
+
var c = OAUTH1;
|
|
25659
|
+
var m = /^(https?):\\/\\/([^/?#]+)([^?#]*)(\\?[^#]*)?/i.exec(url);
|
|
25660
|
+
var scheme = m[1].toLowerCase(), host = m[2].toLowerCase();
|
|
25661
|
+
if ((scheme === "https" && /:443$/.test(host)) || (scheme === "http" && /:80$/.test(host))) host = host.replace(/:\\d+$/, "");
|
|
25662
|
+
var nonce = ""; var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
25663
|
+
for (var i = 0; i < 32; i++) nonce += abc.charAt(Math.floor(Math.random() * abc.length));
|
|
25664
|
+
var oauth = [["oauth_consumer_key", c.consumerKey], ["oauth_nonce", nonce], ["oauth_signature_method", c.signatureMethod], ["oauth_timestamp", String(Math.floor(Date.now() / 1000))], ["oauth_version", "1.0"]];
|
|
25665
|
+
if (c.token) oauth.push(["oauth_token", c.token]);
|
|
25666
|
+
var params = oauth.concat(__atcForm(m[4] || ""));
|
|
25667
|
+
var ct = ""; for (var k in headers) if (k.toLowerCase() === "content-type") ct = String(headers[k]);
|
|
25668
|
+
if (body && ct.indexOf("application/x-www-form-urlencoded") === 0) params = params.concat(__atcForm(body));
|
|
25669
|
+
var norm = params.map(function (p) { return [__atcPct(p[0]), __atcPct(p[1])]; }).sort(function (a, b) { return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0; }).map(function (p) { return p[0] + "=" + p[1]; }).join("&");
|
|
25670
|
+
var baseString = [method.toUpperCase(), __atcPct(scheme + "://" + host + (m[3] || "/")), __atcPct(norm)].join("&");
|
|
25671
|
+
var key = __atcPct(c.consumerSecret) + "&" + __atcPct(c.tokenSecret);
|
|
25672
|
+
var sig = c.signatureMethod === "PLAINTEXT" ? key : crypto.hmac(c.signatureMethod === "HMAC-SHA1" ? "sha1" : "sha256", key, baseString, "base64");
|
|
25673
|
+
oauth.push(["oauth_signature", sig]);
|
|
25674
|
+
if (c.addTo === "query") return url + (m[4] ? "&" : "?") + oauth.map(function (p) { return __atcPct(p[0]) + "=" + __atcPct(p[1]); }).join("&");
|
|
25675
|
+
headers.Authorization = "OAuth " + (c.realm ? 'realm="' + c.realm.replace(/"/g, "") + '", ' : "") + oauth.map(function (p) { return __atcPct(p[0]) + '="' + __atcPct(p[1]) + '"'; }).join(", ");
|
|
25676
|
+
return url;
|
|
25677
|
+
}
|
|
25678
|
+
`;
|
|
25679
|
+
}
|
|
25680
|
+
});
|
|
25681
|
+
|
|
25476
25682
|
// ../shared/src/export-fields.ts
|
|
25477
25683
|
function roundN(n, digits = 2) {
|
|
25478
25684
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -26429,6 +26635,7 @@ var init_src = __esm({
|
|
|
26429
26635
|
init_before_after();
|
|
26430
26636
|
init_ci_templates();
|
|
26431
26637
|
init_sigv4();
|
|
26638
|
+
init_oauth1();
|
|
26432
26639
|
init_latency_bins();
|
|
26433
26640
|
init_checks3();
|
|
26434
26641
|
init_definition();
|
|
@@ -26878,21 +27085,21 @@ function k6Thresholds(targets, hasChecks) {
|
|
|
26878
27085
|
if (hasChecks && targets.checksRate != null) out.checks = [wrap(`rate>=${targets.checksRate}`)];
|
|
26879
27086
|
return out;
|
|
26880
27087
|
}
|
|
26881
|
-
function scenarioBlock(
|
|
26882
|
-
const common = { gracefulStop:
|
|
26883
|
-
switch (
|
|
27088
|
+
function scenarioBlock(load3) {
|
|
27089
|
+
const common = { gracefulStop: load3.gracefulStop };
|
|
27090
|
+
switch (load3.executor) {
|
|
26884
27091
|
case "constant-vus":
|
|
26885
|
-
return { executor: "constant-vus", vus:
|
|
27092
|
+
return { executor: "constant-vus", vus: load3.vus, duration: load3.duration, ...common };
|
|
26886
27093
|
case "ramping-vus":
|
|
26887
|
-
return { executor: "ramping-vus", startVUs:
|
|
27094
|
+
return { executor: "ramping-vus", startVUs: load3.startVUs ?? 0, stages: load3.stages, ...common };
|
|
26888
27095
|
case "constant-arrival-rate":
|
|
26889
27096
|
return {
|
|
26890
27097
|
executor: "constant-arrival-rate",
|
|
26891
|
-
rate:
|
|
27098
|
+
rate: load3.rate,
|
|
26892
27099
|
timeUnit: "1s",
|
|
26893
|
-
duration:
|
|
26894
|
-
preAllocatedVUs:
|
|
26895
|
-
maxVUs: Math.max(
|
|
27100
|
+
duration: load3.duration,
|
|
27101
|
+
preAllocatedVUs: load3.vus,
|
|
27102
|
+
maxVUs: Math.max(load3.vus, load3.maxVUs ?? load3.vus),
|
|
26896
27103
|
...common
|
|
26897
27104
|
};
|
|
26898
27105
|
case "ramping-arrival-rate":
|
|
@@ -26900,9 +27107,9 @@ function scenarioBlock(load2) {
|
|
|
26900
27107
|
executor: "ramping-arrival-rate",
|
|
26901
27108
|
startRate: 0,
|
|
26902
27109
|
timeUnit: "1s",
|
|
26903
|
-
preAllocatedVUs:
|
|
26904
|
-
maxVUs: Math.max(
|
|
26905
|
-
stages:
|
|
27110
|
+
preAllocatedVUs: load3.vus,
|
|
27111
|
+
maxVUs: Math.max(load3.vus, load3.maxVUs ?? load3.vus),
|
|
27112
|
+
stages: load3.stages,
|
|
26906
27113
|
...common
|
|
26907
27114
|
};
|
|
26908
27115
|
}
|
|
@@ -26950,13 +27157,20 @@ function generateK6Script(run2, extra2 = {}) {
|
|
|
26950
27157
|
}
|
|
26951
27158
|
if (run2.auth.mode === "bearer") {
|
|
26952
27159
|
env.ATC_TOKEN = normalizeBearerToken(run2.auth.token);
|
|
26953
|
-
if (extra2.oauthRefresh)
|
|
27160
|
+
if (extra2.oauthRefresh) {
|
|
27161
|
+
const { bodies, ...plan } = extra2.oauthRefresh;
|
|
27162
|
+
env.ATC_OAUTH = JSON.stringify(bodies ? { ...plan, start: bodies.start, stepSec: bodies.stepSec } : plan);
|
|
27163
|
+
if (bodies) files["oauth.json"] = JSON.stringify(bodies.list);
|
|
27164
|
+
}
|
|
26954
27165
|
} else if (run2.auth.mode === "basic") {
|
|
26955
27166
|
env.ATC_BASIC_USER = run2.auth.username;
|
|
26956
27167
|
env.ATC_BASIC_PASS = run2.auth.password;
|
|
26957
27168
|
} else if (run2.auth.mode === "api_key" && run2.auth.in === "header") {
|
|
26958
27169
|
env.ATC_API_NAME = run2.auth.name;
|
|
26959
27170
|
env.ATC_API_KEY = run2.auth.value;
|
|
27171
|
+
} else if (run2.auth.mode === "oauth1") {
|
|
27172
|
+
const { mode: _mode, ...creds } = run2.auth;
|
|
27173
|
+
env.ATC_OAUTH1 = JSON.stringify(creds);
|
|
26960
27174
|
} else if (run2.auth.mode === "aws_sigv4") {
|
|
26961
27175
|
const { mode: _mode, ...creds } = run2.auth;
|
|
26962
27176
|
env.ATC_AWS = JSON.stringify(creds);
|
|
@@ -26990,7 +27204,7 @@ function __atcRow() {
|
|
|
26990
27204
|
const script = `import http from "k6/http";
|
|
26991
27205
|
import { check, sleep } from "k6";
|
|
26992
27206
|
import encoding from "k6/encoding";
|
|
26993
|
-
${run2.auth.mode === "aws_sigv4" ? `import crypto from "k6/crypto";
|
|
27207
|
+
${run2.auth.mode === "aws_sigv4" || run2.auth.mode === "oauth1" ? `import crypto from "k6/crypto";
|
|
26994
27208
|
` : ""}${data ? `import exec from "k6/execution";
|
|
26995
27209
|
import { SharedArray } from "k6/data";
|
|
26996
27210
|
` : ""}
|
|
@@ -26999,18 +27213,23 @@ export const options = Object.assign(${optionsBlock(run2)}, __ENV.ATC_TLS_AUTH ?
|
|
|
26999
27213
|
${CHECK_EVALUATOR_JS}
|
|
27000
27214
|
${dataBlock}${run2.auth.mode === "aws_sigv4" ? `
|
|
27001
27215
|
const AWS = JSON.parse(__ENV.ATC_AWS);
|
|
27002
|
-
${SIGV4_JS}` : ""}
|
|
27216
|
+
${SIGV4_JS}` : ""}${run2.auth.mode === "oauth1" ? `
|
|
27217
|
+
const OAUTH1 = JSON.parse(__ENV.ATC_OAUTH1);
|
|
27218
|
+
${OAUTH1_JS}` : ""}
|
|
27003
27219
|
const CHECKS = JSON.parse(__ENV.ATC_CHECKS || "[]");
|
|
27004
27220
|
// JWT: tokens signed by the app for the whole run; each is used for its stretch of time.
|
|
27005
27221
|
const JWT = __ENV.ATC_JWT ? JSON.parse(__ENV.ATC_JWT) : null;
|
|
27006
27222
|
const JWTS = JWT ? JSON.parse(open("./jwt.json")) : [];
|
|
27007
27223
|
// OAuth 2.0: each simulated user gets a new token shortly before the current one runs out.
|
|
27008
27224
|
const OAUTH = __ENV.ATC_OAUTH ? JSON.parse(__ENV.ATC_OAUTH) : null;
|
|
27225
|
+
const OAUTH_BODIES = OAUTH && OAUTH.stepSec ? JSON.parse(open("./oauth.json")) : null;
|
|
27009
27226
|
let __atcToken = __ENV.ATC_TOKEN || "";
|
|
27010
27227
|
let __atcExpires = OAUTH ? OAUTH.expiresAt : 0;
|
|
27011
27228
|
function __atcFreshToken() {
|
|
27012
27229
|
if (OAUTH && Date.now() > __atcExpires - 30000) {
|
|
27013
|
-
const
|
|
27230
|
+
const body = OAUTH_BODIES ? OAUTH_BODIES[Math.max(0, Math.min(OAUTH_BODIES.length - 1, Math.floor((Date.now() / 1000 - OAUTH.start) / OAUTH.stepSec)))] : OAUTH.body;
|
|
27231
|
+
// responseType: the run may discard bodies to save memory, but the token is in this one.
|
|
27232
|
+
const r = http.post(OAUTH.tokenUrl, body, { headers: OAUTH.headers, responseType: "text", tags: { name: "OAuth token" } });
|
|
27014
27233
|
let json = null;
|
|
27015
27234
|
try { json = r.json(); } catch (e) { json = null; }
|
|
27016
27235
|
if (r.status >= 200 && r.status < 300 && json && json.access_token) {
|
|
@@ -27028,12 +27247,14 @@ export default function () {
|
|
|
27028
27247
|
${data ? 'const vars = __atcRow();\n const f = function (text, mode) { return __atcFill(text, vars, mode || "raw"); };' : "const f = function (text) { return text; };"}
|
|
27029
27248
|
const headers = JSON.parse(__ENV.ATC_HEADERS || "{}");
|
|
27030
27249
|
for (const key in headers) headers[key] = f(headers[key]);
|
|
27250
|
+
if (__ENV.ATC_COOKIE) headers.Cookie = __ENV.ATC_COOKIE;
|
|
27031
27251
|
if (__ENV.ATC_TOKEN) headers.Authorization = "Bearer " + f(__atcFreshToken());
|
|
27032
27252
|
if (__ENV.ATC_BASIC_USER !== undefined) headers.Authorization = "Basic " + encoding.b64encode(f(__ENV.ATC_BASIC_USER) + ":" + f(__ENV.ATC_BASIC_PASS || ""));
|
|
27033
27253
|
if (__ENV.ATC_API_NAME && __ENV.ATC_API_KEY) headers[f(__ENV.ATC_API_NAME)] = f(__ENV.ATC_API_KEY);
|
|
27034
27254
|
if (JWT) headers[JWT.headerName] = (JWT.prefix ? JWT.prefix + " " : "") + JWTS[Math.max(0, Math.min(JWTS.length - 1, Math.floor((Date.now() / 1000 - JWT.start) / JWT.stepSec)))];
|
|
27035
27255
|
const body = __ENV.ATC_BODY ? f(__ENV.ATC_BODY, __ENV.ATC_BODY_FILL) : null;
|
|
27036
27256
|
let target = f(__ENV.ATC_URL, "url");
|
|
27257
|
+
if (__ENV.ATC_OAUTH1) target = __atcOAuth1(__ENV.ATC_METHOD, target, headers, body);
|
|
27037
27258
|
if (__ENV.ATC_AWS) __atcSign(__ENV.ATC_METHOD, target, headers, body);
|
|
27038
27259
|
if (__ENV.ATC_AUTH_KIND) target = target.replace("://", "://" + encodeURIComponent(f(__ENV.ATC_AUTH_USER)) + ":" + encodeURIComponent(f(__ENV.ATC_AUTH_PASS || "")) + "@");
|
|
27039
27260
|
const res = http.request(__ENV.ATC_METHOD, target, body, {
|
|
@@ -27058,17 +27279,18 @@ export default function () {
|
|
|
27058
27279
|
`;
|
|
27059
27280
|
return { script, env, files };
|
|
27060
27281
|
}
|
|
27061
|
-
function loadDurationHintMs(
|
|
27062
|
-
if (
|
|
27063
|
-
return
|
|
27282
|
+
function loadDurationHintMs(load3) {
|
|
27283
|
+
if (load3.stages.length > 0) {
|
|
27284
|
+
return load3.stages.reduce((sum, stage) => sum + durationToMs(stage.duration), 0);
|
|
27064
27285
|
}
|
|
27065
|
-
return durationToMs(
|
|
27286
|
+
return durationToMs(load3.duration);
|
|
27066
27287
|
}
|
|
27067
27288
|
var init_k6_script = __esm({
|
|
27068
27289
|
"../shared/src/k6-script.ts"() {
|
|
27069
27290
|
"use strict";
|
|
27070
27291
|
init_chain();
|
|
27071
27292
|
init_checks3();
|
|
27293
|
+
init_oauth1();
|
|
27072
27294
|
init_sigv4();
|
|
27073
27295
|
init_definition();
|
|
27074
27296
|
}
|
|
@@ -44903,10 +45125,12 @@ var require_lib = __commonJS({
|
|
|
44903
45125
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
44904
45126
|
import { mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
|
|
44905
45127
|
import { join as join4 } from "node:path";
|
|
44906
|
-
import {
|
|
44907
|
-
|
|
45128
|
+
import { X509Certificate } from "node:crypto";
|
|
45129
|
+
import * as tlsModule from "node:tls";
|
|
45130
|
+
import { connect as tlsSocket, createSecureContext, rootCertificates } from "node:tls";
|
|
45131
|
+
function useCertificateStore(dataDir, store3) {
|
|
44908
45132
|
dir = dataDir;
|
|
44909
|
-
secrets =
|
|
45133
|
+
secrets = store3;
|
|
44910
45134
|
}
|
|
44911
45135
|
function addTemporaryCertificate(host2, material) {
|
|
44912
45136
|
checkMaterial(material);
|
|
@@ -44928,23 +45152,104 @@ function hostMatches(pattern, url2) {
|
|
|
44928
45152
|
}
|
|
44929
45153
|
return name === host2;
|
|
44930
45154
|
}
|
|
44931
|
-
async function
|
|
44932
|
-
if (!dir) return [];
|
|
45155
|
+
async function readStore() {
|
|
45156
|
+
if (!dir) return { certificates: [], cas: [] };
|
|
44933
45157
|
try {
|
|
44934
45158
|
const raw = JSON.parse(await readFile2(join4(dir, "certificates.json"), "utf8"));
|
|
44935
|
-
return
|
|
45159
|
+
return {
|
|
45160
|
+
certificates: Array.isArray(raw.certificates) ? raw.certificates.filter((c) => c && typeof c.id === "string" && typeof c.host === "string") : [],
|
|
45161
|
+
cas: Array.isArray(raw.cas) ? raw.cas.filter((c) => c && typeof c.id === "string" && typeof c.pem === "string") : []
|
|
45162
|
+
};
|
|
44936
45163
|
} catch {
|
|
44937
|
-
return [];
|
|
45164
|
+
return { certificates: [], cas: [] };
|
|
44938
45165
|
}
|
|
44939
45166
|
}
|
|
44940
|
-
async function
|
|
45167
|
+
async function readAll() {
|
|
45168
|
+
return (await readStore()).certificates;
|
|
45169
|
+
}
|
|
45170
|
+
async function writeStore(next) {
|
|
44941
45171
|
await mkdir2(dir, { recursive: true });
|
|
44942
45172
|
const file2 = join4(dir, "certificates.json");
|
|
44943
45173
|
const tmp = `${file2}.${process.pid}.tmp`;
|
|
44944
|
-
await writeFile2(tmp, `${JSON.stringify({ version: 1,
|
|
45174
|
+
await writeFile2(tmp, `${JSON.stringify({ version: 1, ...next }, null, 2)}
|
|
44945
45175
|
`, "utf8");
|
|
44946
45176
|
await rename2(tmp, file2);
|
|
44947
45177
|
}
|
|
45178
|
+
async function writeAll(list) {
|
|
45179
|
+
await writeStore({ ...await readStore(), certificates: list });
|
|
45180
|
+
}
|
|
45181
|
+
async function listCas() {
|
|
45182
|
+
return (await readStore()).cas.map(({ pem: _pem, ...rest }) => rest);
|
|
45183
|
+
}
|
|
45184
|
+
async function addCas(pemText) {
|
|
45185
|
+
const blocks = pemText.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g) ?? [];
|
|
45186
|
+
if (!blocks.length) throw new Error("No certificate in that file \u2014 it should contain -----BEGIN CERTIFICATE-----");
|
|
45187
|
+
const store3 = await readStore();
|
|
45188
|
+
for (const pem of blocks) {
|
|
45189
|
+
let x;
|
|
45190
|
+
try {
|
|
45191
|
+
x = new X509Certificate(pem);
|
|
45192
|
+
} catch {
|
|
45193
|
+
throw new Error("A certificate in that file can't be read");
|
|
45194
|
+
}
|
|
45195
|
+
if (!x.ca) throw new Error(`${x.subject.split("\n").find((l) => l.startsWith("CN="))?.slice(3) ?? "That certificate"} is not a certificate authority \u2014 add the CA that issued the server's certificate`);
|
|
45196
|
+
if (store3.cas.some((c) => c.pem.replace(/\s/g, "") === pem.replace(/\s/g, ""))) continue;
|
|
45197
|
+
const cn = x.subject.split("\n").find((l) => l.startsWith("CN="))?.slice(3) ?? x.subject.replace(/\n/g, ", ");
|
|
45198
|
+
store3.cas.push({ id: randomUUID2(), subject: cn, expires: new Date(x.validTo).toISOString(), pem });
|
|
45199
|
+
}
|
|
45200
|
+
await writeStore(store3);
|
|
45201
|
+
casCache = null;
|
|
45202
|
+
return listCas();
|
|
45203
|
+
}
|
|
45204
|
+
async function removeCa(id) {
|
|
45205
|
+
const store3 = await readStore();
|
|
45206
|
+
if (!store3.cas.some((c) => c.id === id)) return false;
|
|
45207
|
+
await writeStore({ ...store3, cas: store3.cas.filter((c) => c.id !== id) });
|
|
45208
|
+
casCache = null;
|
|
45209
|
+
return true;
|
|
45210
|
+
}
|
|
45211
|
+
async function trustedCas() {
|
|
45212
|
+
casCache ??= (await readStore()).cas;
|
|
45213
|
+
return casCache.map((c) => c.pem);
|
|
45214
|
+
}
|
|
45215
|
+
function systemCas() {
|
|
45216
|
+
if (systemCache) return systemCache;
|
|
45217
|
+
const get = tlsModule.getCACertificates;
|
|
45218
|
+
try {
|
|
45219
|
+
systemCache = get ? get("system") : [];
|
|
45220
|
+
} catch {
|
|
45221
|
+
systemCache = [];
|
|
45222
|
+
}
|
|
45223
|
+
return systemCache;
|
|
45224
|
+
}
|
|
45225
|
+
async function trustPool() {
|
|
45226
|
+
const added = await trustedCas();
|
|
45227
|
+
const system = systemCas();
|
|
45228
|
+
return added.length || system.length ? [...rootCertificates, ...system, ...added] : null;
|
|
45229
|
+
}
|
|
45230
|
+
async function needsTrustedCa(target) {
|
|
45231
|
+
const extra2 = await trustedCas();
|
|
45232
|
+
let url2;
|
|
45233
|
+
try {
|
|
45234
|
+
url2 = new URL(target);
|
|
45235
|
+
} catch {
|
|
45236
|
+
return false;
|
|
45237
|
+
}
|
|
45238
|
+
if (!extra2.length || url2.protocol !== "https:") return false;
|
|
45239
|
+
const ok = (ca) => new Promise((resolve5) => {
|
|
45240
|
+
const sock = tlsSocket({ host: url2.hostname, port: Number(url2.port || 443), servername: url2.hostname, ca, timeout: 8e3, rejectUnauthorized: false }, () => {
|
|
45241
|
+
resolve5(sock.authorized);
|
|
45242
|
+
sock.end();
|
|
45243
|
+
});
|
|
45244
|
+
sock.on("error", () => resolve5(false));
|
|
45245
|
+
sock.on("timeout", () => {
|
|
45246
|
+
sock.destroy();
|
|
45247
|
+
resolve5(false);
|
|
45248
|
+
});
|
|
45249
|
+
});
|
|
45250
|
+
const system = systemCas();
|
|
45251
|
+
return !await ok(system.length ? [...rootCertificates, ...system] : void 0) && await ok([...rootCertificates, ...system, ...extra2]);
|
|
45252
|
+
}
|
|
44948
45253
|
async function listCertificates() {
|
|
44949
45254
|
return (await readAll()).map(({ cert: _cert, ...summary }) => summary);
|
|
44950
45255
|
}
|
|
@@ -45049,8 +45354,18 @@ async function k6TlsAuth(urls) {
|
|
|
45049
45354
|
}
|
|
45050
45355
|
async function tlsConnect(target, skipVerify = false) {
|
|
45051
45356
|
const m = await certificateFor(target);
|
|
45052
|
-
|
|
45053
|
-
|
|
45357
|
+
const pool = await trustPool();
|
|
45358
|
+
if (!m && !skipVerify && !pool) return void 0;
|
|
45359
|
+
return {
|
|
45360
|
+
...skipVerify ? { rejectUnauthorized: false } : {},
|
|
45361
|
+
// Added to the usual roots, not instead of them.
|
|
45362
|
+
...pool ? { ca: pool } : {},
|
|
45363
|
+
...m ? { cert: m.cert, key: m.key, pfx: m.pfx, passphrase: m.passphrase } : {}
|
|
45364
|
+
};
|
|
45365
|
+
}
|
|
45366
|
+
async function caBundle() {
|
|
45367
|
+
const cas = await trustedCas();
|
|
45368
|
+
return cas.length ? [...rootCertificates, ...systemCas(), ...cas].join("\n") : null;
|
|
45054
45369
|
}
|
|
45055
45370
|
function registerCertificateRoutes(app2) {
|
|
45056
45371
|
app2.get("/certificates", async () => listCertificates());
|
|
@@ -45067,12 +45382,27 @@ function registerCertificateRoutes(app2) {
|
|
|
45067
45382
|
"/certificates/:id",
|
|
45068
45383
|
async (request3, reply) => await deleteCertificate(request3.params.id) ? { removed: 1 } : reply.code(404).send({ error: "certificate not found" })
|
|
45069
45384
|
);
|
|
45385
|
+
app2.get("/certificates/cas", async () => listCas());
|
|
45386
|
+
app2.get("/certificates/system", async () => ({ count: systemCas().length }));
|
|
45387
|
+
app2.post("/certificates/cas", async (request3, reply) => {
|
|
45388
|
+
const pem = request3.body?.pem;
|
|
45389
|
+
if (typeof pem !== "string" || pem.length > 2e6) return reply.code(400).send({ error: "Send the CA file's text as pem" });
|
|
45390
|
+
try {
|
|
45391
|
+
return await addCas(pem);
|
|
45392
|
+
} catch (err) {
|
|
45393
|
+
return reply.code(422).send({ error: err instanceof Error ? err.message : String(err) });
|
|
45394
|
+
}
|
|
45395
|
+
});
|
|
45396
|
+
app2.delete(
|
|
45397
|
+
"/certificates/cas/:id",
|
|
45398
|
+
async (request3, reply) => await removeCa(request3.params.id) ? { removed: 1 } : reply.code(404).send({ error: "not found" })
|
|
45399
|
+
);
|
|
45070
45400
|
app2.get("/certificates/match", async (request3) => {
|
|
45071
45401
|
const m = await certificateFor(request3.query.url ?? "").catch(() => null);
|
|
45072
45402
|
return { host: m?.host ?? null };
|
|
45073
45403
|
});
|
|
45074
45404
|
}
|
|
45075
|
-
var import_node_forge, dir, secrets, extra, saveBody;
|
|
45405
|
+
var import_node_forge, dir, secrets, extra, casCache, systemCache, saveBody;
|
|
45076
45406
|
var init_certificates = __esm({
|
|
45077
45407
|
"../../apps/engine/src/certificates.ts"() {
|
|
45078
45408
|
"use strict";
|
|
@@ -45081,6 +45411,8 @@ var init_certificates = __esm({
|
|
|
45081
45411
|
dir = "";
|
|
45082
45412
|
secrets = null;
|
|
45083
45413
|
extra = [];
|
|
45414
|
+
casCache = null;
|
|
45415
|
+
systemCache = null;
|
|
45084
45416
|
saveBody = external_exports.object({
|
|
45085
45417
|
id: external_exports.string().optional(),
|
|
45086
45418
|
host: external_exports.string().min(1).max(253),
|
|
@@ -45094,6 +45426,113 @@ var init_certificates = __esm({
|
|
|
45094
45426
|
}
|
|
45095
45427
|
});
|
|
45096
45428
|
|
|
45429
|
+
// ../../apps/engine/src/cookies.ts
|
|
45430
|
+
function useCookieStore(secrets2) {
|
|
45431
|
+
store = secrets2;
|
|
45432
|
+
jar = null;
|
|
45433
|
+
}
|
|
45434
|
+
async function load() {
|
|
45435
|
+
if (jar) return jar;
|
|
45436
|
+
try {
|
|
45437
|
+
const raw = store ? await store.get(KEY) : null;
|
|
45438
|
+
jar = raw ? JSON.parse(raw).filter((c) => c.expires !== null) : [];
|
|
45439
|
+
} catch {
|
|
45440
|
+
jar = [];
|
|
45441
|
+
}
|
|
45442
|
+
return jar;
|
|
45443
|
+
}
|
|
45444
|
+
async function save(next) {
|
|
45445
|
+
const now = Date.now();
|
|
45446
|
+
jar = next.filter((c) => c.expires === null || c.expires > now).slice(-MAX);
|
|
45447
|
+
await store?.set(KEY, JSON.stringify(jar));
|
|
45448
|
+
}
|
|
45449
|
+
function defaultPath(url2) {
|
|
45450
|
+
const p = url2.pathname;
|
|
45451
|
+
if (!p.startsWith("/") || p.lastIndexOf("/") === 0) return "/";
|
|
45452
|
+
return p.slice(0, p.lastIndexOf("/"));
|
|
45453
|
+
}
|
|
45454
|
+
function parseSetCookie(header, url2, now = Date.now()) {
|
|
45455
|
+
const [pair, ...attrs] = header.split(";");
|
|
45456
|
+
const eq = pair.indexOf("=");
|
|
45457
|
+
if (eq <= 0) return null;
|
|
45458
|
+
const host2 = url2.hostname.toLowerCase();
|
|
45459
|
+
const cookie = { name: pair.slice(0, eq).trim(), value: pair.slice(eq + 1).trim(), domain: host2, includeSubdomains: false, path: defaultPath(url2), expires: null, secure: false, httpOnly: false };
|
|
45460
|
+
let maxAge = null;
|
|
45461
|
+
for (const raw of attrs) {
|
|
45462
|
+
const i = raw.indexOf("=");
|
|
45463
|
+
const k = (i < 0 ? raw : raw.slice(0, i)).trim().toLowerCase();
|
|
45464
|
+
const v = i < 0 ? "" : raw.slice(i + 1).trim();
|
|
45465
|
+
if (k === "domain" && v) {
|
|
45466
|
+
const d = v.replace(/^\./, "").toLowerCase();
|
|
45467
|
+
if (host2 !== d && !host2.endsWith(`.${d}`)) return null;
|
|
45468
|
+
cookie.domain = d;
|
|
45469
|
+
cookie.includeSubdomains = true;
|
|
45470
|
+
} else if (k === "path" && v.startsWith("/")) cookie.path = v;
|
|
45471
|
+
else if (k === "expires") {
|
|
45472
|
+
const t = Date.parse(v);
|
|
45473
|
+
if (Number.isFinite(t)) cookie.expires = t;
|
|
45474
|
+
} else if (k === "max-age" && /^-?\d+$/.test(v)) maxAge = Number(v);
|
|
45475
|
+
else if (k === "secure") cookie.secure = true;
|
|
45476
|
+
else if (k === "httponly") cookie.httpOnly = true;
|
|
45477
|
+
else if (k === "samesite") cookie.sameSite = v;
|
|
45478
|
+
}
|
|
45479
|
+
if (maxAge !== null) cookie.expires = now + maxAge * 1e3;
|
|
45480
|
+
return cookie;
|
|
45481
|
+
}
|
|
45482
|
+
function matches(c, url2, now) {
|
|
45483
|
+
const host2 = url2.hostname.toLowerCase();
|
|
45484
|
+
const domainOk = c.includeSubdomains ? host2 === c.domain || host2.endsWith(`.${c.domain}`) : host2 === c.domain;
|
|
45485
|
+
const path = url2.pathname || "/";
|
|
45486
|
+
const pathOk = path === c.path || path.startsWith(c.path) && (c.path.endsWith("/") || path[c.path.length] === "/");
|
|
45487
|
+
return domainOk && pathOk && (!c.secure || url2.protocol === "https:") && (c.expires === null || c.expires > now);
|
|
45488
|
+
}
|
|
45489
|
+
async function cookieHeader(target) {
|
|
45490
|
+
let url2;
|
|
45491
|
+
try {
|
|
45492
|
+
url2 = typeof target === "string" ? new URL(target) : target;
|
|
45493
|
+
} catch {
|
|
45494
|
+
return "";
|
|
45495
|
+
}
|
|
45496
|
+
const now = Date.now();
|
|
45497
|
+
return (await load()).filter((c) => matches(c, url2, now)).sort((a, b) => b.path.length - a.path.length).map((c) => `${c.name}=${c.value}`).join("; ");
|
|
45498
|
+
}
|
|
45499
|
+
async function storeCookies(target, setCookie) {
|
|
45500
|
+
if (!setCookie || Array.isArray(setCookie) && !setCookie.length) return;
|
|
45501
|
+
const url2 = typeof target === "string" ? new URL(target) : target;
|
|
45502
|
+
const now = Date.now();
|
|
45503
|
+
let next = [...await load()];
|
|
45504
|
+
for (const header of Array.isArray(setCookie) ? setCookie : [setCookie]) {
|
|
45505
|
+
const c = parseSetCookie(header, url2, now);
|
|
45506
|
+
if (!c) continue;
|
|
45507
|
+
next = next.filter((o) => !(o.name === c.name && o.domain === c.domain && o.path === c.path));
|
|
45508
|
+
if (c.expires === null || c.expires > now) next.push(c);
|
|
45509
|
+
}
|
|
45510
|
+
await save(next);
|
|
45511
|
+
}
|
|
45512
|
+
async function listCookies() {
|
|
45513
|
+
const now = Date.now();
|
|
45514
|
+
return (await load()).filter((c) => c.expires === null || c.expires > now);
|
|
45515
|
+
}
|
|
45516
|
+
function registerCookieRoutes(app2) {
|
|
45517
|
+
app2.get("/cookies", async () => (await listCookies()).map((c) => ({ ...c, value: c.value.length > 12 ? `${c.value.slice(0, 6)}\u2026${c.value.slice(-3)}` : c.value })));
|
|
45518
|
+
app2.post("/cookies/delete", async (request3) => {
|
|
45519
|
+
const b = request3.body ?? {};
|
|
45520
|
+
const list = await load();
|
|
45521
|
+
await save(b.all ? [] : b.domainOnly ? list.filter((c) => c.domain !== b.domainOnly) : list.filter((c) => !(c.name === b.name && c.domain === b.domain && c.path === b.path)));
|
|
45522
|
+
return { left: (await listCookies()).length };
|
|
45523
|
+
});
|
|
45524
|
+
}
|
|
45525
|
+
var KEY, MAX, store, jar;
|
|
45526
|
+
var init_cookies = __esm({
|
|
45527
|
+
"../../apps/engine/src/cookies.ts"() {
|
|
45528
|
+
"use strict";
|
|
45529
|
+
KEY = "cookies";
|
|
45530
|
+
MAX = 500;
|
|
45531
|
+
store = null;
|
|
45532
|
+
jar = null;
|
|
45533
|
+
}
|
|
45534
|
+
});
|
|
45535
|
+
|
|
45097
45536
|
// ../../apps/engine/src/jwt.ts
|
|
45098
45537
|
import { createHmac, createPrivateKey, sign as cryptoSign, constants as constants2 } from "node:crypto";
|
|
45099
45538
|
function privateKey(pem) {
|
|
@@ -45103,7 +45542,7 @@ function privateKey(pem) {
|
|
|
45103
45542
|
throw new Error(`the private key can't be read (${err instanceof Error ? err.message : "bad PEM"}) \u2014 paste the whole PEM, from -----BEGIN to -----END`);
|
|
45104
45543
|
}
|
|
45105
45544
|
}
|
|
45106
|
-
function signJwt(c, now = Math.floor(Date.now() / 1e3)) {
|
|
45545
|
+
function signJwt(c, now = Math.floor(Date.now() / 1e3), headerExtra = {}) {
|
|
45107
45546
|
let claims;
|
|
45108
45547
|
try {
|
|
45109
45548
|
claims = JSON.parse(c.payload || "{}");
|
|
@@ -45113,6 +45552,7 @@ function signJwt(c, now = Math.floor(Date.now() / 1e3)) {
|
|
|
45113
45552
|
const body = { iat: now, exp: now + c.lifetimeSec, ...claims };
|
|
45114
45553
|
const header = { alg: c.algorithm, typ: "JWT" };
|
|
45115
45554
|
if (c.kid) header.kid = c.kid;
|
|
45555
|
+
Object.assign(header, headerExtra);
|
|
45116
45556
|
const input = `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(body))}`;
|
|
45117
45557
|
const bits = c.algorithm.slice(2);
|
|
45118
45558
|
const hash2 = `sha${bits}`;
|
|
@@ -59388,13 +59828,13 @@ var require_mock_call_history = __commonJS({
|
|
|
59388
59828
|
"use strict";
|
|
59389
59829
|
var { kMockCallHistoryAddLog } = require_mock_symbols();
|
|
59390
59830
|
var { InvalidArgumentError } = require_errors2();
|
|
59391
|
-
function handleFilterCallsWithOptions(criteria, options, handler,
|
|
59831
|
+
function handleFilterCallsWithOptions(criteria, options, handler, store3, allLogs) {
|
|
59392
59832
|
switch (options.operator) {
|
|
59393
59833
|
case "OR":
|
|
59394
|
-
|
|
59395
|
-
return
|
|
59834
|
+
store3.push(...handler(criteria, allLogs));
|
|
59835
|
+
return store3;
|
|
59396
59836
|
case "AND":
|
|
59397
|
-
return handler(criteria,
|
|
59837
|
+
return handler(criteria, store3);
|
|
59398
59838
|
default:
|
|
59399
59839
|
throw new InvalidArgumentError("options.operator must to be a case insensitive string equal to 'OR' or 'AND'");
|
|
59400
59840
|
}
|
|
@@ -62049,12 +62489,12 @@ var require_cache = __commonJS({
|
|
|
62049
62489
|
}
|
|
62050
62490
|
return false;
|
|
62051
62491
|
}
|
|
62052
|
-
function assertCacheStore(
|
|
62053
|
-
if (typeof
|
|
62054
|
-
throw new TypeError(`expected type of ${name} to be a CacheStore, got ${
|
|
62492
|
+
function assertCacheStore(store3, name = "CacheStore") {
|
|
62493
|
+
if (typeof store3 !== "object" || store3 === null) {
|
|
62494
|
+
throw new TypeError(`expected type of ${name} to be a CacheStore, got ${store3 === null ? "null" : typeof store3}`);
|
|
62055
62495
|
}
|
|
62056
62496
|
for (const fn of ["get", "createWriteStream", "delete"]) {
|
|
62057
|
-
if (typeof
|
|
62497
|
+
if (typeof store3[fn] !== "function") {
|
|
62058
62498
|
throw new TypeError(`${name} needs to have a \`${fn}()\` function`);
|
|
62059
62499
|
}
|
|
62060
62500
|
}
|
|
@@ -62677,15 +63117,15 @@ var require_cache_handler = __commonJS({
|
|
|
62677
63117
|
}
|
|
62678
63118
|
return locationUrl.pathname + locationUrl.search;
|
|
62679
63119
|
}
|
|
62680
|
-
function deleteCachedUri(
|
|
62681
|
-
deleteCachedValue(
|
|
63120
|
+
function deleteCachedUri(store3, cacheKey, path) {
|
|
63121
|
+
deleteCachedValue(store3, {
|
|
62682
63122
|
...cacheKey,
|
|
62683
63123
|
path
|
|
62684
63124
|
});
|
|
62685
63125
|
for (let i = 0; i < util.safeHTTPMethods.length; i++) {
|
|
62686
63126
|
const method = util.safeHTTPMethods[i];
|
|
62687
63127
|
if (method !== cacheKey.method) {
|
|
62688
|
-
deleteCachedValue(
|
|
63128
|
+
deleteCachedValue(store3, {
|
|
62689
63129
|
...cacheKey,
|
|
62690
63130
|
method,
|
|
62691
63131
|
path
|
|
@@ -62693,7 +63133,7 @@ var require_cache_handler = __commonJS({
|
|
|
62693
63133
|
}
|
|
62694
63134
|
}
|
|
62695
63135
|
}
|
|
62696
|
-
function deleteLocationTargets(
|
|
63136
|
+
function deleteLocationTargets(store3, cacheKey, headerValue) {
|
|
62697
63137
|
if (headerValue === void 0) {
|
|
62698
63138
|
return;
|
|
62699
63139
|
}
|
|
@@ -62701,14 +63141,14 @@ var require_cache_handler = __commonJS({
|
|
|
62701
63141
|
for (let i = 0; i < values.length; i++) {
|
|
62702
63142
|
const path = getSameOriginPath(cacheKey, values[i]);
|
|
62703
63143
|
if (path !== void 0) {
|
|
62704
|
-
deleteCachedUri(
|
|
63144
|
+
deleteCachedUri(store3, cacheKey, path);
|
|
62705
63145
|
}
|
|
62706
63146
|
}
|
|
62707
63147
|
}
|
|
62708
|
-
function invalidateUnsafeRequest(
|
|
62709
|
-
deleteCachedUri(
|
|
62710
|
-
deleteLocationTargets(
|
|
62711
|
-
deleteLocationTargets(
|
|
63148
|
+
function invalidateUnsafeRequest(store3, cacheKey, resHeaders) {
|
|
63149
|
+
deleteCachedUri(store3, cacheKey, cacheKey.path);
|
|
63150
|
+
deleteLocationTargets(store3, cacheKey, resHeaders.location);
|
|
63151
|
+
deleteLocationTargets(store3, cacheKey, resHeaders["content-location"]);
|
|
62712
63152
|
}
|
|
62713
63153
|
var CacheHandler = class {
|
|
62714
63154
|
/**
|
|
@@ -62740,8 +63180,8 @@ var require_cache_handler = __commonJS({
|
|
|
62740
63180
|
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
|
|
62741
63181
|
* @param {import('../../types/dispatcher.d.ts').default.DispatchHandler} handler
|
|
62742
63182
|
*/
|
|
62743
|
-
constructor({ store:
|
|
62744
|
-
this.#store =
|
|
63183
|
+
constructor({ store: store3, type, cacheByDefault }, cacheKey, handler) {
|
|
63184
|
+
this.#store = store3;
|
|
62745
63185
|
this.#cacheType = type;
|
|
62746
63186
|
this.#cacheByDefault = cacheByDefault;
|
|
62747
63187
|
this.#cacheKey = cacheKey;
|
|
@@ -62935,15 +63375,15 @@ var require_cache_handler = __commonJS({
|
|
|
62935
63375
|
this.#handler.onResponseError?.(controller, err);
|
|
62936
63376
|
}
|
|
62937
63377
|
};
|
|
62938
|
-
function deleteCachedValue(
|
|
63378
|
+
function deleteCachedValue(store3, cacheKey) {
|
|
62939
63379
|
try {
|
|
62940
|
-
|
|
63380
|
+
store3.delete(cacheKey)?.catch?.(noop);
|
|
62941
63381
|
} catch {
|
|
62942
63382
|
}
|
|
62943
63383
|
}
|
|
62944
|
-
function deleteCachedValueIfNotModified(statusCode,
|
|
63384
|
+
function deleteCachedValueIfNotModified(statusCode, store3, cacheKey) {
|
|
62945
63385
|
if (statusCode === 304) {
|
|
62946
|
-
deleteCachedValue(
|
|
63386
|
+
deleteCachedValue(store3, cacheKey);
|
|
62947
63387
|
}
|
|
62948
63388
|
}
|
|
62949
63389
|
function revalidationResponseDisallowsCachedReuse(cacheType, resHeaders, cacheControlDirectives) {
|
|
@@ -63226,7 +63666,7 @@ var require_memory_cache_store = __commonJS({
|
|
|
63226
63666
|
assertCacheKey(key);
|
|
63227
63667
|
assertCacheValue(val);
|
|
63228
63668
|
const topLevelKey = `${key.origin}:${key.path}`;
|
|
63229
|
-
const
|
|
63669
|
+
const store3 = this;
|
|
63230
63670
|
const entry = { ...key, ...val, body: [], size: 0 };
|
|
63231
63671
|
return new Writable({
|
|
63232
63672
|
write(chunk, encoding, callback) {
|
|
@@ -63234,7 +63674,7 @@ var require_memory_cache_store = __commonJS({
|
|
|
63234
63674
|
chunk = Buffer.from(chunk, encoding);
|
|
63235
63675
|
}
|
|
63236
63676
|
entry.size += chunk.byteLength;
|
|
63237
|
-
if (entry.size >
|
|
63677
|
+
if (entry.size > store3.#maxEntrySize) {
|
|
63238
63678
|
this.destroy();
|
|
63239
63679
|
} else {
|
|
63240
63680
|
entry.body.push(chunk);
|
|
@@ -63242,42 +63682,42 @@ var require_memory_cache_store = __commonJS({
|
|
|
63242
63682
|
callback(null);
|
|
63243
63683
|
},
|
|
63244
63684
|
final(callback) {
|
|
63245
|
-
let entries =
|
|
63685
|
+
let entries = store3.#entries.get(topLevelKey);
|
|
63246
63686
|
if (!entries) {
|
|
63247
63687
|
entries = [];
|
|
63248
|
-
|
|
63688
|
+
store3.#entries.set(topLevelKey, entries);
|
|
63249
63689
|
}
|
|
63250
63690
|
const previousEntry = findEntry(key, entries, Date.now());
|
|
63251
63691
|
if (previousEntry) {
|
|
63252
63692
|
const index = entries.indexOf(previousEntry);
|
|
63253
63693
|
entries.splice(index, 1, entry);
|
|
63254
|
-
|
|
63694
|
+
store3.#size -= previousEntry.size;
|
|
63255
63695
|
} else {
|
|
63256
63696
|
entries.push(entry);
|
|
63257
|
-
|
|
63258
|
-
}
|
|
63259
|
-
|
|
63260
|
-
if (
|
|
63261
|
-
if (!
|
|
63262
|
-
|
|
63263
|
-
size:
|
|
63264
|
-
maxSize:
|
|
63265
|
-
count:
|
|
63266
|
-
maxCount:
|
|
63697
|
+
store3.#count += 1;
|
|
63698
|
+
}
|
|
63699
|
+
store3.#size += entry.size;
|
|
63700
|
+
if (store3.#size > store3.#maxSize || store3.#count > store3.#maxCount) {
|
|
63701
|
+
if (!store3.#hasEmittedMaxSizeEvent) {
|
|
63702
|
+
store3.emit("maxSizeExceeded", {
|
|
63703
|
+
size: store3.#size,
|
|
63704
|
+
maxSize: store3.#maxSize,
|
|
63705
|
+
count: store3.#count,
|
|
63706
|
+
maxCount: store3.#maxCount
|
|
63267
63707
|
});
|
|
63268
|
-
|
|
63708
|
+
store3.#hasEmittedMaxSizeEvent = true;
|
|
63269
63709
|
}
|
|
63270
|
-
for (const [key2, entries2] of
|
|
63710
|
+
for (const [key2, entries2] of store3.#entries) {
|
|
63271
63711
|
for (const entry2 of entries2.splice(0, entries2.length / 2)) {
|
|
63272
|
-
|
|
63273
|
-
|
|
63712
|
+
store3.#size -= entry2.size;
|
|
63713
|
+
store3.#count -= 1;
|
|
63274
63714
|
}
|
|
63275
63715
|
if (entries2.length === 0) {
|
|
63276
|
-
|
|
63716
|
+
store3.#entries.delete(key2);
|
|
63277
63717
|
}
|
|
63278
63718
|
}
|
|
63279
|
-
if (
|
|
63280
|
-
|
|
63719
|
+
if (store3.#size < store3.#maxSize && store3.#count < store3.#maxCount) {
|
|
63720
|
+
store3.#hasEmittedMaxSizeEvent = false;
|
|
63281
63721
|
}
|
|
63282
63722
|
}
|
|
63283
63723
|
callback(null);
|
|
@@ -63524,9 +63964,9 @@ var require_cache2 = __commonJS({
|
|
|
63524
63964
|
function revalidationResponseUpdatesCacheControl(headers) {
|
|
63525
63965
|
return headers["cache-control"] !== void 0;
|
|
63526
63966
|
}
|
|
63527
|
-
function deleteCachedValue(
|
|
63967
|
+
function deleteCachedValue(store3, cacheKey) {
|
|
63528
63968
|
try {
|
|
63529
|
-
|
|
63969
|
+
store3.delete(cacheKey)?.catch?.(nop);
|
|
63530
63970
|
} catch {
|
|
63531
63971
|
}
|
|
63532
63972
|
}
|
|
@@ -63761,7 +64201,7 @@ var require_cache2 = __commonJS({
|
|
|
63761
64201
|
}
|
|
63762
64202
|
module.exports = (opts = {}) => {
|
|
63763
64203
|
const {
|
|
63764
|
-
store:
|
|
64204
|
+
store: store3 = new MemoryCacheStore(),
|
|
63765
64205
|
methods = ["GET"],
|
|
63766
64206
|
cacheByDefault = void 0,
|
|
63767
64207
|
type = "shared",
|
|
@@ -63770,7 +64210,7 @@ var require_cache2 = __commonJS({
|
|
|
63770
64210
|
if (typeof opts !== "object" || opts === null) {
|
|
63771
64211
|
throw new TypeError(`expected type of opts to be an Object, got ${opts === null ? "null" : typeof opts}`);
|
|
63772
64212
|
}
|
|
63773
|
-
assertCacheStore(
|
|
64213
|
+
assertCacheStore(store3, "opts.store");
|
|
63774
64214
|
assertCacheMethods(methods, "opts.methods");
|
|
63775
64215
|
assertCacheOrigins(origins, "opts.origins");
|
|
63776
64216
|
if (typeof cacheByDefault !== "undefined" && typeof cacheByDefault !== "number") {
|
|
@@ -63780,7 +64220,7 @@ var require_cache2 = __commonJS({
|
|
|
63780
64220
|
throw new TypeError(`expected opts.type to be shared, private, or undefined, got ${typeof type}`);
|
|
63781
64221
|
}
|
|
63782
64222
|
const globalOpts = {
|
|
63783
|
-
store:
|
|
64223
|
+
store: store3,
|
|
63784
64224
|
methods,
|
|
63785
64225
|
cacheByDefault,
|
|
63786
64226
|
type
|
|
@@ -63828,7 +64268,7 @@ var require_cache2 = __commonJS({
|
|
|
63828
64268
|
return dispatch(opts2, handler);
|
|
63829
64269
|
}
|
|
63830
64270
|
const cacheKey = makeCacheKey(opts2);
|
|
63831
|
-
const result =
|
|
64271
|
+
const result = store3.get(cacheKey);
|
|
63832
64272
|
if (result && typeof result.then === "function") {
|
|
63833
64273
|
return result.then((result2) => handleResult(
|
|
63834
64274
|
dispatch,
|
|
@@ -64791,12 +65231,12 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
64791
65231
|
assertCacheValue(value);
|
|
64792
65232
|
let size = 0;
|
|
64793
65233
|
const body = [];
|
|
64794
|
-
const
|
|
65234
|
+
const store3 = this;
|
|
64795
65235
|
return new Writable({
|
|
64796
65236
|
decodeStrings: true,
|
|
64797
65237
|
write(chunk, encoding, callback) {
|
|
64798
65238
|
size += chunk.byteLength;
|
|
64799
|
-
if (size <=
|
|
65239
|
+
if (size <= store3.#maxEntrySize) {
|
|
64800
65240
|
body.push(chunk);
|
|
64801
65241
|
} else {
|
|
64802
65242
|
this.destroy();
|
|
@@ -64804,7 +65244,7 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
64804
65244
|
callback();
|
|
64805
65245
|
},
|
|
64806
65246
|
final(callback) {
|
|
64807
|
-
|
|
65247
|
+
store3.set(key, { ...value, body });
|
|
64808
65248
|
callback();
|
|
64809
65249
|
}
|
|
64810
65250
|
});
|
|
@@ -64868,17 +65308,17 @@ var require_sqlite_cache_store = __commonJS({
|
|
|
64868
65308
|
if (now >= value.deleteAt && !canBeExpired) {
|
|
64869
65309
|
continue;
|
|
64870
65310
|
}
|
|
64871
|
-
let
|
|
65311
|
+
let matches2 = true;
|
|
64872
65312
|
if (value.vary) {
|
|
64873
65313
|
const vary = JSON.parse(value.vary);
|
|
64874
65314
|
for (const header in vary) {
|
|
64875
65315
|
if (!headerValueEquals(headers[header], vary[header])) {
|
|
64876
|
-
|
|
65316
|
+
matches2 = false;
|
|
64877
65317
|
break;
|
|
64878
65318
|
}
|
|
64879
65319
|
}
|
|
64880
65320
|
}
|
|
64881
|
-
if (
|
|
65321
|
+
if (matches2) {
|
|
64882
65322
|
return value;
|
|
64883
65323
|
}
|
|
64884
65324
|
}
|
|
@@ -68771,7 +69211,7 @@ var require_parse = __commonJS({
|
|
|
68771
69211
|
var { maxNameValuePairSize, maxAttributeValueSize } = require_constants4();
|
|
68772
69212
|
var { isCTLExcludingHtab } = require_util5();
|
|
68773
69213
|
var assert2 = __require("node:assert");
|
|
68774
|
-
function
|
|
69214
|
+
function parseSetCookie2(header) {
|
|
68775
69215
|
if (isCTLExcludingHtab(header)) {
|
|
68776
69216
|
return null;
|
|
68777
69217
|
}
|
|
@@ -68895,7 +69335,7 @@ var require_parse = __commonJS({
|
|
|
68895
69335
|
return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList);
|
|
68896
69336
|
}
|
|
68897
69337
|
module.exports = {
|
|
68898
|
-
parseSetCookie,
|
|
69338
|
+
parseSetCookie: parseSetCookie2,
|
|
68899
69339
|
parseUnparsedAttributes
|
|
68900
69340
|
};
|
|
68901
69341
|
}
|
|
@@ -68905,7 +69345,7 @@ var require_parse = __commonJS({
|
|
|
68905
69345
|
var require_cookies = __commonJS({
|
|
68906
69346
|
"../../node_modules/.pnpm/undici@8.10.0/node_modules/undici/lib/web/cookies/index.js"(exports, module) {
|
|
68907
69347
|
"use strict";
|
|
68908
|
-
var { parseSetCookie } = require_parse();
|
|
69348
|
+
var { parseSetCookie: parseSetCookie2 } = require_parse();
|
|
68909
69349
|
var { stringify } = require_util5();
|
|
68910
69350
|
var { webidl } = require_webidl();
|
|
68911
69351
|
var { Headers } = require_headers();
|
|
@@ -68944,11 +69384,11 @@ var require_cookies = __commonJS({
|
|
|
68944
69384
|
if (!cookies) {
|
|
68945
69385
|
return [];
|
|
68946
69386
|
}
|
|
68947
|
-
return cookies.map((pair) =>
|
|
69387
|
+
return cookies.map((pair) => parseSetCookie2(pair));
|
|
68948
69388
|
}
|
|
68949
69389
|
function parseCookie(cookie) {
|
|
68950
69390
|
cookie = webidl.converters.DOMString(cookie);
|
|
68951
|
-
return
|
|
69391
|
+
return parseSetCookie2(cookie);
|
|
68952
69392
|
}
|
|
68953
69393
|
function setCookie(headers, cookie) {
|
|
68954
69394
|
webidl.argumentLengthCheck(arguments, 2, "setCookie");
|
|
@@ -72104,19 +72544,19 @@ ${captureLines}` : capture.stack;
|
|
|
72104
72544
|
});
|
|
72105
72545
|
|
|
72106
72546
|
// ../../apps/engine/src/oauth.ts
|
|
72107
|
-
import { createHash as createHash2, randomBytes, randomUUID as randomUUID3 } from "node:crypto";
|
|
72547
|
+
import { X509Certificate as X509Certificate2, createHash as createHash2, randomBytes, randomUUID as randomUUID3 } from "node:crypto";
|
|
72108
72548
|
import { createServer } from "node:http";
|
|
72109
72549
|
function useOAuthStore(secrets2) {
|
|
72110
|
-
|
|
72550
|
+
store2 = secrets2;
|
|
72111
72551
|
}
|
|
72112
72552
|
function oauthKey(c) {
|
|
72113
72553
|
const id = JSON.stringify([c.grant, c.tokenUrl, c.authUrl, c.clientId, c.clientSecret, c.scope, c.username, c.password, [...c.extra].map((e) => `${e.key}=${e.value}`).sort()]);
|
|
72114
72554
|
return createHash2("sha256").update(id).digest("hex").slice(0, 32);
|
|
72115
72555
|
}
|
|
72116
|
-
async function
|
|
72556
|
+
async function load2(key) {
|
|
72117
72557
|
const hit = memory.get(key);
|
|
72118
72558
|
if (hit) return hit;
|
|
72119
|
-
const raw = await
|
|
72559
|
+
const raw = await store2?.get(`oauth:${key}`);
|
|
72120
72560
|
if (!raw) return null;
|
|
72121
72561
|
try {
|
|
72122
72562
|
const token = JSON.parse(raw);
|
|
@@ -72126,21 +72566,54 @@ async function load(key) {
|
|
|
72126
72566
|
return null;
|
|
72127
72567
|
}
|
|
72128
72568
|
}
|
|
72129
|
-
async function
|
|
72569
|
+
async function save2(key, token) {
|
|
72130
72570
|
memory.set(key, token);
|
|
72131
|
-
await
|
|
72571
|
+
await store2?.set(`oauth:${key}`, JSON.stringify(token));
|
|
72132
72572
|
}
|
|
72133
72573
|
async function clearToken(c) {
|
|
72134
72574
|
const key = oauthKey(c);
|
|
72135
72575
|
memory.delete(key);
|
|
72136
|
-
await
|
|
72576
|
+
await store2?.set(`oauth:${key}`, "");
|
|
72577
|
+
}
|
|
72578
|
+
function thumbprint(pem) {
|
|
72579
|
+
if (!pem.trim()) return void 0;
|
|
72580
|
+
try {
|
|
72581
|
+
return Buffer.from(new X509Certificate2(pem).fingerprint.replace(/:/g, ""), "hex").toString("base64url");
|
|
72582
|
+
} catch {
|
|
72583
|
+
throw new OAuthError("the certificate can't be read \u2014 paste the whole PEM, from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----");
|
|
72584
|
+
}
|
|
72137
72585
|
}
|
|
72138
|
-
function
|
|
72586
|
+
function signedAssertion(c, claims, now) {
|
|
72587
|
+
const x5t = thumbprint(c.certificate);
|
|
72588
|
+
try {
|
|
72589
|
+
return signJwt(
|
|
72590
|
+
{ algorithm: c.assertionAlgorithm, key: c.privateKey, payload: JSON.stringify({ jti: randomUUID3(), ...claims }), lifetimeSec: 300, kid: c.kid, headerName: "", prefix: "" },
|
|
72591
|
+
now,
|
|
72592
|
+
x5t ? { x5t } : {}
|
|
72593
|
+
);
|
|
72594
|
+
} catch (err) {
|
|
72595
|
+
throw new OAuthError(err instanceof Error ? err.message : String(err));
|
|
72596
|
+
}
|
|
72597
|
+
}
|
|
72598
|
+
function extraClaims(c) {
|
|
72599
|
+
if (!c.extraClaims) return {};
|
|
72600
|
+
try {
|
|
72601
|
+
return JSON.parse(c.extraClaims);
|
|
72602
|
+
} catch {
|
|
72603
|
+
throw new OAuthError("the extra claims are not valid JSON");
|
|
72604
|
+
}
|
|
72605
|
+
}
|
|
72606
|
+
function tokenRequest(c, fields, now = Math.floor(Date.now() / 1e3)) {
|
|
72139
72607
|
const form = new URLSearchParams(fields);
|
|
72140
72608
|
if (c.scope && !form.has("scope") && fields.grant_type !== "authorization_code") form.set("scope", c.scope);
|
|
72141
72609
|
for (const e of c.extra) if (e.key.trim()) form.set(e.key.trim(), e.value);
|
|
72142
72610
|
const headers = { "content-type": "application/x-www-form-urlencoded", accept: "application/json" };
|
|
72143
|
-
if (c.clientAuth === "
|
|
72611
|
+
if (c.clientAuth === "private_key_jwt") {
|
|
72612
|
+
form.set("client_id", c.clientId);
|
|
72613
|
+
form.set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
|
|
72614
|
+
form.set("client_assertion", signedAssertion(c, { iss: c.clientId, sub: c.clientId, aud: c.audience || c.tokenUrl }, now));
|
|
72615
|
+
} else if (fields.grant_type === JWT_BEARER && !c.clientSecret) {
|
|
72616
|
+
} else if (c.clientAuth === "basic" && c.clientSecret) {
|
|
72144
72617
|
headers.authorization = `Basic ${Buffer.from(`${encodeURIComponent(c.clientId)}:${encodeURIComponent(c.clientSecret)}`).toString("base64")}`;
|
|
72145
72618
|
} else {
|
|
72146
72619
|
form.set("client_id", c.clientId);
|
|
@@ -72182,39 +72655,84 @@ async function postToken(c, fields) {
|
|
|
72182
72655
|
obtainedAt: Date.now()
|
|
72183
72656
|
};
|
|
72184
72657
|
}
|
|
72185
|
-
function grantFields(c) {
|
|
72658
|
+
async function grantFields(c, now = Math.floor(Date.now() / 1e3)) {
|
|
72186
72659
|
if (c.grant === "client_credentials") return { grant_type: "client_credentials" };
|
|
72187
72660
|
if (c.grant === "password") return { grant_type: "password", username: c.username, password: c.password };
|
|
72661
|
+
if (c.grant === "jwt_bearer") {
|
|
72662
|
+
const claims = { iss: c.issuer || c.clientId, ...c.subject ? { sub: c.subject } : {}, aud: c.audience || c.tokenUrl, ...extraClaims(c) };
|
|
72663
|
+
return { grant_type: JWT_BEARER, assertion: signedAssertion(c, claims, now) };
|
|
72664
|
+
}
|
|
72665
|
+
if (c.grant === "saml_bearer") {
|
|
72666
|
+
const fields = { grant_type: SAML_BEARER, assertion: c.samlSource === "assertion" ? c.assertion : await samlFromIdp(c) };
|
|
72667
|
+
if (c.companyId) fields.company_id = c.companyId;
|
|
72668
|
+
return fields;
|
|
72669
|
+
}
|
|
72188
72670
|
throw new OAuthError("sign in first \u2014 press \u201CSign in in the browser\u201D on the Auth tab; the token is then kept and refreshed");
|
|
72189
72671
|
}
|
|
72672
|
+
async function samlFromIdp(c) {
|
|
72673
|
+
const key = c.privateKey.replace(/-----[^-]+-----/g, "").replace(/\s+/g, "");
|
|
72674
|
+
const form = new URLSearchParams({ client_id: c.clientId, user_id: c.userId, token_url: c.tokenUrl, private_key: key });
|
|
72675
|
+
if (c.companyId) form.set("company_id", c.companyId);
|
|
72676
|
+
let status;
|
|
72677
|
+
let text;
|
|
72678
|
+
try {
|
|
72679
|
+
const connect = await tlsConnect(c.idpUrl);
|
|
72680
|
+
const res = await (0, import_undici.request)(c.idpUrl, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: form.toString(), headersTimeout: 2e4, bodyTimeout: 2e4, dispatcher: connect ? new import_undici.Agent({ connect }) : void 0 });
|
|
72681
|
+
status = res.statusCode;
|
|
72682
|
+
text = (await res.body.text()).trim();
|
|
72683
|
+
} catch (err) {
|
|
72684
|
+
throw new OAuthError(`couldn't reach the assertion URL (${err instanceof Error ? err.message : "network error"})`);
|
|
72685
|
+
}
|
|
72686
|
+
if (status < 200 || status >= 300 || !text || text.startsWith("{") || text.startsWith("<")) {
|
|
72687
|
+
throw new OAuthError(`the assertion URL answered ${status} (${text.slice(0, 160) || "no details"}) \u2014 check the client ID, user ID and private key`);
|
|
72688
|
+
}
|
|
72689
|
+
return text;
|
|
72690
|
+
}
|
|
72190
72691
|
async function getToken(c, opts = {}) {
|
|
72191
72692
|
const key = oauthKey(c);
|
|
72192
|
-
const kept = await
|
|
72693
|
+
const kept = await load2(key);
|
|
72193
72694
|
if (!opts.force && fresh(kept)) return kept;
|
|
72194
72695
|
if (kept?.refreshToken) {
|
|
72195
72696
|
try {
|
|
72196
72697
|
const next = await postToken(c, { grant_type: "refresh_token", refresh_token: kept.refreshToken });
|
|
72197
72698
|
const token2 = { ...next, refreshToken: next.refreshToken ?? kept.refreshToken };
|
|
72198
|
-
await
|
|
72699
|
+
await save2(key, token2);
|
|
72199
72700
|
return token2;
|
|
72200
72701
|
} catch (err) {
|
|
72201
72702
|
if (c.grant === "authorization_code") throw new OAuthError(`the refresh token stopped working (${err instanceof Error ? err.message : "error"}) \u2014 sign in in the browser again`);
|
|
72202
72703
|
}
|
|
72203
72704
|
}
|
|
72204
|
-
const token = await postToken(c, grantFields(c));
|
|
72205
|
-
await
|
|
72705
|
+
const token = await postToken(c, await grantFields(c));
|
|
72706
|
+
await save2(key, token);
|
|
72206
72707
|
return token;
|
|
72207
72708
|
}
|
|
72208
72709
|
async function tokenStatus(c) {
|
|
72209
|
-
const t = await
|
|
72710
|
+
const t = await load2(oauthKey(c));
|
|
72210
72711
|
if (!t?.accessToken) return { hasToken: false, expiresAt: null, canRefresh: c.grant !== "authorization_code" };
|
|
72211
72712
|
return { hasToken: true, expiresAt: t.expiresAt, scope: t.scope, canRefresh: Boolean(t.refreshToken) || c.grant !== "authorization_code", preview: `${t.accessToken.slice(0, 6)}\u2026` };
|
|
72212
72713
|
}
|
|
72213
|
-
function refreshPlan(c, t) {
|
|
72714
|
+
async function refreshPlan(c, t, runMs = 36e5) {
|
|
72214
72715
|
if (t.expiresAt === null) return null;
|
|
72215
|
-
|
|
72216
|
-
|
|
72217
|
-
|
|
72716
|
+
if (c.grant === "authorization_code") {
|
|
72717
|
+
return t.refreshToken ? { tokenUrl: c.tokenUrl, ...tokenRequest(c, { grant_type: "refresh_token", refresh_token: t.refreshToken }), expiresAt: t.expiresAt } : null;
|
|
72718
|
+
}
|
|
72719
|
+
if (c.grant === "saml_bearer" && c.samlSource === "idp") return null;
|
|
72720
|
+
const signs = c.grant === "jwt_bearer" || c.clientAuth === "private_key_jwt";
|
|
72721
|
+
if (!signs) {
|
|
72722
|
+
return { tokenUrl: c.tokenUrl, ...tokenRequest(c, await grantFields(c)), expiresAt: t.expiresAt };
|
|
72723
|
+
}
|
|
72724
|
+
const start = Math.floor(Date.now() / 1e3);
|
|
72725
|
+
const stepSec = 240;
|
|
72726
|
+
const count = Math.min(2e3, Math.ceil((runMs / 1e3 + 120) / stepSec));
|
|
72727
|
+
const list = [];
|
|
72728
|
+
let headers = {};
|
|
72729
|
+
for (let i = 0; i < count; i++) {
|
|
72730
|
+
const now = start + i * stepSec;
|
|
72731
|
+
const req = tokenRequest(c, await grantFields(c, now), now);
|
|
72732
|
+
headers = req.headers;
|
|
72733
|
+
list.push(req.body);
|
|
72734
|
+
}
|
|
72735
|
+
return { tokenUrl: c.tokenUrl, headers, body: list[0], expiresAt: t.expiresAt, bodies: { start, stepSec, list } };
|
|
72218
72736
|
}
|
|
72219
72737
|
async function startAuthorization(c) {
|
|
72220
72738
|
const redirect = new URL(c.redirectUri);
|
|
@@ -72257,7 +72775,7 @@ async function startAuthorization(c) {
|
|
|
72257
72775
|
if (!code) return finish(false, "No code came back.");
|
|
72258
72776
|
const fields = { grant_type: "authorization_code", code, redirect_uri: c.redirectUri };
|
|
72259
72777
|
if (c.pkce) fields.code_verifier = verifier;
|
|
72260
|
-
postToken(c, fields).then((token) =>
|
|
72778
|
+
postToken(c, fields).then((token) => save2(oauthKey(c), token)).then(() => finish(true, "You can close this tab and go back to APITestCenter.")).catch((err) => finish(false, err instanceof Error ? `Couldn't get the token: ${err.message}` : "Couldn't get the token."));
|
|
72261
72779
|
});
|
|
72262
72780
|
await new Promise((resolve5, reject) => {
|
|
72263
72781
|
server.once(
|
|
@@ -72319,14 +72837,15 @@ function registerOAuthRoutes(app2) {
|
|
|
72319
72837
|
});
|
|
72320
72838
|
app2.get("/oauth/authorize/:id", async (request3) => authorizationStatus(request3.params.id));
|
|
72321
72839
|
}
|
|
72322
|
-
var import_undici,
|
|
72840
|
+
var import_undici, store2, memory, OAuthError, HINTS, JWT_BEARER, SAML_BEARER, fresh, pending, page, b64url2;
|
|
72323
72841
|
var init_oauth = __esm({
|
|
72324
72842
|
"../../apps/engine/src/oauth.ts"() {
|
|
72325
72843
|
"use strict";
|
|
72326
72844
|
init_src();
|
|
72327
72845
|
import_undici = __toESM(require_undici(), 1);
|
|
72328
72846
|
init_certificates();
|
|
72329
|
-
|
|
72847
|
+
init_jwt();
|
|
72848
|
+
store2 = null;
|
|
72330
72849
|
memory = /* @__PURE__ */ new Map();
|
|
72331
72850
|
OAuthError = class extends Error {
|
|
72332
72851
|
};
|
|
@@ -72337,6 +72856,8 @@ var init_oauth = __esm({
|
|
|
72337
72856
|
invalid_scope: "the scope isn't allowed for this client",
|
|
72338
72857
|
unsupported_grant_type: "the server doesn't offer this grant type"
|
|
72339
72858
|
};
|
|
72859
|
+
JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
72860
|
+
SAML_BEARER = "urn:ietf:params:oauth:grant-type:saml2-bearer";
|
|
72340
72861
|
fresh = (t, marginMs = 6e4) => Boolean(t && (t.expiresAt === null || t.expiresAt - marginMs > Date.now()));
|
|
72341
72862
|
pending = /* @__PURE__ */ new Map();
|
|
72342
72863
|
page = (title, text) => `<!doctype html><meta charset="utf-8"><title>${title}</title><body style="font-family:system-ui;background:#0b0f14;color:#e6edf3;display:grid;place-items:center;height:100vh;margin:0"><div style="max-width:28rem;text-align:center"><h1 style="font-size:1.3rem">${title}</h1><p style="color:#9aa7b4">${text}</p></div>`;
|
|
@@ -72518,6 +73039,30 @@ var init_aws_sign = __esm({
|
|
|
72518
73039
|
}
|
|
72519
73040
|
});
|
|
72520
73041
|
|
|
73042
|
+
// ../../apps/engine/src/oauth1-sign.ts
|
|
73043
|
+
import { createHmac as createHmac4, randomBytes as randomBytes3 } from "node:crypto";
|
|
73044
|
+
function signOAuth1(c, req, nonce = randomBytes3(16).toString("hex"), timestamp = Math.floor(Date.now() / 1e3)) {
|
|
73045
|
+
const oauth = oauth1Params(c, nonce, timestamp);
|
|
73046
|
+
const query = /\?([^#]*)/.exec(req.url)?.[1] ?? "";
|
|
73047
|
+
const params = [...oauth, ...formPairs(query)];
|
|
73048
|
+
if (req.body && /^application\/x-www-form-urlencoded/i.test(req.contentType ?? "")) params.push(...formPairs(req.body));
|
|
73049
|
+
const baseString = oauth1BaseString(req.method, req.url, params);
|
|
73050
|
+
const key = oauth1SigningKey(c);
|
|
73051
|
+
const signature = c.signatureMethod === "PLAINTEXT" ? key : createHmac4(c.signatureMethod === "HMAC-SHA1" ? "sha1" : "sha256", key).update(baseString).digest("base64");
|
|
73052
|
+
const signed = [...oauth, ["oauth_signature", signature]];
|
|
73053
|
+
if (c.addTo === "query") {
|
|
73054
|
+
const extra2 = signed.map(([k, v]) => `${pctEncode(k)}=${pctEncode(v)}`).join("&");
|
|
73055
|
+
return { url: `${req.url}${req.url.includes("?") ? "&" : "?"}${extra2}`, signature, baseString };
|
|
73056
|
+
}
|
|
73057
|
+
return { url: req.url, authorization: oauth1Header(c, signed), signature, baseString };
|
|
73058
|
+
}
|
|
73059
|
+
var init_oauth1_sign = __esm({
|
|
73060
|
+
"../../apps/engine/src/oauth1-sign.ts"() {
|
|
73061
|
+
"use strict";
|
|
73062
|
+
init_src();
|
|
73063
|
+
}
|
|
73064
|
+
});
|
|
73065
|
+
|
|
72521
73066
|
// ../../apps/engine/src/probe.ts
|
|
72522
73067
|
function redactHeaders(headers, extraNames = []) {
|
|
72523
73068
|
const extra2 = new Set(extraNames.map((n) => n.toLowerCase()));
|
|
@@ -72714,6 +73259,16 @@ async function sendRaw(lab, extra2 = {}) {
|
|
|
72714
73259
|
if (encoded.contentType && !Object.keys(headers).some((k) => k.toLowerCase() === "content-type")) {
|
|
72715
73260
|
headers["content-type"] = encoded.contentType;
|
|
72716
73261
|
}
|
|
73262
|
+
let target = url2;
|
|
73263
|
+
if (lab.auth.mode === "oauth1") {
|
|
73264
|
+
const { mode: _mode, ...creds } = lab.auth;
|
|
73265
|
+
const contentType = Object.entries(headers).find(([k]) => k.toLowerCase() === "content-type")?.[1];
|
|
73266
|
+
const signed = signOAuth1(creds, { method: lab.request.method, url: url2.toString(), contentType, body: encoded.body });
|
|
73267
|
+
if (signed.authorization) {
|
|
73268
|
+
headers.authorization = signed.authorization;
|
|
73269
|
+
secretNames.push("authorization");
|
|
73270
|
+
} else target = new URL(signed.url);
|
|
73271
|
+
}
|
|
72717
73272
|
if (lab.auth.mode === "aws_sigv4") {
|
|
72718
73273
|
const { mode: _mode, ...creds } = lab.auth;
|
|
72719
73274
|
Object.assign(headers, signAws(creds, { method: lab.request.method, url: url2.toString(), headers, body: encoded.body }));
|
|
@@ -72721,20 +73276,39 @@ async function sendRaw(lab, extra2 = {}) {
|
|
|
72721
73276
|
}
|
|
72722
73277
|
const options = lab.options;
|
|
72723
73278
|
const timeout = durationToMs(options.timeout);
|
|
72724
|
-
const
|
|
72725
|
-
|
|
72726
|
-
|
|
72727
|
-
|
|
73279
|
+
const useJar = options.cookies !== false && !extra2.dispatcher;
|
|
73280
|
+
const ownCookie = Object.keys(headers).some((k) => k.toLowerCase() === "cookie");
|
|
73281
|
+
const agent = extra2.dispatcher ?? new import_undici2.Agent({ connect: await tlsConnect(url2, options.tlsSkipVerify) });
|
|
73282
|
+
const dispatcher = extra2.dispatcher ?? (useJar ? agent : agent.compose(import_undici2.interceptors.redirect({ maxRedirections: options.maxRedirects })));
|
|
72728
73283
|
const started = performance.now();
|
|
72729
73284
|
try {
|
|
72730
|
-
|
|
72731
|
-
|
|
72732
|
-
|
|
72733
|
-
|
|
72734
|
-
|
|
72735
|
-
|
|
72736
|
-
|
|
72737
|
-
|
|
73285
|
+
let current = target;
|
|
73286
|
+
let method = lab.request.method;
|
|
73287
|
+
let body = encoded.body;
|
|
73288
|
+
let response;
|
|
73289
|
+
for (let hops = 0; ; hops++) {
|
|
73290
|
+
const sendHeaders = { ...headers };
|
|
73291
|
+
if (useJar && !ownCookie) {
|
|
73292
|
+
const jar2 = await cookieHeader(current);
|
|
73293
|
+
if (jar2) sendHeaders.cookie = jar2;
|
|
73294
|
+
}
|
|
73295
|
+
response = await (0, import_undici2.request)(current, { method, headers: sendHeaders, body, headersTimeout: timeout, bodyTimeout: timeout, dispatcher });
|
|
73296
|
+
if (!useJar) break;
|
|
73297
|
+
await storeCookies(current, response.headers["set-cookie"]);
|
|
73298
|
+
const location = response.headers.location;
|
|
73299
|
+
if (![301, 302, 303, 307, 308].includes(response.statusCode) || typeof location !== "string" || hops >= options.maxRedirects) break;
|
|
73300
|
+
await response.body.dump();
|
|
73301
|
+
const next = new URL(location, current);
|
|
73302
|
+
if (next.origin !== current.origin) {
|
|
73303
|
+
for (const k of Object.keys(headers)) if (k.toLowerCase() === "authorization") delete headers[k];
|
|
73304
|
+
}
|
|
73305
|
+
if (response.statusCode === 303 || (response.statusCode === 301 || response.statusCode === 302) && method === "POST") {
|
|
73306
|
+
method = "GET";
|
|
73307
|
+
body = void 0;
|
|
73308
|
+
for (const k of Object.keys(headers)) if (k.toLowerCase() === "content-type") delete headers[k];
|
|
73309
|
+
}
|
|
73310
|
+
current = next;
|
|
73311
|
+
}
|
|
72738
73312
|
const raw = await response.body.text();
|
|
72739
73313
|
const durationMs = Math.round((performance.now() - started) * 10) / 10;
|
|
72740
73314
|
const truncated = raw.length > BODY_LIMIT;
|
|
@@ -72789,8 +73363,10 @@ var init_probe = __esm({
|
|
|
72789
73363
|
import_undici2 = __toESM(require_undici(), 1);
|
|
72790
73364
|
init_challenge_auth();
|
|
72791
73365
|
init_aws_sign();
|
|
73366
|
+
init_oauth1_sign();
|
|
72792
73367
|
init_jwt();
|
|
72793
73368
|
init_certificates();
|
|
73369
|
+
init_cookies();
|
|
72794
73370
|
init_oauth();
|
|
72795
73371
|
BODY_LIMIT = 64 * 1024;
|
|
72796
73372
|
}
|
|
@@ -73138,12 +73714,12 @@ function dataDefinition(lab) {
|
|
|
73138
73714
|
};
|
|
73139
73715
|
}
|
|
73140
73716
|
function loadDefinition(run2) {
|
|
73141
|
-
const
|
|
73142
|
-
const rate = isArrivalRate(
|
|
73717
|
+
const load3 = run2.lab.load;
|
|
73718
|
+
const rate = isArrivalRate(load3.executor);
|
|
73143
73719
|
return {
|
|
73144
|
-
executor:
|
|
73145
|
-
rate: rate ?
|
|
73146
|
-
stages:
|
|
73720
|
+
executor: load3.executor,
|
|
73721
|
+
rate: rate ? load3.rate ?? Math.max(0, ...load3.stages.map((s) => s.target)) : void 0,
|
|
73722
|
+
stages: load3.stages.length > 0 ? load3.stages : [{ duration: load3.duration, target: rate ? load3.rate ?? 0 : load3.vus }]
|
|
73147
73723
|
};
|
|
73148
73724
|
}
|
|
73149
73725
|
function liveSummaryParts(run2) {
|
|
@@ -73362,7 +73938,7 @@ async function startRun(lab, repoRoot2) {
|
|
|
73362
73938
|
} catch (err) {
|
|
73363
73939
|
throw Object.assign(new Error(`OAuth 2.0: ${err instanceof Error ? err.message : String(err)}`), { statusCode: 422 });
|
|
73364
73940
|
}
|
|
73365
|
-
refresh = refreshPlan(config2, token);
|
|
73941
|
+
refresh = await refreshPlan(config2, token, loadDurationHintMs(filled.load));
|
|
73366
73942
|
filled = { ...filled, auth: { mode: "bearer", token: token.accessToken } };
|
|
73367
73943
|
}
|
|
73368
73944
|
let tlsAuth;
|
|
@@ -73382,7 +73958,19 @@ async function startRun(lab, repoRoot2) {
|
|
|
73382
73958
|
}
|
|
73383
73959
|
filled = { ...filled, auth: { mode: "none" } };
|
|
73384
73960
|
}
|
|
73961
|
+
const bundle = await caBundle();
|
|
73962
|
+
if (bundle && process.platform !== "linux" && !filled.options.tlsSkipVerify && await needsTrustedCa(filled.request.url)) {
|
|
73963
|
+
filled = { ...filled, options: { ...filled.options, tlsSkipVerify: true } };
|
|
73964
|
+
}
|
|
73385
73965
|
const generated = generateK6Script(filled, { oauthRefresh: refresh, tlsAuth, jwt: jwt2 });
|
|
73966
|
+
if (filled.options.cookies !== false && !filled.request.headers.some((h) => h.key.toLowerCase() === "cookie")) {
|
|
73967
|
+
const jar2 = await cookieHeader(filled.request.url);
|
|
73968
|
+
if (jar2) generated.env.ATC_COOKIE = jar2;
|
|
73969
|
+
}
|
|
73970
|
+
if (bundle && process.platform === "linux") {
|
|
73971
|
+
await writeFile3(join5(dir2, "ca-bundle.pem"), bundle, "utf8");
|
|
73972
|
+
generated.env.SSL_CERT_FILE = join5(dir2, "ca-bundle.pem");
|
|
73973
|
+
}
|
|
73386
73974
|
await writeFile3(scriptPath, generated.script, "utf8");
|
|
73387
73975
|
for (const [name, text] of Object.entries(generated.files)) await writeFile3(join5(dir2, name), text, "utf8");
|
|
73388
73976
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -73529,6 +74117,7 @@ var init_load_run = __esm({
|
|
|
73529
74117
|
init_k6_script();
|
|
73530
74118
|
init_src();
|
|
73531
74119
|
init_certificates();
|
|
74120
|
+
init_cookies();
|
|
73532
74121
|
init_jwt();
|
|
73533
74122
|
init_oauth();
|
|
73534
74123
|
init_probe();
|
|
@@ -73542,7 +74131,7 @@ var init_load_run = __esm({
|
|
|
73542
74131
|
});
|
|
73543
74132
|
|
|
73544
74133
|
// ../../apps/engine/src/secret-store.ts
|
|
73545
|
-
import { createCipheriv, createDecipheriv, randomBytes as
|
|
74134
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4 } from "node:crypto";
|
|
73546
74135
|
import { readFile as readFile4, rename as rename3, writeFile as writeFile4 } from "node:fs/promises";
|
|
73547
74136
|
import { join as join6 } from "node:path";
|
|
73548
74137
|
var SecretStore;
|
|
@@ -73579,7 +74168,7 @@ var init_secret_store = __esm({
|
|
|
73579
74168
|
}
|
|
73580
74169
|
async persist() {
|
|
73581
74170
|
if (!this.key) return;
|
|
73582
|
-
const iv =
|
|
74171
|
+
const iv = randomBytes4(12);
|
|
73583
74172
|
const cipher = createCipheriv("aes-256-gcm", this.key, iv);
|
|
73584
74173
|
const body = Buffer.concat([cipher.update(JSON.stringify(Object.fromEntries(this.values)), "utf8"), cipher.final()]);
|
|
73585
74174
|
const tmp = `${this.file}.${process.pid}.tmp`;
|
|
@@ -78624,14 +79213,14 @@ var require_wrap_thenable = __commonJS({
|
|
|
78624
79213
|
var { setErrorStatusCode } = require_error_status();
|
|
78625
79214
|
var diagnostics = __require("node:diagnostics_channel");
|
|
78626
79215
|
var channels = diagnostics.tracingChannel("fastify.request.handler");
|
|
78627
|
-
function wrapThenable(thenable, reply,
|
|
78628
|
-
if (
|
|
79216
|
+
function wrapThenable(thenable, reply, store3) {
|
|
79217
|
+
if (store3) store3.async = true;
|
|
78629
79218
|
thenable.then(function(payload) {
|
|
78630
79219
|
if (reply[kReplyHijacked] === true) {
|
|
78631
79220
|
return;
|
|
78632
79221
|
}
|
|
78633
|
-
if (
|
|
78634
|
-
channels.asyncStart.publish(
|
|
79222
|
+
if (store3) {
|
|
79223
|
+
channels.asyncStart.publish(store3);
|
|
78635
79224
|
}
|
|
78636
79225
|
try {
|
|
78637
79226
|
if (payload !== void 0 || //
|
|
@@ -78645,16 +79234,16 @@ var require_wrap_thenable = __commonJS({
|
|
|
78645
79234
|
}
|
|
78646
79235
|
}
|
|
78647
79236
|
} finally {
|
|
78648
|
-
if (
|
|
78649
|
-
channels.asyncEnd.publish(
|
|
79237
|
+
if (store3) {
|
|
79238
|
+
channels.asyncEnd.publish(store3);
|
|
78650
79239
|
}
|
|
78651
79240
|
}
|
|
78652
79241
|
}, function(err) {
|
|
78653
|
-
if (
|
|
78654
|
-
|
|
79242
|
+
if (store3) {
|
|
79243
|
+
store3.error = err;
|
|
78655
79244
|
setErrorStatusCode(reply, err);
|
|
78656
|
-
channels.error.publish(
|
|
78657
|
-
channels.asyncStart.publish(
|
|
79245
|
+
channels.error.publish(store3);
|
|
79246
|
+
channels.asyncStart.publish(store3);
|
|
78658
79247
|
}
|
|
78659
79248
|
try {
|
|
78660
79249
|
if (reply.sent === true) {
|
|
@@ -78666,8 +79255,8 @@ var require_wrap_thenable = __commonJS({
|
|
|
78666
79255
|
} catch (err2) {
|
|
78667
79256
|
reply.send(err2);
|
|
78668
79257
|
} finally {
|
|
78669
|
-
if (
|
|
78670
|
-
channels.asyncEnd.publish(
|
|
79258
|
+
if (store3) {
|
|
79259
|
+
channels.asyncEnd.publish(store3);
|
|
78671
79260
|
}
|
|
78672
79261
|
}
|
|
78673
79262
|
});
|
|
@@ -78994,10 +79583,10 @@ var require_content_type = __commonJS({
|
|
|
78994
79583
|
this.#subtype = subtype;
|
|
78995
79584
|
this.#valid = true;
|
|
78996
79585
|
this.#empty = false;
|
|
78997
|
-
let
|
|
78998
|
-
while (
|
|
78999
|
-
const key =
|
|
79000
|
-
let value =
|
|
79586
|
+
let matches2 = keyValuePairsReg.exec(paramsList);
|
|
79587
|
+
while (matches2) {
|
|
79588
|
+
const key = matches2[1].toLowerCase();
|
|
79589
|
+
let value = matches2[2];
|
|
79001
79590
|
if (value.charCodeAt(0) === 34) {
|
|
79002
79591
|
value = value.slice(1, -1);
|
|
79003
79592
|
if (value.indexOf("\\") !== -1) {
|
|
@@ -79005,7 +79594,7 @@ var require_content_type = __commonJS({
|
|
|
79005
79594
|
}
|
|
79006
79595
|
}
|
|
79007
79596
|
this.#parameters.set(key, value);
|
|
79008
|
-
|
|
79597
|
+
matches2 = keyValuePairsReg.exec(paramsList);
|
|
79009
79598
|
}
|
|
79010
79599
|
}
|
|
79011
79600
|
get [Symbol.toStringTag]() {
|
|
@@ -79183,7 +79772,7 @@ var require_handle_request = __commonJS({
|
|
|
79183
79772
|
if (!channels.hasSubscribers || context[kFourOhFourContext] === null) {
|
|
79184
79773
|
preHandlerCallbackInner(err, request3, reply);
|
|
79185
79774
|
} else {
|
|
79186
|
-
const
|
|
79775
|
+
const store3 = {
|
|
79187
79776
|
request: request3,
|
|
79188
79777
|
reply,
|
|
79189
79778
|
async: false,
|
|
@@ -79192,19 +79781,19 @@ var require_handle_request = __commonJS({
|
|
|
79192
79781
|
method: context.config.method
|
|
79193
79782
|
}
|
|
79194
79783
|
};
|
|
79195
|
-
reply[kDiagnosticsStore] =
|
|
79196
|
-
channels.start.runStores(
|
|
79784
|
+
reply[kDiagnosticsStore] = store3;
|
|
79785
|
+
channels.start.runStores(store3, preHandlerCallbackInner, void 0, err, request3, reply, store3);
|
|
79197
79786
|
}
|
|
79198
79787
|
}
|
|
79199
|
-
function preHandlerCallbackInner(err, request3, reply,
|
|
79788
|
+
function preHandlerCallbackInner(err, request3, reply, store3) {
|
|
79200
79789
|
const context = request3[kRouteContext];
|
|
79201
79790
|
try {
|
|
79202
79791
|
if (err != null) {
|
|
79203
79792
|
reply[kReplyIsError] = true;
|
|
79204
|
-
if (
|
|
79205
|
-
|
|
79793
|
+
if (store3) {
|
|
79794
|
+
store3.error = err;
|
|
79206
79795
|
setErrorStatusCode(reply, err);
|
|
79207
|
-
channels.error.publish(
|
|
79796
|
+
channels.error.publish(store3);
|
|
79208
79797
|
}
|
|
79209
79798
|
reply.send(err);
|
|
79210
79799
|
return;
|
|
@@ -79213,10 +79802,10 @@ var require_handle_request = __commonJS({
|
|
|
79213
79802
|
try {
|
|
79214
79803
|
result = context.handler(request3, reply);
|
|
79215
79804
|
} catch (err2) {
|
|
79216
|
-
if (
|
|
79217
|
-
|
|
79805
|
+
if (store3) {
|
|
79806
|
+
store3.error = err2;
|
|
79218
79807
|
setErrorStatusCode(reply, err2);
|
|
79219
|
-
channels.error.publish(
|
|
79808
|
+
channels.error.publish(store3);
|
|
79220
79809
|
}
|
|
79221
79810
|
reply[kReplyIsError] = true;
|
|
79222
79811
|
reply.send(err2);
|
|
@@ -79224,13 +79813,13 @@ var require_handle_request = __commonJS({
|
|
|
79224
79813
|
}
|
|
79225
79814
|
if (result !== void 0) {
|
|
79226
79815
|
if (result !== null && typeof result.then === "function") {
|
|
79227
|
-
wrapThenable(result, reply,
|
|
79816
|
+
wrapThenable(result, reply, store3);
|
|
79228
79817
|
} else {
|
|
79229
79818
|
reply.send(result);
|
|
79230
79819
|
}
|
|
79231
79820
|
}
|
|
79232
79821
|
} finally {
|
|
79233
|
-
if (
|
|
79822
|
+
if (store3) channels.end.publish(store3);
|
|
79234
79823
|
}
|
|
79235
79824
|
}
|
|
79236
79825
|
module.exports = handleRequest;
|
|
@@ -83627,8 +84216,8 @@ var require_tools = __commonJS({
|
|
|
83627
84216
|
if (asJsonChan.hasSubscribers === false) {
|
|
83628
84217
|
return _asJson.call(this, obj, msg, num3, time3);
|
|
83629
84218
|
}
|
|
83630
|
-
const
|
|
83631
|
-
return asJsonChan.traceSync(_asJson,
|
|
84219
|
+
const store3 = { instance: this, arguments };
|
|
84220
|
+
return asJsonChan.traceSync(_asJson, store3, this, obj, msg, num3, time3);
|
|
83632
84221
|
}
|
|
83633
84222
|
function _asJson(obj, msg, num3, time3) {
|
|
83634
84223
|
const stringify2 = this[stringifySym];
|
|
@@ -85896,8 +86485,8 @@ var require_error_handler = __commonJS({
|
|
|
85896
86485
|
const result = func(error51, reply.request, reply);
|
|
85897
86486
|
if (result !== void 0) {
|
|
85898
86487
|
if (result !== null && typeof result.then === "function") {
|
|
85899
|
-
const
|
|
85900
|
-
wrapThenable(result, reply,
|
|
86488
|
+
const store3 = reply[kDiagnosticsStore] || null;
|
|
86489
|
+
wrapThenable(result, reply, store3);
|
|
85901
86490
|
} else {
|
|
85902
86491
|
reply.send(result);
|
|
85903
86492
|
}
|
|
@@ -88216,11 +88805,11 @@ var require_request3 = __commonJS({
|
|
|
88216
88805
|
port: {
|
|
88217
88806
|
get() {
|
|
88218
88807
|
const portReg = /(?<port>:\d+)$/;
|
|
88219
|
-
const
|
|
88220
|
-
if (
|
|
88808
|
+
const matches2 = portReg.exec(this.host);
|
|
88809
|
+
if (matches2 === null || matches2[1] === void 0) {
|
|
88221
88810
|
return null;
|
|
88222
88811
|
}
|
|
88223
|
-
return parseInt(
|
|
88812
|
+
return parseInt(matches2.groups.port.slice(1), 10);
|
|
88224
88813
|
}
|
|
88225
88814
|
},
|
|
88226
88815
|
protocol: {
|
|
@@ -91627,11 +92216,11 @@ var require_validate = __commonJS({
|
|
|
91627
92216
|
jsonPointer = $data;
|
|
91628
92217
|
data = names_1.default.rootData;
|
|
91629
92218
|
} else {
|
|
91630
|
-
const
|
|
91631
|
-
if (!
|
|
92219
|
+
const matches2 = RELATIVE_JSON_POINTER.exec($data);
|
|
92220
|
+
if (!matches2)
|
|
91632
92221
|
throw new Error(`Invalid JSON-pointer: ${$data}`);
|
|
91633
|
-
const up = +
|
|
91634
|
-
jsonPointer =
|
|
92222
|
+
const up = +matches2[1];
|
|
92223
|
+
jsonPointer = matches2[2];
|
|
91635
92224
|
if (jsonPointer === "#") {
|
|
91636
92225
|
if (up >= dataLevel)
|
|
91637
92226
|
throw new Error(errorMsg("property/index", up));
|
|
@@ -92328,11 +92917,11 @@ var require_schemes = __commonJS({
|
|
|
92328
92917
|
urnComponent.error = "URN can not be parsed";
|
|
92329
92918
|
return urnComponent;
|
|
92330
92919
|
}
|
|
92331
|
-
const
|
|
92332
|
-
if (
|
|
92920
|
+
const matches2 = urnComponent.path.match(URN_REG);
|
|
92921
|
+
if (matches2) {
|
|
92333
92922
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
92334
|
-
urnComponent.nid =
|
|
92335
|
-
urnComponent.nss =
|
|
92923
|
+
urnComponent.nid = matches2[1].toLowerCase();
|
|
92924
|
+
urnComponent.nss = matches2[2];
|
|
92336
92925
|
const urnScheme = `${scheme}:${options.nid || urnComponent.nid}`;
|
|
92337
92926
|
const schemeHandler = getSchemeHandler(urnScheme);
|
|
92338
92927
|
urnComponent.path = void 0;
|
|
@@ -92609,8 +93198,8 @@ var require_fast_uri = __commonJS({
|
|
|
92609
93198
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
92610
93199
|
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
92611
93200
|
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
92612
|
-
function getParseError(parsed,
|
|
92613
|
-
if (
|
|
93201
|
+
function getParseError(parsed, matches2) {
|
|
93202
|
+
if (matches2[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
92614
93203
|
return 'URI path must start with "/" when authority is present.';
|
|
92615
93204
|
}
|
|
92616
93205
|
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
@@ -92657,19 +93246,19 @@ var require_fast_uri = __commonJS({
|
|
|
92657
93246
|
}
|
|
92658
93247
|
}
|
|
92659
93248
|
}
|
|
92660
|
-
const
|
|
92661
|
-
if (
|
|
92662
|
-
parsed.scheme =
|
|
92663
|
-
parsed.userinfo =
|
|
92664
|
-
parsed.host =
|
|
92665
|
-
parsed.port = parseInt(
|
|
92666
|
-
parsed.path =
|
|
92667
|
-
parsed.query =
|
|
92668
|
-
parsed.fragment =
|
|
93249
|
+
const matches2 = uri.match(URI_PARSE);
|
|
93250
|
+
if (matches2) {
|
|
93251
|
+
parsed.scheme = matches2[1];
|
|
93252
|
+
parsed.userinfo = matches2[3];
|
|
93253
|
+
parsed.host = matches2[4];
|
|
93254
|
+
parsed.port = parseInt(matches2[5], 10);
|
|
93255
|
+
parsed.path = matches2[6] || "";
|
|
93256
|
+
parsed.query = matches2[7];
|
|
93257
|
+
parsed.fragment = matches2[8];
|
|
92669
93258
|
if (isNaN(parsed.port)) {
|
|
92670
|
-
parsed.port =
|
|
93259
|
+
parsed.port = matches2[5];
|
|
92671
93260
|
}
|
|
92672
|
-
const parseError = getParseError(parsed,
|
|
93261
|
+
const parseError = getParseError(parsed, matches2);
|
|
92673
93262
|
if (parseError !== void 0) {
|
|
92674
93263
|
parsed.error = parsed.error || parseError;
|
|
92675
93264
|
malformedAuthorityOrPort = true;
|
|
@@ -95547,24 +96136,24 @@ var require_timestamp2 = __commonJS({
|
|
|
95547
96136
|
}
|
|
95548
96137
|
exports.default = validTimestamp;
|
|
95549
96138
|
function validDate(str2) {
|
|
95550
|
-
const
|
|
95551
|
-
if (!
|
|
96139
|
+
const matches2 = DATE.exec(str2);
|
|
96140
|
+
if (!matches2)
|
|
95552
96141
|
return false;
|
|
95553
|
-
const y = +
|
|
95554
|
-
const m = +
|
|
95555
|
-
const d = +
|
|
96142
|
+
const y = +matches2[1];
|
|
96143
|
+
const m = +matches2[2];
|
|
96144
|
+
const d = +matches2[3];
|
|
95556
96145
|
return m >= 1 && m <= 12 && d >= 1 && (d <= DAYS[m] || // leap year: https://tools.ietf.org/html/rfc3339#appendix-C
|
|
95557
96146
|
m === 2 && d === 29 && (y % 100 === 0 ? y % 400 === 0 : y % 4 === 0));
|
|
95558
96147
|
}
|
|
95559
96148
|
function validTime(str2) {
|
|
95560
|
-
const
|
|
95561
|
-
if (!
|
|
96149
|
+
const matches2 = TIME.exec(str2);
|
|
96150
|
+
if (!matches2)
|
|
95562
96151
|
return false;
|
|
95563
|
-
const hr = +
|
|
95564
|
-
const min = +
|
|
95565
|
-
const sec = +
|
|
95566
|
-
const tzH = +(
|
|
95567
|
-
const tzM = +(
|
|
96152
|
+
const hr = +matches2[1];
|
|
96153
|
+
const min = +matches2[2];
|
|
96154
|
+
const sec = +matches2[3];
|
|
96155
|
+
const tzH = +(matches2[4] || 0);
|
|
96156
|
+
const tzM = +(matches2[5] || 0);
|
|
95568
96157
|
return hr <= 23 && min <= 59 && sec <= 59 || // leap second
|
|
95569
96158
|
hr - tzH === 23 && min - tzM === 59 && sec === 60;
|
|
95570
96159
|
}
|
|
@@ -96518,19 +97107,19 @@ var require_parseJson = __commonJS({
|
|
|
96518
97107
|
function parseJson(s, pos) {
|
|
96519
97108
|
let endPos;
|
|
96520
97109
|
parseJson.message = void 0;
|
|
96521
|
-
let
|
|
97110
|
+
let matches2;
|
|
96522
97111
|
if (pos)
|
|
96523
97112
|
s = s.slice(pos);
|
|
96524
97113
|
try {
|
|
96525
97114
|
parseJson.position = pos + s.length;
|
|
96526
97115
|
return JSON.parse(s);
|
|
96527
97116
|
} catch (e) {
|
|
96528
|
-
|
|
96529
|
-
if (!
|
|
97117
|
+
matches2 = rxParseJson.exec(e.message);
|
|
97118
|
+
if (!matches2) {
|
|
96530
97119
|
parseJson.message = "unexpected end";
|
|
96531
97120
|
return void 0;
|
|
96532
97121
|
}
|
|
96533
|
-
endPos = +
|
|
97122
|
+
endPos = +matches2[1];
|
|
96534
97123
|
const c = s[endPos];
|
|
96535
97124
|
s = s.slice(0, endPos);
|
|
96536
97125
|
parseJson.position = pos + endPos;
|
|
@@ -97612,11 +98201,11 @@ var require_schemes2 = __commonJS({
|
|
|
97612
98201
|
urnComponent.error = "URN can not be parsed";
|
|
97613
98202
|
return urnComponent;
|
|
97614
98203
|
}
|
|
97615
|
-
const
|
|
97616
|
-
if (
|
|
98204
|
+
const matches2 = urnComponent.path.match(URN_REG);
|
|
98205
|
+
if (matches2) {
|
|
97617
98206
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
97618
|
-
urnComponent.nid =
|
|
97619
|
-
urnComponent.nss =
|
|
98207
|
+
urnComponent.nid = matches2[1].toLowerCase();
|
|
98208
|
+
urnComponent.nss = matches2[2];
|
|
97620
98209
|
const urnScheme = `${scheme}:${options.nid || urnComponent.nid}`;
|
|
97621
98210
|
const schemeHandler = getSchemeHandler(urnScheme);
|
|
97622
98211
|
urnComponent.path = void 0;
|
|
@@ -97893,8 +98482,8 @@ var require_fast_uri2 = __commonJS({
|
|
|
97893
98482
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
97894
98483
|
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
97895
98484
|
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
97896
|
-
function getParseError(parsed,
|
|
97897
|
-
if (
|
|
98485
|
+
function getParseError(parsed, matches2) {
|
|
98486
|
+
if (matches2[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
97898
98487
|
return 'URI path must start with "/" when authority is present.';
|
|
97899
98488
|
}
|
|
97900
98489
|
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
@@ -97941,19 +98530,19 @@ var require_fast_uri2 = __commonJS({
|
|
|
97941
98530
|
}
|
|
97942
98531
|
}
|
|
97943
98532
|
}
|
|
97944
|
-
const
|
|
97945
|
-
if (
|
|
97946
|
-
parsed.scheme =
|
|
97947
|
-
parsed.userinfo =
|
|
97948
|
-
parsed.host =
|
|
97949
|
-
parsed.port = parseInt(
|
|
97950
|
-
parsed.path =
|
|
97951
|
-
parsed.query =
|
|
97952
|
-
parsed.fragment =
|
|
98533
|
+
const matches2 = uri.match(URI_PARSE);
|
|
98534
|
+
if (matches2) {
|
|
98535
|
+
parsed.scheme = matches2[1] === void 0 ? void 0 : matches2[1].toLowerCase();
|
|
98536
|
+
parsed.userinfo = matches2[3];
|
|
98537
|
+
parsed.host = matches2[4];
|
|
98538
|
+
parsed.port = parseInt(matches2[5], 10);
|
|
98539
|
+
parsed.path = matches2[6] || "";
|
|
98540
|
+
parsed.query = matches2[7];
|
|
98541
|
+
parsed.fragment = matches2[8];
|
|
97953
98542
|
if (isNaN(parsed.port)) {
|
|
97954
|
-
parsed.port =
|
|
98543
|
+
parsed.port = matches2[5];
|
|
97955
98544
|
}
|
|
97956
|
-
const parseError = getParseError(parsed,
|
|
98545
|
+
const parseError = getParseError(parsed, matches2);
|
|
97957
98546
|
if (parseError !== void 0) {
|
|
97958
98547
|
parsed.error = parsed.error || parseError;
|
|
97959
98548
|
malformedAuthorityOrPort = true;
|
|
@@ -98150,12 +98739,12 @@ var require_formats = __commonJS({
|
|
|
98150
98739
|
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
98151
98740
|
var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
98152
98741
|
function date5(str2) {
|
|
98153
|
-
const
|
|
98154
|
-
if (!
|
|
98742
|
+
const matches2 = DATE.exec(str2);
|
|
98743
|
+
if (!matches2)
|
|
98155
98744
|
return false;
|
|
98156
|
-
const year = +
|
|
98157
|
-
const month = +
|
|
98158
|
-
const day = +
|
|
98745
|
+
const year = +matches2[1];
|
|
98746
|
+
const month = +matches2[2];
|
|
98747
|
+
const day = +matches2[3];
|
|
98159
98748
|
return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]);
|
|
98160
98749
|
}
|
|
98161
98750
|
function compareDate(d1, d2) {
|
|
@@ -98170,16 +98759,16 @@ var require_formats = __commonJS({
|
|
|
98170
98759
|
var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
|
|
98171
98760
|
function getTime(strictTimeZone) {
|
|
98172
98761
|
return function time3(str2) {
|
|
98173
|
-
const
|
|
98174
|
-
if (!
|
|
98762
|
+
const matches2 = TIME.exec(str2);
|
|
98763
|
+
if (!matches2)
|
|
98175
98764
|
return false;
|
|
98176
|
-
const hr = +
|
|
98177
|
-
const min = +
|
|
98178
|
-
const sec = +
|
|
98179
|
-
const tz =
|
|
98180
|
-
const tzSign =
|
|
98181
|
-
const tzH = +(
|
|
98182
|
-
const tzM = +(
|
|
98765
|
+
const hr = +matches2[1];
|
|
98766
|
+
const min = +matches2[2];
|
|
98767
|
+
const sec = +matches2[3];
|
|
98768
|
+
const tz = matches2[4];
|
|
98769
|
+
const tzSign = matches2[5] === "-" ? -1 : 1;
|
|
98770
|
+
const tzH = +(matches2[6] || 0);
|
|
98771
|
+
const tzM = +(matches2[7] || 0);
|
|
98183
98772
|
if (tzH > 23 || tzM > 59 || strictTimeZone && !tz)
|
|
98184
98773
|
return false;
|
|
98185
98774
|
if (hr <= 23 && min <= 59 && sec < 60)
|
|
@@ -105663,8 +106252,8 @@ var require_http_method = __commonJS({
|
|
|
105663
106252
|
get: (type) => {
|
|
105664
106253
|
return handlers.get(type) || null;
|
|
105665
106254
|
},
|
|
105666
|
-
set: (type,
|
|
105667
|
-
handlers.set(type,
|
|
106255
|
+
set: (type, store3) => {
|
|
106256
|
+
handlers.set(type, store3);
|
|
105668
106257
|
}
|
|
105669
106258
|
};
|
|
105670
106259
|
},
|
|
@@ -105903,14 +106492,14 @@ var require_handler_storage = __commonJS({
|
|
|
105903
106492
|
// Builds a store object that maps from constraint values to a bitmap of handler indexes which pass the constraint for a value
|
|
105904
106493
|
// So for a host constraint, this might look like { "fastify.io": 0b0010, "google.ca": 0b0101 }, meaning the 3rd handler is constrainted to fastify.io, and the 2nd and 4th handlers are constrained to google.ca.
|
|
105905
106494
|
// The store's implementation comes from the strategies provided to the Router.
|
|
105906
|
-
_buildConstraintStore(
|
|
106495
|
+
_buildConstraintStore(store3, constraint) {
|
|
105907
106496
|
for (let i = 0; i < this.handlers.length; i++) {
|
|
105908
106497
|
const handler = this.handlers[i];
|
|
105909
106498
|
const constraintValue = handler.constraints[constraint];
|
|
105910
106499
|
if (constraintValue !== void 0) {
|
|
105911
|
-
let indexes =
|
|
106500
|
+
let indexes = store3.get(constraintValue) || 0;
|
|
105912
106501
|
indexes |= 1 << i;
|
|
105913
|
-
|
|
106502
|
+
store3.set(constraintValue, indexes);
|
|
105914
106503
|
}
|
|
105915
106504
|
}
|
|
105916
106505
|
}
|
|
@@ -105935,9 +106524,9 @@ var require_handler_storage = __commonJS({
|
|
|
105935
106524
|
_compileGetHandlerMatchingConstraints(constrainer) {
|
|
105936
106525
|
this.constrainedHandlerStores = {};
|
|
105937
106526
|
for (const constraint of this.constraints) {
|
|
105938
|
-
const
|
|
105939
|
-
this.constrainedHandlerStores[constraint] =
|
|
105940
|
-
this._buildConstraintStore(
|
|
106527
|
+
const store3 = constrainer.newStoreForConstraint(constraint);
|
|
106528
|
+
this.constrainedHandlerStores[constraint] = store3;
|
|
106529
|
+
this._buildConstraintStore(store3, constraint);
|
|
105941
106530
|
}
|
|
105942
106531
|
const lines = [];
|
|
105943
106532
|
lines.push(`
|
|
@@ -106200,7 +106789,7 @@ var require_accept_version = __commonJS({
|
|
|
106200
106789
|
this.maxMinors = {};
|
|
106201
106790
|
this.maxPatches = {};
|
|
106202
106791
|
}
|
|
106203
|
-
SemVerStore.prototype.set = function(version2,
|
|
106792
|
+
SemVerStore.prototype.set = function(version2, store3) {
|
|
106204
106793
|
if (typeof version2 !== "string") {
|
|
106205
106794
|
throw new TypeError("Version should be a string");
|
|
106206
106795
|
}
|
|
@@ -106213,21 +106802,21 @@ var require_accept_version = __commonJS({
|
|
|
106213
106802
|
patch = Number(patch) || 0;
|
|
106214
106803
|
if (major >= this.maxMajor) {
|
|
106215
106804
|
this.maxMajor = major;
|
|
106216
|
-
this.store.set("x",
|
|
106217
|
-
this.store.set("*",
|
|
106218
|
-
this.store.set("x.x",
|
|
106219
|
-
this.store.set("x.x.x",
|
|
106805
|
+
this.store.set("x", store3);
|
|
106806
|
+
this.store.set("*", store3);
|
|
106807
|
+
this.store.set("x.x", store3);
|
|
106808
|
+
this.store.set("x.x.x", store3);
|
|
106220
106809
|
}
|
|
106221
106810
|
if (minor >= (this.maxMinors[major] || 0)) {
|
|
106222
106811
|
this.maxMinors[major] = minor;
|
|
106223
|
-
this.store.set(`${major}.x`,
|
|
106224
|
-
this.store.set(`${major}.x.x`,
|
|
106812
|
+
this.store.set(`${major}.x`, store3);
|
|
106813
|
+
this.store.set(`${major}.x.x`, store3);
|
|
106225
106814
|
}
|
|
106226
106815
|
if (patch >= (this.maxPatches[`${major}.${minor}`] || 0)) {
|
|
106227
106816
|
this.maxPatches[`${major}.${minor}`] = patch;
|
|
106228
|
-
this.store.set(`${major}.${minor}.x`,
|
|
106817
|
+
this.store.set(`${major}.${minor}.x`, store3);
|
|
106229
106818
|
}
|
|
106230
|
-
this.store.set(`${major}.${minor}.${patch}`,
|
|
106819
|
+
this.store.set(`${major}.${minor}.${patch}`, store3);
|
|
106231
106820
|
return this;
|
|
106232
106821
|
};
|
|
106233
106822
|
SemVerStore.prototype.get = function(version2) {
|
|
@@ -106695,10 +107284,10 @@ var require_find_my_way = __commonJS({
|
|
|
106695
107284
|
this.trees = /* @__PURE__ */ Object.create(null);
|
|
106696
107285
|
this._treeGET = null;
|
|
106697
107286
|
}
|
|
106698
|
-
Router.prototype.on = function on(method, path, opts, handler,
|
|
107287
|
+
Router.prototype.on = function on(method, path, opts, handler, store3) {
|
|
106699
107288
|
if (typeof opts === "function") {
|
|
106700
107289
|
if (handler !== void 0) {
|
|
106701
|
-
|
|
107290
|
+
store3 = handler;
|
|
106702
107291
|
}
|
|
106703
107292
|
handler = opts;
|
|
106704
107293
|
opts = {};
|
|
@@ -106712,8 +107301,8 @@ var require_find_my_way = __commonJS({
|
|
|
106712
107301
|
assert2(path.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
|
|
106713
107302
|
const pathFull = path.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
|
|
106714
107303
|
const pathOptional = path.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
|
|
106715
|
-
this.on(method, pathFull, opts, handler,
|
|
106716
|
-
this.on(method, pathOptional, opts, handler,
|
|
107304
|
+
this.on(method, pathFull, opts, handler, store3);
|
|
107305
|
+
this.on(method, pathOptional, opts, handler, store3);
|
|
106717
107306
|
return;
|
|
106718
107307
|
}
|
|
106719
107308
|
const route = path;
|
|
@@ -106727,10 +107316,10 @@ var require_find_my_way = __commonJS({
|
|
|
106727
107316
|
for (const method2 of methods) {
|
|
106728
107317
|
assert2(typeof method2 === "string", "Method should be a string");
|
|
106729
107318
|
assert2(httpMethods.includes(method2), `Method '${method2}' is not an http method.`);
|
|
106730
|
-
this._on(method2, path, opts, handler,
|
|
107319
|
+
this._on(method2, path, opts, handler, store3, route);
|
|
106731
107320
|
}
|
|
106732
107321
|
};
|
|
106733
|
-
Router.prototype._on = function _on(method, path, opts, handler,
|
|
107322
|
+
Router.prototype._on = function _on(method, path, opts, handler, store3) {
|
|
106734
107323
|
let constraints = {};
|
|
106735
107324
|
if (opts.constraints !== void 0) {
|
|
106736
107325
|
assert2(typeof opts.constraints === "object" && opts.constraints !== null, "Constraints should be an object");
|
|
@@ -106851,7 +107440,7 @@ var require_find_my_way = __commonJS({
|
|
|
106851
107440
|
throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`);
|
|
106852
107441
|
}
|
|
106853
107442
|
}
|
|
106854
|
-
const route = { method, path, pattern, params, opts, handler, store:
|
|
107443
|
+
const route = { method, path, pattern, params, opts, handler, store: store3 };
|
|
106855
107444
|
this.routes.push(route);
|
|
106856
107445
|
currentNode.addRoute(route, this.constrainer);
|
|
106857
107446
|
};
|
|
@@ -107199,8 +107788,8 @@ var require_find_my_way = __commonJS({
|
|
|
107199
107788
|
Router.prototype._rebuild = function(routes2) {
|
|
107200
107789
|
this.reset();
|
|
107201
107790
|
for (const route of routes2) {
|
|
107202
|
-
const { method, path, opts, handler, store:
|
|
107203
|
-
this._on(method, path, opts, handler,
|
|
107791
|
+
const { method, path, opts, handler, store: store3 } = route;
|
|
107792
|
+
this._on(method, path, opts, handler, store3);
|
|
107204
107793
|
}
|
|
107205
107794
|
};
|
|
107206
107795
|
Router.prototype._defaultRoute = function(req, res, ctx) {
|
|
@@ -107260,12 +107849,12 @@ var require_find_my_way = __commonJS({
|
|
|
107260
107849
|
if (!httpMethods.hasOwnProperty(i)) continue;
|
|
107261
107850
|
const m = httpMethods[i];
|
|
107262
107851
|
const methodName = m.toLowerCase();
|
|
107263
|
-
Router.prototype[methodName] = function(path, handler,
|
|
107264
|
-
return this.on(m, path, handler,
|
|
107852
|
+
Router.prototype[methodName] = function(path, handler, store3) {
|
|
107853
|
+
return this.on(m, path, handler, store3);
|
|
107265
107854
|
};
|
|
107266
107855
|
}
|
|
107267
|
-
Router.prototype.all = function(path, handler,
|
|
107268
|
-
this.on(httpMethods, path, handler,
|
|
107856
|
+
Router.prototype.all = function(path, handler, store3) {
|
|
107857
|
+
this.on(httpMethods, path, handler, store3);
|
|
107269
107858
|
};
|
|
107270
107859
|
Router.sanitizeUrlPath = function sanitizeUrlPath(url2, useSemicolonDelimiter) {
|
|
107271
107860
|
const decoded = safeDecodeURI(url2, useSemicolonDelimiter);
|
|
@@ -108145,7 +108734,7 @@ var require_dist5 = __commonJS({
|
|
|
108145
108734
|
exports.stringifyCookie = stringifyCookie;
|
|
108146
108735
|
exports.stringifySetCookie = stringifySetCookie;
|
|
108147
108736
|
exports.serialize = stringifySetCookie;
|
|
108148
|
-
exports.parseSetCookie =
|
|
108737
|
+
exports.parseSetCookie = parseSetCookie2;
|
|
108149
108738
|
exports.stringifySetCookie = stringifySetCookie;
|
|
108150
108739
|
exports.serialize = stringifySetCookie;
|
|
108151
108740
|
var cookieNameRegExp = /^[\u0021-\u003A\u003C\u003E-\u007E]+$/;
|
|
@@ -108282,7 +108871,7 @@ var require_dist5 = __commonJS({
|
|
|
108282
108871
|
}
|
|
108283
108872
|
return str2;
|
|
108284
108873
|
}
|
|
108285
|
-
function
|
|
108874
|
+
function parseSetCookie2(str2, options) {
|
|
108286
108875
|
const dec = options?.decode || decode4;
|
|
108287
108876
|
const len = str2.length;
|
|
108288
108877
|
const endIdx = endIndex(str2, 0, len);
|
|
@@ -110973,43 +111562,43 @@ var init_serve_ui = __esm({
|
|
|
110973
111562
|
});
|
|
110974
111563
|
|
|
110975
111564
|
// ../../apps/engine/src/history-routes.ts
|
|
110976
|
-
function registerHistoryRoutes(app2,
|
|
110977
|
-
app2.get("/history", async () =>
|
|
111565
|
+
function registerHistoryRoutes(app2, store3) {
|
|
111566
|
+
app2.get("/history", async () => store3.index());
|
|
110978
111567
|
app2.get("/history/runs/:id", async (request3, reply) => {
|
|
110979
|
-
const doc = await
|
|
111568
|
+
const doc = await store3.readRun(request3.params.id);
|
|
110980
111569
|
return doc ?? reply.code(404).send({ error: "run not found in history" });
|
|
110981
111570
|
});
|
|
110982
111571
|
app2.get("/history/compares/:id", async (request3, reply) => {
|
|
110983
|
-
const doc = await
|
|
111572
|
+
const doc = await store3.readCompare(request3.params.id);
|
|
110984
111573
|
return doc ?? reply.code(404).send({ error: "compare not found in history" });
|
|
110985
111574
|
});
|
|
110986
111575
|
app2.patch("/history/runs/:id", async (request3, reply) => {
|
|
110987
111576
|
const parsed = runPatch.safeParse(request3.body);
|
|
110988
111577
|
if (!parsed.success) return reply.code(400).send({ error: "invalid update", issues: parsed.error.issues });
|
|
110989
|
-
const summary = await
|
|
111578
|
+
const summary = await store3.updateRun(request3.params.id, parsed.data);
|
|
110990
111579
|
return summary ?? reply.code(404).send({ error: "run not found in history" });
|
|
110991
111580
|
});
|
|
110992
111581
|
app2.patch("/history/compares/:id", async (request3, reply) => {
|
|
110993
111582
|
const parsed = comparePatch.safeParse(request3.body);
|
|
110994
111583
|
if (!parsed.success) return reply.code(400).send({ error: "invalid update", issues: parsed.error.issues });
|
|
110995
|
-
const summary = await
|
|
111584
|
+
const summary = await store3.updateCompare(request3.params.id, parsed.data);
|
|
110996
111585
|
return summary ?? reply.code(404).send({ error: "compare not found in history" });
|
|
110997
111586
|
});
|
|
110998
111587
|
app2.post("/history/delete", async (request3, reply) => {
|
|
110999
111588
|
const parsed = removeBody.safeParse(request3.body);
|
|
111000
111589
|
if (!parsed.success) return reply.code(400).send({ error: "invalid delete", issues: parsed.error.issues });
|
|
111001
|
-
return { removed: await
|
|
111590
|
+
return { removed: await store3.remove(parsed.data) };
|
|
111002
111591
|
});
|
|
111003
111592
|
app2.post("/history/import", async (request3, reply) => {
|
|
111004
111593
|
try {
|
|
111005
111594
|
const raw = request3.body;
|
|
111006
111595
|
const parsed = parseExportFile(raw);
|
|
111007
111596
|
if (parsed.kind === "report") {
|
|
111008
|
-
return { kind: "run", summary: await
|
|
111597
|
+
return { kind: "run", summary: await store3.saveRun(parsed.report, { ...raw?.meta, source: "import" }) };
|
|
111009
111598
|
}
|
|
111010
111599
|
return {
|
|
111011
111600
|
kind: "compare",
|
|
111012
|
-
summary: await
|
|
111601
|
+
summary: await store3.saveCompare({ apis: parsed.doc.apis, mode: parsed.doc.mode, name: raw?.meta?.name, source: "import" })
|
|
111013
111602
|
};
|
|
111014
111603
|
} catch (err) {
|
|
111015
111604
|
return reply.code(400).send({ error: err instanceof Error ? err.message : "Not an APITestCenter report" });
|
|
@@ -111020,7 +111609,7 @@ function registerHistoryRoutes(app2, store2) {
|
|
|
111020
111609
|
if (!parsed.success) return reply.code(400).send({ error: "invalid compare", issues: parsed.error.issues });
|
|
111021
111610
|
const doc = { kind: "compare", apis: parsed.data.apis };
|
|
111022
111611
|
if (!isCompareExport(doc)) return reply.code(400).send({ error: "each API needs a run report" });
|
|
111023
|
-
return
|
|
111612
|
+
return store3.saveCompare({
|
|
111024
111613
|
apis: parsed.data.apis,
|
|
111025
111614
|
mode: parsed.data.mode,
|
|
111026
111615
|
name: parsed.data.name,
|
|
@@ -111031,7 +111620,7 @@ function registerHistoryRoutes(app2, store2) {
|
|
|
111031
111620
|
const parsed = revealBody.safeParse(request3.body ?? {});
|
|
111032
111621
|
if (!parsed.success) return reply.code(400).send({ error: "invalid target" });
|
|
111033
111622
|
const { folder, id } = parsed.data;
|
|
111034
|
-
return { path: await
|
|
111623
|
+
return { path: await store3.reveal(folder && id ? { folder, id } : void 0) };
|
|
111035
111624
|
});
|
|
111036
111625
|
}
|
|
111037
111626
|
var runPatch, comparePatch, removeBody, compareBody, revealBody;
|
|
@@ -111089,53 +111678,53 @@ var init_settings_routes = __esm({
|
|
|
111089
111678
|
});
|
|
111090
111679
|
|
|
111091
111680
|
// ../../apps/engine/src/workspace-routes.ts
|
|
111092
|
-
function registerWorkspaceRoutes(app2,
|
|
111093
|
-
app2.get("/workspace", async () =>
|
|
111094
|
-
app2.get("/workspace/folders", async (request3) =>
|
|
111095
|
-
app2.get("/workspace/folders/chain", async (request3) =>
|
|
111681
|
+
function registerWorkspaceRoutes(app2, store3, onFolderMoved) {
|
|
111682
|
+
app2.get("/workspace", async () => store3.index());
|
|
111683
|
+
app2.get("/workspace/folders", async (request3) => store3.getFolder(request3.query.path ?? ""));
|
|
111684
|
+
app2.get("/workspace/folders/chain", async (request3) => store3.folderChain(request3.query.collection ?? ""));
|
|
111096
111685
|
app2.put("/workspace/folders", async (request3, reply) => {
|
|
111097
111686
|
const parsed = external_exports.object({ path: external_exports.string().min(1).max(400), settings: external_exports.unknown() }).strict().safeParse(request3.body);
|
|
111098
111687
|
if (!parsed.success) return reply.code(400).send({ error: "invalid folder", issues: parsed.error.issues });
|
|
111099
|
-
return
|
|
111688
|
+
return store3.saveFolder(parsed.data.path, parsed.data.settings);
|
|
111100
111689
|
});
|
|
111101
111690
|
app2.post("/workspace/folders/move", async (request3, reply) => {
|
|
111102
111691
|
const parsed = external_exports.object({ from: external_exports.string().min(1).max(400), to: external_exports.string().min(1).max(400) }).strict().safeParse(request3.body);
|
|
111103
111692
|
if (!parsed.success) return reply.code(400).send({ error: "invalid move", issues: parsed.error.issues });
|
|
111104
|
-
const moved = await
|
|
111693
|
+
const moved = await store3.moveFolder(parsed.data.from, parsed.data.to);
|
|
111105
111694
|
await onFolderMoved?.(moved.from, moved.to);
|
|
111106
111695
|
return moved;
|
|
111107
111696
|
});
|
|
111108
111697
|
app2.delete("/workspace/folders", async (request3, reply) => {
|
|
111109
|
-
return await
|
|
111698
|
+
return await store3.deleteFolder(request3.query.path ?? "") ? { removed: 1 } : reply.code(404).send({ error: "folder not found" });
|
|
111110
111699
|
});
|
|
111111
111700
|
app2.get("/workspace/requests/:id", async (request3, reply) => {
|
|
111112
|
-
const saved = await
|
|
111701
|
+
const saved = await store3.getRequest(request3.params.id);
|
|
111113
111702
|
return saved ?? reply.code(404).send({ error: "saved request not found" });
|
|
111114
111703
|
});
|
|
111115
111704
|
app2.post("/workspace/requests", async (request3, reply) => {
|
|
111116
111705
|
const parsed = requestBody.safeParse(request3.body);
|
|
111117
111706
|
if (!parsed.success) return reply.code(400).send({ error: "invalid request", issues: parsed.error.issues });
|
|
111118
|
-
return
|
|
111707
|
+
return store3.saveRequest(parsed.data);
|
|
111119
111708
|
});
|
|
111120
111709
|
app2.put("/workspace/requests/:id", async (request3, reply) => {
|
|
111121
111710
|
const parsed = requestBody.safeParse(request3.body);
|
|
111122
111711
|
if (!parsed.success) return reply.code(400).send({ error: "invalid request", issues: parsed.error.issues });
|
|
111123
|
-
return
|
|
111712
|
+
return store3.saveRequest({ ...parsed.data, id: request3.params.id });
|
|
111124
111713
|
});
|
|
111125
111714
|
app2.delete("/workspace/requests/:id", async (request3, reply) => {
|
|
111126
|
-
return await
|
|
111715
|
+
return await store3.deleteRequest(request3.params.id) ? { removed: 1 } : reply.code(404).send({ error: "saved request not found" });
|
|
111127
111716
|
});
|
|
111128
|
-
app2.put("/workspace/environments", async (request3) =>
|
|
111717
|
+
app2.put("/workspace/environments", async (request3) => store3.saveEnvironments(request3.body));
|
|
111129
111718
|
app2.post("/workspace/import", async (request3, reply) => {
|
|
111130
111719
|
const parsed = importBody.safeParse(request3.body);
|
|
111131
111720
|
if (!parsed.success) return reply.code(400).send({ error: "invalid import", issues: parsed.error.issues });
|
|
111132
111721
|
const saved = [];
|
|
111133
|
-
for (const f of parsed.data.folders) await
|
|
111134
|
-
for (const r of parsed.data.requests) saved.push(await
|
|
111722
|
+
for (const f of parsed.data.folders) await store3.saveFolder(f.path, f.settings);
|
|
111723
|
+
for (const r of parsed.data.requests) saved.push(await store3.saveRequest(r));
|
|
111135
111724
|
let added = 0;
|
|
111136
111725
|
let merged = 0;
|
|
111137
111726
|
if (parsed.data.environments.length) {
|
|
111138
|
-
const envs = await
|
|
111727
|
+
const envs = await store3.environments();
|
|
111139
111728
|
for (const incoming of parsed.data.environments) {
|
|
111140
111729
|
const existing = envs.find((e) => e.name.toLowerCase() === incoming.name.toLowerCase());
|
|
111141
111730
|
if (existing) {
|
|
@@ -111147,7 +111736,7 @@ function registerWorkspaceRoutes(app2, store2, onFolderMoved) {
|
|
|
111147
111736
|
added++;
|
|
111148
111737
|
}
|
|
111149
111738
|
}
|
|
111150
|
-
await
|
|
111739
|
+
await store3.saveEnvironments(envs);
|
|
111151
111740
|
}
|
|
111152
111741
|
return { requests: saved.length, firstId: saved[0]?.id ?? null, environments: { added, merged } };
|
|
111153
111742
|
});
|
|
@@ -111178,7 +111767,7 @@ var init_workspace_routes = __esm({
|
|
|
111178
111767
|
});
|
|
111179
111768
|
|
|
111180
111769
|
// ../../apps/engine/src/demo-api.ts
|
|
111181
|
-
import { randomBytes as
|
|
111770
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
111182
111771
|
function registerDemoApi(api) {
|
|
111183
111772
|
const tokens = /* @__PURE__ */ new Map();
|
|
111184
111773
|
const created = /* @__PURE__ */ new Map();
|
|
@@ -111204,7 +111793,7 @@ function registerDemoApi(api) {
|
|
|
111204
111793
|
return reply.code(401).send({ error: 'Use any username with the password "demo".' });
|
|
111205
111794
|
}
|
|
111206
111795
|
if (tokens.size > 5e3) tokens.clear();
|
|
111207
|
-
const token = `demo-${
|
|
111796
|
+
const token = `demo-${randomBytes5(12).toString("hex")}`;
|
|
111208
111797
|
tokens.set(token, username);
|
|
111209
111798
|
return { data: { token, user: username, expiresIn: 3600 } };
|
|
111210
111799
|
});
|
|
@@ -111598,6 +112187,8 @@ async function routes(api) {
|
|
|
111598
112187
|
useOAuthStore(secrets2);
|
|
111599
112188
|
registerOAuthRoutes(api);
|
|
111600
112189
|
useCertificateStore(history.dir, secrets2);
|
|
112190
|
+
useCookieStore(secrets2);
|
|
112191
|
+
registerCookieRoutes(api);
|
|
111601
112192
|
registerCertificateRoutes(api);
|
|
111602
112193
|
const suitePlans = new SuitePlans(history.dir);
|
|
111603
112194
|
registerWorkspaceRoutes(api, workspace, (from, to) => suitePlans.move(from, to));
|
|
@@ -111639,7 +112230,7 @@ async function routes(api) {
|
|
|
111639
112230
|
function engineUrl() {
|
|
111640
112231
|
return listeningUrl;
|
|
111641
112232
|
}
|
|
111642
|
-
var import_cors, import_dotenv, import_fastify, root, host, port, history, appVersion, usage, app, listeningUrl, uiDir;
|
|
112233
|
+
var import_cors, import_dotenv, import_fastify, root, tlsCheckWasOff, host, port, history, appVersion, usage, app, listeningUrl, uiDir;
|
|
111643
112234
|
var init_index = __esm({
|
|
111644
112235
|
async "../../apps/engine/src/index.ts"() {
|
|
111645
112236
|
"use strict";
|
|
@@ -111662,9 +112253,12 @@ var init_index = __esm({
|
|
|
111662
112253
|
init_suite_run();
|
|
111663
112254
|
init_oauth();
|
|
111664
112255
|
init_certificates();
|
|
112256
|
+
init_cookies();
|
|
111665
112257
|
init_local_servers();
|
|
111666
112258
|
root = resolve3(dirname2(fileURLToPath(import.meta.url)), "../../..");
|
|
111667
112259
|
if (!process.env.ATC_NO_DOTENV) (0, import_dotenv.config)({ path: resolve3(root, ".env") });
|
|
112260
|
+
tlsCheckWasOff = process.env.NODE_TLS_REJECT_UNAUTHORIZED === "0";
|
|
112261
|
+
if (tlsCheckWasOff) delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
111668
112262
|
host = process.env.ENGINE_HOST ?? "127.0.0.1";
|
|
111669
112263
|
port = Number(process.env.ENGINE_PORT ?? 4100);
|
|
111670
112264
|
history = new HistoryStore();
|
|
@@ -111696,6 +112290,7 @@ var init_index = __esm({
|
|
|
111696
112290
|
const url2 = `http://${host}:${typeof address === "object" && address ? address.port : port}`;
|
|
111697
112291
|
listeningUrl = url2;
|
|
111698
112292
|
app.log.info(`engine listening on ${url2}`);
|
|
112293
|
+
if (tlsCheckWasOff) app.log.warn("NODE_TLS_REJECT_UNAUTHORIZED=0 is set on this computer and was ignored: certificates are checked against the system's trusted certificates; use Skip TLS certificate check on a request to turn it off there");
|
|
111699
112294
|
if (!process.env.ATC_NO_READY_LINE) console.log(`ATC_READY ${url2}`);
|
|
111700
112295
|
} catch (err) {
|
|
111701
112296
|
app.log.error(err);
|
|
@@ -111794,10 +112389,11 @@ init_secret_store();
|
|
|
111794
112389
|
init_suite_run();
|
|
111795
112390
|
init_oauth();
|
|
111796
112391
|
init_certificates();
|
|
112392
|
+
init_cookies();
|
|
111797
112393
|
init_workspace_store();
|
|
111798
112394
|
var repoRoot = resolve4(dirname3(fileURLToPath2(import.meta.url)), "../../..");
|
|
111799
112395
|
var EXIT = { passed: 0, failed: 1, error: 2 };
|
|
111800
|
-
var VERSION = "0.
|
|
112396
|
+
var VERSION = "0.8.0";
|
|
111801
112397
|
var HELP = `APITestCenter CLI ${VERSION} \u2014 https://apitestcenter.com/docs/cli-and-ci.html
|
|
111802
112398
|
|
|
111803
112399
|
Usage (apitestcenter, or the short name atc once installed)
|
|
@@ -111909,6 +112505,7 @@ async function main() {
|
|
|
111909
112505
|
const workspace = new WorkspaceStore(dataDir, secrets2);
|
|
111910
112506
|
useOAuthStore(secrets2);
|
|
111911
112507
|
useCertificateStore(dataDir, secrets2);
|
|
112508
|
+
useCookieStore(secrets2);
|
|
111912
112509
|
for (const spec of values.cert ?? []) {
|
|
111913
112510
|
const eq = spec.indexOf("=");
|
|
111914
112511
|
const files = eq > 0 ? spec.slice(eq + 1).split(",").map((f) => f.trim()).filter(Boolean) : [];
|
|
@@ -111967,7 +112564,7 @@ Environments (${index.environments.length})`);
|
|
|
111967
112564
|
const message = err instanceof Error ? err.message : String(err);
|
|
111968
112565
|
fail(message.replace(/needs an environment.*$/, "is not set \u2014 use --env <name> or --var name=value"));
|
|
111969
112566
|
}
|
|
111970
|
-
let
|
|
112567
|
+
let load3 = values.preset ? applyPreset(DEFAULT_LOAD, values.preset) : { ...DEFAULT_LOAD };
|
|
111971
112568
|
const num3 = (v, label) => {
|
|
111972
112569
|
if (v == null) return void 0;
|
|
111973
112570
|
const n = Number(v);
|
|
@@ -111984,8 +112581,8 @@ Environments (${index.environments.length})`);
|
|
|
111984
112581
|
};
|
|
111985
112582
|
if (custom2.rps != null) custom2.mode = "rate";
|
|
111986
112583
|
const overrides = Object.fromEntries(Object.entries(custom2).filter(([, v]) => v !== void 0));
|
|
111987
|
-
if (Object.keys(overrides).length)
|
|
111988
|
-
const problem = loadProblem(
|
|
112584
|
+
if (Object.keys(overrides).length) load3 = { ...load3, ...overrides, stages: load3.stages && !values.duration ? load3.stages : null, preset: "custom" };
|
|
112585
|
+
const problem = loadProblem(load3);
|
|
111989
112586
|
if (problem) fail(problem);
|
|
111990
112587
|
const pct3 = (v) => v == null ? void 0 : (num3(v, "percent") ?? 0) / 100;
|
|
111991
112588
|
const targets = values.p95 || values.p99 || values.errors || values.checks ? { p95Ms: num3(values.p95, "--p95"), p99Ms: num3(values.p99, "--p99"), errorRate: pct3(values.errors), checksRate: pct3(values.checks), abortOnFail: values.abort === true } : void 0;
|
|
@@ -112005,7 +112602,7 @@ Environments (${index.environments.length})`);
|
|
|
112005
112602
|
if (!Number.isFinite(n) || n < 0) fail("--max-slower must be a percentage, like 10");
|
|
112006
112603
|
return n / 100;
|
|
112007
112604
|
})();
|
|
112008
|
-
const payload = buildPayload(draft, toLoadConfig(
|
|
112605
|
+
const payload = buildPayload(draft, toLoadConfig(load3), `${name} \xB7 CLI`, targets);
|
|
112009
112606
|
const log = (line) => !values.quiet && console.log(line);
|
|
112010
112607
|
if (draft.before) {
|
|
112011
112608
|
const before = draft.before;
|
|
@@ -112036,7 +112633,7 @@ Environments (${index.environments.length})`);
|
|
|
112036
112633
|
}
|
|
112037
112634
|
}
|
|
112038
112635
|
const started = await startRun(labRunSchema.parse(payload), repoRoot).catch((err) => fail(err instanceof Error ? err.message : String(err)));
|
|
112039
|
-
log(`load ${payload.request.method} ${displayTemplate(payload.request.url)} \xB7 ${
|
|
112636
|
+
log(`load ${payload.request.method} ${displayTemplate(payload.request.url)} \xB7 ${load3.mode === "rate" ? `${load3.rps} req/s` : `${load3.vus} VUs`} \xB7 ${load3.duration}`);
|
|
112040
112637
|
let interrupted = false;
|
|
112041
112638
|
process.on("SIGINT", () => {
|
|
112042
112639
|
if (interrupted) process.exit(EXIT.error);
|
|
@@ -112134,9 +112731,9 @@ async function init(collection, folder) {
|
|
|
112134
112731
|
fail(`${folder} already has saved requests. Open them with: npx apitestcenter ui --data ${folder}`);
|
|
112135
112732
|
}
|
|
112136
112733
|
mkdirSync2(dir2, { recursive: true });
|
|
112137
|
-
const
|
|
112138
|
-
await
|
|
112139
|
-
await
|
|
112734
|
+
const store3 = new WorkspaceStore(dir2, new SecretStore(dir2));
|
|
112735
|
+
await store3.saveEnvironments([{ id: randomUUID7(), name: "Local", variables: [{ key: "baseUrl", value: "http://localhost:3000", secret: false }] }]);
|
|
112736
|
+
await store3.saveRequest({
|
|
112140
112737
|
name: "Health check",
|
|
112141
112738
|
collection: name,
|
|
112142
112739
|
request: { method: "GET", url: "{{baseUrl}}/health", checks: [{ type: "status", expect: "2xx" }] }
|