@leanmcp/auth 0.3.1 → 0.4.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/README.md +148 -661
- package/dist/{auth0-54GZT2EI.mjs → auth0-UTD4QBG6.mjs} +4 -2
- package/dist/chunk-LPEX4YW6.mjs +13 -0
- package/dist/{chunk-EVD2TRPR.mjs → chunk-P4HFKA5R.mjs} +50 -21
- package/dist/chunk-RGCCBQWG.mjs +113 -0
- package/dist/chunk-ZOPKMOPV.mjs +53 -0
- package/dist/{clerk-FR7ITM33.mjs → clerk-3SDKGD6C.mjs} +4 -2
- package/dist/client/index.d.mts +499 -0
- package/dist/client/index.d.ts +499 -0
- package/dist/client/index.js +1039 -0
- package/dist/client/index.mjs +869 -0
- package/dist/{cognito-I6V5YNYM.mjs → cognito-QQT7LK2Y.mjs} +4 -2
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +186 -15
- package/dist/index.mjs +2 -1
- package/dist/leanmcp-Y7TXNSTD.mjs +140 -0
- package/dist/proxy/index.d.mts +376 -0
- package/dist/proxy/index.d.ts +376 -0
- package/dist/proxy/index.js +536 -0
- package/dist/proxy/index.mjs +480 -0
- package/dist/server/index.d.mts +496 -0
- package/dist/server/index.d.ts +496 -0
- package/dist/server/index.js +882 -0
- package/dist/server/index.mjs +847 -0
- package/dist/storage/index.d.mts +181 -0
- package/dist/storage/index.d.ts +181 -0
- package/dist/storage/index.js +499 -0
- package/dist/storage/index.mjs +372 -0
- package/dist/types-DMpGN530.d.mts +122 -0
- package/dist/types-DMpGN530.d.ts +122 -0
- package/package.json +45 -8
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JWT Utilities for Stateless OAuth
|
|
5
|
+
*
|
|
6
|
+
* Provides cryptographic functions for:
|
|
7
|
+
* - JWT signing and verification (HS256)
|
|
8
|
+
* - Upstream token encryption/decryption (AES-256-GCM)
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Encrypted token structure for upstream credentials
|
|
12
|
+
*/
|
|
13
|
+
interface EncryptedToken {
|
|
14
|
+
ciphertext: string;
|
|
15
|
+
iv: string;
|
|
16
|
+
tag: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* JWT payload structure (RFC 7519 + custom claims)
|
|
20
|
+
*/
|
|
21
|
+
interface JWTPayload {
|
|
22
|
+
iss: string;
|
|
23
|
+
sub: string;
|
|
24
|
+
aud: string | string[];
|
|
25
|
+
exp: number;
|
|
26
|
+
iat: number;
|
|
27
|
+
jti?: string;
|
|
28
|
+
scope?: string;
|
|
29
|
+
client_id?: string;
|
|
30
|
+
name?: string;
|
|
31
|
+
email?: string;
|
|
32
|
+
picture?: string;
|
|
33
|
+
upstream_provider?: string;
|
|
34
|
+
upstream_token?: EncryptedToken;
|
|
35
|
+
upstream_refresh_token?: EncryptedToken;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Server-side OAuth types for MCP Authorization
|
|
40
|
+
*
|
|
41
|
+
* Types for Authorization Server, Dynamic Client Registration,
|
|
42
|
+
* and Token Verification per MCP spec.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Client registration request (RFC 7591 Section 2)
|
|
46
|
+
*/
|
|
47
|
+
interface ClientRegistrationRequest {
|
|
48
|
+
/** Array of redirect URIs */
|
|
49
|
+
redirect_uris?: string[];
|
|
50
|
+
/** OAuth 2.0 grant types */
|
|
51
|
+
grant_types?: ('authorization_code' | 'refresh_token' | 'client_credentials')[];
|
|
52
|
+
/** OAuth 2.0 response types */
|
|
53
|
+
response_types?: ('code' | 'token')[];
|
|
54
|
+
/** Client name */
|
|
55
|
+
client_name?: string;
|
|
56
|
+
/** Client URI */
|
|
57
|
+
client_uri?: string;
|
|
58
|
+
/** Logo URI */
|
|
59
|
+
logo_uri?: string;
|
|
60
|
+
/** Token endpoint auth method */
|
|
61
|
+
token_endpoint_auth_method?: 'none' | 'client_secret_post' | 'client_secret_basic';
|
|
62
|
+
/** Scope */
|
|
63
|
+
scope?: string;
|
|
64
|
+
/** Contacts */
|
|
65
|
+
contacts?: string[];
|
|
66
|
+
/** Software ID */
|
|
67
|
+
software_id?: string;
|
|
68
|
+
/** Software version */
|
|
69
|
+
software_version?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Client registration response (RFC 7591 Section 3.2.1)
|
|
73
|
+
*/
|
|
74
|
+
interface ClientRegistrationResponse {
|
|
75
|
+
/** Issued client ID */
|
|
76
|
+
client_id: string;
|
|
77
|
+
/** Issued client secret (for confidential clients) */
|
|
78
|
+
client_secret?: string;
|
|
79
|
+
/** Timestamp when client_id was issued */
|
|
80
|
+
client_id_issued_at?: number;
|
|
81
|
+
/** Timestamp when client_secret expires (0 = never) */
|
|
82
|
+
client_secret_expires_at?: number;
|
|
83
|
+
/** All registration request fields echoed back */
|
|
84
|
+
redirect_uris?: string[];
|
|
85
|
+
grant_types?: string[];
|
|
86
|
+
response_types?: string[];
|
|
87
|
+
client_name?: string;
|
|
88
|
+
token_endpoint_auth_method?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Registered client stored in memory/storage
|
|
92
|
+
*/
|
|
93
|
+
interface RegisteredClient {
|
|
94
|
+
client_id: string;
|
|
95
|
+
client_secret?: string;
|
|
96
|
+
redirect_uris: string[];
|
|
97
|
+
grant_types: string[];
|
|
98
|
+
response_types: string[];
|
|
99
|
+
client_name?: string;
|
|
100
|
+
token_endpoint_auth_method: string;
|
|
101
|
+
created_at: number;
|
|
102
|
+
expires_at?: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* OAuth 2.0 Authorization Server Metadata (RFC 8414)
|
|
106
|
+
*/
|
|
107
|
+
interface AuthorizationServerMetadata {
|
|
108
|
+
/** Authorization server's issuer identifier URL */
|
|
109
|
+
issuer: string;
|
|
110
|
+
/** URL of the authorization endpoint */
|
|
111
|
+
authorization_endpoint: string;
|
|
112
|
+
/** URL of the token endpoint */
|
|
113
|
+
token_endpoint: string;
|
|
114
|
+
/** URL of the dynamic client registration endpoint */
|
|
115
|
+
registration_endpoint?: string;
|
|
116
|
+
/** URL of the JWKS endpoint */
|
|
117
|
+
jwks_uri?: string;
|
|
118
|
+
/** Supported scopes */
|
|
119
|
+
scopes_supported?: string[];
|
|
120
|
+
/** Supported response types */
|
|
121
|
+
response_types_supported: string[];
|
|
122
|
+
/** Supported grant types */
|
|
123
|
+
grant_types_supported?: string[];
|
|
124
|
+
/** Supported PKCE code challenge methods */
|
|
125
|
+
code_challenge_methods_supported?: string[];
|
|
126
|
+
/** Supported token endpoint auth methods */
|
|
127
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
128
|
+
/** Service documentation URL */
|
|
129
|
+
service_documentation?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* OAuth 2.0 Protected Resource Metadata (RFC 9728)
|
|
133
|
+
*/
|
|
134
|
+
interface ProtectedResourceMetadata {
|
|
135
|
+
/** Canonical resource identifier */
|
|
136
|
+
resource: string;
|
|
137
|
+
/** Authorization servers that can authorize access */
|
|
138
|
+
authorization_servers: string[];
|
|
139
|
+
/** Scopes supported by this resource */
|
|
140
|
+
scopes_supported?: string[];
|
|
141
|
+
/** Resource documentation URL */
|
|
142
|
+
resource_documentation?: string;
|
|
143
|
+
/** Token endpoint auth methods supported */
|
|
144
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
145
|
+
/** Introspection endpoint */
|
|
146
|
+
introspection_endpoint?: string;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Token claims extracted from access token
|
|
150
|
+
*/
|
|
151
|
+
interface TokenClaims {
|
|
152
|
+
/** Subject (user ID) */
|
|
153
|
+
sub: string;
|
|
154
|
+
/** Issuer */
|
|
155
|
+
iss: string;
|
|
156
|
+
/** Audience (resource server) */
|
|
157
|
+
aud: string | string[];
|
|
158
|
+
/** Expiration timestamp */
|
|
159
|
+
exp: number;
|
|
160
|
+
/** Issued at timestamp */
|
|
161
|
+
iat: number;
|
|
162
|
+
/** Scopes (space-separated or array) */
|
|
163
|
+
scope?: string | string[];
|
|
164
|
+
/** Client ID */
|
|
165
|
+
client_id?: string;
|
|
166
|
+
/** Additional claims */
|
|
167
|
+
[key: string]: unknown;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Token verification result
|
|
171
|
+
*/
|
|
172
|
+
interface TokenVerificationResult {
|
|
173
|
+
/** Whether token is valid */
|
|
174
|
+
valid: boolean;
|
|
175
|
+
/** Extracted claims (if valid) */
|
|
176
|
+
claims?: JWTPayload;
|
|
177
|
+
/** Decrypted upstream token (if present and valid) */
|
|
178
|
+
upstreamToken?: string;
|
|
179
|
+
/** Error message (if invalid) */
|
|
180
|
+
error?: string;
|
|
181
|
+
/** Error code */
|
|
182
|
+
errorCode?: 'invalid_token' | 'expired_token' | 'insufficient_scope';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface OAuthAuthorizationServerOptions {
|
|
186
|
+
/** Issuer URL (e.g., https://auth.example.com) */
|
|
187
|
+
issuer: string;
|
|
188
|
+
/** Session secret for signing state parameters */
|
|
189
|
+
sessionSecret: string;
|
|
190
|
+
/** JWT signing secret (for HS256) */
|
|
191
|
+
jwtSigningSecret?: string;
|
|
192
|
+
/** JWT encryption secret (32 bytes for AES-256) */
|
|
193
|
+
jwtEncryptionSecret?: Buffer;
|
|
194
|
+
/** Upstream OAuth provider configuration (e.g., GitHub, Google) */
|
|
195
|
+
upstreamProvider?: {
|
|
196
|
+
id: string;
|
|
197
|
+
authorizationEndpoint: string;
|
|
198
|
+
tokenEndpoint: string;
|
|
199
|
+
clientId: string;
|
|
200
|
+
clientSecret: string;
|
|
201
|
+
scopes?: string[];
|
|
202
|
+
userInfoEndpoint?: string;
|
|
203
|
+
};
|
|
204
|
+
/** Scopes to advertise */
|
|
205
|
+
scopesSupported?: string[];
|
|
206
|
+
/** Enable dynamic client registration */
|
|
207
|
+
enableDCR?: boolean;
|
|
208
|
+
/** Token TTL in seconds (default: 3600) */
|
|
209
|
+
tokenTTL?: number;
|
|
210
|
+
/** Refresh token TTL in seconds (default: 2592000 = 30 days) */
|
|
211
|
+
refreshTokenTTL?: number;
|
|
212
|
+
/** Custom token mapper */
|
|
213
|
+
tokenMapper?: (upstreamTokens: {
|
|
214
|
+
access_token: string;
|
|
215
|
+
refresh_token?: string;
|
|
216
|
+
expires_in?: number;
|
|
217
|
+
}, userInfo: Record<string, unknown>) => Promise<{
|
|
218
|
+
access_token: string;
|
|
219
|
+
refresh_token?: string;
|
|
220
|
+
expires_in?: number;
|
|
221
|
+
}>;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* DCR options
|
|
225
|
+
*/
|
|
226
|
+
interface DynamicClientRegistrationOptions {
|
|
227
|
+
/** Client ID prefix */
|
|
228
|
+
clientIdPrefix?: string;
|
|
229
|
+
/** Client secret length in bytes */
|
|
230
|
+
clientSecretLength?: number;
|
|
231
|
+
/** Client TTL in seconds (0 = never expires) */
|
|
232
|
+
clientTTL?: number;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Token verifier options
|
|
236
|
+
*/
|
|
237
|
+
interface TokenVerifierOptions {
|
|
238
|
+
/** Expected audience (resource server URL) */
|
|
239
|
+
audience: string;
|
|
240
|
+
/** Expected issuer */
|
|
241
|
+
issuer: string;
|
|
242
|
+
/** JWKS URI for RS256/ES256 signature verification */
|
|
243
|
+
jwksUri?: string;
|
|
244
|
+
/** Symmetric secret for HS256 tokens */
|
|
245
|
+
secret?: string;
|
|
246
|
+
/** Encryption secret for decrypting upstream tokens (32 bytes) */
|
|
247
|
+
encryptionSecret?: Buffer;
|
|
248
|
+
/** Clock tolerance in seconds for exp/nbf checks */
|
|
249
|
+
clockTolerance?: number;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* OAuth Authorization Server
|
|
254
|
+
*
|
|
255
|
+
* MCP-compliant OAuth 2.1 authorization server that can proxy to
|
|
256
|
+
* external providers like GitHub, Google, etc.
|
|
257
|
+
*
|
|
258
|
+
* Implements:
|
|
259
|
+
* - RFC 8414: Authorization Server Metadata
|
|
260
|
+
* - RFC 7591: Dynamic Client Registration
|
|
261
|
+
* - RFC 8707: Resource Indicators
|
|
262
|
+
* - OAuth 2.1 with PKCE
|
|
263
|
+
*/
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* OAuth Authorization Server for MCP
|
|
267
|
+
*
|
|
268
|
+
* Creates Express routes for a complete OAuth 2.1 authorization server
|
|
269
|
+
* that can proxy authentication to external providers.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* import express from 'express';
|
|
274
|
+
* import { OAuthAuthorizationServer } from '@leanmcp/auth/server';
|
|
275
|
+
*
|
|
276
|
+
* const app = express();
|
|
277
|
+
*
|
|
278
|
+
* const authServer = new OAuthAuthorizationServer({
|
|
279
|
+
* issuer: 'https://mcp.example.com',
|
|
280
|
+
* sessionSecret: process.env.SESSION_SECRET!,
|
|
281
|
+
* upstreamProvider: {
|
|
282
|
+
* id: 'github',
|
|
283
|
+
* authorizationEndpoint: 'https://github.com/login/oauth/authorize',
|
|
284
|
+
* tokenEndpoint: 'https://github.com/login/oauth/access_token',
|
|
285
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
286
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
287
|
+
* scopes: ['read:user', 'repo'],
|
|
288
|
+
* userInfoEndpoint: 'https://api.github.com/user',
|
|
289
|
+
* },
|
|
290
|
+
* scopesSupported: ['read:user', 'repo'],
|
|
291
|
+
* });
|
|
292
|
+
*
|
|
293
|
+
* app.use(authServer.getRouter());
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
declare class OAuthAuthorizationServer {
|
|
297
|
+
private options;
|
|
298
|
+
private dcr;
|
|
299
|
+
constructor(options: OAuthAuthorizationServerOptions);
|
|
300
|
+
/**
|
|
301
|
+
* Generate state parameter with HMAC signature
|
|
302
|
+
*/
|
|
303
|
+
private generateState;
|
|
304
|
+
/**
|
|
305
|
+
* Verify state parameter signature
|
|
306
|
+
*/
|
|
307
|
+
private verifyState;
|
|
308
|
+
/**
|
|
309
|
+
* Generate an authorization code
|
|
310
|
+
*/
|
|
311
|
+
private generateAuthCode;
|
|
312
|
+
/**
|
|
313
|
+
* Generate JWT access token with encrypted upstream credentials
|
|
314
|
+
*/
|
|
315
|
+
private generateAccessToken;
|
|
316
|
+
/**
|
|
317
|
+
* Get authorization server metadata (RFC 8414)
|
|
318
|
+
*/
|
|
319
|
+
getMetadata(): AuthorizationServerMetadata;
|
|
320
|
+
/**
|
|
321
|
+
* Get Express router with all OAuth endpoints
|
|
322
|
+
*/
|
|
323
|
+
getRouter(): Router;
|
|
324
|
+
/**
|
|
325
|
+
* Handle authorization request
|
|
326
|
+
*/
|
|
327
|
+
private handleAuthorize;
|
|
328
|
+
/**
|
|
329
|
+
* Handle callback from upstream provider
|
|
330
|
+
*/
|
|
331
|
+
private handleCallback;
|
|
332
|
+
/**
|
|
333
|
+
* Handle token request
|
|
334
|
+
*/
|
|
335
|
+
private handleToken;
|
|
336
|
+
/**
|
|
337
|
+
* Handle authorization code grant
|
|
338
|
+
*/
|
|
339
|
+
private handleAuthCodeGrant;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Dynamic Client Registration (RFC 7591) - Stateless Implementation
|
|
344
|
+
*
|
|
345
|
+
* Uses signed JWTs as client credentials for serverless compatibility.
|
|
346
|
+
* No storage required - all client data is encoded in the credentials.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Dynamic Client Registration handler (Stateless)
|
|
351
|
+
*
|
|
352
|
+
* Client credentials are JWTs signed by the server:
|
|
353
|
+
* - client_id: JWT containing client metadata
|
|
354
|
+
* - client_secret: HMAC signature derived from client_id
|
|
355
|
+
*
|
|
356
|
+
* This eliminates the need for storage while maintaining security.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```typescript
|
|
360
|
+
* const dcr = new DynamicClientRegistration({
|
|
361
|
+
* signingSecret: process.env.DCR_SIGNING_SECRET,
|
|
362
|
+
* clientIdPrefix: 'chatgpt_',
|
|
363
|
+
* clientTTL: 0, // Never expires
|
|
364
|
+
* });
|
|
365
|
+
*
|
|
366
|
+
* // Register a client
|
|
367
|
+
* const { client_id, client_secret } = dcr.register({
|
|
368
|
+
* redirect_uris: ['https://chatgpt.com/callback'],
|
|
369
|
+
* grant_types: ['authorization_code'],
|
|
370
|
+
* });
|
|
371
|
+
*
|
|
372
|
+
* // Validate credentials (no storage lookup needed)
|
|
373
|
+
* if (dcr.validate(client_id, client_secret)) {
|
|
374
|
+
* // Valid client
|
|
375
|
+
* }
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
declare class DynamicClientRegistration {
|
|
379
|
+
private options;
|
|
380
|
+
constructor(options: DynamicClientRegistrationOptions & {
|
|
381
|
+
signingSecret: string;
|
|
382
|
+
});
|
|
383
|
+
/**
|
|
384
|
+
* Register a new OAuth client (stateless)
|
|
385
|
+
*
|
|
386
|
+
* @param request - Client registration request per RFC 7591
|
|
387
|
+
* @returns Client registration response with JWT credentials
|
|
388
|
+
*/
|
|
389
|
+
register(request: ClientRegistrationRequest): ClientRegistrationResponse;
|
|
390
|
+
/**
|
|
391
|
+
* Validate client credentials (stateless)
|
|
392
|
+
*
|
|
393
|
+
* @param clientId - Client ID (JWT with prefix)
|
|
394
|
+
* @param clientSecret - Client secret (optional for public clients)
|
|
395
|
+
* @returns Whether credentials are valid
|
|
396
|
+
*/
|
|
397
|
+
validate(clientId: string, clientSecret?: string): boolean;
|
|
398
|
+
/**
|
|
399
|
+
* Get a registered client by ID (stateless)
|
|
400
|
+
*/
|
|
401
|
+
getClient(clientId: string): RegisteredClient | undefined;
|
|
402
|
+
/**
|
|
403
|
+
* Validate redirect URI for a client
|
|
404
|
+
*/
|
|
405
|
+
validateRedirectUri(clientId: string, redirectUri: string): boolean;
|
|
406
|
+
/**
|
|
407
|
+
* Delete a client (no-op in stateless mode)
|
|
408
|
+
*
|
|
409
|
+
* In stateless mode, clients cannot be truly "deleted" because
|
|
410
|
+
* their credentials are self-contained. They will expire naturally
|
|
411
|
+
* or when the signing secret is rotated.
|
|
412
|
+
*/
|
|
413
|
+
delete(clientId: string): boolean;
|
|
414
|
+
/**
|
|
415
|
+
* List all registered clients (not supported in stateless mode)
|
|
416
|
+
*/
|
|
417
|
+
listClients(): RegisteredClient[];
|
|
418
|
+
/**
|
|
419
|
+
* Clear all clients (no-op in stateless mode)
|
|
420
|
+
*/
|
|
421
|
+
clearAll(): void;
|
|
422
|
+
/**
|
|
423
|
+
* Extract JWT from prefixed client_id
|
|
424
|
+
*/
|
|
425
|
+
private extractJWT;
|
|
426
|
+
/**
|
|
427
|
+
* Derive client secret from client_id JWT
|
|
428
|
+
*
|
|
429
|
+
* Uses HMAC to create a deterministic secret that can be
|
|
430
|
+
* validated without storage.
|
|
431
|
+
*/
|
|
432
|
+
private deriveClientSecret;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Token Verifier
|
|
437
|
+
*
|
|
438
|
+
* Verifies JWT access tokens on the resource server side.
|
|
439
|
+
*/
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Token Verifier for resource servers
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* const verifier = new TokenVerifier({
|
|
447
|
+
* audience: 'https://mcp.example.com',
|
|
448
|
+
* issuer: 'https://auth.example.com',
|
|
449
|
+
* secret: process.env.JWT_SIGNING_SECRET,
|
|
450
|
+
* encryptionSecret: Buffer.from(process.env.JWT_ENCRYPTION_SECRET, 'hex'),
|
|
451
|
+
* });
|
|
452
|
+
*
|
|
453
|
+
* const result = await verifier.verify(accessToken);
|
|
454
|
+
* if (result.valid) {
|
|
455
|
+
* console.log('User:', result.claims.sub);
|
|
456
|
+
* console.log('Upstream token:', result.upstreamToken);
|
|
457
|
+
* } else {
|
|
458
|
+
* console.error('Invalid token:', result.error);
|
|
459
|
+
* }
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare class TokenVerifier {
|
|
463
|
+
private options;
|
|
464
|
+
constructor(options: TokenVerifierOptions & {
|
|
465
|
+
encryptionSecret?: Buffer;
|
|
466
|
+
});
|
|
467
|
+
/**
|
|
468
|
+
* Verify a JWT access token
|
|
469
|
+
*
|
|
470
|
+
* @param token - The JWT access token to verify
|
|
471
|
+
* @returns Verification result with claims and decrypted upstream token if valid
|
|
472
|
+
*/
|
|
473
|
+
verify(token: string): Promise<TokenVerificationResult & {
|
|
474
|
+
upstreamToken?: string;
|
|
475
|
+
}>;
|
|
476
|
+
/**
|
|
477
|
+
* Generate WWW-Authenticate header for 401 responses
|
|
478
|
+
*
|
|
479
|
+
* Per RFC 9728, this should include the resource_metadata URL
|
|
480
|
+
*
|
|
481
|
+
* @param options - Header options
|
|
482
|
+
* @returns WWW-Authenticate header value
|
|
483
|
+
*/
|
|
484
|
+
static getWWWAuthenticateHeader(options: {
|
|
485
|
+
resourceMetadataUrl: string;
|
|
486
|
+
error?: string;
|
|
487
|
+
errorDescription?: string;
|
|
488
|
+
scope?: string;
|
|
489
|
+
}): string;
|
|
490
|
+
/**
|
|
491
|
+
* Check if token has required scopes
|
|
492
|
+
*/
|
|
493
|
+
hasScopes(claims: JWTPayload, requiredScopes: string[]): boolean;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export { type AuthorizationServerMetadata, type ClientRegistrationRequest, type ClientRegistrationResponse, DynamicClientRegistration, type DynamicClientRegistrationOptions, OAuthAuthorizationServer, type OAuthAuthorizationServerOptions, type ProtectedResourceMetadata, type RegisteredClient, type TokenClaims, type TokenVerificationResult, TokenVerifier, type TokenVerifierOptions };
|