@haikit/mcp 0.32.0 → 0.34.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.
Files changed (52) hide show
  1. package/README.md +60 -1
  2. package/dist/auth.d.ts +151 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +334 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/credential.d.ts +55 -0
  7. package/dist/credential.d.ts.map +1 -0
  8. package/dist/credential.js +62 -0
  9. package/dist/credential.js.map +1 -0
  10. package/dist/errors.d.ts +24 -1
  11. package/dist/errors.d.ts.map +1 -1
  12. package/dist/errors.js +3 -0
  13. package/dist/errors.js.map +1 -1
  14. package/dist/index.d.ts +44 -11
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +511 -144
  17. package/dist/index.js.map +1 -1
  18. package/dist/oauth.d.ts +193 -0
  19. package/dist/oauth.d.ts.map +1 -0
  20. package/dist/oauth.js +558 -0
  21. package/dist/oauth.js.map +1 -0
  22. package/dist/postgres.d.ts +25 -0
  23. package/dist/postgres.d.ts.map +1 -0
  24. package/dist/postgres.js +97 -0
  25. package/dist/postgres.js.map +1 -0
  26. package/dist/routes.d.ts +17 -0
  27. package/dist/routes.d.ts.map +1 -0
  28. package/dist/routes.js +228 -0
  29. package/dist/routes.js.map +1 -0
  30. package/dist/seal.d.ts +25 -0
  31. package/dist/seal.d.ts.map +1 -0
  32. package/dist/seal.js +60 -0
  33. package/dist/seal.js.map +1 -0
  34. package/dist/store.d.ts +50 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +83 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/transports.d.ts +17 -3
  39. package/dist/transports.d.ts.map +1 -1
  40. package/dist/transports.js +13 -3
  41. package/dist/transports.js.map +1 -1
  42. package/package.json +6 -2
  43. package/src/auth.ts +466 -0
  44. package/src/credential.ts +78 -0
  45. package/src/errors.ts +26 -2
  46. package/src/index.ts +555 -158
  47. package/src/oauth.ts +659 -0
  48. package/src/postgres.ts +127 -0
  49. package/src/routes.ts +243 -0
  50. package/src/seal.ts +62 -0
  51. package/src/store.ts +118 -0
  52. package/src/transports.ts +34 -4
