tiny-http-mcp-server 0.1.21 → 0.1.23
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/composition.json +1 -1
- package/node_modules/mcp-oauth/README.md +31 -1
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +63 -14
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +5 -0
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.js +134 -72
- package/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +2 -0
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +5 -1
- package/node_modules/mcp-oauth/dist/client/types.d.ts +14 -1
- package/node_modules/tiny-mcp-client/README.md +3 -1
- package/node_modules/tiny-mcp-client/dist/index.d.ts +17 -2
- package/node_modules/tiny-mcp-client/dist/index.js +273 -116
- package/package.json +1 -1
|
@@ -152,11 +152,17 @@ var HttpResponseMessages = class {
|
|
|
152
152
|
};
|
|
153
153
|
|
|
154
154
|
// ../toolcraft-schema/dist/json.js
|
|
155
|
-
function isJsonValue(value) {
|
|
155
|
+
function isJsonValue(value, options = {}) {
|
|
156
|
+
const maxNodes = options.maxNodes ?? 1e4;
|
|
157
|
+
const maxDepth = options.maxDepth ?? 64;
|
|
158
|
+
if (!Number.isSafeInteger(maxNodes) || maxNodes < 1)
|
|
159
|
+
throw new Error("maxNodes must be a positive safe integer");
|
|
160
|
+
if (!Number.isSafeInteger(maxDepth) || maxDepth < 0 || maxDepth > 256)
|
|
161
|
+
throw new Error("maxDepth must be an integer between 0 and 256");
|
|
156
162
|
const ancestors = /* @__PURE__ */ new Set();
|
|
157
163
|
let nodes = 0;
|
|
158
164
|
const visit = (item, depth) => {
|
|
159
|
-
if (++nodes >
|
|
165
|
+
if (++nodes > maxNodes || depth > maxDepth)
|
|
160
166
|
return false;
|
|
161
167
|
if (item === null || typeof item === "string" || typeof item === "boolean")
|
|
162
168
|
return true;
|
|
@@ -182,7 +188,7 @@ function isJsonValue(value) {
|
|
|
182
188
|
ancestors.add(item);
|
|
183
189
|
let valid = true;
|
|
184
190
|
if (Array.isArray(item)) {
|
|
185
|
-
if (item.length >
|
|
191
|
+
if (item.length > maxNodes)
|
|
186
192
|
valid = false;
|
|
187
193
|
else
|
|
188
194
|
for (let index = 0; index < item.length; index++) {
|
|
@@ -4102,47 +4108,137 @@ function getOwnEntry4(record2, key2) {
|
|
|
4102
4108
|
|
|
4103
4109
|
// ../mcp-oauth/dist/client/loopback-authorization.js
|
|
4104
4110
|
async function createLoopbackAuthorizationSession(options = {}) {
|
|
4105
|
-
|
|
4111
|
+
options.signal?.throwIfAborted();
|
|
4112
|
+
const timeoutMs = options.timeoutMs ?? 12e4;
|
|
4113
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
|
|
4114
|
+
throw new Error("OAuth authorization timeoutMs must be a positive supported timer interval");
|
|
4115
|
+
const target = loopbackTarget(options);
|
|
4106
4116
|
const server = options.createServer ? options.createServer() : http.createServer();
|
|
4107
|
-
const
|
|
4108
|
-
|
|
4117
|
+
const controller = new AbortController();
|
|
4118
|
+
let closed = false;
|
|
4119
|
+
let used = false;
|
|
4120
|
+
const callerAbort = () => controller.abort(options.signal?.reason);
|
|
4121
|
+
const teardown = () => {
|
|
4122
|
+
if (closed)
|
|
4123
|
+
return;
|
|
4124
|
+
closed = true;
|
|
4125
|
+
clearTimeout(timer);
|
|
4126
|
+
options.signal?.removeEventListener("abort", callerAbort);
|
|
4127
|
+
server.closeAllConnections?.();
|
|
4128
|
+
server.close();
|
|
4129
|
+
};
|
|
4130
|
+
const timer = setTimeout(() => controller.abort(new Error("OAuth authorization timed out")), timeoutMs);
|
|
4131
|
+
timer.unref?.();
|
|
4132
|
+
controller.signal.addEventListener("abort", teardown, { once: true });
|
|
4133
|
+
options.signal?.addEventListener("abort", callerAbort, { once: true });
|
|
4134
|
+
if (options.signal?.aborted)
|
|
4135
|
+
callerAbort();
|
|
4136
|
+
let port;
|
|
4137
|
+
try {
|
|
4138
|
+
port = await startServer(server, target.port, target.host, controller.signal);
|
|
4139
|
+
} catch (error) {
|
|
4140
|
+
controller.abort(error);
|
|
4141
|
+
throw error;
|
|
4142
|
+
}
|
|
4143
|
+
const redirectUri = options.redirectUri ?? `http://127.0.0.1:${port}${target.callbackPath}`;
|
|
4109
4144
|
return {
|
|
4110
4145
|
redirectUri,
|
|
4111
4146
|
async waitForCode(authorizationUrl) {
|
|
4112
|
-
|
|
4147
|
+
controller.signal.throwIfAborted();
|
|
4148
|
+
if (used)
|
|
4149
|
+
throw new Error("OAuth authorization session has already been used");
|
|
4150
|
+
used = true;
|
|
4151
|
+
try {
|
|
4152
|
+
return await waitForAuthorizationCode(server, authorizationUrl, options, target.callbackPath, controller.signal);
|
|
4153
|
+
} finally {
|
|
4154
|
+
clearTimeout(timer);
|
|
4155
|
+
}
|
|
4113
4156
|
},
|
|
4114
4157
|
close() {
|
|
4115
|
-
|
|
4116
|
-
server.close();
|
|
4158
|
+
controller.abort(new Error("OAuth authorization session closed"));
|
|
4117
4159
|
}
|
|
4118
4160
|
};
|
|
4119
4161
|
}
|
|
4120
|
-
|
|
4162
|
+
function loopbackTarget(options) {
|
|
4163
|
+
if (options.redirectUri !== void 0) {
|
|
4164
|
+
let url;
|
|
4165
|
+
try {
|
|
4166
|
+
url = new URL(options.redirectUri);
|
|
4167
|
+
} catch (cause) {
|
|
4168
|
+
throw new Error("Invalid OAuth loopback redirect URI", { cause });
|
|
4169
|
+
}
|
|
4170
|
+
const forbiddenQuery = ["code", "state", "error", "error_description", "iss"];
|
|
4171
|
+
if (url.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.username || url.password || url.hash || url.port === "0" || forbiddenQuery.some((name) => url.searchParams.has(name)) || [...options.redirectUri].some((char) => char.codePointAt(0) <= 32) || options.callbackPath !== void 0 && options.callbackPath !== url.pathname)
|
|
4172
|
+
throw new Error("Invalid OAuth loopback redirect URI");
|
|
4173
|
+
return { port: url.port ? Number(url.port) : 80, host: url.hostname === "[::1]" ? "::1" : url.hostname, callbackPath: url.pathname };
|
|
4174
|
+
}
|
|
4175
|
+
const callbackPath = options.callbackPath ?? "/callback";
|
|
4176
|
+
const parsed = new URL(callbackPath, "http://127.0.0.1");
|
|
4177
|
+
if (!callbackPath.startsWith("/") || parsed.origin !== "http://127.0.0.1" || parsed.pathname !== callbackPath || parsed.search || parsed.hash)
|
|
4178
|
+
throw new Error("Invalid OAuth loopback callback path");
|
|
4179
|
+
return { port: 0, host: "127.0.0.1", callbackPath };
|
|
4180
|
+
}
|
|
4181
|
+
async function startServer(server, port, host, signal) {
|
|
4182
|
+
signal.throwIfAborted();
|
|
4121
4183
|
return new Promise((resolve, reject) => {
|
|
4122
|
-
const
|
|
4184
|
+
const cleanup = () => {
|
|
4123
4185
|
server.off("error", handleError);
|
|
4186
|
+
signal.removeEventListener("abort", aborted);
|
|
4187
|
+
};
|
|
4188
|
+
const handleError = (error) => {
|
|
4189
|
+
cleanup();
|
|
4124
4190
|
reject(error);
|
|
4125
4191
|
};
|
|
4192
|
+
const aborted = () => {
|
|
4193
|
+
cleanup();
|
|
4194
|
+
reject(signal.reason);
|
|
4195
|
+
};
|
|
4126
4196
|
server.once("error", handleError);
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4197
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
4198
|
+
try {
|
|
4199
|
+
server.listen(port, host, () => {
|
|
4200
|
+
cleanup();
|
|
4201
|
+
if (signal.aborted) {
|
|
4202
|
+
server.close();
|
|
4203
|
+
reject(signal.reason);
|
|
4204
|
+
return;
|
|
4205
|
+
}
|
|
4206
|
+
const address = server.address();
|
|
4207
|
+
if (address === null || typeof address === "string") {
|
|
4208
|
+
reject(new Error("OAuth listener has no TCP address"));
|
|
4209
|
+
return;
|
|
4210
|
+
}
|
|
4211
|
+
resolve(address.port);
|
|
4212
|
+
});
|
|
4213
|
+
} catch (error) {
|
|
4214
|
+
cleanup();
|
|
4215
|
+
reject(error);
|
|
4216
|
+
}
|
|
4132
4217
|
});
|
|
4133
4218
|
}
|
|
4134
|
-
function waitForAuthorizationCode(server, authorizationUrl, options, callbackPath) {
|
|
4219
|
+
function waitForAuthorizationCode(server, authorizationUrl, options, callbackPath, signal) {
|
|
4220
|
+
signal.throwIfAborted();
|
|
4135
4221
|
const expectedAuthorization = readExpectedAuthorizationCallback(authorizationUrl);
|
|
4136
4222
|
return new Promise((resolve, reject) => {
|
|
4137
4223
|
let settled = false;
|
|
4138
4224
|
const settle = (fn) => {
|
|
4139
|
-
if (
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4225
|
+
if (settled)
|
|
4226
|
+
return;
|
|
4227
|
+
settled = true;
|
|
4228
|
+
server.off("request", request);
|
|
4229
|
+
signal.removeEventListener("abort", aborted);
|
|
4230
|
+
fn();
|
|
4143
4231
|
};
|
|
4144
|
-
|
|
4145
|
-
|
|
4232
|
+
const aborted = () => settle(() => reject(signal.reason));
|
|
4233
|
+
const request = (req, res) => {
|
|
4234
|
+
let url;
|
|
4235
|
+
try {
|
|
4236
|
+
url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
4237
|
+
} catch {
|
|
4238
|
+
res.writeHead(400);
|
|
4239
|
+
res.end("Invalid callback URL");
|
|
4240
|
+
return;
|
|
4241
|
+
}
|
|
4146
4242
|
if (url.pathname !== callbackPath) {
|
|
4147
4243
|
res.writeHead(404);
|
|
4148
4244
|
res.end("Not found");
|
|
@@ -4157,21 +4253,8 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
4157
4253
|
};
|
|
4158
4254
|
try {
|
|
4159
4255
|
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
4163
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
4164
|
-
return;
|
|
4165
|
-
}
|
|
4166
|
-
const authorizationError = callbackParameters.error;
|
|
4167
|
-
if (authorizationError !== null) {
|
|
4168
|
-
const description = callbackParameters.errorDescription ?? authorizationError;
|
|
4169
|
-
res.writeHead(400);
|
|
4170
|
-
res.end(`Authorization failed: ${description}`);
|
|
4171
|
-
settle(() => reject(createAuthorizationError(authorizationError, description)));
|
|
4172
|
-
return;
|
|
4173
|
-
}
|
|
4174
|
-
try {
|
|
4256
|
+
if (callbackParameters.error !== null)
|
|
4257
|
+
throw createAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
4175
4258
|
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
4176
4259
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
4177
4260
|
res.end(buildSuccessPage(options.landingPage));
|
|
@@ -4179,35 +4262,27 @@ function waitForAuthorizationCode(server, authorizationUrl, options, callbackPat
|
|
|
4179
4262
|
} catch (error) {
|
|
4180
4263
|
res.writeHead(400);
|
|
4181
4264
|
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
4182
|
-
settle(() => reject(error
|
|
4265
|
+
settle(() => reject(error));
|
|
4183
4266
|
}
|
|
4184
|
-
}
|
|
4267
|
+
};
|
|
4268
|
+
server.on("request", request);
|
|
4269
|
+
signal.addEventListener("abort", aborted, { once: true });
|
|
4185
4270
|
if (options.readLine !== void 0) {
|
|
4186
|
-
options.readLine().then((input) => {
|
|
4187
|
-
|
|
4188
|
-
if (callbackParameters === null) {
|
|
4189
|
-
settle(() => reject(new Error("OAuth callback missing authorization code")));
|
|
4271
|
+
void Promise.resolve().then(() => settled ? void 0 : options.readLine()).then((input) => {
|
|
4272
|
+
if (settled)
|
|
4190
4273
|
return;
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
} catch (error) {
|
|
4201
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
4202
|
-
}
|
|
4203
|
-
}).catch((error) => {
|
|
4204
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
4205
|
-
});
|
|
4274
|
+
const callbackParameters = extractCallbackParametersFromInput(input);
|
|
4275
|
+
if (callbackParameters === null)
|
|
4276
|
+
throw new Error("OAuth callback missing authorization code");
|
|
4277
|
+
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
4278
|
+
if (callbackParameters.error !== null)
|
|
4279
|
+
throw createAuthorizationError(callbackParameters.error, callbackParameters.errorDescription ?? callbackParameters.error);
|
|
4280
|
+
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
4281
|
+
settle(() => resolve(code));
|
|
4282
|
+
}).catch((error) => settle(() => reject(error)));
|
|
4206
4283
|
}
|
|
4207
4284
|
if (options.openBrowser !== void 0) {
|
|
4208
|
-
options.openBrowser(authorizationUrl).catch((error) =>
|
|
4209
|
-
settle(() => reject(error));
|
|
4210
|
-
});
|
|
4285
|
+
void Promise.resolve().then(() => settled ? void 0 : options.openBrowser(authorizationUrl)).catch((error) => settle(() => reject(error)));
|
|
4211
4286
|
}
|
|
4212
4287
|
});
|
|
4213
4288
|
}
|
|
@@ -4387,6 +4462,7 @@ async function exchangeAuthorizationCode(input) {
|
|
|
4387
4462
|
resource
|
|
4388
4463
|
},
|
|
4389
4464
|
fetch: input.fetch,
|
|
4465
|
+
signal: input.signal,
|
|
4390
4466
|
now: input.now
|
|
4391
4467
|
});
|
|
4392
4468
|
}
|
|
@@ -4402,6 +4478,7 @@ async function refreshAccessToken(input) {
|
|
|
4402
4478
|
resource
|
|
4403
4479
|
},
|
|
4404
4480
|
fetch: input.fetch,
|
|
4481
|
+
signal: input.signal,
|
|
4405
4482
|
now: input.now
|
|
4406
4483
|
});
|
|
4407
4484
|
}
|
|
@@ -4413,7 +4490,9 @@ async function requestTokens(input) {
|
|
|
4413
4490
|
if (input.clientSecret !== void 0) {
|
|
4414
4491
|
body.set("client_secret", input.clientSecret);
|
|
4415
4492
|
}
|
|
4416
|
-
|
|
4493
|
+
input.signal?.throwIfAborted();
|
|
4494
|
+
const deadline = AbortSignal.timeout(3e4);
|
|
4495
|
+
const signal = input.signal === void 0 ? deadline : AbortSignal.any([input.signal, deadline]);
|
|
4417
4496
|
const response = await fetchMcpResponse(input.fetch, input.tokenEndpoint, {
|
|
4418
4497
|
method: "POST",
|
|
4419
4498
|
headers: {
|
|
@@ -4521,12 +4600,34 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4521
4600
|
const registeredClients = /* @__PURE__ */ new Map();
|
|
4522
4601
|
const refreshPromises = /* @__PURE__ */ new Map();
|
|
4523
4602
|
const authorizationPromises = /* @__PURE__ */ new Map();
|
|
4603
|
+
if (options.initialGrant !== void 0) {
|
|
4604
|
+
let resource;
|
|
4605
|
+
try {
|
|
4606
|
+
resource = new URL2(options.initialGrant.resource);
|
|
4607
|
+
} catch {
|
|
4608
|
+
throw new Error("OAuth initial grant resource must be an absolute HTTP URL");
|
|
4609
|
+
}
|
|
4610
|
+
if (resource.protocol !== "http:" && resource.protocol !== "https:" || resource.username || resource.password || resource.hash)
|
|
4611
|
+
throw new Error("OAuth initial grant resource must be an HTTP URL without credentials or fragments");
|
|
4612
|
+
}
|
|
4613
|
+
const initialGrant = options.initialGrant === void 0 ? void 0 : {
|
|
4614
|
+
resource: canonicalizeResourceIndicator(options.initialGrant.resource),
|
|
4615
|
+
tokens: normalizeStoredTokens(options.initialGrant.tokens),
|
|
4616
|
+
client: normalizeConfiguredClient(options.client)
|
|
4617
|
+
};
|
|
4618
|
+
if (initialGrant !== void 0 && (initialGrant.tokens === void 0 || initialGrant.client === null))
|
|
4619
|
+
throw new Error("OAuth initial grant requires valid tokens and the original client ID");
|
|
4620
|
+
let initialGrantConsumed = false;
|
|
4524
4621
|
return {
|
|
4525
4622
|
async authorizeRequest(input) {
|
|
4526
4623
|
assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
|
|
4527
4624
|
const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
|
|
4528
|
-
const session = await ensureAuthorizedSession(requestUrl, void 0, input.fetch, false);
|
|
4625
|
+
const session = await ensureAuthorizedSession(requestUrl, void 0, input.fetch, false, false, input.signal);
|
|
4529
4626
|
const accessToken = session?.tokens?.accessToken;
|
|
4627
|
+
if (session === null && !initialGrantConsumed && initialGrant?.resource === requestUrl && initialGrant.tokens !== void 0 && !isExpired(initialGrant.tokens, now)) {
|
|
4628
|
+
input.headers.set("Authorization", `Bearer ${initialGrant.tokens.accessToken}`);
|
|
4629
|
+
return;
|
|
4630
|
+
}
|
|
4530
4631
|
if (session === null || accessToken === void 0 || session.tokens === void 0 || isExpired(session.tokens, now)) {
|
|
4531
4632
|
return;
|
|
4532
4633
|
}
|
|
@@ -4539,16 +4640,17 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4539
4640
|
const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
|
|
4540
4641
|
const resource = canonicalizeResourceIndicator(input.discovery.resource);
|
|
4541
4642
|
assertRequestMatchesResource(requestUrl, resource);
|
|
4542
|
-
const forceRefresh = hasCachedAccessToken(await loadSession(resource)) && input.challenge?.params.error === "invalid_token";
|
|
4643
|
+
const forceRefresh = (hasCachedAccessToken(await loadSession(resource)) || !initialGrantConsumed && initialGrant?.resource === resource) && input.challenge?.params.error === "invalid_token";
|
|
4543
4644
|
const session = await ensureAuthorizedSession(resource, {
|
|
4544
4645
|
...input.discovery,
|
|
4545
4646
|
resource
|
|
4546
|
-
}, input.fetch, true, forceRefresh);
|
|
4647
|
+
}, input.fetch, true, forceRefresh, input.signal);
|
|
4547
4648
|
if (session?.tokens?.accessToken === void 0) {
|
|
4548
4649
|
return { action: "fail" };
|
|
4549
4650
|
}
|
|
4550
4651
|
return { action: "retry" };
|
|
4551
4652
|
} catch (error) {
|
|
4653
|
+
input.signal?.throwIfAborted();
|
|
4552
4654
|
return {
|
|
4553
4655
|
action: "fail",
|
|
4554
4656
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -4556,9 +4658,13 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4556
4658
|
}
|
|
4557
4659
|
}
|
|
4558
4660
|
};
|
|
4559
|
-
async function ensureAuthorizedSession(resource, discovery, fetch2, allowInteractive, forceRefresh = false) {
|
|
4661
|
+
async function ensureAuthorizedSession(resource, discovery, fetch2, allowInteractive, forceRefresh = false, signal) {
|
|
4662
|
+
signal?.throwIfAborted();
|
|
4560
4663
|
const canonicalResource = canonicalizeResourceIndicator(resource);
|
|
4561
4664
|
let session = await loadSession(canonicalResource);
|
|
4665
|
+
if (session !== null && initialGrant?.resource === canonicalResource)
|
|
4666
|
+
initialGrantConsumed = true;
|
|
4667
|
+
signal?.throwIfAborted();
|
|
4562
4668
|
if (discovery !== void 0 && getOwnString2(discovery.authorizationServerMetadata, "issuer") !== discovery.authorizationServer) {
|
|
4563
4669
|
throw new Error("OAuth discovery authorization-server issuer mismatch");
|
|
4564
4670
|
}
|
|
@@ -4566,12 +4672,25 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4566
4672
|
await clearSession(canonicalResource);
|
|
4567
4673
|
session = null;
|
|
4568
4674
|
}
|
|
4675
|
+
if (session === null && discovery !== void 0 && !initialGrantConsumed && initialGrant?.resource === canonicalResource && initialGrant.tokens !== void 0 && initialGrant.client !== null) {
|
|
4676
|
+
assertSecureOAuthFlowEndpoints(discovery.authorizationServerMetadata);
|
|
4677
|
+
session = {
|
|
4678
|
+
resource: canonicalResource,
|
|
4679
|
+
authorizationServer: discovery.authorizationServer,
|
|
4680
|
+
client: initialGrant.client,
|
|
4681
|
+
tokens: initialGrant.tokens,
|
|
4682
|
+
discovery: toStoredDiscovery(discovery)
|
|
4683
|
+
};
|
|
4684
|
+
await saveSession(canonicalResource, session);
|
|
4685
|
+
initialGrantConsumed = true;
|
|
4686
|
+
signal?.throwIfAborted();
|
|
4687
|
+
}
|
|
4569
4688
|
const sessionDiscovery = resolveDiscovery(discovery, session);
|
|
4570
4689
|
if (session?.tokens !== void 0 && !forceRefresh && !isExpired(session.tokens, now)) {
|
|
4571
4690
|
return session;
|
|
4572
4691
|
}
|
|
4573
4692
|
if (session?.tokens?.refreshToken !== void 0 && sessionDiscovery !== void 0 && (forceRefresh || isExpired(session.tokens, now))) {
|
|
4574
|
-
session = await refreshSession(canonicalResource, session, sessionDiscovery, fetch2);
|
|
4693
|
+
session = await refreshSession(canonicalResource, session, sessionDiscovery, fetch2, signal);
|
|
4575
4694
|
if (session?.tokens !== void 0 && !isExpired(session.tokens, now)) {
|
|
4576
4695
|
return session;
|
|
4577
4696
|
}
|
|
@@ -4583,9 +4702,12 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4583
4702
|
if (!allowInteractive || sessionDiscovery === void 0) {
|
|
4584
4703
|
return session;
|
|
4585
4704
|
}
|
|
4586
|
-
|
|
4705
|
+
if (options.allowInteractive === false)
|
|
4706
|
+
throw new Error("OAuth interactive authorization is disabled");
|
|
4707
|
+
return authorizeSession(canonicalResource, session, sessionDiscovery, fetch2, signal);
|
|
4587
4708
|
}
|
|
4588
|
-
async function refreshSession(resource, session, discovery, fetch2) {
|
|
4709
|
+
async function refreshSession(resource, session, discovery, fetch2, signal) {
|
|
4710
|
+
signal?.throwIfAborted();
|
|
4589
4711
|
assertSecureOAuthFlowEndpoints(discovery.authorizationServerMetadata);
|
|
4590
4712
|
const inFlight = refreshPromises.get(resource);
|
|
4591
4713
|
if (inFlight !== void 0) {
|
|
@@ -4607,10 +4729,12 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4607
4729
|
refreshToken: session.tokens.refreshToken,
|
|
4608
4730
|
resource,
|
|
4609
4731
|
fetch: fetch2,
|
|
4732
|
+
signal,
|
|
4610
4733
|
now
|
|
4611
4734
|
});
|
|
4612
4735
|
break;
|
|
4613
4736
|
} catch (error) {
|
|
4737
|
+
signal?.throwIfAborted();
|
|
4614
4738
|
if (error instanceof OAuthError && error.error === "invalid_grant") {
|
|
4615
4739
|
const clearedSession = clearSessionTokens(session);
|
|
4616
4740
|
await saveSession(resource, clearedSession);
|
|
@@ -4645,7 +4769,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4645
4769
|
refreshPromises.set(resource, promise);
|
|
4646
4770
|
return promise;
|
|
4647
4771
|
}
|
|
4648
|
-
async function authorizeSession(resource, existingSession, discovery, fetch2) {
|
|
4772
|
+
async function authorizeSession(resource, existingSession, discovery, fetch2, signal) {
|
|
4773
|
+
signal?.throwIfAborted();
|
|
4649
4774
|
const inFlight = authorizationPromises.get(resource);
|
|
4650
4775
|
if (inFlight !== void 0) {
|
|
4651
4776
|
return inFlight;
|
|
@@ -4661,11 +4786,14 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4661
4786
|
openBrowser: options.browser.openBrowser,
|
|
4662
4787
|
readLine: options.browser.readLine,
|
|
4663
4788
|
createServer: options.browser.createServer,
|
|
4664
|
-
landingPage: options.browser.landingPage
|
|
4789
|
+
landingPage: options.browser.landingPage,
|
|
4790
|
+
redirectUri: options.browser.redirectUri,
|
|
4791
|
+
signal: options.browser.signal === void 0 ? signal : signal === void 0 ? options.browser.signal : AbortSignal.any([signal, options.browser.signal]),
|
|
4792
|
+
timeoutMs: options.browser.timeoutMs
|
|
4665
4793
|
});
|
|
4666
4794
|
let resolvedClient = null;
|
|
4667
4795
|
try {
|
|
4668
|
-
resolvedClient = await resolveClient(currentSession, discovery, loopback.redirectUri, fetch2);
|
|
4796
|
+
resolvedClient = await resolveClient(currentSession, discovery, loopback.redirectUri, fetch2, signal);
|
|
4669
4797
|
const sessionWithoutTokens = {
|
|
4670
4798
|
resource,
|
|
4671
4799
|
authorizationServer: discovery.authorizationServer,
|
|
@@ -4693,6 +4821,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4693
4821
|
redirectUri: loopback.redirectUri,
|
|
4694
4822
|
resource,
|
|
4695
4823
|
fetch: fetch2,
|
|
4824
|
+
signal,
|
|
4696
4825
|
now
|
|
4697
4826
|
});
|
|
4698
4827
|
const session = {
|
|
@@ -4702,6 +4831,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4702
4831
|
await saveSession(resource, session);
|
|
4703
4832
|
return session;
|
|
4704
4833
|
} catch (error) {
|
|
4834
|
+
signal?.throwIfAborted();
|
|
4705
4835
|
if (shouldReRegisterStoredDynamicClient(error, resolvedClient, reRegistrationAttempted)) {
|
|
4706
4836
|
reRegistrationAttempted = true;
|
|
4707
4837
|
await clearRegisteredClient(discovery.authorizationServer);
|
|
@@ -4727,7 +4857,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4727
4857
|
authorizationPromises.set(resource, finalPromise);
|
|
4728
4858
|
return finalPromise;
|
|
4729
4859
|
}
|
|
4730
|
-
async function resolveClient(existingSession, discovery, redirectUri, fetch2) {
|
|
4860
|
+
async function resolveClient(existingSession, discovery, redirectUri, fetch2, parentSignal) {
|
|
4861
|
+
parentSignal?.throwIfAborted();
|
|
4731
4862
|
const configuredClient = normalizeConfiguredClient(options.client);
|
|
4732
4863
|
if (options.client.mode === "static") {
|
|
4733
4864
|
if (configuredClient === null) {
|
|
@@ -4777,7 +4908,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4777
4908
|
}
|
|
4778
4909
|
}
|
|
4779
4910
|
const registrationBody = buildClientRegistrationBody(getClientMetadata(options.client), redirectUri);
|
|
4780
|
-
const
|
|
4911
|
+
const deadline = AbortSignal.timeout(3e4);
|
|
4912
|
+
const signal = parentSignal === void 0 ? deadline : AbortSignal.any([parentSignal, deadline]);
|
|
4781
4913
|
const response = await fetchMcpResponse(fetch2, registrationEndpoint, {
|
|
4782
4914
|
method: "POST",
|
|
4783
4915
|
headers: {
|
|
@@ -5340,8 +5472,10 @@ async function readJsonResponse(response, label, signal) {
|
|
|
5340
5472
|
throw new Error(`${label} response must be valid JSON`);
|
|
5341
5473
|
}
|
|
5342
5474
|
}
|
|
5343
|
-
async function fetchMetadata(fetch2, location, label) {
|
|
5344
|
-
|
|
5475
|
+
async function fetchMetadata(fetch2, location, label, parentSignal) {
|
|
5476
|
+
parentSignal?.throwIfAborted();
|
|
5477
|
+
const deadline = AbortSignal.timeout(1e4);
|
|
5478
|
+
const signal = parentSignal === void 0 ? deadline : AbortSignal.any([deadline, parentSignal]);
|
|
5345
5479
|
const response = await fetchMcpResponse(fetch2, location, {
|
|
5346
5480
|
method: "GET",
|
|
5347
5481
|
headers: { Accept: "application/json" },
|
|
@@ -5443,7 +5577,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
5443
5577
|
this.fetchImpl = fetch2;
|
|
5444
5578
|
this.cache = cache;
|
|
5445
5579
|
}
|
|
5446
|
-
async discoverProtectedResource(resource, resourceMetadataUrl) {
|
|
5580
|
+
async discoverProtectedResource(resource, resourceMetadataUrl, signal) {
|
|
5447
5581
|
const locations = /* @__PURE__ */ new Set([resolveProtectedResourceMetadataUrl(resource, resourceMetadataUrl)]);
|
|
5448
5582
|
if (resourceMetadataUrl === void 0) {
|
|
5449
5583
|
locations.add(new URL("/.well-known/oauth-protected-resource", resource).toString());
|
|
@@ -5452,17 +5586,19 @@ var OAuthMetadataDiscovery = class {
|
|
|
5452
5586
|
for (const location of locations) {
|
|
5453
5587
|
try {
|
|
5454
5588
|
const metadata = validateProtectedResourceMetadata(
|
|
5455
|
-
await fetchMetadata(this.fetchImpl, location, "Protected resource metadata"),
|
|
5589
|
+
await fetchMetadata(this.fetchImpl, location, "Protected resource metadata", signal),
|
|
5456
5590
|
resource
|
|
5457
5591
|
);
|
|
5458
5592
|
return { location, metadata };
|
|
5459
5593
|
} catch (error) {
|
|
5594
|
+
signal?.throwIfAborted();
|
|
5460
5595
|
lastError = error;
|
|
5461
5596
|
}
|
|
5462
5597
|
}
|
|
5463
5598
|
throw lastError;
|
|
5464
5599
|
}
|
|
5465
|
-
async discover(resourceUrl, { resourceMetadataUrl } = {}) {
|
|
5600
|
+
async discover(resourceUrl, { resourceMetadataUrl, signal } = {}) {
|
|
5601
|
+
signal?.throwIfAborted();
|
|
5466
5602
|
const cacheKey = canonicalizeResourceIndicator(resourceUrl);
|
|
5467
5603
|
resolveProtectedResourceMetadataUrl(cacheKey, resourceMetadataUrl);
|
|
5468
5604
|
const memoryCachedResult = this.memoryCache.get(cacheKey);
|
|
@@ -5470,6 +5606,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
5470
5606
|
return structuredClone(memoryCachedResult);
|
|
5471
5607
|
}
|
|
5472
5608
|
const sharedCachedResult = await this.cache?.get(cacheKey);
|
|
5609
|
+
signal?.throwIfAborted();
|
|
5473
5610
|
if (sharedCachedResult !== null && sharedCachedResult !== void 0 && resourceMetadataUrl === void 0) {
|
|
5474
5611
|
try {
|
|
5475
5612
|
const result = validateCachedDiscovery(sharedCachedResult, cacheKey);
|
|
@@ -5479,7 +5616,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
5479
5616
|
await this.cache?.delete?.(cacheKey);
|
|
5480
5617
|
}
|
|
5481
5618
|
}
|
|
5482
|
-
const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl);
|
|
5619
|
+
const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl, signal);
|
|
5483
5620
|
const authorizationServerErrors = [];
|
|
5484
5621
|
for (const authorizationServer of resourceMetadata.authorization_servers) {
|
|
5485
5622
|
const normalizedAuthorizationServer = validateAuthorizationServerIssuer(authorizationServer);
|
|
@@ -5487,7 +5624,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
5487
5624
|
for (const authorizationServerMetadataUrl of metadataLocations) {
|
|
5488
5625
|
try {
|
|
5489
5626
|
const authorizationServerMetadata = validateAuthorizationServerMetadata(
|
|
5490
|
-
await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "Authorization server metadata"),
|
|
5627
|
+
await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "Authorization server metadata", signal),
|
|
5491
5628
|
normalizedAuthorizationServer
|
|
5492
5629
|
);
|
|
5493
5630
|
const result = {
|
|
@@ -5502,6 +5639,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
5502
5639
|
await this.cache?.set(cacheKey, structuredClone(result));
|
|
5503
5640
|
return result;
|
|
5504
5641
|
} catch (error) {
|
|
5642
|
+
signal?.throwIfAborted();
|
|
5505
5643
|
authorizationServerErrors.push(
|
|
5506
5644
|
`${authorizationServerMetadataUrl}: ${error instanceof Error ? error.message : String(error)}`
|
|
5507
5645
|
);
|
|
@@ -6642,6 +6780,7 @@ var HttpTransport = class {
|
|
|
6642
6780
|
oauthProvider;
|
|
6643
6781
|
oauthMetadataDiscovery;
|
|
6644
6782
|
inFlightFetchAbortControllers = /* @__PURE__ */ new Set();
|
|
6783
|
+
inFlightOAuthAbortControllers = /* @__PURE__ */ new Set();
|
|
6645
6784
|
openResponseReaders = /* @__PURE__ */ new Set();
|
|
6646
6785
|
modernRequests = /* @__PURE__ */ new Map();
|
|
6647
6786
|
modernMode = false;
|
|
@@ -6711,7 +6850,7 @@ var HttpTransport = class {
|
|
|
6711
6850
|
this.rejectLegacyEndpoint = void 0;
|
|
6712
6851
|
this.resolveLegacyEndpoint = void 0;
|
|
6713
6852
|
this.toolParameterHeaders.clear();
|
|
6714
|
-
this.abortInFlightFetches();
|
|
6853
|
+
this.abortInFlightFetches(reason);
|
|
6715
6854
|
this.cancelOpenResponseReaders();
|
|
6716
6855
|
if (!this.writeStream.destroyed && !this.writeStream.writableEnded) {
|
|
6717
6856
|
this.writeStream.end();
|
|
@@ -6747,12 +6886,14 @@ var HttpTransport = class {
|
|
|
6747
6886
|
this.resolveClosed = void 0;
|
|
6748
6887
|
resolveClosed?.({ reason: closeReason });
|
|
6749
6888
|
}
|
|
6750
|
-
abortInFlightFetches() {
|
|
6751
|
-
for (const controller of this.modernRequests.values()) controller.abort();
|
|
6889
|
+
abortInFlightFetches(reason) {
|
|
6890
|
+
for (const controller of this.modernRequests.values()) controller.abort(reason);
|
|
6752
6891
|
this.modernRequests.clear();
|
|
6753
6892
|
for (const abortController of this.inFlightFetchAbortControllers) {
|
|
6754
|
-
abortController.abort();
|
|
6893
|
+
abortController.abort(reason);
|
|
6755
6894
|
}
|
|
6895
|
+
for (const controller of this.inFlightOAuthAbortControllers) controller.abort(reason);
|
|
6896
|
+
this.inFlightOAuthAbortControllers.clear();
|
|
6756
6897
|
this.inFlightFetchAbortControllers.clear();
|
|
6757
6898
|
}
|
|
6758
6899
|
cancelOpenResponseReaders() {
|
|
@@ -6818,7 +6959,7 @@ var HttpTransport = class {
|
|
|
6818
6959
|
const response = await this.fetchWithOAuthRetry({
|
|
6819
6960
|
url: postUrl,
|
|
6820
6961
|
method: "POST",
|
|
6821
|
-
createHeaders: () => this.createPostHeaders(message, modern),
|
|
6962
|
+
createHeaders: (signal) => this.createPostHeaders(message, modern, signal),
|
|
6822
6963
|
body: line,
|
|
6823
6964
|
controller
|
|
6824
6965
|
});
|
|
@@ -6858,7 +6999,7 @@ var HttpTransport = class {
|
|
|
6858
6999
|
this.modernRequests.delete(id);
|
|
6859
7000
|
}
|
|
6860
7001
|
}
|
|
6861
|
-
async createPostHeaders(message, modern = false) {
|
|
7002
|
+
async createPostHeaders(message, modern = false, signal) {
|
|
6862
7003
|
const headers = new Headers(this.headers);
|
|
6863
7004
|
headers.set("Accept", "application/json, text/event-stream");
|
|
6864
7005
|
headers.set("Content-Type", "application/json");
|
|
@@ -6888,9 +7029,9 @@ var HttpTransport = class {
|
|
|
6888
7029
|
headers.set("Mcp-Session-Id", this.sessionId);
|
|
6889
7030
|
headers.set("MCP-Protocol-Version", MCP_PROTOCOL_VERSION);
|
|
6890
7031
|
}
|
|
6891
|
-
return this.authorizeRequestHeaders(headers);
|
|
7032
|
+
return this.authorizeRequestHeaders(headers, signal);
|
|
6892
7033
|
}
|
|
6893
|
-
async createGetHeaders() {
|
|
7034
|
+
async createGetHeaders(signal) {
|
|
6894
7035
|
const headers = new Headers(this.headers);
|
|
6895
7036
|
headers.set("Accept", "text/event-stream");
|
|
6896
7037
|
if (this.sessionId !== void 0) {
|
|
@@ -6900,20 +7041,26 @@ var HttpTransport = class {
|
|
|
6900
7041
|
if (this.lastEventId !== void 0) {
|
|
6901
7042
|
headers.set("Last-Event-ID", this.lastEventId);
|
|
6902
7043
|
}
|
|
6903
|
-
return this.authorizeRequestHeaders(headers);
|
|
7044
|
+
return this.authorizeRequestHeaders(headers, signal);
|
|
6904
7045
|
}
|
|
6905
|
-
async createDeleteHeaders(sessionId) {
|
|
7046
|
+
async createDeleteHeaders(sessionId, signal) {
|
|
6906
7047
|
const headers = new Headers(this.headers);
|
|
6907
7048
|
headers.set("Mcp-Session-Id", sessionId);
|
|
6908
7049
|
headers.set("MCP-Protocol-Version", MCP_PROTOCOL_VERSION);
|
|
6909
|
-
return this.authorizeRequestHeaders(headers);
|
|
7050
|
+
return this.authorizeRequestHeaders(headers, signal);
|
|
6910
7051
|
}
|
|
6911
|
-
async authorizeRequestHeaders(headers) {
|
|
7052
|
+
async authorizeRequestHeaders(headers, signal) {
|
|
7053
|
+
signal?.throwIfAborted();
|
|
6912
7054
|
await this.oauthProvider?.authorizeRequest?.({
|
|
6913
7055
|
requestUrl: new URL(this.url),
|
|
6914
7056
|
headers,
|
|
6915
|
-
|
|
7057
|
+
signal,
|
|
7058
|
+
fetch: (url, init) => fetchMcpResponse(this.fetchImpl, url, {
|
|
7059
|
+
...init,
|
|
7060
|
+
signal: signal === void 0 ? init?.signal : init?.signal == null ? signal : AbortSignal.any([signal, init.signal])
|
|
7061
|
+
})
|
|
6916
7062
|
});
|
|
7063
|
+
signal?.throwIfAborted();
|
|
6917
7064
|
return headers;
|
|
6918
7065
|
}
|
|
6919
7066
|
captureSessionId(response) {
|
|
@@ -6950,7 +7097,7 @@ var HttpTransport = class {
|
|
|
6950
7097
|
return this.legacyEndpointReady;
|
|
6951
7098
|
}
|
|
6952
7099
|
async sendSessionTerminationRequest(sessionId, signal) {
|
|
6953
|
-
const headers = await this.createDeleteHeaders(sessionId);
|
|
7100
|
+
const headers = await this.createDeleteHeaders(sessionId, signal);
|
|
6954
7101
|
signal.throwIfAborted();
|
|
6955
7102
|
const response = await fetchMcpResponse(this.fetchImpl, this.url, {
|
|
6956
7103
|
method: "DELETE",
|
|
@@ -6973,7 +7120,7 @@ var HttpTransport = class {
|
|
|
6973
7120
|
async consumeGetSseStream() {
|
|
6974
7121
|
const response = await this.fetchWithOAuthRetry({
|
|
6975
7122
|
method: "GET",
|
|
6976
|
-
createHeaders: () => this.createGetHeaders()
|
|
7123
|
+
createHeaders: (signal) => this.createGetHeaders(signal)
|
|
6977
7124
|
});
|
|
6978
7125
|
if (this.disposed) {
|
|
6979
7126
|
void response.body?.cancel().catch(() => void 0);
|
|
@@ -7056,7 +7203,7 @@ var HttpTransport = class {
|
|
|
7056
7203
|
const message = responseBody.length === 0 ? `HTTP transport POST failed (${statusDescriptor})` : `HTTP transport POST failed (${statusDescriptor}): ${responseBody}`;
|
|
7057
7204
|
throw new HttpTransportError(message, response.status, "POST");
|
|
7058
7205
|
}
|
|
7059
|
-
async maybeHandleUnauthorizedResponse(response) {
|
|
7206
|
+
async maybeHandleUnauthorizedResponse(response, signal) {
|
|
7060
7207
|
if (response.status !== 401 || this.oauthProvider === void 0) {
|
|
7061
7208
|
return false;
|
|
7062
7209
|
}
|
|
@@ -7067,7 +7214,7 @@ var HttpTransport = class {
|
|
|
7067
7214
|
const challenge = parseBearerWwwAuthenticateHeader(response.headers.get("WWW-Authenticate"));
|
|
7068
7215
|
const resourceMetadataUrl = challenge?.params.resource_metadata;
|
|
7069
7216
|
try {
|
|
7070
|
-
const discovery = await discoveryClient.discover(this.url, { resourceMetadataUrl });
|
|
7217
|
+
const discovery = await discoveryClient.discover(this.url, { resourceMetadataUrl, signal });
|
|
7071
7218
|
const providerResponse = response.clone();
|
|
7072
7219
|
let result;
|
|
7073
7220
|
try {
|
|
@@ -7076,8 +7223,13 @@ var HttpTransport = class {
|
|
|
7076
7223
|
response: providerResponse,
|
|
7077
7224
|
challenge,
|
|
7078
7225
|
discovery,
|
|
7079
|
-
|
|
7226
|
+
signal,
|
|
7227
|
+
fetch: (url, init) => fetchMcpResponse(this.fetchImpl, url, {
|
|
7228
|
+
...init,
|
|
7229
|
+
signal: init?.signal == null ? signal : AbortSignal.any([signal, init.signal])
|
|
7230
|
+
})
|
|
7080
7231
|
});
|
|
7232
|
+
signal.throwIfAborted();
|
|
7081
7233
|
} finally {
|
|
7082
7234
|
void providerResponse.body?.cancel().catch(() => void 0);
|
|
7083
7235
|
}
|
|
@@ -7207,25 +7359,30 @@ var HttpTransport = class {
|
|
|
7207
7359
|
`);
|
|
7208
7360
|
}
|
|
7209
7361
|
async fetchWithOAuthRetry(input) {
|
|
7210
|
-
const
|
|
7211
|
-
|
|
7212
|
-
|
|
7362
|
+
const controller = input.controller ?? new AbortController();
|
|
7363
|
+
this.inFlightOAuthAbortControllers.add(controller);
|
|
7364
|
+
const request = async () => {
|
|
7365
|
+
controller.signal.throwIfAborted();
|
|
7366
|
+
const headers = await input.createHeaders(controller.signal);
|
|
7367
|
+
controller.signal.throwIfAborted();
|
|
7368
|
+
return this.fetchWithAbort(input.url ?? this.url, {
|
|
7213
7369
|
method: input.method,
|
|
7214
|
-
headers
|
|
7370
|
+
headers,
|
|
7215
7371
|
body: input.body
|
|
7216
|
-
},
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7372
|
+
}, controller);
|
|
7373
|
+
};
|
|
7374
|
+
try {
|
|
7375
|
+
let response = await request();
|
|
7376
|
+
if (await this.maybeHandleUnauthorizedResponse(response, controller.signal)) response = await request();
|
|
7377
|
+
const oauthError = this.oauthProvider === void 0 ? null : this.readOAuthChallengeError(response);
|
|
7378
|
+
if (oauthError !== null) {
|
|
7379
|
+
void response.body?.cancel().catch(() => void 0);
|
|
7380
|
+
throw oauthError;
|
|
7381
|
+
}
|
|
7382
|
+
return response;
|
|
7383
|
+
} finally {
|
|
7384
|
+
this.inFlightOAuthAbortControllers.delete(controller);
|
|
7227
7385
|
}
|
|
7228
|
-
return response;
|
|
7229
7386
|
}
|
|
7230
7387
|
readOAuthChallengeError(response) {
|
|
7231
7388
|
if (response.status !== 401 && response.status !== 403) {
|