db-mcp 1.0.1
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/LICENSE +21 -0
- package/README.md +860 -0
- package/dist/adapters/DatabaseAdapter.d.ts +141 -0
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -0
- package/dist/adapters/DatabaseAdapter.js +131 -0
- package/dist/adapters/DatabaseAdapter.js.map +1 -0
- package/dist/adapters/sqlite/SchemaManager.d.ts +58 -0
- package/dist/adapters/sqlite/SchemaManager.d.ts.map +1 -0
- package/dist/adapters/sqlite/SchemaManager.js +187 -0
- package/dist/adapters/sqlite/SchemaManager.js.map +1 -0
- package/dist/adapters/sqlite/SqliteAdapter.d.ts +161 -0
- package/dist/adapters/sqlite/SqliteAdapter.d.ts.map +1 -0
- package/dist/adapters/sqlite/SqliteAdapter.js +741 -0
- package/dist/adapters/sqlite/SqliteAdapter.js.map +1 -0
- package/dist/adapters/sqlite/index.d.ts +9 -0
- package/dist/adapters/sqlite/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/index.js +8 -0
- package/dist/adapters/sqlite/index.js.map +1 -0
- package/dist/adapters/sqlite/json-utils.d.ts +100 -0
- package/dist/adapters/sqlite/json-utils.d.ts.map +1 -0
- package/dist/adapters/sqlite/json-utils.js +274 -0
- package/dist/adapters/sqlite/json-utils.js.map +1 -0
- package/dist/adapters/sqlite/output-schemas.d.ts +1187 -0
- package/dist/adapters/sqlite/output-schemas.d.ts.map +1 -0
- package/dist/adapters/sqlite/output-schemas.js +1337 -0
- package/dist/adapters/sqlite/output-schemas.js.map +1 -0
- package/dist/adapters/sqlite/prompts.d.ts +13 -0
- package/dist/adapters/sqlite/prompts.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts.js +605 -0
- package/dist/adapters/sqlite/prompts.js.map +1 -0
- package/dist/adapters/sqlite/resources.d.ts +13 -0
- package/dist/adapters/sqlite/resources.d.ts.map +1 -0
- package/dist/adapters/sqlite/resources.js +251 -0
- package/dist/adapters/sqlite/resources.js.map +1 -0
- package/dist/adapters/sqlite/tools/admin.d.ts +14 -0
- package/dist/adapters/sqlite/tools/admin.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin.js +788 -0
- package/dist/adapters/sqlite/tools/admin.js.map +1 -0
- package/dist/adapters/sqlite/tools/core.d.ts +25 -0
- package/dist/adapters/sqlite/tools/core.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core.js +359 -0
- package/dist/adapters/sqlite/tools/core.js.map +1 -0
- package/dist/adapters/sqlite/tools/fts.d.ts +13 -0
- package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/fts.js +347 -0
- package/dist/adapters/sqlite/tools/fts.js.map +1 -0
- package/dist/adapters/sqlite/tools/geo.d.ts +14 -0
- package/dist/adapters/sqlite/tools/geo.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/geo.js +252 -0
- package/dist/adapters/sqlite/tools/geo.js.map +1 -0
- package/dist/adapters/sqlite/tools/index.d.ts +30 -0
- package/dist/adapters/sqlite/tools/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/index.js +61 -0
- package/dist/adapters/sqlite/tools/index.js.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers.d.ts +14 -0
- package/dist/adapters/sqlite/tools/json-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers.js +477 -0
- package/dist/adapters/sqlite/tools/json-helpers.js.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations.d.ts +14 -0
- package/dist/adapters/sqlite/tools/json-operations.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations.js +839 -0
- package/dist/adapters/sqlite/tools/json-operations.js.map +1 -0
- package/dist/adapters/sqlite/tools/stats.d.ts +15 -0
- package/dist/adapters/sqlite/tools/stats.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats.js +1219 -0
- package/dist/adapters/sqlite/tools/stats.js.map +1 -0
- package/dist/adapters/sqlite/tools/text.d.ts +14 -0
- package/dist/adapters/sqlite/tools/text.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text.js +1141 -0
- package/dist/adapters/sqlite/tools/text.js.map +1 -0
- package/dist/adapters/sqlite/tools/vector.d.ts +14 -0
- package/dist/adapters/sqlite/tools/vector.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector.js +613 -0
- package/dist/adapters/sqlite/tools/vector.js.map +1 -0
- package/dist/adapters/sqlite/tools/virtual.d.ts +13 -0
- package/dist/adapters/sqlite/tools/virtual.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual.js +930 -0
- package/dist/adapters/sqlite/tools/virtual.js.map +1 -0
- package/dist/adapters/sqlite/types.d.ts +207 -0
- package/dist/adapters/sqlite/types.d.ts.map +1 -0
- package/dist/adapters/sqlite/types.js +186 -0
- package/dist/adapters/sqlite/types.js.map +1 -0
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts +163 -0
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js +748 -0
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js.map +1 -0
- package/dist/adapters/sqlite-native/index.d.ts +11 -0
- package/dist/adapters/sqlite-native/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/index.js +11 -0
- package/dist/adapters/sqlite-native/index.js.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts +19 -0
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite.js +628 -0
- package/dist/adapters/sqlite-native/tools/spatialite.js.map +1 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts +12 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/transactions.js +255 -0
- package/dist/adapters/sqlite-native/tools/transactions.js.map +1 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts +12 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/window.js +370 -0
- package/dist/adapters/sqlite-native/tools/window.js.map +1 -0
- package/dist/auth/AuthorizationServerDiscovery.d.ts +90 -0
- package/dist/auth/AuthorizationServerDiscovery.d.ts.map +1 -0
- package/dist/auth/AuthorizationServerDiscovery.js +204 -0
- package/dist/auth/AuthorizationServerDiscovery.js.map +1 -0
- package/dist/auth/OAuthResourceServer.d.ts +65 -0
- package/dist/auth/OAuthResourceServer.d.ts.map +1 -0
- package/dist/auth/OAuthResourceServer.js +121 -0
- package/dist/auth/OAuthResourceServer.js.map +1 -0
- package/dist/auth/TokenValidator.d.ts +60 -0
- package/dist/auth/TokenValidator.d.ts.map +1 -0
- package/dist/auth/TokenValidator.js +235 -0
- package/dist/auth/TokenValidator.js.map +1 -0
- package/dist/auth/errors.d.ts +74 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +133 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +15 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +81 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +291 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/scopes.d.ts +136 -0
- package/dist/auth/scopes.d.ts.map +1 -0
- package/dist/auth/scopes.js +349 -0
- package/dist/auth/scopes.js.map +1 -0
- package/dist/auth/types.d.ts +257 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +8 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +236 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants/ServerInstructions.d.ts +45 -0
- package/dist/constants/ServerInstructions.d.ts.map +1 -0
- package/dist/constants/ServerInstructions.js +356 -0
- package/dist/constants/ServerInstructions.js.map +1 -0
- package/dist/filtering/ToolConstants.d.ts +34 -0
- package/dist/filtering/ToolConstants.d.ts.map +1 -0
- package/dist/filtering/ToolConstants.js +174 -0
- package/dist/filtering/ToolConstants.js.map +1 -0
- package/dist/filtering/ToolFilter.d.ts +82 -0
- package/dist/filtering/ToolFilter.d.ts.map +1 -0
- package/dist/filtering/ToolFilter.js +296 -0
- package/dist/filtering/ToolFilter.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/server/McpServer.d.ts +61 -0
- package/dist/server/McpServer.d.ts.map +1 -0
- package/dist/server/McpServer.js +270 -0
- package/dist/server/McpServer.js.map +1 -0
- package/dist/transports/http.d.ts +134 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +516 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/index.d.ts +5 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +5 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/types/index.d.ts +380 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +68 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/annotations.d.ts +44 -0
- package/dist/utils/annotations.d.ts.map +1 -0
- package/dist/utils/annotations.js +77 -0
- package/dist/utils/annotations.js.map +1 -0
- package/dist/utils/errors.d.ts +155 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +329 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/identifiers.d.ts +121 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/identifiers.js +319 -0
- package/dist/utils/identifiers.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/insightsManager.d.ts +39 -0
- package/dist/utils/insightsManager.d.ts.map +1 -0
- package/dist/utils/insightsManager.js +63 -0
- package/dist/utils/insightsManager.js.map +1 -0
- package/dist/utils/logger.d.ts +189 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +394 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/progress-utils.d.ts +54 -0
- package/dist/utils/progress-utils.d.ts.map +1 -0
- package/dist/utils/progress-utils.js +74 -0
- package/dist/utils/progress-utils.js.map +1 -0
- package/dist/utils/resourceAnnotations.d.ts +36 -0
- package/dist/utils/resourceAnnotations.d.ts.map +1 -0
- package/dist/utils/resourceAnnotations.js +57 -0
- package/dist/utils/resourceAnnotations.js.map +1 -0
- package/dist/utils/where-clause.d.ts +41 -0
- package/dist/utils/where-clause.d.ts.map +1 -0
- package/dist/utils/where-clause.js +116 -0
- package/dist/utils/where-clause.js.map +1 -0
- package/package.json +83 -0
- package/server.json +53 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - Authorization Server Discovery (RFC 8414)
|
|
3
|
+
*
|
|
4
|
+
* Discovers and caches OAuth 2.0 Authorization Server Metadata
|
|
5
|
+
* as specified in RFC 8414.
|
|
6
|
+
*
|
|
7
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8414
|
|
8
|
+
*/
|
|
9
|
+
import type { AuthorizationServerMetadata, AuthServerDiscoveryConfig } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Authorization Server Metadata Discovery
|
|
12
|
+
*
|
|
13
|
+
* Fetches and caches OAuth 2.0 authorization server metadata
|
|
14
|
+
* from the /.well-known/oauth-authorization-server endpoint.
|
|
15
|
+
*/
|
|
16
|
+
export declare class AuthorizationServerDiscovery {
|
|
17
|
+
private readonly authServerUrl;
|
|
18
|
+
private readonly cacheTtl;
|
|
19
|
+
private readonly timeout;
|
|
20
|
+
private cachedMetadata;
|
|
21
|
+
private cacheExpiry;
|
|
22
|
+
constructor(config: AuthServerDiscoveryConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Discover authorization server metadata
|
|
25
|
+
*
|
|
26
|
+
* Fetches from /.well-known/oauth-authorization-server
|
|
27
|
+
* Results are cached for cacheTtl seconds.
|
|
28
|
+
*
|
|
29
|
+
* @returns Authorization server metadata
|
|
30
|
+
* @throws AuthServerDiscoveryError if discovery fails
|
|
31
|
+
*/
|
|
32
|
+
discover(): Promise<AuthorizationServerMetadata>;
|
|
33
|
+
/**
|
|
34
|
+
* Validate required metadata fields per RFC 8414
|
|
35
|
+
*/
|
|
36
|
+
private validateMetadata;
|
|
37
|
+
/**
|
|
38
|
+
* Get cached metadata (throws if not discovered)
|
|
39
|
+
*/
|
|
40
|
+
getMetadata(): AuthorizationServerMetadata;
|
|
41
|
+
/**
|
|
42
|
+
* Get JWKS URI from metadata
|
|
43
|
+
*
|
|
44
|
+
* @throws Error if metadata not discovered or jwks_uri not present
|
|
45
|
+
*/
|
|
46
|
+
getJwksUri(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Get token endpoint from metadata
|
|
49
|
+
*/
|
|
50
|
+
getTokenEndpoint(): string;
|
|
51
|
+
/**
|
|
52
|
+
* Get issuer from metadata
|
|
53
|
+
*/
|
|
54
|
+
getIssuer(): string;
|
|
55
|
+
/**
|
|
56
|
+
* Get registration endpoint from metadata (RFC 7591)
|
|
57
|
+
*
|
|
58
|
+
* @returns Registration endpoint or null if not supported
|
|
59
|
+
*/
|
|
60
|
+
getRegistrationEndpoint(): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Check if dynamic client registration is supported
|
|
63
|
+
*/
|
|
64
|
+
supportsClientRegistration(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get supported scopes from metadata
|
|
67
|
+
*/
|
|
68
|
+
getSupportedScopes(): string[];
|
|
69
|
+
/**
|
|
70
|
+
* Check if a specific scope is supported
|
|
71
|
+
*/
|
|
72
|
+
isScopeSupported(scope: string): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Clear cached metadata
|
|
75
|
+
*/
|
|
76
|
+
clearCache(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Check if cache is valid
|
|
79
|
+
*/
|
|
80
|
+
isCacheValid(): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Get the authorization server URL
|
|
83
|
+
*/
|
|
84
|
+
getAuthServerUrl(): string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Create an Authorization Server Discovery instance
|
|
88
|
+
*/
|
|
89
|
+
export declare function createAuthServerDiscovery(authServerUrl: string, options?: Partial<Omit<AuthServerDiscoveryConfig, "authServerUrl">>): AuthorizationServerDiscovery;
|
|
90
|
+
//# sourceMappingURL=AuthorizationServerDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorizationServerDiscovery.d.ts","sourceRoot":"","sources":["../../src/auth/AuthorizationServerDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAUpB;;;;;GAKG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,WAAW,CAAK;gBAEZ,MAAM,EAAE,yBAAyB;IAY7C;;;;;;;;OAQG;IACG,QAAQ,IAAI,OAAO,CAAC,2BAA2B,CAAC;IAmEtD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;OAEG;IACH,WAAW,IAAI,2BAA2B;IAS1C;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAUpB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;;;OAIG;IACH,uBAAuB,IAAI,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,0BAA0B,IAAI,OAAO;IAIrC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAMxC;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG3B;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,eAAe,CAAC,CAAC,GAClE,4BAA4B,CAM9B"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - Authorization Server Discovery (RFC 8414)
|
|
3
|
+
*
|
|
4
|
+
* Discovers and caches OAuth 2.0 Authorization Server Metadata
|
|
5
|
+
* as specified in RFC 8414.
|
|
6
|
+
*
|
|
7
|
+
* @see https://datatracker.ietf.org/doc/html/rfc8414
|
|
8
|
+
*/
|
|
9
|
+
import { AuthServerDiscoveryError } from "./errors.js";
|
|
10
|
+
import { createModuleLogger, ERROR_CODES } from "../utils/logger.js";
|
|
11
|
+
const logger = createModuleLogger("AUTH");
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Authorization Server Discovery
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Authorization Server Metadata Discovery
|
|
17
|
+
*
|
|
18
|
+
* Fetches and caches OAuth 2.0 authorization server metadata
|
|
19
|
+
* from the /.well-known/oauth-authorization-server endpoint.
|
|
20
|
+
*/
|
|
21
|
+
export class AuthorizationServerDiscovery {
|
|
22
|
+
authServerUrl;
|
|
23
|
+
cacheTtl;
|
|
24
|
+
timeout;
|
|
25
|
+
cachedMetadata = null;
|
|
26
|
+
cacheExpiry = 0;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
// Normalize URL (remove trailing slash)
|
|
29
|
+
this.authServerUrl = config.authServerUrl.replace(/\/+$/, "");
|
|
30
|
+
this.cacheTtl = config.cacheTtl ?? 3600;
|
|
31
|
+
this.timeout = config.timeout ?? 5000;
|
|
32
|
+
logger.info(`Authorization Server Discovery initialized for: ${this.authServerUrl}`, { code: "AUTH_INIT" });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Discover authorization server metadata
|
|
36
|
+
*
|
|
37
|
+
* Fetches from /.well-known/oauth-authorization-server
|
|
38
|
+
* Results are cached for cacheTtl seconds.
|
|
39
|
+
*
|
|
40
|
+
* @returns Authorization server metadata
|
|
41
|
+
* @throws AuthServerDiscoveryError if discovery fails
|
|
42
|
+
*/
|
|
43
|
+
async discover() {
|
|
44
|
+
// Check cache
|
|
45
|
+
if (this.cachedMetadata && Date.now() < this.cacheExpiry) {
|
|
46
|
+
logger.info("Using cached authorization server metadata", {
|
|
47
|
+
code: "AUTH_CACHE_HIT",
|
|
48
|
+
});
|
|
49
|
+
return this.cachedMetadata;
|
|
50
|
+
}
|
|
51
|
+
const metadataUrl = `${this.authServerUrl}/.well-known/oauth-authorization-server`;
|
|
52
|
+
logger.info(`Fetching authorization server metadata from: ${metadataUrl}`, {
|
|
53
|
+
code: "AUTH_DISCOVERY",
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
const controller = new AbortController();
|
|
57
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
58
|
+
const response = await fetch(metadataUrl, {
|
|
59
|
+
method: "GET",
|
|
60
|
+
headers: {
|
|
61
|
+
Accept: "application/json",
|
|
62
|
+
},
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
});
|
|
65
|
+
clearTimeout(timeoutId);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`HTTP ${String(response.status)}: ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
const metadata = (await response.json());
|
|
70
|
+
// Validate required fields per RFC 8414
|
|
71
|
+
this.validateMetadata(metadata);
|
|
72
|
+
// Cache the metadata
|
|
73
|
+
this.cachedMetadata = metadata;
|
|
74
|
+
this.cacheExpiry = Date.now() + this.cacheTtl * 1000;
|
|
75
|
+
logger.info(`Authorization server metadata cached for ${String(this.cacheTtl)}s`, { code: "AUTH_DISCOVERY_SUCCESS" });
|
|
76
|
+
return metadata;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
80
|
+
logger.error(`Failed to discover authorization server: ${this.authServerUrl}`, {
|
|
81
|
+
code: ERROR_CODES.AUTH.DISCOVERY_FAILED.full,
|
|
82
|
+
operation: "discover",
|
|
83
|
+
entityId: this.authServerUrl,
|
|
84
|
+
error: cause,
|
|
85
|
+
});
|
|
86
|
+
throw new AuthServerDiscoveryError(this.authServerUrl, cause);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validate required metadata fields per RFC 8414
|
|
91
|
+
*/
|
|
92
|
+
validateMetadata(metadata) {
|
|
93
|
+
if (!metadata.issuer) {
|
|
94
|
+
throw new Error("Missing required field: issuer");
|
|
95
|
+
}
|
|
96
|
+
if (!metadata.token_endpoint) {
|
|
97
|
+
throw new Error("Missing required field: token_endpoint");
|
|
98
|
+
}
|
|
99
|
+
// Validate issuer matches the expected URL
|
|
100
|
+
// Per RFC 8414, issuer MUST be identical to the authorization server URL
|
|
101
|
+
const expectedIssuer = this.authServerUrl;
|
|
102
|
+
if (metadata.issuer !== expectedIssuer) {
|
|
103
|
+
logger.warning(`Issuer mismatch: expected ${expectedIssuer}, got ${metadata.issuer}`, { code: "AUTH_ISSUER_MISMATCH" });
|
|
104
|
+
// Note: This is a warning, not an error, as some auth servers may use different URLs
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get cached metadata (throws if not discovered)
|
|
109
|
+
*/
|
|
110
|
+
getMetadata() {
|
|
111
|
+
if (!this.cachedMetadata) {
|
|
112
|
+
throw new Error("Authorization server metadata not yet discovered. Call discover() first.");
|
|
113
|
+
}
|
|
114
|
+
return this.cachedMetadata;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get JWKS URI from metadata
|
|
118
|
+
*
|
|
119
|
+
* @throws Error if metadata not discovered or jwks_uri not present
|
|
120
|
+
*/
|
|
121
|
+
getJwksUri() {
|
|
122
|
+
const metadata = this.getMetadata();
|
|
123
|
+
if (!metadata.jwks_uri) {
|
|
124
|
+
throw new Error("Authorization server does not provide jwks_uri");
|
|
125
|
+
}
|
|
126
|
+
return metadata.jwks_uri;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get token endpoint from metadata
|
|
130
|
+
*/
|
|
131
|
+
getTokenEndpoint() {
|
|
132
|
+
return this.getMetadata().token_endpoint;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get issuer from metadata
|
|
136
|
+
*/
|
|
137
|
+
getIssuer() {
|
|
138
|
+
return this.getMetadata().issuer;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get registration endpoint from metadata (RFC 7591)
|
|
142
|
+
*
|
|
143
|
+
* @returns Registration endpoint or null if not supported
|
|
144
|
+
*/
|
|
145
|
+
getRegistrationEndpoint() {
|
|
146
|
+
return this.getMetadata().registration_endpoint ?? null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if dynamic client registration is supported
|
|
150
|
+
*/
|
|
151
|
+
supportsClientRegistration() {
|
|
152
|
+
return this.getRegistrationEndpoint() !== null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get supported scopes from metadata
|
|
156
|
+
*/
|
|
157
|
+
getSupportedScopes() {
|
|
158
|
+
return this.getMetadata().scopes_supported ?? [];
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Check if a specific scope is supported
|
|
162
|
+
*/
|
|
163
|
+
isScopeSupported(scope) {
|
|
164
|
+
const supportedScopes = this.getSupportedScopes();
|
|
165
|
+
// If no scopes are listed, assume all scopes are supported
|
|
166
|
+
return supportedScopes.length === 0 || supportedScopes.includes(scope);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Clear cached metadata
|
|
170
|
+
*/
|
|
171
|
+
clearCache() {
|
|
172
|
+
this.cachedMetadata = null;
|
|
173
|
+
this.cacheExpiry = 0;
|
|
174
|
+
logger.info("Authorization server metadata cache cleared", {
|
|
175
|
+
code: "AUTH_CACHE_CLEARED",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if cache is valid
|
|
180
|
+
*/
|
|
181
|
+
isCacheValid() {
|
|
182
|
+
return this.cachedMetadata !== null && Date.now() < this.cacheExpiry;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get the authorization server URL
|
|
186
|
+
*/
|
|
187
|
+
getAuthServerUrl() {
|
|
188
|
+
return this.authServerUrl;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// =============================================================================
|
|
192
|
+
// Factory Function
|
|
193
|
+
// =============================================================================
|
|
194
|
+
/**
|
|
195
|
+
* Create an Authorization Server Discovery instance
|
|
196
|
+
*/
|
|
197
|
+
export function createAuthServerDiscovery(authServerUrl, options) {
|
|
198
|
+
return new AuthorizationServerDiscovery({
|
|
199
|
+
authServerUrl,
|
|
200
|
+
cacheTtl: options?.cacheTtl,
|
|
201
|
+
timeout: options?.timeout,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=AuthorizationServerDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorizationServerDiscovery.js","sourceRoot":"","sources":["../../src/auth/AuthorizationServerDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE1C,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,OAAO,4BAA4B;IACtB,aAAa,CAAS;IACtB,QAAQ,CAAS;IACjB,OAAO,CAAS;IAEzB,cAAc,GAAuC,IAAI,CAAC;IAC1D,WAAW,GAAG,CAAC,CAAC;IAExB,YAAY,MAAiC;QAC3C,wCAAwC;QACxC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QAEtC,MAAM,CAAC,IAAI,CACT,mDAAmD,IAAI,CAAC,aAAa,EAAE,EACvE,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ;QACZ,cAAc;QACd,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE;gBACxD,IAAI,EAAE,gBAAgB;aACvB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,aAAa,yCAAyC,CAAC;QAEnF,MAAM,CAAC,IAAI,CAAC,gDAAgD,WAAW,EAAE,EAAE;YACzE,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAErE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;gBACxC,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,MAAM,EAAE,kBAAkB;iBAC3B;gBACD,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,YAAY,CAAC,SAAS,CAAC,CAAC;YAExB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,QAAQ,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,UAAU,EAAE,CAC1D,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAgC,CAAC;YAExE,wCAAwC;YACxC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAEhC,qBAAqB;YACrB,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YAErD,MAAM,CAAC,IAAI,CACT,4CAA4C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EACpE,EAAE,IAAI,EAAE,wBAAwB,EAAE,CACnC,CAAC;YAEF,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAExE,MAAM,CAAC,KAAK,CACV,4CAA4C,IAAI,CAAC,aAAa,EAAE,EAChE;gBACE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI;gBAC5C,SAAS,EAAE,UAAU;gBACrB,QAAQ,EAAE,IAAI,CAAC,aAAa;gBAC5B,KAAK,EAAE,KAAK;aACb,CACF,CAAC;YAEF,MAAM,IAAI,wBAAwB,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,QAAqC;QAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,2CAA2C;QAC3C,yEAAyE;QACzE,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;QAC1C,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACvC,MAAM,CAAC,OAAO,CACZ,6BAA6B,cAAc,SAAS,QAAQ,CAAC,MAAM,EAAE,EACrE,EAAE,IAAI,EAAE,sBAAsB,EAAE,CACjC,CAAC;YACF,qFAAqF;QACvF,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,0EAA0E,CAC3E,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAEpC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,cAAc,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,uBAAuB;QACrB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,qBAAqB,IAAI,IAAI,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,0BAA0B;QACxB,OAAO,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,KAAa;QAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClD,2DAA2D;QAC3D,OAAO,eAAe,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,6CAA6C,EAAE;YACzD,IAAI,EAAE,oBAAoB;SAC3B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,cAAc,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,aAAqB,EACrB,OAAmE;IAEnE,OAAO,IAAI,4BAA4B,CAAC;QACtC,aAAa;QACb,QAAQ,EAAE,OAAO,EAAE,QAAQ;QAC3B,OAAO,EAAE,OAAO,EAAE,OAAO;KAC1B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - OAuth Protected Resource Server (RFC 9728)
|
|
3
|
+
*
|
|
4
|
+
* Implements the OAuth 2.0 Protected Resource Metadata endpoint
|
|
5
|
+
* as specified in RFC 9728.
|
|
6
|
+
*
|
|
7
|
+
* @see https://datatracker.ietf.org/doc/html/rfc9728
|
|
8
|
+
*/
|
|
9
|
+
import type { RequestHandler } from "express";
|
|
10
|
+
import type { ProtectedResourceMetadata, ResourceServerConfig } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* OAuth 2.0 Protected Resource Server
|
|
13
|
+
*
|
|
14
|
+
* Provides Protected Resource Metadata (RFC 9728) for MCP authorization.
|
|
15
|
+
*/
|
|
16
|
+
export declare class OAuthResourceServer {
|
|
17
|
+
private readonly config;
|
|
18
|
+
private metadata;
|
|
19
|
+
constructor(config: ResourceServerConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Get the Protected Resource Metadata document
|
|
22
|
+
*
|
|
23
|
+
* @returns RFC 9728 compliant metadata
|
|
24
|
+
*/
|
|
25
|
+
getMetadata(): ProtectedResourceMetadata;
|
|
26
|
+
/**
|
|
27
|
+
* Build the Protected Resource Metadata document
|
|
28
|
+
*/
|
|
29
|
+
private buildMetadata;
|
|
30
|
+
/**
|
|
31
|
+
* Get Express request handler for the metadata endpoint
|
|
32
|
+
*
|
|
33
|
+
* Serves: GET /.well-known/oauth-protected-resource
|
|
34
|
+
*/
|
|
35
|
+
getMetadataHandler(): RequestHandler;
|
|
36
|
+
/**
|
|
37
|
+
* Generate WWW-Authenticate header for 401 responses
|
|
38
|
+
*
|
|
39
|
+
* @param error - Error type for the header
|
|
40
|
+
* @param errorDescription - Human-readable error description
|
|
41
|
+
* @returns WWW-Authenticate header value
|
|
42
|
+
*/
|
|
43
|
+
getWWWAuthenticateHeader(error?: string, errorDescription?: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get the resource URI
|
|
46
|
+
*/
|
|
47
|
+
getResourceUri(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get the authorization servers
|
|
50
|
+
*/
|
|
51
|
+
getAuthorizationServers(): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Get supported scopes
|
|
54
|
+
*/
|
|
55
|
+
getSupportedScopes(): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Clear cached metadata (useful when configuration changes)
|
|
58
|
+
*/
|
|
59
|
+
clearCache(): void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create an OAuth Resource Server instance
|
|
63
|
+
*/
|
|
64
|
+
export declare function createOAuthResourceServer(config: ResourceServerConfig): OAuthResourceServer;
|
|
65
|
+
//# sourceMappingURL=OAuthResourceServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthResourceServer.d.ts","sourceRoot":"","sources":["../../src/auth/OAuthResourceServer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EACV,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAUpB;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAA0C;gBAE9C,MAAM,EAAE,oBAAoB;IAiBxC;;;;OAIG;IACH,WAAW,IAAI,yBAAyB;IAKxC;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;;;OAIG;IACH,kBAAkB,IAAI,cAAc;IAcpC;;;;;;OAMG;IACH,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM;IAc3E;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,uBAAuB,IAAI,MAAM,EAAE;IAInC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,oBAAoB,GAC3B,mBAAmB,CAErB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - OAuth Protected Resource Server (RFC 9728)
|
|
3
|
+
*
|
|
4
|
+
* Implements the OAuth 2.0 Protected Resource Metadata endpoint
|
|
5
|
+
* as specified in RFC 9728.
|
|
6
|
+
*
|
|
7
|
+
* @see https://datatracker.ietf.org/doc/html/rfc9728
|
|
8
|
+
*/
|
|
9
|
+
import { SUPPORTED_SCOPES } from "./scopes.js";
|
|
10
|
+
import { createModuleLogger } from "../utils/logger.js";
|
|
11
|
+
const logger = createModuleLogger("AUTH");
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// OAuth Resource Server
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* OAuth 2.0 Protected Resource Server
|
|
17
|
+
*
|
|
18
|
+
* Provides Protected Resource Metadata (RFC 9728) for MCP authorization.
|
|
19
|
+
*/
|
|
20
|
+
export class OAuthResourceServer {
|
|
21
|
+
config;
|
|
22
|
+
metadata = null;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = {
|
|
25
|
+
resource: config.resource,
|
|
26
|
+
authorizationServers: config.authorizationServers,
|
|
27
|
+
scopesSupported: config.scopesSupported.length > 0
|
|
28
|
+
? config.scopesSupported
|
|
29
|
+
: [...SUPPORTED_SCOPES],
|
|
30
|
+
bearerMethodsSupported: config.bearerMethodsSupported ?? ["header"],
|
|
31
|
+
};
|
|
32
|
+
logger.info(`OAuth Resource Server initialized for: ${this.config.resource}`, { code: "AUTH_INIT" });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the Protected Resource Metadata document
|
|
36
|
+
*
|
|
37
|
+
* @returns RFC 9728 compliant metadata
|
|
38
|
+
*/
|
|
39
|
+
getMetadata() {
|
|
40
|
+
this.metadata ??= this.buildMetadata();
|
|
41
|
+
return this.metadata;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build the Protected Resource Metadata document
|
|
45
|
+
*/
|
|
46
|
+
buildMetadata() {
|
|
47
|
+
return {
|
|
48
|
+
resource: this.config.resource,
|
|
49
|
+
authorization_servers: this.config.authorizationServers,
|
|
50
|
+
scopes_supported: this.config.scopesSupported,
|
|
51
|
+
bearer_methods_supported: this.config.bearerMethodsSupported,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get Express request handler for the metadata endpoint
|
|
56
|
+
*
|
|
57
|
+
* Serves: GET /.well-known/oauth-protected-resource
|
|
58
|
+
*/
|
|
59
|
+
getMetadataHandler() {
|
|
60
|
+
return (_req, res) => {
|
|
61
|
+
const metadata = this.getMetadata();
|
|
62
|
+
res.setHeader("Content-Type", "application/json");
|
|
63
|
+
res.setHeader("Cache-Control", "public, max-age=3600");
|
|
64
|
+
res.json(metadata);
|
|
65
|
+
logger.info("Protected Resource Metadata served", {
|
|
66
|
+
code: "AUTH_METADATA_SERVED",
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate WWW-Authenticate header for 401 responses
|
|
72
|
+
*
|
|
73
|
+
* @param error - Error type for the header
|
|
74
|
+
* @param errorDescription - Human-readable error description
|
|
75
|
+
* @returns WWW-Authenticate header value
|
|
76
|
+
*/
|
|
77
|
+
getWWWAuthenticateHeader(error, errorDescription) {
|
|
78
|
+
const parts = [`Bearer realm="${this.config.resource}"`];
|
|
79
|
+
if (error) {
|
|
80
|
+
parts.push(`error="${error}"`);
|
|
81
|
+
}
|
|
82
|
+
if (errorDescription) {
|
|
83
|
+
parts.push(`error_description="${errorDescription}"`);
|
|
84
|
+
}
|
|
85
|
+
return parts.join(", ");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the resource URI
|
|
89
|
+
*/
|
|
90
|
+
getResourceUri() {
|
|
91
|
+
return this.config.resource;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the authorization servers
|
|
95
|
+
*/
|
|
96
|
+
getAuthorizationServers() {
|
|
97
|
+
return [...this.config.authorizationServers];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get supported scopes
|
|
101
|
+
*/
|
|
102
|
+
getSupportedScopes() {
|
|
103
|
+
return [...this.config.scopesSupported];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Clear cached metadata (useful when configuration changes)
|
|
107
|
+
*/
|
|
108
|
+
clearCache() {
|
|
109
|
+
this.metadata = null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// =============================================================================
|
|
113
|
+
// Factory Function
|
|
114
|
+
// =============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Create an OAuth Resource Server instance
|
|
117
|
+
*/
|
|
118
|
+
export function createOAuthResourceServer(config) {
|
|
119
|
+
return new OAuthResourceServer(config);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=OAuthResourceServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthResourceServer.js","sourceRoot":"","sources":["../../src/auth/OAuthResourceServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - Token Validator
|
|
3
|
+
*
|
|
4
|
+
* JWT access token validation using JWKS for signature verification.
|
|
5
|
+
* Supports RSA and EC algorithms commonly used with OAuth 2.0.
|
|
6
|
+
*/
|
|
7
|
+
import type { TokenValidationResult, TokenValidatorConfig } from "./types.js";
|
|
8
|
+
import { InvalidTokenError, TokenExpiredError, InvalidSignatureError } from "./errors.js";
|
|
9
|
+
/**
|
|
10
|
+
* JWT Token Validator
|
|
11
|
+
*
|
|
12
|
+
* Validates OAuth 2.0 access tokens using JWKS for signature verification.
|
|
13
|
+
*/
|
|
14
|
+
export declare class TokenValidator {
|
|
15
|
+
/** Resolved configuration with all defaults applied */
|
|
16
|
+
private readonly jwksUri;
|
|
17
|
+
private readonly issuer;
|
|
18
|
+
private readonly audience;
|
|
19
|
+
private readonly clockTolerance;
|
|
20
|
+
private readonly jwksCacheTtl;
|
|
21
|
+
private jwks;
|
|
22
|
+
private jwksExpiry;
|
|
23
|
+
constructor(config: TokenValidatorConfig);
|
|
24
|
+
/**
|
|
25
|
+
* Validate an access token
|
|
26
|
+
*
|
|
27
|
+
* @param token - The JWT access token
|
|
28
|
+
* @returns Validation result with claims or error
|
|
29
|
+
*/
|
|
30
|
+
validate(token: string): Promise<TokenValidationResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Get or refresh the JWKS
|
|
33
|
+
*/
|
|
34
|
+
private getJwks;
|
|
35
|
+
/**
|
|
36
|
+
* Extract and normalize token claims
|
|
37
|
+
*/
|
|
38
|
+
private extractClaims;
|
|
39
|
+
/**
|
|
40
|
+
* Handle validation errors and convert to TokenValidationResult
|
|
41
|
+
*/
|
|
42
|
+
private handleValidationError;
|
|
43
|
+
/**
|
|
44
|
+
* Refresh the JWKS cache
|
|
45
|
+
*/
|
|
46
|
+
refreshJwks(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Clear the JWKS cache
|
|
49
|
+
*/
|
|
50
|
+
clearCache(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Convert a validation error to the appropriate OAuth error class
|
|
53
|
+
*/
|
|
54
|
+
static toOAuthError(result: TokenValidationResult): InvalidTokenError | TokenExpiredError | InvalidSignatureError;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a Token Validator instance
|
|
58
|
+
*/
|
|
59
|
+
export declare function createTokenValidator(config: TokenValidatorConfig): TokenValidator;
|
|
60
|
+
//# sourceMappingURL=TokenValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenValidator.d.ts","sourceRoot":"","sources":["../../src/auth/TokenValidator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,qBAAqB,EAErB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,aAAa,CAAC;AAUrB;;;;GAIG;AACH,qBAAa,cAAc;IACzB,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,OAAO,CAAC,IAAI,CAAqC;IACjD,OAAO,CAAC,UAAU,CAAK;gBAEX,MAAM,EAAE,oBAAoB;IAYxC;;;;;OAKG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA+B7D;;OAEG;IACH,OAAO,CAAC,OAAO;IAoCf;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqE7B;;OAEG;IACH,WAAW,IAAI,IAAI;IAOnB;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB;;OAEG;IACH,MAAM,CAAC,YAAY,CACjB,MAAM,EAAE,qBAAqB,GAC5B,iBAAiB,GAAG,iBAAiB,GAAG,qBAAqB;CAWjE;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,GAC3B,cAAc,CAEhB"}
|