@leanmcp/auth 0.4.3 → 0.4.4-alpha.8.f4673cd

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.
@@ -114,11 +114,11 @@ var DynamicClientRegistration = class {
114
114
  };
115
115
  }
116
116
  /**
117
- * Register a new OAuth client (stateless)
118
- *
119
- * @param request - Client registration request per RFC 7591
120
- * @returns Client registration response with JWT credentials
121
- */
117
+ * Register a new OAuth client (stateless)
118
+ *
119
+ * @param request - Client registration request per RFC 7591
120
+ * @returns Client registration response with JWT credentials
121
+ */
122
122
  register(request) {
123
123
  const now = Date.now();
124
124
  const nowSeconds = Math.floor(now / 1e3);
@@ -160,12 +160,12 @@ var DynamicClientRegistration = class {
160
160
  return response;
161
161
  }
162
162
  /**
163
- * Validate client credentials (stateless)
164
- *
165
- * @param clientId - Client ID (JWT with prefix)
166
- * @param clientSecret - Client secret (optional for public clients)
167
- * @returns Whether credentials are valid
168
- */
163
+ * Validate client credentials (stateless)
164
+ *
165
+ * @param clientId - Client ID (JWT with prefix)
166
+ * @param clientSecret - Client secret (optional for public clients)
167
+ * @returns Whether credentials are valid
168
+ */
169
169
  validate(clientId, clientSecret) {
170
170
  try {
171
171
  const jwtWithoutPrefix = this.extractJWT(clientId);
@@ -182,8 +182,8 @@ var DynamicClientRegistration = class {
182
182
  }
183
183
  }
184
184
  /**
185
- * Get a registered client by ID (stateless)
186
- */
185
+ * Get a registered client by ID (stateless)
186
+ */
187
187
  getClient(clientId) {
188
188
  try {
189
189
  const jwtWithoutPrefix = this.extractJWT(clientId);
@@ -205,8 +205,8 @@ var DynamicClientRegistration = class {
205
205
  }
206
206
  }
207
207
  /**
208
- * Validate redirect URI for a client
209
- */
208
+ * Validate redirect URI for a client
209
+ */
210
210
  validateRedirectUri(clientId, redirectUri) {
211
211
  const client = this.getClient(clientId);
212
212
  if (!client) return false;
@@ -214,29 +214,29 @@ var DynamicClientRegistration = class {
214
214
  return client.redirect_uris.includes(redirectUri);
215
215
  }
216
216
  /**
217
- * Delete a client (no-op in stateless mode)
218
- *
219
- * In stateless mode, clients cannot be truly "deleted" because
220
- * their credentials are self-contained. They will expire naturally
221
- * or when the signing secret is rotated.
222
- */
217
+ * Delete a client (no-op in stateless mode)
218
+ *
219
+ * In stateless mode, clients cannot be truly "deleted" because
220
+ * their credentials are self-contained. They will expire naturally
221
+ * or when the signing secret is rotated.
222
+ */
223
223
  delete(clientId) {
224
224
  return this.getClient(clientId) !== void 0;
225
225
  }
226
226
  /**
227
- * List all registered clients (not supported in stateless mode)
228
- */
227
+ * List all registered clients (not supported in stateless mode)
228
+ */
229
229
  listClients() {
230
230
  throw new Error("listClients() is not supported in stateless DCR mode");
231
231
  }
232
232
  /**
233
- * Clear all clients (no-op in stateless mode)
234
- */
233
+ * Clear all clients (no-op in stateless mode)
234
+ */
235
235
  clearAll() {
236
236
  }
237
237
  /**
238
- * Extract JWT from prefixed client_id
239
- */
238
+ * Extract JWT from prefixed client_id
239
+ */
240
240
  extractJWT(clientId) {
241
241
  if (!clientId.startsWith(this.options.clientIdPrefix)) {
242
242
  return null;
@@ -244,11 +244,11 @@ var DynamicClientRegistration = class {
244
244
  return clientId.slice(this.options.clientIdPrefix.length);
245
245
  }
246
246
  /**
247
- * Derive client secret from client_id JWT
248
- *
249
- * Uses HMAC to create a deterministic secret that can be
250
- * validated without storage.
251
- */
247
+ * Derive client secret from client_id JWT
248
+ *
249
+ * Uses HMAC to create a deterministic secret that can be
250
+ * validated without storage.
251
+ */
252
252
  deriveClientSecret(clientIdJWT) {
253
253
  const { createHmac: createHmac3 } = __require("crypto");
254
254
  return createHmac3("sha256", this.options.signingSecret).update(clientIdJWT).digest("hex");
@@ -297,16 +297,16 @@ var OAuthAuthorizationServer = class {
297
297
  });
298
298
  }
299
299
  /**
300
- * Generate state parameter with HMAC signature
301
- */
300
+ * Generate state parameter with HMAC signature
301
+ */
302
302
  generateState() {
303
303
  const nonce = randomUUID2();
304
304
  const signature = createHmac2("sha256", this.options.sessionSecret).update(nonce).digest("hex").substring(0, 8);
305
305
  return `${nonce}.${signature}`;
306
306
  }
307
307
  /**
308
- * Verify state parameter signature
309
- */
308
+ * Verify state parameter signature
309
+ */
310
310
  verifyState(state) {
311
311
  const [nonce, signature] = state.split(".");
312
312
  if (!nonce || !signature) return false;
@@ -314,14 +314,14 @@ var OAuthAuthorizationServer = class {
314
314
  return signature === expectedSignature;
315
315
  }
316
316
  /**
317
- * Generate an authorization code
318
- */
317
+ * Generate an authorization code
318
+ */
319
319
  generateAuthCode() {
320
320
  return randomBytes2(32).toString("hex");
321
321
  }
322
322
  /**
323
- * Generate JWT access token with encrypted upstream credentials
324
- */
323
+ * Generate JWT access token with encrypted upstream credentials
324
+ */
325
325
  generateAccessToken(claims, upstreamToken) {
326
326
  const now = Math.floor(Date.now() / 1e3);
327
327
  const jwtSigningSecret = this.options.jwtSigningSecret || this.options.sessionSecret;
@@ -348,8 +348,8 @@ var OAuthAuthorizationServer = class {
348
348
  return signJWT(payload, jwtSigningSecret);
349
349
  }
350
350
  /**
351
- * Get authorization server metadata (RFC 8414)
352
- */
351
+ * Get authorization server metadata (RFC 8414)
352
+ */
353
353
  getMetadata() {
354
354
  const issuer = this.options.issuer;
355
355
  return {
@@ -376,8 +376,8 @@ var OAuthAuthorizationServer = class {
376
376
  };
377
377
  }
378
378
  /**
379
- * Get Express router with all OAuth endpoints
380
- */
379
+ * Get Express router with all OAuth endpoints
380
+ */
381
381
  getRouter() {
382
382
  const router = express.Router();
383
383
  router.get("/.well-known/oauth-authorization-server", (_req, res) => {
@@ -410,8 +410,8 @@ var OAuthAuthorizationServer = class {
410
410
  return router;
411
411
  }
412
412
  /**
413
- * Handle authorization request
414
- */
413
+ * Handle authorization request
414
+ */
415
415
  handleAuthorize(req, res) {
416
416
  const { response_type, client_id, redirect_uri, scope, state, code_challenge, code_challenge_method, resource } = req.query;
417
417
  if (response_type !== "code") {
@@ -480,8 +480,8 @@ var OAuthAuthorizationServer = class {
480
480
  res.redirect(authUrl.toString());
481
481
  }
482
482
  /**
483
- * Handle callback from upstream provider
484
- */
483
+ * Handle callback from upstream provider
484
+ */
485
485
  async handleCallback(req, res) {
486
486
  const { code, state, error, error_description } = req.query;
487
487
  if (error) {
@@ -533,7 +533,7 @@ var OAuthAuthorizationServer = class {
533
533
  const tokenResponse = await fetch(upstream.tokenEndpoint, {
534
534
  method: "POST",
535
535
  headers: {
536
- "Accept": "application/json",
536
+ Accept: "application/json",
537
537
  "Content-Type": "application/x-www-form-urlencoded"
538
538
  },
539
539
  body: new URLSearchParams({
@@ -553,8 +553,8 @@ var OAuthAuthorizationServer = class {
553
553
  if (upstream.userInfoEndpoint && upstreamTokens.access_token) {
554
554
  const userInfoResponse = await fetch(upstream.userInfoEndpoint, {
555
555
  headers: {
556
- "Authorization": `Bearer ${upstreamTokens.access_token}`,
557
- "Accept": "application/json"
556
+ Authorization: `Bearer ${upstreamTokens.access_token}`,
557
+ Accept: "application/json"
558
558
  }
559
559
  });
560
560
  if (userInfoResponse.ok) {
@@ -591,8 +591,8 @@ var OAuthAuthorizationServer = class {
591
591
  }
592
592
  }
593
593
  /**
594
- * Handle token request
595
- */
594
+ * Handle token request
595
+ */
596
596
  async handleToken(req, res) {
597
597
  const { grant_type, code, redirect_uri, client_id, client_secret, code_verifier } = req.body;
598
598
  let clientId = client_id;
@@ -638,8 +638,8 @@ var OAuthAuthorizationServer = class {
638
638
  }
639
639
  }
640
640
  /**
641
- * Handle authorization code grant
642
- */
641
+ * Handle authorization code grant
642
+ */
643
643
  async handleAuthCodeGrant(res, clientId, code, redirectUri, codeVerifier) {
644
644
  if (!code) {
645
645
  res.status(400).json({
@@ -742,11 +742,11 @@ var TokenVerifier = class {
742
742
  };
743
743
  }
744
744
  /**
745
- * Verify a JWT access token
746
- *
747
- * @param token - The JWT access token to verify
748
- * @returns Verification result with claims and decrypted upstream token if valid
749
- */
745
+ * Verify a JWT access token
746
+ *
747
+ * @param token - The JWT access token to verify
748
+ * @returns Verification result with claims and decrypted upstream token if valid
749
+ */
750
750
  async verify(token) {
751
751
  if (!token) {
752
752
  return {
@@ -809,13 +809,13 @@ var TokenVerifier = class {
809
809
  }
810
810
  }
811
811
  /**
812
- * Generate WWW-Authenticate header for 401 responses
813
- *
814
- * Per RFC 9728, this should include the resource_metadata URL
815
- *
816
- * @param options - Header options
817
- * @returns WWW-Authenticate header value
818
- */
812
+ * Generate WWW-Authenticate header for 401 responses
813
+ *
814
+ * Per RFC 9728, this should include the resource_metadata URL
815
+ *
816
+ * @param options - Header options
817
+ * @returns WWW-Authenticate header value
818
+ */
819
819
  static getWWWAuthenticateHeader(options) {
820
820
  const parts = [
821
821
  `Bearer resource_metadata="${options.resourceMetadataUrl}"`
@@ -832,8 +832,8 @@ var TokenVerifier = class {
832
832
  return parts.join(", ");
833
833
  }
834
834
  /**
835
- * Check if token has required scopes
836
- */
835
+ * Check if token has required scopes
836
+ */
837
837
  hasScopes(claims, requiredScopes) {
838
838
  if (requiredScopes.length === 0) return true;
839
839
  const tokenScopes = typeof claims.scope === "string" ? claims.scope.split(" ") : claims.scope || [];
@@ -59,14 +59,14 @@ var MemoryStorage = class {
59
59
  tokens = /* @__PURE__ */ new Map();
60
60
  clients = /* @__PURE__ */ new Map();
61
61
  /**
62
- * Normalize server URL for consistent key lookup
63
- */
62
+ * Normalize server URL for consistent key lookup
63
+ */
64
64
  normalizeUrl(serverUrl) {
65
65
  return serverUrl.replace(/\/+$/, "").toLowerCase();
66
66
  }
67
67
  /**
68
- * Check if an entry is expired
69
- */
68
+ * Check if an entry is expired
69
+ */
70
70
  isExpired(entry) {
71
71
  if (!entry) return true;
72
72
  if (!entry.expiresAt) return false;
@@ -162,8 +162,8 @@ var FileStorage = class {
162
162
  }
163
163
  }
164
164
  /**
165
- * Expand ~ to home directory
166
- */
165
+ * Expand ~ to home directory
166
+ */
167
167
  expandPath(filePath) {
168
168
  if (filePath.startsWith("~")) {
169
169
  const home = process.env.HOME || process.env.USERPROFILE || "";
@@ -172,14 +172,14 @@ var FileStorage = class {
172
172
  return filePath;
173
173
  }
174
174
  /**
175
- * Normalize server URL for consistent key lookup
176
- */
175
+ * Normalize server URL for consistent key lookup
176
+ */
177
177
  normalizeUrl(serverUrl) {
178
178
  return serverUrl.replace(/\/+$/, "").toLowerCase();
179
179
  }
180
180
  /**
181
- * Encrypt data
182
- */
181
+ * Encrypt data
182
+ */
183
183
  encrypt(data) {
184
184
  if (!this.encryptionKey) return data;
185
185
  const iv = (0, import_crypto.randomBytes)(16);
@@ -190,8 +190,8 @@ var FileStorage = class {
190
190
  return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
191
191
  }
192
192
  /**
193
- * Decrypt data
194
- */
193
+ * Decrypt data
194
+ */
195
195
  decrypt(data) {
196
196
  if (!this.encryptionKey) return data;
197
197
  const [ivHex, authTagHex, encrypted] = data.split(":");
@@ -204,8 +204,8 @@ var FileStorage = class {
204
204
  return decrypted;
205
205
  }
206
206
  /**
207
- * Read data from file
208
- */
207
+ * Read data from file
208
+ */
209
209
  async readFile() {
210
210
  if (this.cache) return this.cache;
211
211
  try {
@@ -225,8 +225,8 @@ var FileStorage = class {
225
225
  }
226
226
  }
227
227
  /**
228
- * Write data to file (coalesced to avoid race conditions)
229
- */
228
+ * Write data to file (coalesced to avoid race conditions)
229
+ */
230
230
  async writeFile(data) {
231
231
  this.cache = data;
232
232
  if (this.writePromise) {
@@ -361,8 +361,8 @@ var KeychainStorage = class {
361
361
  this.serviceName = options.serviceName ?? SERVICE_NAME;
362
362
  }
363
363
  /**
364
- * Initialize keytar (lazy load)
365
- */
364
+ * Initialize keytar (lazy load)
365
+ */
366
366
  async init() {
367
367
  if (this.keytar) return;
368
368
  if (this.initPromise) {
@@ -379,20 +379,20 @@ var KeychainStorage = class {
379
379
  await this.initPromise;
380
380
  }
381
381
  /**
382
- * Normalize server URL for consistent key lookup
383
- */
382
+ * Normalize server URL for consistent key lookup
383
+ */
384
384
  normalizeUrl(serverUrl) {
385
385
  return serverUrl.replace(/\/+$/, "").toLowerCase();
386
386
  }
387
387
  /**
388
- * Get account key for tokens
389
- */
388
+ * Get account key for tokens
389
+ */
390
390
  getTokensAccount(serverUrl) {
391
391
  return `tokens:${this.normalizeUrl(serverUrl)}`;
392
392
  }
393
393
  /**
394
- * Get account key for client info
395
- */
394
+ * Get account key for client info
395
+ */
396
396
  getClientAccount(serverUrl) {
397
397
  return `client:${this.normalizeUrl(serverUrl)}`;
398
398
  }
@@ -2,7 +2,7 @@ import {
2
2
  MemoryStorage,
3
3
  isTokenExpired,
4
4
  withExpiresAt
5
- } from "../chunk-RGCCBQWG.mjs";
5
+ } from "../chunk-MXTUNMHA.mjs";
6
6
  import {
7
7
  __name,
8
8
  __require
@@ -36,8 +36,8 @@ var FileStorage = class {
36
36
  }
37
37
  }
38
38
  /**
39
- * Expand ~ to home directory
40
- */
39
+ * Expand ~ to home directory
40
+ */
41
41
  expandPath(filePath) {
42
42
  if (filePath.startsWith("~")) {
43
43
  const home = process.env.HOME || process.env.USERPROFILE || "";
@@ -46,14 +46,14 @@ var FileStorage = class {
46
46
  return filePath;
47
47
  }
48
48
  /**
49
- * Normalize server URL for consistent key lookup
50
- */
49
+ * Normalize server URL for consistent key lookup
50
+ */
51
51
  normalizeUrl(serverUrl) {
52
52
  return serverUrl.replace(/\/+$/, "").toLowerCase();
53
53
  }
54
54
  /**
55
- * Encrypt data
56
- */
55
+ * Encrypt data
56
+ */
57
57
  encrypt(data) {
58
58
  if (!this.encryptionKey) return data;
59
59
  const iv = randomBytes(16);
@@ -64,8 +64,8 @@ var FileStorage = class {
64
64
  return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
65
65
  }
66
66
  /**
67
- * Decrypt data
68
- */
67
+ * Decrypt data
68
+ */
69
69
  decrypt(data) {
70
70
  if (!this.encryptionKey) return data;
71
71
  const [ivHex, authTagHex, encrypted] = data.split(":");
@@ -78,8 +78,8 @@ var FileStorage = class {
78
78
  return decrypted;
79
79
  }
80
80
  /**
81
- * Read data from file
82
- */
81
+ * Read data from file
82
+ */
83
83
  async readFile() {
84
84
  if (this.cache) return this.cache;
85
85
  try {
@@ -99,8 +99,8 @@ var FileStorage = class {
99
99
  }
100
100
  }
101
101
  /**
102
- * Write data to file (coalesced to avoid race conditions)
103
- */
102
+ * Write data to file (coalesced to avoid race conditions)
103
+ */
104
104
  async writeFile(data) {
105
105
  this.cache = data;
106
106
  if (this.writePromise) {
@@ -235,8 +235,8 @@ var KeychainStorage = class {
235
235
  this.serviceName = options.serviceName ?? SERVICE_NAME;
236
236
  }
237
237
  /**
238
- * Initialize keytar (lazy load)
239
- */
238
+ * Initialize keytar (lazy load)
239
+ */
240
240
  async init() {
241
241
  if (this.keytar) return;
242
242
  if (this.initPromise) {
@@ -253,20 +253,20 @@ var KeychainStorage = class {
253
253
  await this.initPromise;
254
254
  }
255
255
  /**
256
- * Normalize server URL for consistent key lookup
257
- */
256
+ * Normalize server URL for consistent key lookup
257
+ */
258
258
  normalizeUrl(serverUrl) {
259
259
  return serverUrl.replace(/\/+$/, "").toLowerCase();
260
260
  }
261
261
  /**
262
- * Get account key for tokens
263
- */
262
+ * Get account key for tokens
263
+ */
264
264
  getTokensAccount(serverUrl) {
265
265
  return `tokens:${this.normalizeUrl(serverUrl)}`;
266
266
  }
267
267
  /**
268
- * Get account key for client info
269
- */
268
+ * Get account key for client info
269
+ */
270
270
  getClientAccount(serverUrl) {
271
271
  return `client:${this.normalizeUrl(serverUrl)}`;
272
272
  }