@cat-factory/integrations 0.130.1 → 0.131.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/audit/AuditService.d.ts +36 -0
- package/dist/modules/audit/AuditService.d.ts.map +1 -0
- package/dist/modules/audit/AuditService.js +39 -0
- package/dist/modules/audit/AuditService.js.map +1 -0
- package/dist/modules/mcpOAuth/McpOAuthService.d.ts +199 -0
- package/dist/modules/mcpOAuth/McpOAuthService.d.ts.map +1 -0
- package/dist/modules/mcpOAuth/McpOAuthService.js +489 -0
- package/dist/modules/mcpOAuth/McpOAuthService.js.map +1 -0
- package/dist/modules/mcpOAuth/mcpOAuthClient.d.ts +101 -0
- package/dist/modules/mcpOAuth/mcpOAuthClient.d.ts.map +1 -0
- package/dist/modules/mcpOAuth/mcpOAuthClient.js +389 -0
- package/dist/modules/mcpOAuth/mcpOAuthClient.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { isAllowedMcpHttpUrl, isCloudMetadataHost, redactSecrets } from '@cat-factory/kernel';
|
|
2
|
+
import { safeFetch } from '../shared/safe-fetch.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// The OAuth 2.1 wire half of MCP authorization: discovering where a remote server's authorization
|
|
5
|
+
// server lives, and the three token-endpoint calls that follow.
|
|
6
|
+
//
|
|
7
|
+
// Hand-rolled on `fetch`, for the reason slice 4's probe recorded about its MCP client and slice 3
|
|
8
|
+
// recorded about the server: this code is bundled into a Worker, so it is typed against the Web
|
|
9
|
+
// platform alone and may not reach for a library that assumes Node. It is also small — three form
|
|
10
|
+
// POSTs and a metadata walk — next to an OAuth client library's session handling, storage
|
|
11
|
+
// abstractions and interactive flows, none of which apply when the "client" is a backend minting a
|
|
12
|
+
// token for a container to use.
|
|
13
|
+
//
|
|
14
|
+
// Everything here is stateless. What PERSISTS (the grant) is `McpOAuthService`'s business; this
|
|
15
|
+
// module only ever turns a request into a token response or a cause.
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/** How long the whole discovery walk, or one token call, may take. */
|
|
18
|
+
export const MCP_OAUTH_TIMEOUT_MS = 10_000;
|
|
19
|
+
/** How many metadata documents one discovery walk fetches before giving up. */
|
|
20
|
+
const MAX_METADATA_FETCHES = 6;
|
|
21
|
+
/**
|
|
22
|
+
* Redirect hops one METADATA fetch follows. Well-known paths redirect in the wild (a vendor
|
|
23
|
+
* serving `/.well-known/openid-configuration` off its identity host), and a metadata GET carries
|
|
24
|
+
* no credential, so following is right where refusing would be wrong. Every hop is re-validated:
|
|
25
|
+
* see {@link assertAllowedOAuthUrl}.
|
|
26
|
+
*/
|
|
27
|
+
const MAX_METADATA_REDIRECTS = 3;
|
|
28
|
+
/**
|
|
29
|
+
* The one URL floor every request in this module is held to, applied to DECLARED endpoints,
|
|
30
|
+
* DISCOVERED ones, and every redirect hop alike.
|
|
31
|
+
*
|
|
32
|
+
* Two rules, and the second is here because discovery reads a THIRD PARTY's document. A remote
|
|
33
|
+
* server's protected-resource metadata names its authorization servers, so a compromised or hostile
|
|
34
|
+
* server chooses URLs this deployment then fetches; `isAllowedMcpHttpUrl` alone would accept
|
|
35
|
+
* `https://169.254.169.254/…` and turn the walk into a probe of the instance-metadata service.
|
|
36
|
+
* Blocking metadata hosts while still ALLOWING private and loopback ones is the same trade the
|
|
37
|
+
* Kubernetes apiserver guard makes, and it keeps a sidecar MCP server on a private host connectable.
|
|
38
|
+
*
|
|
39
|
+
* One floor for every URL rather than a stricter rule for discovered ones: a declaration pointing an
|
|
40
|
+
* OAuth endpoint at a metadata host is nonsense too, so there is nothing to gain by admitting it.
|
|
41
|
+
*/
|
|
42
|
+
export function assertAllowedOAuthUrl(raw, what) {
|
|
43
|
+
if (!isAllowedMcpHttpUrl(raw)) {
|
|
44
|
+
throw new McpOAuthError(`The ${what} ${raw} is not https (plain http is accepted only on loopback), and an OAuth ` +
|
|
45
|
+
`exchange carries the client secret and the tokens.`, true);
|
|
46
|
+
}
|
|
47
|
+
let host;
|
|
48
|
+
try {
|
|
49
|
+
host = new URL(raw).hostname;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// silent-catch-ok: `isAllowedMcpHttpUrl` already parsed it, so this cannot be reached with a
|
|
53
|
+
// value that would tell an operator anything the refusal above did not.
|
|
54
|
+
throw new McpOAuthError(`The ${what} ${raw} is not a URL this deployment can use.`, true);
|
|
55
|
+
}
|
|
56
|
+
if (isCloudMetadataHost(host)) {
|
|
57
|
+
throw new McpOAuthError(`The ${what} ${raw} names a cloud instance-metadata address. An OAuth endpoint is never ` +
|
|
58
|
+
`link-local, and following one would point this deployment's own credentials at its ` +
|
|
59
|
+
`instance metadata.`, true);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** A failure with a cause an operator can act on. Never carries a credential (see `describe`). */
|
|
63
|
+
export class McpOAuthError extends Error {
|
|
64
|
+
permanent;
|
|
65
|
+
constructor(message,
|
|
66
|
+
/** True when retrying cannot help: the grant or the client registration must change. */
|
|
67
|
+
permanent) {
|
|
68
|
+
super(message);
|
|
69
|
+
this.permanent = permanent;
|
|
70
|
+
this.name = 'McpOAuthError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Discover a remote MCP server's authorization endpoints, per the MCP authorization spec: the
|
|
75
|
+
* server's own protected-resource metadata (RFC 9728) names its authorization server, and that
|
|
76
|
+
* server's metadata (RFC 8414, or OpenID Connect discovery) names the endpoints.
|
|
77
|
+
*
|
|
78
|
+
* The walk is what makes a vendor server connectable from a declaration that names only its url.
|
|
79
|
+
* Without it a deployment has to find two endpoint URLs in a vendor's docs, and they are exactly
|
|
80
|
+
* the strings a vendor changes when it re-platforms.
|
|
81
|
+
*
|
|
82
|
+
* EVERY url the walk touches goes through {@link assertAllowedOAuthUrl}: each candidate, each
|
|
83
|
+
* redirect hop, and both endpoints that come out of it. A metadata document is a third party
|
|
84
|
+
* telling this deployment where to send its client secret and receive its tokens, which is the one
|
|
85
|
+
* place in this flow where an outsider chooses a URL this side then fetches, so it is also the one
|
|
86
|
+
* place where checking the first URL and trusting the rest would not be checking at all.
|
|
87
|
+
*/
|
|
88
|
+
export async function discoverMcpOAuthEndpoints(serverUrl, deps = {}) {
|
|
89
|
+
const doFetch = deps.fetch ?? fetch;
|
|
90
|
+
const controller = new AbortController();
|
|
91
|
+
const timer = setTimeout(() => controller.abort(), MCP_OAUTH_TIMEOUT_MS);
|
|
92
|
+
let spent = 0;
|
|
93
|
+
const getJson = async (url) => {
|
|
94
|
+
if (spent++ >= MAX_METADATA_FETCHES)
|
|
95
|
+
return undefined;
|
|
96
|
+
try {
|
|
97
|
+
// Redirects followed BY HAND so the floor runs on every hop, not just the first URL: with
|
|
98
|
+
// the platform's `redirect: 'follow'` a permitted metadata host could bounce the walk to an
|
|
99
|
+
// internal address or downgrade it to http, and nothing would re-check. Same helper, and
|
|
100
|
+
// the same reason, as the environment and runner-pool adapters.
|
|
101
|
+
const res = await safeFetch(url, { headers: { accept: 'application/json' }, signal: controller.signal }, (hop) => assertAllowedOAuthUrl(hop, 'OAuth metadata endpoint'), (_status, message) => new McpOAuthError(message, true), MAX_METADATA_REDIRECTS, doFetch);
|
|
102
|
+
if (!res.ok)
|
|
103
|
+
return undefined;
|
|
104
|
+
const body = (await res.json());
|
|
105
|
+
return body && typeof body === 'object' ? body : undefined;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// A URL this deployment REFUSES is not a candidate that merely missed, so it propagates
|
|
109
|
+
// instead of reading as one more 404. The distinction matters to whoever has to act: an
|
|
110
|
+
// exhausted walk means "declare the endpoints", while a refused hop means a third party's
|
|
111
|
+
// metadata pointed somewhere this deployment will not send its client secret, and silently
|
|
112
|
+
// trying the next candidate would leave that fact nowhere.
|
|
113
|
+
if (error instanceof McpOAuthError)
|
|
114
|
+
throw error;
|
|
115
|
+
// A metadata document that is absent, unparseable or unreachable is not a failure on its
|
|
116
|
+
// own: the walk has several candidates and only the LAST one exhausting them is the error.
|
|
117
|
+
// silent-catch-ok: the caller throws a single, better-worded failure once every candidate is
|
|
118
|
+
// spent, and reporting each 404 of a well-known probe would be noise about the normal path.
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
try {
|
|
123
|
+
const resource = await fetchProtectedResourceMetadata(serverUrl, getJson);
|
|
124
|
+
const issuers = resource ? authorizationServersOf(resource) : [];
|
|
125
|
+
// No protected-resource metadata is the common case for a server that predates RFC 9728, and
|
|
126
|
+
// the spec's own fallback is to treat the resource's origin as the issuer.
|
|
127
|
+
const candidates = issuers.length ? issuers : [new URL(serverUrl).origin];
|
|
128
|
+
for (const issuer of candidates) {
|
|
129
|
+
const metadata = await fetchAuthorizationServerMetadata(issuer, getJson);
|
|
130
|
+
if (!metadata)
|
|
131
|
+
continue;
|
|
132
|
+
const endpoints = readEndpoints(metadata);
|
|
133
|
+
if (endpoints)
|
|
134
|
+
return endpoints;
|
|
135
|
+
}
|
|
136
|
+
throw new McpOAuthError(`No OAuth metadata was found for ${serverUrl}. The server published neither protected-resource ` +
|
|
137
|
+
`metadata nor authorization-server metadata this deployment could read, so its endpoints ` +
|
|
138
|
+
`cannot be discovered. Declare authorizationUrl and tokenUrl on the tool server instead.`, true);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The server's protected-resource metadata (RFC 9728). Tried PATH-AWARE first
|
|
146
|
+
* (`/.well-known/oauth-protected-resource/v1/mcp` for a server at `/v1/mcp`), which is what the
|
|
147
|
+
* RFC prescribes and what a host serving several resources under one origin needs, then at the
|
|
148
|
+
* bare well-known path for the single-resource case.
|
|
149
|
+
*/
|
|
150
|
+
async function fetchProtectedResourceMetadata(serverUrl, getJson) {
|
|
151
|
+
const url = new URL(serverUrl);
|
|
152
|
+
const path = url.pathname.replace(/\/+$/, '');
|
|
153
|
+
const candidates = [
|
|
154
|
+
...(path && path !== '/' ? [`${url.origin}/.well-known/oauth-protected-resource${path}`] : []),
|
|
155
|
+
`${url.origin}/.well-known/oauth-protected-resource`,
|
|
156
|
+
];
|
|
157
|
+
for (const candidate of candidates) {
|
|
158
|
+
const body = await getJson(candidate);
|
|
159
|
+
if (body)
|
|
160
|
+
return body;
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The authorization server's own metadata, over the three well-known locations in the order the
|
|
166
|
+
* specs put them: RFC 8414's path-INSERTING form, its path-appending sibling, then OpenID Connect
|
|
167
|
+
* discovery, which many vendors publish and no OAuth-only client would otherwise find.
|
|
168
|
+
*/
|
|
169
|
+
async function fetchAuthorizationServerMetadata(issuer, getJson) {
|
|
170
|
+
let url;
|
|
171
|
+
try {
|
|
172
|
+
url = new URL(issuer);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// silent-catch-ok: an unparseable issuer is one exhausted candidate among several, and the
|
|
176
|
+
// caller reports the exhausted walk once.
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
const path = url.pathname.replace(/\/+$/, '');
|
|
180
|
+
for (const candidate of [
|
|
181
|
+
`${url.origin}/.well-known/oauth-authorization-server${path}`,
|
|
182
|
+
`${url.origin}${path}/.well-known/oauth-authorization-server`,
|
|
183
|
+
`${url.origin}${path}/.well-known/openid-configuration`,
|
|
184
|
+
]) {
|
|
185
|
+
const body = await getJson(candidate);
|
|
186
|
+
if (body)
|
|
187
|
+
return body;
|
|
188
|
+
}
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
/** The `authorization_servers` list of a protected-resource document, as strings. */
|
|
192
|
+
function authorizationServersOf(metadata) {
|
|
193
|
+
const raw = metadata.authorization_servers;
|
|
194
|
+
return Array.isArray(raw) ? raw.filter((entry) => typeof entry === 'string') : [];
|
|
195
|
+
}
|
|
196
|
+
/** The two endpoints out of an AS metadata document, refusing either if it fails the URL floor. */
|
|
197
|
+
function readEndpoints(metadata) {
|
|
198
|
+
const authorizationUrl = metadata.authorization_endpoint;
|
|
199
|
+
const tokenUrl = metadata.token_endpoint;
|
|
200
|
+
if (typeof authorizationUrl !== 'string' || typeof tokenUrl !== 'string')
|
|
201
|
+
return undefined;
|
|
202
|
+
assertAllowedOAuthUrl(authorizationUrl, "authorization server's authorization endpoint");
|
|
203
|
+
assertAllowedOAuthUrl(tokenUrl, "authorization server's token endpoint");
|
|
204
|
+
const methods = metadata.token_endpoint_auth_methods_supported;
|
|
205
|
+
const supported = Array.isArray(methods) ? methods : [];
|
|
206
|
+
return {
|
|
207
|
+
authorizationUrl,
|
|
208
|
+
tokenUrl,
|
|
209
|
+
useBasicAuth: supported.includes('client_secret_basic') && !supported.includes('client_secret_post'),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/** The authorization URL an operator's browser is sent to. */
|
|
213
|
+
export function buildAuthorizationUrl(input) {
|
|
214
|
+
const url = new URL(input.authorizationUrl);
|
|
215
|
+
url.searchParams.set('response_type', 'code');
|
|
216
|
+
url.searchParams.set('client_id', input.clientId);
|
|
217
|
+
url.searchParams.set('redirect_uri', input.redirectUri);
|
|
218
|
+
url.searchParams.set('state', input.state);
|
|
219
|
+
url.searchParams.set('code_challenge', input.codeChallenge);
|
|
220
|
+
url.searchParams.set('code_challenge_method', 'S256');
|
|
221
|
+
// RFC 8707. The MCP authorization spec REQUIRES it: without it an authorization server serving
|
|
222
|
+
// several MCP servers issues a token that any of them accepts, so a token granted for one
|
|
223
|
+
// vendor surface is replayable against another.
|
|
224
|
+
url.searchParams.set('resource', input.resource);
|
|
225
|
+
if (input.scopes?.length)
|
|
226
|
+
url.searchParams.set('scope', input.scopes.join(' '));
|
|
227
|
+
return url.toString();
|
|
228
|
+
}
|
|
229
|
+
/** Exchange an authorization code (plus its PKCE verifier) for a token set. */
|
|
230
|
+
export function exchangeAuthorizationCode(input, deps = {}) {
|
|
231
|
+
return tokenRequest(input, {
|
|
232
|
+
grant_type: 'authorization_code',
|
|
233
|
+
code: input.code,
|
|
234
|
+
redirect_uri: input.redirectUri,
|
|
235
|
+
code_verifier: input.codeVerifier,
|
|
236
|
+
}, deps);
|
|
237
|
+
}
|
|
238
|
+
/** Exchange a refresh token for a fresh token set. */
|
|
239
|
+
export function refreshAccessToken(input, deps = {}) {
|
|
240
|
+
return tokenRequest(input, {
|
|
241
|
+
grant_type: 'refresh_token',
|
|
242
|
+
refresh_token: input.refreshToken,
|
|
243
|
+
...(input.scopes?.length ? { scope: input.scopes.join(' ') } : {}),
|
|
244
|
+
}, deps);
|
|
245
|
+
}
|
|
246
|
+
/** Mint a token from the deployment's own client credentials — the no-human grant. */
|
|
247
|
+
export function requestClientCredentialsToken(input, deps = {}) {
|
|
248
|
+
return tokenRequest(input, {
|
|
249
|
+
grant_type: 'client_credentials',
|
|
250
|
+
...(input.scopes?.length ? { scope: input.scopes.join(' ') } : {}),
|
|
251
|
+
}, deps);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* One token-endpoint POST.
|
|
255
|
+
*
|
|
256
|
+
* The PERMANENCE of a failure is decided here rather than by the caller, and it is the field the
|
|
257
|
+
* whole surface is built on: a 400 `invalid_grant` means the refresh token is dead and the board
|
|
258
|
+
* must re-connect, while a 503 or a dropped connection means try again later. A caller that could
|
|
259
|
+
* not tell them apart would either nag an operator to re-authorise through a vendor's outage or
|
|
260
|
+
* silently retry a grant that will never work again.
|
|
261
|
+
*/
|
|
262
|
+
async function tokenRequest(input, params, deps) {
|
|
263
|
+
assertAllowedOAuthUrl(input.tokenUrl, 'token endpoint');
|
|
264
|
+
const body = new URLSearchParams({
|
|
265
|
+
...params,
|
|
266
|
+
client_id: input.clientId,
|
|
267
|
+
resource: input.resource,
|
|
268
|
+
});
|
|
269
|
+
const headers = {
|
|
270
|
+
accept: 'application/json',
|
|
271
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
272
|
+
};
|
|
273
|
+
if (input.clientSecret) {
|
|
274
|
+
if (input.useBasicAuth) {
|
|
275
|
+
headers.authorization = `Basic ${base64(`${encodeURIComponent(input.clientId)}:${encodeURIComponent(input.clientSecret)}`)}`;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
body.set('client_secret', input.clientSecret);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const doFetch = deps.fetch ?? fetch;
|
|
282
|
+
const controller = new AbortController();
|
|
283
|
+
const timer = setTimeout(() => controller.abort(), MCP_OAUTH_TIMEOUT_MS);
|
|
284
|
+
let response;
|
|
285
|
+
try {
|
|
286
|
+
response = await doFetch(input.tokenUrl, {
|
|
287
|
+
method: 'POST',
|
|
288
|
+
headers,
|
|
289
|
+
body,
|
|
290
|
+
// NOT followed, unlike the metadata walk above, and this is the sharpest rule in the file:
|
|
291
|
+
// this request body carries the client secret and the grant. The platform's `fetch` would
|
|
292
|
+
// follow a 30x itself, and while it strips `Authorization` across origins it does NOT strip
|
|
293
|
+
// a form body, so a token endpoint that redirects would hand the deployment's client secret
|
|
294
|
+
// to wherever it pointed. RFC 6749's token endpoint is a fixed URL, so a redirect here is a
|
|
295
|
+
// misconfiguration or an attack and neither is worth following: refused BY NAME, because
|
|
296
|
+
// "your token endpoint redirects" is the fix, where a silently re-sent secret is not.
|
|
297
|
+
redirect: 'manual',
|
|
298
|
+
signal: controller.signal,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
throw new McpOAuthError(`The token endpoint could not be reached: ${describe(error)}`,
|
|
303
|
+
// Transient by construction: nothing answered, so nothing has judged the grant.
|
|
304
|
+
false);
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
clearTimeout(timer);
|
|
308
|
+
}
|
|
309
|
+
if (response.status >= 300 && response.status < 400) {
|
|
310
|
+
throw new McpOAuthError(`The token endpoint answered with a redirect (HTTP ${response.status}). This deployment ` +
|
|
311
|
+
`will not follow it: the request carries the OAuth client secret, so re-sending it to ` +
|
|
312
|
+
`wherever the redirect points is exactly what must not happen. Point tokenUrl at the ` +
|
|
313
|
+
`endpoint that answers directly.`, true);
|
|
314
|
+
}
|
|
315
|
+
const text = await readBody(response);
|
|
316
|
+
const payload = parseJson(text);
|
|
317
|
+
if (!response.ok) {
|
|
318
|
+
const code = typeof payload?.error === 'string' ? payload.error : undefined;
|
|
319
|
+
const detail = (typeof payload?.error_description === 'string' ? payload.error_description : undefined) ??
|
|
320
|
+
(text ? preview(text) : undefined);
|
|
321
|
+
throw new McpOAuthError(`The token endpoint answered HTTP ${response.status}` +
|
|
322
|
+
`${code ? ` (${code})` : ''}${detail ? `: ${detail}` : ''}`,
|
|
323
|
+
// 4xx is the authorization server JUDGING the request; 5xx is the server having a bad day.
|
|
324
|
+
// `invalid_grant` inside a 4xx is the specific one that means "re-connect".
|
|
325
|
+
response.status >= 400 && response.status < 500);
|
|
326
|
+
}
|
|
327
|
+
const accessToken = payload && typeof payload.access_token === 'string' ? payload.access_token : '';
|
|
328
|
+
if (!accessToken) {
|
|
329
|
+
throw new McpOAuthError(`The token endpoint answered 200 with no access_token${text ? `: ${preview(text)}` : ''}`, true);
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
accessToken,
|
|
333
|
+
...(typeof payload?.refresh_token === 'string' ? { refreshToken: payload.refresh_token } : {}),
|
|
334
|
+
...(typeof payload?.expires_in === 'number' ? { expiresIn: payload.expires_in } : {}),
|
|
335
|
+
...(typeof payload?.scope === 'string' ? { scope: payload.scope } : {}),
|
|
336
|
+
...(typeof payload?.token_type === 'string' ? { tokenType: payload.token_type } : {}),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* The response body as text, or an empty string when the stream itself failed.
|
|
341
|
+
*
|
|
342
|
+
* A body that cannot be read is not a separate outcome worth reporting: the STATUS is what decides
|
|
343
|
+
* the disposition above, and an unreadable 200 falls through to "answered with no access_token",
|
|
344
|
+
* which is the honest description of what happened either way.
|
|
345
|
+
*/
|
|
346
|
+
async function readBody(response) {
|
|
347
|
+
try {
|
|
348
|
+
return await response.text();
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
// silent-catch-ok: see above — the status has already decided the outcome, and the caller
|
|
352
|
+
// reports the missing body as part of a better-worded failure.
|
|
353
|
+
return '';
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function parseJson(text) {
|
|
357
|
+
try {
|
|
358
|
+
const parsed = JSON.parse(text);
|
|
359
|
+
return parsed && typeof parsed === 'object' ? parsed : undefined;
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// silent-catch-ok: a non-JSON error body is reported through `preview` by the caller, which is
|
|
363
|
+
// the whole reason the raw text is kept beside the parse.
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* A bounded, SCRUBBED excerpt of a body or an error.
|
|
369
|
+
*
|
|
370
|
+
* Both are rendered in a browser and written to a log line, and an authorization server answers a
|
|
371
|
+
* bad request with anything from a JSON error object to an HTML page from an auth proxy that
|
|
372
|
+
* echoes the request — including, on the token endpoint above all, the credentials it just
|
|
373
|
+
* refused. `redactSecrets` at the emit site is the rule that covers exactly this.
|
|
374
|
+
*/
|
|
375
|
+
function preview(text) {
|
|
376
|
+
return redactSecrets(text.slice(0, 400)) ?? '';
|
|
377
|
+
}
|
|
378
|
+
function describe(error) {
|
|
379
|
+
return preview(error instanceof Error ? error.message : String(error));
|
|
380
|
+
}
|
|
381
|
+
/** base64 (not url-safe) of a UTF-8 string, for the HTTP Basic header. */
|
|
382
|
+
function base64(value) {
|
|
383
|
+
const bytes = new TextEncoder().encode(value);
|
|
384
|
+
let binary = '';
|
|
385
|
+
for (const byte of bytes)
|
|
386
|
+
binary += String.fromCharCode(byte);
|
|
387
|
+
return btoa(binary);
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=mcpOAuthClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpOAuthClient.js","sourceRoot":"","sources":["../../../src/modules/mcpOAuth/mcpOAuthClient.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/integrations",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.131.0",
|
|
4
4
|
"description": "External-system integration domain logic for the Agent Architecture Board (GitHub, documents, tasks, environments, runners).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"ai": "^7.0.51",
|
|
28
28
|
"p-map": "^7.0.6",
|
|
29
29
|
"yaml": "^2.9.0",
|
|
30
|
-
"@cat-factory/contracts": "0.
|
|
31
|
-
"@cat-factory/kernel": "0.
|
|
30
|
+
"@cat-factory/contracts": "0.246.0",
|
|
31
|
+
"@cat-factory/kernel": "0.244.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"typescript": "7.0.2",
|
|
35
35
|
"undici": "^8.10.0",
|
|
36
36
|
"valibot": "^1.4.2",
|
|
37
37
|
"vitest": "^4.1.10",
|
|
38
|
-
"@cat-factory/caching": "0.14.
|
|
38
|
+
"@cat-factory/caching": "0.14.27"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b tsconfig.build.json",
|