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,235 @@
|
|
|
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 * as jose from "jose";
|
|
8
|
+
import { InvalidTokenError, TokenExpiredError, InvalidSignatureError, JwksFetchError, } from "./errors.js";
|
|
9
|
+
import { parseScopes } from "./scopes.js";
|
|
10
|
+
import { createModuleLogger, ERROR_CODES } from "../utils/logger.js";
|
|
11
|
+
const logger = createModuleLogger("AUTH");
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Token Validator
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* JWT Token Validator
|
|
17
|
+
*
|
|
18
|
+
* Validates OAuth 2.0 access tokens using JWKS for signature verification.
|
|
19
|
+
*/
|
|
20
|
+
export class TokenValidator {
|
|
21
|
+
/** Resolved configuration with all defaults applied */
|
|
22
|
+
jwksUri;
|
|
23
|
+
issuer;
|
|
24
|
+
audience;
|
|
25
|
+
clockTolerance;
|
|
26
|
+
jwksCacheTtl;
|
|
27
|
+
jwks = null;
|
|
28
|
+
jwksExpiry = 0;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.jwksUri = config.jwksUri;
|
|
31
|
+
this.issuer = config.issuer;
|
|
32
|
+
this.audience = config.audience;
|
|
33
|
+
this.clockTolerance = config.clockTolerance ?? 60;
|
|
34
|
+
this.jwksCacheTtl = config.jwksCacheTtl ?? 3600;
|
|
35
|
+
logger.info(`Token Validator initialized for issuer: ${this.issuer}`, {
|
|
36
|
+
code: "AUTH_INIT",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate an access token
|
|
41
|
+
*
|
|
42
|
+
* @param token - The JWT access token
|
|
43
|
+
* @returns Validation result with claims or error
|
|
44
|
+
*/
|
|
45
|
+
async validate(token) {
|
|
46
|
+
try {
|
|
47
|
+
// Get or refresh JWKS
|
|
48
|
+
const jwks = this.getJwks();
|
|
49
|
+
// Verify the token
|
|
50
|
+
const { payload } = await jose.jwtVerify(token, jwks, {
|
|
51
|
+
issuer: this.issuer,
|
|
52
|
+
audience: this.audience,
|
|
53
|
+
clockTolerance: this.clockTolerance,
|
|
54
|
+
});
|
|
55
|
+
// Extract and normalize claims
|
|
56
|
+
const claims = this.extractClaims(payload);
|
|
57
|
+
logger.info(`Token validated for subject: ${claims.sub}`, {
|
|
58
|
+
code: "AUTH_TOKEN_VALID",
|
|
59
|
+
sub: claims.sub,
|
|
60
|
+
scopes: claims.scopes.length,
|
|
61
|
+
exp: new Date(claims.exp * 1000).toISOString(),
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
valid: true,
|
|
65
|
+
claims,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return this.handleValidationError(error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get or refresh the JWKS
|
|
74
|
+
*/
|
|
75
|
+
getJwks() {
|
|
76
|
+
// Check if JWKS is cached and valid
|
|
77
|
+
if (this.jwks && Date.now() < this.jwksExpiry) {
|
|
78
|
+
return this.jwks;
|
|
79
|
+
}
|
|
80
|
+
logger.info(`Fetching JWKS from: ${this.jwksUri}`, {
|
|
81
|
+
code: "AUTH_JWKS_FETCH",
|
|
82
|
+
});
|
|
83
|
+
try {
|
|
84
|
+
// Create JWKS remote key set
|
|
85
|
+
this.jwks = jose.createRemoteJWKSet(new URL(this.jwksUri), {
|
|
86
|
+
cooldownDuration: 30000, // 30 seconds between retries
|
|
87
|
+
cacheMaxAge: this.jwksCacheTtl * 1000,
|
|
88
|
+
});
|
|
89
|
+
this.jwksExpiry = Date.now() + this.jwksCacheTtl * 1000;
|
|
90
|
+
logger.info(`JWKS cached for ${String(this.jwksCacheTtl)}s`, {
|
|
91
|
+
code: "AUTH_JWKS_CACHED",
|
|
92
|
+
});
|
|
93
|
+
return this.jwks;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
97
|
+
logger.error(`Failed to fetch JWKS: ${this.jwksUri}`, {
|
|
98
|
+
code: ERROR_CODES.AUTH.JWKS_FETCH_FAILED.full,
|
|
99
|
+
error: cause,
|
|
100
|
+
});
|
|
101
|
+
throw new JwksFetchError(this.jwksUri, cause);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Extract and normalize token claims
|
|
106
|
+
*/
|
|
107
|
+
extractClaims(payload) {
|
|
108
|
+
// Get scopes from 'scope' claim (space-delimited) or 'scopes' claim (array)
|
|
109
|
+
let scopes = [];
|
|
110
|
+
if (typeof payload["scope"] === "string") {
|
|
111
|
+
scopes = parseScopes(payload["scope"]);
|
|
112
|
+
}
|
|
113
|
+
else if (Array.isArray(payload["scopes"])) {
|
|
114
|
+
scopes = payload["scopes"].filter((s) => typeof s === "string");
|
|
115
|
+
}
|
|
116
|
+
else if (Array.isArray(payload["scope"])) {
|
|
117
|
+
scopes = payload["scope"].filter((s) => typeof s === "string");
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
sub: payload.sub ?? "unknown",
|
|
121
|
+
scopes,
|
|
122
|
+
exp: payload.exp ?? 0,
|
|
123
|
+
iat: payload.iat ?? 0,
|
|
124
|
+
iss: payload.iss,
|
|
125
|
+
aud: payload.aud,
|
|
126
|
+
nbf: payload.nbf ?? undefined,
|
|
127
|
+
jti: payload.jti,
|
|
128
|
+
client_id: payload["client_id"],
|
|
129
|
+
// Include all other claims
|
|
130
|
+
...payload,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Handle validation errors and convert to TokenValidationResult
|
|
135
|
+
*/
|
|
136
|
+
handleValidationError(error) {
|
|
137
|
+
// Handle jose-specific errors
|
|
138
|
+
if (error instanceof jose.errors.JWTExpired) {
|
|
139
|
+
logger.warning("Token has expired", {
|
|
140
|
+
code: ERROR_CODES.AUTH.TOKEN_EXPIRED.full,
|
|
141
|
+
error: error,
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
valid: false,
|
|
145
|
+
error: "Token has expired",
|
|
146
|
+
errorCode: ERROR_CODES.AUTH.TOKEN_EXPIRED.full,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (error instanceof jose.errors.JWTClaimValidationFailed) {
|
|
150
|
+
logger.warning(`Token claim validation failed: ${error.message}`, {
|
|
151
|
+
code: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
152
|
+
error,
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
valid: false,
|
|
156
|
+
error: `Token claim validation failed: ${error.message}`,
|
|
157
|
+
errorCode: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (error instanceof jose.errors.JWSSignatureVerificationFailed) {
|
|
161
|
+
logger.warning("Token signature verification failed", {
|
|
162
|
+
code: ERROR_CODES.AUTH.SIGNATURE_INVALID.full,
|
|
163
|
+
error,
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
valid: false,
|
|
167
|
+
error: "Token signature verification failed",
|
|
168
|
+
errorCode: ERROR_CODES.AUTH.SIGNATURE_INVALID.full,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (error instanceof jose.errors.JWKSNoMatchingKey) {
|
|
172
|
+
logger.warning("No matching key found in JWKS", {
|
|
173
|
+
code: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
174
|
+
error,
|
|
175
|
+
});
|
|
176
|
+
return {
|
|
177
|
+
valid: false,
|
|
178
|
+
error: "No matching key found in JWKS",
|
|
179
|
+
errorCode: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Handle other errors
|
|
183
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
+
logger.error(`Token validation failed: ${message}`, {
|
|
185
|
+
code: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
186
|
+
error: error instanceof Error ? error : undefined,
|
|
187
|
+
});
|
|
188
|
+
return {
|
|
189
|
+
valid: false,
|
|
190
|
+
error: `Token validation failed: ${message}`,
|
|
191
|
+
errorCode: ERROR_CODES.AUTH.TOKEN_INVALID.full,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Refresh the JWKS cache
|
|
196
|
+
*/
|
|
197
|
+
refreshJwks() {
|
|
198
|
+
this.jwks = null;
|
|
199
|
+
this.jwksExpiry = 0;
|
|
200
|
+
this.getJwks();
|
|
201
|
+
logger.info("JWKS cache refreshed", { code: "AUTH_JWKS_REFRESHED" });
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Clear the JWKS cache
|
|
205
|
+
*/
|
|
206
|
+
clearCache() {
|
|
207
|
+
this.jwks = null;
|
|
208
|
+
this.jwksExpiry = 0;
|
|
209
|
+
logger.info("Token validator cache cleared", {
|
|
210
|
+
code: "AUTH_CACHE_CLEARED",
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Convert a validation error to the appropriate OAuth error class
|
|
215
|
+
*/
|
|
216
|
+
static toOAuthError(result) {
|
|
217
|
+
if (result.errorCode === ERROR_CODES.AUTH.TOKEN_EXPIRED.full) {
|
|
218
|
+
return new TokenExpiredError();
|
|
219
|
+
}
|
|
220
|
+
if (result.errorCode === ERROR_CODES.AUTH.SIGNATURE_INVALID.full) {
|
|
221
|
+
return new InvalidSignatureError();
|
|
222
|
+
}
|
|
223
|
+
return new InvalidTokenError(result.error);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// =============================================================================
|
|
227
|
+
// Factory Function
|
|
228
|
+
// =============================================================================
|
|
229
|
+
/**
|
|
230
|
+
* Create a Token Validator instance
|
|
231
|
+
*/
|
|
232
|
+
export function createTokenValidator(config) {
|
|
233
|
+
return new TokenValidator(config);
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=TokenValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenValidator.js","sourceRoot":"","sources":["../../src/auth/TokenValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - OAuth Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Module-prefixed error classes for OAuth 2.0 authentication
|
|
5
|
+
* and authorization failures.
|
|
6
|
+
*/
|
|
7
|
+
import { DbMcpError } from "../types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Base class for OAuth-related errors
|
|
10
|
+
*/
|
|
11
|
+
export declare class OAuthError extends DbMcpError {
|
|
12
|
+
/** HTTP status code for this error */
|
|
13
|
+
readonly httpStatus: number;
|
|
14
|
+
/** WWW-Authenticate header value */
|
|
15
|
+
readonly wwwAuthenticate?: string | undefined;
|
|
16
|
+
constructor(message: string, code: string, httpStatus: number, details?: Record<string, unknown>, wwwAuthenticate?: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Token is missing from the request
|
|
20
|
+
*/
|
|
21
|
+
export declare class TokenMissingError extends OAuthError {
|
|
22
|
+
constructor(realm?: string);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Token is invalid (malformed, wrong format, etc.)
|
|
26
|
+
*/
|
|
27
|
+
export declare class InvalidTokenError extends OAuthError {
|
|
28
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Token has expired
|
|
32
|
+
*/
|
|
33
|
+
export declare class TokenExpiredError extends OAuthError {
|
|
34
|
+
constructor(expiredAt?: Date);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Token signature is invalid
|
|
38
|
+
*/
|
|
39
|
+
export declare class InvalidSignatureError extends OAuthError {
|
|
40
|
+
constructor(message?: string);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Token does not have required scope
|
|
44
|
+
*/
|
|
45
|
+
export declare class InsufficientScopeError extends OAuthError {
|
|
46
|
+
constructor(requiredScope: string | string[], providedScopes?: string[]);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Failed to discover authorization server metadata
|
|
50
|
+
*/
|
|
51
|
+
export declare class AuthServerDiscoveryError extends OAuthError {
|
|
52
|
+
constructor(serverUrl: string, cause?: Error);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Failed to fetch JWKS
|
|
56
|
+
*/
|
|
57
|
+
export declare class JwksFetchError extends OAuthError {
|
|
58
|
+
constructor(jwksUri: string, cause?: Error);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Failed to register client
|
|
62
|
+
*/
|
|
63
|
+
export declare class ClientRegistrationError extends OAuthError {
|
|
64
|
+
constructor(message: string, details?: Record<string, unknown>);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if an error is an OAuth error
|
|
68
|
+
*/
|
|
69
|
+
export declare function isOAuthError(error: unknown): error is OAuthError;
|
|
70
|
+
/**
|
|
71
|
+
* Get WWW-Authenticate header for an OAuth error
|
|
72
|
+
*/
|
|
73
|
+
export declare function getWWWAuthenticateHeader(error: OAuthError, realm?: string): string;
|
|
74
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAO/C;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,oCAAoC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAG5C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,eAAe,CAAC,EAAE,MAAM;CAO3B;AAMD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;gBACnC,KAAK,SAAW;CAU7B;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;gBAE7C,OAAO,SAAyB,EAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAWpC;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;gBACnC,SAAS,CAAC,EAAE,IAAI;CAU7B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,UAAU;gBACvC,OAAO,SAAwC;CAU5D;AAMD;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,UAAU;gBACxC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE;CAexE;AAMD;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,UAAU;gBAC1C,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAY7C;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,UAAU;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAY3C;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,UAAU;gBACzC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAI/D;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,KAAK,SAAW,GACf,MAAM,CAER"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - OAuth Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Module-prefixed error classes for OAuth 2.0 authentication
|
|
5
|
+
* and authorization failures.
|
|
6
|
+
*/
|
|
7
|
+
import { DbMcpError } from "../types/index.js";
|
|
8
|
+
import { ERROR_CODES } from "../utils/logger.js";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Base OAuth Error
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Base class for OAuth-related errors
|
|
14
|
+
*/
|
|
15
|
+
export class OAuthError extends DbMcpError {
|
|
16
|
+
/** HTTP status code for this error */
|
|
17
|
+
httpStatus;
|
|
18
|
+
/** WWW-Authenticate header value */
|
|
19
|
+
wwwAuthenticate;
|
|
20
|
+
constructor(message, code, httpStatus, details, wwwAuthenticate) {
|
|
21
|
+
super(message, code, details);
|
|
22
|
+
this.name = "OAuthError";
|
|
23
|
+
this.httpStatus = httpStatus;
|
|
24
|
+
this.wwwAuthenticate = wwwAuthenticate;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Authentication Errors (401)
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* Token is missing from the request
|
|
32
|
+
*/
|
|
33
|
+
export class TokenMissingError extends OAuthError {
|
|
34
|
+
constructor(realm = "db-mcp") {
|
|
35
|
+
super("No access token provided", ERROR_CODES.AUTH.TOKEN_MISSING.full, 401, undefined, `Bearer realm="${realm}"`);
|
|
36
|
+
this.name = "TokenMissingError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Token is invalid (malformed, wrong format, etc.)
|
|
41
|
+
*/
|
|
42
|
+
export class InvalidTokenError extends OAuthError {
|
|
43
|
+
constructor(message = "Invalid access token", details) {
|
|
44
|
+
super(message, ERROR_CODES.AUTH.TOKEN_INVALID.full, 401, details, 'Bearer error="invalid_token"');
|
|
45
|
+
this.name = "InvalidTokenError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Token has expired
|
|
50
|
+
*/
|
|
51
|
+
export class TokenExpiredError extends OAuthError {
|
|
52
|
+
constructor(expiredAt) {
|
|
53
|
+
super("Access token has expired", ERROR_CODES.AUTH.TOKEN_EXPIRED.full, 401, expiredAt ? { expiredAt: expiredAt.toISOString() } : undefined, 'Bearer error="invalid_token", error_description="Token has expired"');
|
|
54
|
+
this.name = "TokenExpiredError";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Token signature is invalid
|
|
59
|
+
*/
|
|
60
|
+
export class InvalidSignatureError extends OAuthError {
|
|
61
|
+
constructor(message = "Token signature verification failed") {
|
|
62
|
+
super(message, ERROR_CODES.AUTH.SIGNATURE_INVALID.full, 401, undefined, 'Bearer error="invalid_token", error_description="Signature verification failed"');
|
|
63
|
+
this.name = "InvalidSignatureError";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// Authorization Errors (403)
|
|
68
|
+
// =============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Token does not have required scope
|
|
71
|
+
*/
|
|
72
|
+
export class InsufficientScopeError extends OAuthError {
|
|
73
|
+
constructor(requiredScope, providedScopes) {
|
|
74
|
+
const required = Array.isArray(requiredScope)
|
|
75
|
+
? requiredScope
|
|
76
|
+
: [requiredScope];
|
|
77
|
+
const scopeValue = required.join(" ");
|
|
78
|
+
super(`Insufficient scope. Required: ${scopeValue}`, ERROR_CODES.AUTH.SCOPE_DENIED.full, 403, { requiredScope: required, providedScopes }, `Bearer error="insufficient_scope", scope="${scopeValue}"`);
|
|
79
|
+
this.name = "InsufficientScopeError";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// =============================================================================
|
|
83
|
+
// Server Errors (500)
|
|
84
|
+
// =============================================================================
|
|
85
|
+
/**
|
|
86
|
+
* Failed to discover authorization server metadata
|
|
87
|
+
*/
|
|
88
|
+
export class AuthServerDiscoveryError extends OAuthError {
|
|
89
|
+
constructor(serverUrl, cause) {
|
|
90
|
+
super(`Failed to discover authorization server metadata: ${serverUrl}`, ERROR_CODES.AUTH.DISCOVERY_FAILED.full, 500, {
|
|
91
|
+
serverUrl,
|
|
92
|
+
cause: cause?.message,
|
|
93
|
+
});
|
|
94
|
+
this.name = "AuthServerDiscoveryError";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Failed to fetch JWKS
|
|
99
|
+
*/
|
|
100
|
+
export class JwksFetchError extends OAuthError {
|
|
101
|
+
constructor(jwksUri, cause) {
|
|
102
|
+
super(`Failed to fetch JWKS: ${jwksUri}`, ERROR_CODES.AUTH.JWKS_FETCH_FAILED.full, 500, {
|
|
103
|
+
jwksUri,
|
|
104
|
+
cause: cause?.message,
|
|
105
|
+
});
|
|
106
|
+
this.name = "JwksFetchError";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Failed to register client
|
|
111
|
+
*/
|
|
112
|
+
export class ClientRegistrationError extends OAuthError {
|
|
113
|
+
constructor(message, details) {
|
|
114
|
+
super(message, ERROR_CODES.AUTH.REGISTRATION_FAILED.full, 500, details);
|
|
115
|
+
this.name = "ClientRegistrationError";
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Utility Functions
|
|
120
|
+
// =============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Check if an error is an OAuth error
|
|
123
|
+
*/
|
|
124
|
+
export function isOAuthError(error) {
|
|
125
|
+
return error instanceof OAuthError;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get WWW-Authenticate header for an OAuth error
|
|
129
|
+
*/
|
|
130
|
+
export function getWWWAuthenticateHeader(error, realm = "db-mcp") {
|
|
131
|
+
return error.wwwAuthenticate ?? `Bearer realm="${realm}"`;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - Auth Module Public Exports
|
|
3
|
+
*
|
|
4
|
+
* OAuth 2.0 authentication and authorization components.
|
|
5
|
+
*/
|
|
6
|
+
export type * from "./types.js";
|
|
7
|
+
export * from "./errors.js";
|
|
8
|
+
export * from "./scopes.js";
|
|
9
|
+
export { OAuthResourceServer, createOAuthResourceServer, } from "./OAuthResourceServer.js";
|
|
10
|
+
export { AuthorizationServerDiscovery, createAuthServerDiscovery, } from "./AuthorizationServerDiscovery.js";
|
|
11
|
+
export { TokenValidator, createTokenValidator } from "./TokenValidator.js";
|
|
12
|
+
export { createAuthMiddleware, extractBearerToken, requireScope, requireAnyScope, requireToolScope, oauthErrorHandler, type AuthMiddlewareConfig, } from "./middleware.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,mBAAmB,YAAY,CAAC;AAChC,cAAc,aAAa,CAAC;AAG5B,cAAc,aAAa,CAAC;AAG5B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3E,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - Auth Module Public Exports
|
|
3
|
+
*
|
|
4
|
+
* OAuth 2.0 authentication and authorization components.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./errors.js";
|
|
7
|
+
// Scopes
|
|
8
|
+
export * from "./scopes.js";
|
|
9
|
+
// Core classes
|
|
10
|
+
export { OAuthResourceServer, createOAuthResourceServer, } from "./OAuthResourceServer.js";
|
|
11
|
+
export { AuthorizationServerDiscovery, createAuthServerDiscovery, } from "./AuthorizationServerDiscovery.js";
|
|
12
|
+
export { TokenValidator, createTokenValidator } from "./TokenValidator.js";
|
|
13
|
+
// Middleware
|
|
14
|
+
export { createAuthMiddleware, extractBearerToken, requireScope, requireAnyScope, requireToolScope, oauthErrorHandler, } from "./middleware.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,cAAc,aAAa,CAAC;AAE5B,SAAS;AACT,cAAc,aAAa,CAAC;AAE5B,eAAe;AACf,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,aAAa;AACb,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-mcp - OAuth Middleware
|
|
3
|
+
*
|
|
4
|
+
* Express middleware for OAuth 2.0 authentication and authorization.
|
|
5
|
+
* Extracts Bearer tokens, validates them, and enforces scope requirements.
|
|
6
|
+
*/
|
|
7
|
+
import type { Request, Response, NextFunction, RequestHandler } from "express";
|
|
8
|
+
import type { TokenClaims } from "./types.js";
|
|
9
|
+
import type { TokenValidator } from "./TokenValidator.js";
|
|
10
|
+
import type { OAuthResourceServer } from "./OAuthResourceServer.js";
|
|
11
|
+
/**
|
|
12
|
+
* Extended Express Request with auth context
|
|
13
|
+
* Uses module augmentation to extend Express.Request interface
|
|
14
|
+
*/
|
|
15
|
+
declare module "express-serve-static-core" {
|
|
16
|
+
interface Request {
|
|
17
|
+
/** Authenticated user claims */
|
|
18
|
+
auth?: TokenClaims;
|
|
19
|
+
/** Raw access token */
|
|
20
|
+
accessToken?: string;
|
|
21
|
+
/** Request ID for tracing */
|
|
22
|
+
requestId?: string;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Auth middleware configuration
|
|
27
|
+
*/
|
|
28
|
+
export interface AuthMiddlewareConfig {
|
|
29
|
+
/** Token validator instance */
|
|
30
|
+
tokenValidator: TokenValidator;
|
|
31
|
+
/** Resource server instance (for WWW-Authenticate header) */
|
|
32
|
+
resourceServer: OAuthResourceServer;
|
|
33
|
+
/** Paths that bypass authentication (e.g., '/.well-known/*', '/health') */
|
|
34
|
+
publicPaths?: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Extract Bearer token from Authorization header
|
|
38
|
+
*
|
|
39
|
+
* @param authHeader - Authorization header value
|
|
40
|
+
* @returns The token or null if not present/invalid
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractBearerToken(authHeader: string | undefined): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Create the main authentication middleware
|
|
45
|
+
*
|
|
46
|
+
* This middleware:
|
|
47
|
+
* 1. Skips authentication for public paths (e.g., /.well-known/*)
|
|
48
|
+
* 2. Extracts Bearer token from Authorization header
|
|
49
|
+
* 3. Validates the token using the TokenValidator
|
|
50
|
+
* 4. Attaches validated claims to req.auth
|
|
51
|
+
* 5. Returns 401 with WWW-Authenticate header on failure
|
|
52
|
+
*/
|
|
53
|
+
export declare function createAuthMiddleware(config: AuthMiddlewareConfig): RequestHandler;
|
|
54
|
+
/**
|
|
55
|
+
* Middleware factory that requires a specific scope
|
|
56
|
+
*
|
|
57
|
+
* @param scope - Required scope
|
|
58
|
+
* @returns Express middleware
|
|
59
|
+
*/
|
|
60
|
+
export declare function requireScope(scope: string): RequestHandler;
|
|
61
|
+
/**
|
|
62
|
+
* Middleware factory that requires any of the specified scopes
|
|
63
|
+
*
|
|
64
|
+
* @param scopes - Array of acceptable scopes (user must have at least one)
|
|
65
|
+
* @returns Express middleware
|
|
66
|
+
*/
|
|
67
|
+
export declare function requireAnyScope(scopes: string[]): RequestHandler;
|
|
68
|
+
/**
|
|
69
|
+
* Middleware factory that requires scope for a specific tool
|
|
70
|
+
*
|
|
71
|
+
* @param toolName - Name of the tool being accessed
|
|
72
|
+
* @returns Express middleware
|
|
73
|
+
*/
|
|
74
|
+
export declare function requireToolScope(toolName: string): RequestHandler;
|
|
75
|
+
/**
|
|
76
|
+
* Error handler middleware for OAuth errors
|
|
77
|
+
*
|
|
78
|
+
* Should be added after all routes to catch OAuth-related errors
|
|
79
|
+
*/
|
|
80
|
+
export declare function oauthErrorHandler(error: Error, _req: Request, res: Response, next: NextFunction): void;
|
|
81
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAgBpE;;;GAGG;AACH,OAAO,QAAQ,2BAA2B,CAAC;IACzC,UAAU,OAAO;QACf,gCAAgC;QAChC,IAAI,CAAC,EAAE,WAAW,CAAC;QACnB,uBAAuB;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,6BAA6B;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;CACF;AAMD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+BAA+B;IAC/B,cAAc,EAAE,cAAc,CAAC;IAE/B,6DAA6D;IAC7D,cAAc,EAAE,mBAAmB,CAAC;IAEpC,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAMD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,GAAG,IAAI,CAmBf;AA0CD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,GAC3B,cAAc,CA4FhB;AAMD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAoC1D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,CA6ChE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAqCjE;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAiBN"}
|