package/dist/oauth.js ADDED
@@ -0,0 +1,558 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { OAuthError, OAuthErrorCode, assertSecureTokenEndpoint, auth, computeScopeUnion, discoverOAuthServerInfo, exchangeAuthorization, extractWWWAuthenticateParams, refreshAuthorization, selectClientAuthMethod, selectResourceURL, } from "@modelcontextprotocol/client";
3
+ import { LookupFailed, Lookup, Mismatch, NeedsAuth } from "./credential.js";
4
+ import { binding } from "./seal.js";
5
+ /** How long a connect flow lasts: from the connect route to the callback. */
6
+ export const FLOW_MS = 600_000;
7
+ /** A refresh lease lasts this many `timeoutMs`: past the refresh request, which `timeoutMs` bounds, and the write after it. */
8
+ const LEASE_TIMEOUTS = 2;
9
+ /** How often the store is read while another process holds the refresh lease. */
10
+ const LEASE_POLL_MS = 250;
11
+ /** Tries at writing a refreshed credential while the store fails, and the pause between them. */
12
+ const WRITE_TRIES = 3;
13
+ const WRITE_PAUSE_MS = 250;
14
+ /** A wait that doesn't keep the process going. */
15
+ const pause = (ms) => new Promise((resolve) => {
16
+ setTimeout(resolve, ms).unref();
17
+ });
18
+ /** What a refresh refused for good: the user must connect again. */
19
+ const REFUSED = new Set([OAuthErrorCode.InvalidGrant, OAuthErrorCode.InvalidClient, OAuthErrorCode.UnauthorizedClient]);
20
+ /** Loopback hosts, exempt from https: what the SDK exempts, and RFC 8252 does. */
21
+ export const isLoopback = (host) => host === "localhost" || host.endsWith(".localhost") || host === "127.0.0.1" || host === "[::1]" || host === "::1";
22
+ /** https, or http on this machine. */
23
+ export const isSecure = (url) => {
24
+ try {
25
+ const { protocol, hostname } = new URL(url);
26
+ return protocol === "https:" || (protocol === "http:" && isLoopback(hostname));
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ };
32
+ /** The same authorization server: one trailing slash apart at most, as the SDK allows. */
33
+ const sameIssuer = (a, b) => a === b || a === `${b}/` || b === `${a}/`;
34
+ /** The connect flow a `state` names, once: null if there's none, it has expired, or it doesn't open. */
35
+ export async function takeFlow(core, state) {
36
+ const sealed = await core.store.takeFlow(state);
37
+ if (sealed === null)
38
+ return null;
39
+ const flow = core.sealer.open(sealed, binding.flow(state));
40
+ if (typeof flow?.user !== "string" ||
41
+ typeof flow.server !== "string" ||
42
+ typeof flow.verifier !== "string" ||
43
+ typeof flow.client?.client_id !== "string" ||
44
+ typeof flow.discovery?.authorizationServerUrl !== "string" ||
45
+ typeof flow.expiresAt !== "number" ||
46
+ flow.expiresAt <= Date.now()) {
47
+ return null;
48
+ }
49
+ return flow;
50
+ }
51
+ /**
52
+ * One server's OAuth: its connect route and callback, each user's
53
+ * credential, refreshing, and revoking on disconnect.
54
+ */
55
+ export class OAuthServer {
56
+ core;
57
+ options;
58
+ name;
59
+ url;
60
+ baseFetch;
61
+ timeoutMs;
62
+ forget;
63
+ /** The authorization server, discovered on the first refresh or revocation, or seeded by a callback. */
64
+ found = null;
65
+ /** Each user's refresh on its way, which every 401 of theirs shares until it settles. */
66
+ refreshing = new Map();
67
+ constructor(core, options, name, url, baseFetch, timeoutMs,
68
+ /** Closes the user's connection to this server, so their next call dials with what's stored now. */
69
+ forget) {
70
+ this.core = core;
71
+ this.options = options;
72
+ this.name = name;
73
+ this.url = url;
74
+ this.baseFetch = baseFetch;
75
+ this.timeoutMs = timeoutMs;
76
+ this.forget = forget;
77
+ }
78
+ /** Every request to the authorization server, bounded by `timeoutMs`. */
79
+ fetch = (url, init) => {
80
+ const timeout = AbortSignal.timeout(this.timeoutMs);
81
+ return this.baseFetch(url, { ...init, signal: init?.signal ? AbortSignal.any([init.signal, timeout]) : timeout });
82
+ };
83
+ credential(user) {
84
+ return new OAuthCredential(this, user);
85
+ }
86
+ /** A user's credential as the store holds it, or null if there's none, or none that opens. `known` is given back as it is if the store still holds it. */
87
+ async read(user, known = null) {
88
+ const sealed = await this.core.store.get(user, this.name);
89
+ if (sealed === null)
90
+ return null;
91
+ if (sealed === known?.sealed)
92
+ return known;
93
+ const kept = this.core.sealer.open(sealed, binding.credential(user, this.name));
94
+ if (typeof kept?.tokens?.access_token !== "string" ||
95
+ typeof kept.tokens.issuer !== "string" ||
96
+ typeof kept.client?.client_id !== "string" ||
97
+ typeof kept.connectedAt !== "number") {
98
+ console.error(`@haikit/mcp: ${this.name}: the credential of user ${user} doesn't open: sealed with a secret that's gone, or for another row`);
99
+ return null;
100
+ }
101
+ return { sealed, kept };
102
+ }
103
+ seal(user, kept) {
104
+ return this.core.sealer.seal(kept, binding.credential(user, this.name));
105
+ }
106
+ /** The client configured, stamped with the pinned issuer: the SDK refuses it for any other. */
107
+ configured() {
108
+ const { client, issuer } = this.options;
109
+ return client && { client_id: client.id, ...(client.secret === undefined ? {} : { client_secret: client.secret }), issuer: issuer };
110
+ }
111
+ /**
112
+ * The client to connect with at an authorization server: the one
113
+ * configured, or the one registered for the app. One registered for
114
+ * another redirect URI or metadata document, or that doesn't open, is no
115
+ * use, and is registered again.
116
+ */
117
+ async client(issuer) {
118
+ const configured = this.configured();
119
+ if (configured)
120
+ return configured;
121
+ const sealed = await this.core.store.getClient(this.name, issuer);
122
+ if (sealed === null)
123
+ return undefined;
124
+ const info = this.core.sealer.open(sealed, binding.client(this.name, issuer));
125
+ if (typeof info?.client_id !== "string")
126
+ return undefined;
127
+ const fits = "redirect_uris" in info && Array.isArray(info.redirect_uris)
128
+ ? info.redirect_uris.includes(this.core.redirectUri)
129
+ : info.client_id === this.core.clientMetadataUrl;
130
+ return fits ? info : undefined;
131
+ }
132
+ /** The client a flow or credential was issued to, as it's sent: the configured one with its secret as configured now. */
133
+ issuedTo(client) {
134
+ return this.options.client?.id === client.client_id ? this.configured() : client;
135
+ }
136
+ async saveClient(issuer, info) {
137
+ await this.core.store.putClient(this.name, issuer, this.core.sealer.seal(info, binding.client(this.name, issuer)));
138
+ }
139
+ /**
140
+ * Checks what discovery found: the pinned issuer, and an authorization
141
+ * endpoint the browser can be sent to. Called by the SDK straight after
142
+ * discovery, before it looks up or registers a client, so a server that
143
+ * names another authorization server gets nothing from the app.
144
+ */
145
+ async check(state) {
146
+ const metadata = state.authorizationServerMetadata;
147
+ const issuer = metadata?.issuer ?? String(state.authorizationServerUrl);
148
+ const pinned = this.options.issuer;
149
+ if (pinned !== undefined && !sameIssuer(issuer, pinned)) {
150
+ throw new Mismatch(`${this.name} names ${JSON.stringify(issuer)} as its authorization server, not ${JSON.stringify(pinned)}`);
151
+ }
152
+ const endpoint = metadata?.authorization_endpoint ?? new URL("/authorize", state.authorizationServerUrl).href;
153
+ if (!isSecure(endpoint))
154
+ throw new Mismatch(`${this.name}'s authorization server signs users in at ${JSON.stringify(endpoint)}, which isn't https`);
155
+ // the indicator as the metadata has it, as the SDK's auth() sends it
156
+ const selected = await selectResourceURL(this.url, {}, state.resourceMetadata);
157
+ const resource = selected && state.resourceMetadata ? state.resourceMetadata.resource : selected?.href;
158
+ return { url: String(state.authorizationServerUrl), issuer, metadata, resource };
159
+ }
160
+ /**
161
+ * The authorization server, which must be the one that issued a credential:
162
+ * found again once if it isn't, in case the server moved since.
163
+ */
164
+ async where(issuer, resourceMetadataUrl) {
165
+ for (let fresh = false;; fresh = true) {
166
+ this.found ??= discoverOAuthServerInfo(this.url, { fetchFn: this.fetch, ...(resourceMetadataUrl ? { resourceMetadataUrl } : {}) })
167
+ .then((info) => this.check(info))
168
+ .catch((err) => {
169
+ this.found = null;
170
+ throw err;
171
+ });
172
+ const where = await this.found;
173
+ if (sameIssuer(where.issuer, issuer))
174
+ return where;
175
+ this.found = null;
176
+ if (fresh)
177
+ throw new Mismatch(`${this.name} now names ${JSON.stringify(where.issuer)} as its authorization server, not ${JSON.stringify(issuer)}, which issued the credential`);
178
+ }
179
+ }
180
+ /**
181
+ * The connect route: where to send the browser, with the flow stored under
182
+ * its `state` meanwhile. The SDK's `auth()` discovers the authorization
183
+ * server, registers a client if none is kept, and makes the PKCE challenge.
184
+ */
185
+ async start(user, conversation, asked) {
186
+ const { core } = this;
187
+ const state = randomBytes(32).toString("base64url");
188
+ let discovery;
189
+ let verifier;
190
+ let to;
191
+ // the client the code is issued to: the one auth() is given, or the one it registers
192
+ let client;
193
+ const provider = {
194
+ redirectUrl: core.redirectUri,
195
+ clientMetadata: core.clientMetadata,
196
+ ...(core.clientMetadataUrl === undefined ? {} : { clientMetadataUrl: core.clientMetadataUrl }),
197
+ clientInformation: async (ctx) => (client = await this.client(ctx?.issuer ?? "")),
198
+ // a configured client is never replaced by one registered on the fly
199
+ ...(this.options.client
200
+ ? {}
201
+ : {
202
+ saveClientInformation: async (info, ctx) => {
203
+ client = info;
204
+ await this.saveClient(ctx?.issuer ?? info.issuer ?? "", info);
205
+ },
206
+ }),
207
+ state: () => state,
208
+ // a reconnect starts over, whatever is kept
209
+ tokens: () => undefined,
210
+ saveTokens: () => {
211
+ throw new Error("no tokens are saved before the user comes back");
212
+ },
213
+ redirectToAuthorization: (url) => {
214
+ to = url;
215
+ },
216
+ saveCodeVerifier: (v) => {
217
+ verifier = v;
218
+ },
219
+ codeVerifier: () => {
220
+ throw new Error("no code is exchanged before the user comes back");
221
+ },
222
+ saveDiscoveryState: async (found) => {
223
+ await this.check(found);
224
+ discovery = found;
225
+ },
226
+ };
227
+ const scope = computeScopeUnion(this.options.scopes?.join(" "), asked);
228
+ const result = await auth(provider, { serverUrl: this.url, fetchFn: this.fetch, ...(scope ? { scope } : {}) });
229
+ if (result !== "REDIRECT" || !to || verifier === undefined || !discovery || !client) {
230
+ throw new Error(`the SDK's auth() answered ${result}, with nowhere to send the user`);
231
+ }
232
+ // a configured client's secret isn't kept: it's read from the options when used, so it can be changed
233
+ if (this.options.client)
234
+ client = { client_id: client.client_id, ...(client.issuer === undefined ? {} : { issuer: client.issuer }) };
235
+ const expiresAt = Date.now() + FLOW_MS;
236
+ const flow = { user, server: this.name, conversation, verifier, client, discovery, scope: to.searchParams.get("scope"), expiresAt };
237
+ await core.store.putFlow(state, core.sealer.seal(flow, binding.flow(state)), expiresAt);
238
+ return to;
239
+ }
240
+ /**
241
+ * The callback: exchanges the code with the authorization server and as
242
+ * the client the flow was started with, which checks `iss` (RFC 9207)
243
+ * before it asks for any token, stores the credential, and closes the
244
+ * user's connection.
245
+ */
246
+ async finish(flow, code, iss) {
247
+ const where = await this.check(flow.discovery);
248
+ const tokens = await exchangeAuthorization(where.url, {
249
+ metadata: where.metadata,
250
+ clientInformation: this.issuedTo(flow.client),
251
+ authorizationCode: code,
252
+ iss,
253
+ codeVerifier: flow.verifier,
254
+ redirectUri: this.core.redirectUri,
255
+ ...(where.resource ? { resource: where.resource } : {}),
256
+ fetchFn: this.fetch,
257
+ });
258
+ const kept = { tokens: { ...tokens, issuer: where.issuer }, client: flow.client, scope: tokens.scope ?? flow.scope, connectedAt: Date.now() };
259
+ const sealed = this.seal(flow.user, kept);
260
+ // the newest connect wins over whatever was kept
261
+ let written = false;
262
+ for (let tries = 0; tries < 3 && !written; tries++) {
263
+ written = await this.core.store.put(flow.user, this.name, sealed, await this.core.store.get(flow.user, this.name));
264
+ }
265
+ if (!written)
266
+ throw new Error("the user's credential kept changing as the new one was written");
267
+ this.found = Promise.resolve(where);
268
+ await this.forget(flow.user);
269
+ }
270
+ /** Revokes the user's tokens where the authorization server takes it, then deletes them and closes the connection. */
271
+ async disconnect(user) {
272
+ const held = await this.read(user);
273
+ if (held) {
274
+ try {
275
+ await this.revoke(held.kept);
276
+ }
277
+ catch (err) {
278
+ console.error(`@haikit/mcp: ${this.name}: the tokens of user ${user} couldn't be revoked, and are deleted anyway:`, err);
279
+ }
280
+ }
281
+ await this.core.store.delete(user, this.name);
282
+ await this.forget(user);
283
+ }
284
+ /** RFC 7009, at the authorization server's revocation endpoint, if it has one. */
285
+ async revoke(kept) {
286
+ const { tokens } = kept;
287
+ const where = await this.where(tokens.issuer);
288
+ const endpoint = where.metadata?.revocation_endpoint;
289
+ if (!endpoint)
290
+ return;
291
+ const client = this.issuedTo(kept.client);
292
+ const url = assertSecureTokenEndpoint(endpoint);
293
+ const body = new URLSearchParams(tokens.refresh_token ? { token: tokens.refresh_token, token_type_hint: "refresh_token" } : { token: tokens.access_token, token_type_hint: "access_token" });
294
+ const headers = new Headers({ "content-type": "application/x-www-form-urlencoded", accept: "application/json" });
295
+ const metadata = where.metadata;
296
+ const method = selectClientAuthMethod(client, metadata.revocation_endpoint_auth_methods_supported ?? metadata.token_endpoint_auth_methods_supported ?? []);
297
+ if (method === "client_secret_basic" && client.client_secret !== undefined) {
298
+ // as the SDK's own token requests send it: the authorization server checks the client the same way at both
299
+ headers.set("authorization", `Basic ${btoa(`${client.client_id}:${client.client_secret}`)}`);
300
+ }
301
+ else {
302
+ body.set("client_id", client.client_id);
303
+ if (method === "client_secret_post" && client.client_secret !== undefined)
304
+ body.set("client_secret", client.client_secret);
305
+ }
306
+ const response = await this.fetch(url, { method: "POST", headers, body, redirect: "error" });
307
+ await response.text().catch(() => { });
308
+ if (!response.ok)
309
+ throw new Error(`the revocation endpoint answered ${response.status}`);
310
+ }
311
+ /**
312
+ * After a 401: the credential to use instead of `before`. One refresh for
313
+ * each user at a time, shared until it settles, however long that takes,
314
+ * on whichever connection of theirs: a second would spend a refresh token
315
+ * the first may have spent already, and delete the credential when it's
316
+ * refused. Across processes, the store's lease does the same.
317
+ */
318
+ refresh(user, before, resourceMetadataUrl) {
319
+ let refreshing = this.refreshing.get(user);
320
+ if (!refreshing) {
321
+ refreshing = this.renew(user, before, resourceMetadataUrl)
322
+ .catch((err) => {
323
+ if (err instanceof Mismatch)
324
+ console.error(`@haikit/mcp: ${this.name}: no refresh for user ${user}: ${err.message}`);
325
+ throw err;
326
+ })
327
+ .finally(() => this.refreshing.delete(user));
328
+ this.refreshing.set(user, refreshing);
329
+ }
330
+ return refreshing;
331
+ }
332
+ /**
333
+ * The store's newer credential if another refresh wrote one, else a
334
+ * refresh of `before`, under the store's lease. A refusal deletes it,
335
+ * unless another write came first; an outage keeps it.
336
+ */
337
+ async renew(user, before, resourceMetadataUrl) {
338
+ const moved = await this.newer(user, before);
339
+ if (moved)
340
+ return moved;
341
+ const { tokens } = before.kept;
342
+ if (!tokens.refresh_token) {
343
+ await this.drop(user, before);
344
+ throw new NeedsAuth("reconnect");
345
+ }
346
+ const where = await this.where(tokens.issuer, resourceMetadataUrl);
347
+ const holder = randomBytes(16).toString("base64url");
348
+ const written = await this.lease(user, before, holder);
349
+ if (written)
350
+ return written;
351
+ // given back when this refresh writes nothing; a write or delete ends it anyway
352
+ const giveBack = () => this.core.store.lease(user, this.name, before.sealed, holder, 0).catch(() => false);
353
+ let fresh;
354
+ try {
355
+ fresh = await refreshAuthorization(where.url, {
356
+ metadata: where.metadata,
357
+ clientInformation: this.issuedTo(before.kept.client),
358
+ refreshToken: tokens.refresh_token,
359
+ ...(where.resource ? { resource: where.resource } : {}),
360
+ fetchFn: this.fetch,
361
+ });
362
+ }
363
+ catch (err) {
364
+ if (err instanceof OAuthError && REFUSED.has(err.code)) {
365
+ // Refused: unless another refresh spent the token first, after this
366
+ // one's lease lapsed, and stored what it got, which is then the one
367
+ // to use.
368
+ const moved = await this.newer(user, before);
369
+ if (moved)
370
+ return moved;
371
+ await this.drop(user, before);
372
+ throw new NeedsAuth("reconnect");
373
+ }
374
+ // an outage, or an answer that isn't OAuth's: kept, for the next 401 to try
375
+ await giveBack();
376
+ throw new LookupFailed(err);
377
+ }
378
+ const kept = { ...before.kept, tokens: { ...fresh, issuer: tokens.issuer }, scope: fresh.scope ?? before.kept.scope };
379
+ const sealed = this.seal(user, kept);
380
+ if (await this.write(user, before, sealed))
381
+ return { sealed, kept };
382
+ // Another write came first, or a delete, as by a disconnect: the tokens
383
+ // just issued are no one's, so they're revoked rather than left live.
384
+ await this.orphaned(user, kept, tokens.refresh_token);
385
+ const stands = await this.newer(user, before);
386
+ if (stands)
387
+ return stands;
388
+ await giveBack();
389
+ throw new Error("the store refused a write of what it still holds");
390
+ }
391
+ /**
392
+ * Writes a refresh's credential onto `before`, tried again while the
393
+ * store fails: the old refresh token is spent, so this is the only copy,
394
+ * and the lease is still held. False if another write or a delete came
395
+ * first. A try that landed, though its answer was lost, is written.
396
+ */
397
+ async write(user, before, sealed) {
398
+ for (let tries = 1;; tries++) {
399
+ try {
400
+ if (await this.core.store.put(user, this.name, sealed, before.sealed))
401
+ return true;
402
+ return tries > 1 && (await this.core.store.get(user, this.name)) === sealed;
403
+ }
404
+ catch (err) {
405
+ if (tries < WRITE_TRIES) {
406
+ await pause(WRITE_PAUSE_MS);
407
+ continue;
408
+ }
409
+ // the last may have landed too, though its answer was lost
410
+ if ((await this.core.store.get(user, this.name).catch(() => null)) === sealed)
411
+ return true;
412
+ throw err;
413
+ }
414
+ }
415
+ }
416
+ /**
417
+ * Revokes the tokens a refresh got but couldn't store: its refresh token
418
+ * if the authorization server rotated it, else only its access token, as
419
+ * the one refresh token may be what the store holds now.
420
+ */
421
+ async orphaned(user, kept, spent) {
422
+ const { refresh_token, ...access } = kept.tokens;
423
+ try {
424
+ await this.revoke(refresh_token === spent ? { ...kept, tokens: access } : kept);
425
+ }
426
+ catch (err) {
427
+ console.error(`@haikit/mcp: ${this.name}: the tokens refreshed for user ${user} weren't stored, and couldn't be revoked:`, err);
428
+ }
429
+ }
430
+ /**
431
+ * Takes the refresh lease of the user's credential, so one process at a
432
+ * time spends its refresh token. While another holds it: the credential
433
+ * that one writes, which is then the one to use, or the lease once it
434
+ * lapses, as it does when that process is gone.
435
+ */
436
+ async lease(user, before, holder) {
437
+ const ms = LEASE_TIMEOUTS * this.timeoutMs;
438
+ const giveUp = Date.now() + 2 * ms;
439
+ while (!(await this.core.store.lease(user, this.name, before.sealed, holder, ms))) {
440
+ const moved = await this.newer(user, before);
441
+ if (moved)
442
+ return moved;
443
+ if (Date.now() >= giveUp)
444
+ throw new Error(`other processes held the refresh lease for ${2 * ms} ms`);
445
+ await pause(LEASE_POLL_MS);
446
+ }
447
+ return null;
448
+ }
449
+ /** The store's credential if it's newer than `before`, or null if it's still `before`. With none, the server's refusal stands. */
450
+ async newer(user, before) {
451
+ const now = await this.read(user);
452
+ if (now === null)
453
+ throw new NeedsAuth("reconnect");
454
+ return now.sealed === before.sealed ? null : now;
455
+ }
456
+ /** Deletes the credential, if the store still holds `before`: never a newer one. */
457
+ async drop(user, before) {
458
+ await this.core.store.delete(user, this.name, before.sealed);
459
+ }
460
+ }
461
+ /**
462
+ * One user's OAuth credential for one server. The transport is given an
463
+ * `AuthProvider` of this package's own, never the SDK's
464
+ * `OAuthClientProvider`: so a call never starts a sign-in or registers a
465
+ * client, refreshes once at a time, and tells an outage from a refusal.
466
+ */
467
+ class OAuthCredential {
468
+ server;
469
+ user;
470
+ /** What the store held when this read or wrote it. Only a lookup, a refresh or the store's newer value sets it. */
471
+ held = null;
472
+ /** The lookup on its way, which every caller shares. */
473
+ looking = null;
474
+ /** The account, by its `connectedAt`, that the last check found, and the user's connection is made as. */
475
+ account = null;
476
+ lookups;
477
+ refreshes;
478
+ constructor(server, user) {
479
+ this.server = server;
480
+ this.user = user;
481
+ this.lookups = new Lookup(server.timeoutMs, "credential");
482
+ this.refreshes = new Lookup(server.timeoutMs, "refresh");
483
+ }
484
+ /**
485
+ * Before every call: the store's credential, since another process may
486
+ * have refreshed it, connected it again, or deleted it. A refresh is used
487
+ * as it is; another connect says so, for the connection to be made again.
488
+ */
489
+ async ensure() {
490
+ await this.look();
491
+ const now = this.held;
492
+ if (now === null) {
493
+ this.account = null;
494
+ throw new NeedsAuth("connect");
495
+ }
496
+ const changed = this.account !== null && now.kept.connectedAt !== this.account;
497
+ this.account = now.kept.connectedAt;
498
+ return changed;
499
+ }
500
+ close() {
501
+ // A refresh on its way isn't stopped: a provider that rotates refresh
502
+ // tokens has spent the old one, and what it gives back must be stored.
503
+ this.lookups.stop();
504
+ }
505
+ // The transport asks for the token before every request, and on a 401
506
+ // calls onUnauthorized, then tries once more with what it finds. Each
507
+ // connection has its own, bound to the account it was made as: once the
508
+ // user has connected again, as a refresh can find, nothing more is sent
509
+ // on it, and the next call makes it again.
510
+ get provider() {
511
+ const account = this.account;
512
+ const mine = (held) => {
513
+ // gone since this call began, as when another call's 401 was refused
514
+ if (held === null)
515
+ throw new NeedsAuth("reconnect");
516
+ if (held.kept.connectedAt !== account)
517
+ throw new LookupFailed(new Error("the user connected again since this connection was made"));
518
+ return held;
519
+ };
520
+ return {
521
+ token: async () => mine(this.held).kept.tokens.access_token,
522
+ onUnauthorized: async (ctx) => {
523
+ const before = mine(this.held);
524
+ // held when the refresh settles, though this 401 gave up waiting for it
525
+ const refreshing = this.server.refresh(this.user, before, extractWWWAuthenticateParams(ctx.response).resourceMetadataUrl).then((next) => this.take(before, next), (err) => {
526
+ if (err instanceof NeedsAuth)
527
+ this.take(before, null);
528
+ throw err;
529
+ });
530
+ try {
531
+ await this.refreshes.run(() => refreshing);
532
+ }
533
+ catch (err) {
534
+ throw err instanceof NeedsAuth || err instanceof Mismatch || err instanceof LookupFailed ? err : new LookupFailed(err);
535
+ }
536
+ },
537
+ };
538
+ }
539
+ look() {
540
+ this.looking ??= this.lookups
541
+ .run(() => this.server.read(this.user, this.held))
542
+ .then((found) => {
543
+ this.held = found;
544
+ }, (err) => {
545
+ throw new LookupFailed(err);
546
+ })
547
+ .finally(() => {
548
+ this.looking = null;
549
+ });
550
+ return this.looking;
551
+ }
552
+ /** Holds `next`, unless something newer than `before` is held already, as by a refresh that outlived its wait. */
553
+ take(before, next) {
554
+ if (this.held === before)
555
+ this.held = next;
556
+ }
557
+ }
558
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @haikit/mcp/postgres — each user's credentials in Postgres, shared by every
3
+ * server. As in @haikit/postgres, every method is one statement, and the
4
+ * driver is yours.
5
+ */
6
+ import type { CredentialStore } from "./store.js";
7
+ /**
8
+ * Anything that runs a parameterised statement and returns rows: a `pg.Pool`,
9
+ * a `pg.Client` and PGlite all fit as they are. The same shape as
10
+ * @haikit/postgres's and @haikit/auth/postgres's `Queryable`, so one pool
11
+ * serves all three.
12
+ */
13
+ export interface Queryable {
14
+ query(text: string, params?: unknown[]): Promise<{
15
+ rows: any[];
16
+ }>;
17
+ }
18
+ /**
19
+ * The schema, one statement per entry. `migrate()` runs these; export them to
20
+ * your own migration tool instead if you have one.
21
+ */
22
+ export declare const schema: readonly string[];
23
+ export declare function migrate(db: Queryable): Promise<void>;
24
+ export declare function pgCredentialStore(db: Queryable): CredentialStore;
25
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAC;CACnE;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EAqBnC,CAAC;AAEF,wBAAsB,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,SAAS,GAAG,eAAe,CA6EhE"}