@1mcp/agent 0.12.0 → 0.13.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 +22 -37
- package/build/auth/clientSessionManager.d.ts +94 -0
- package/build/auth/clientSessionManager.d.ts.map +1 -0
- package/build/auth/clientSessionManager.js +220 -0
- package/build/auth/clientSessionManager.js.map +1 -0
- package/build/auth/sdkOAuthClientProvider.d.ts +93 -0
- package/build/auth/sdkOAuthClientProvider.d.ts.map +1 -0
- package/build/auth/sdkOAuthClientProvider.js +199 -0
- package/build/auth/sdkOAuthClientProvider.js.map +1 -0
- package/build/auth/sdkOAuthServerProvider.d.ts +63 -0
- package/build/auth/sdkOAuthServerProvider.d.ts.map +1 -0
- package/build/auth/sdkOAuthServerProvider.js +428 -0
- package/build/auth/sdkOAuthServerProvider.js.map +1 -0
- package/build/auth/{sessionManager.d.ts → serverSessionManager.d.ts} +24 -36
- package/build/auth/serverSessionManager.d.ts.map +1 -0
- package/build/auth/{sessionManager.js → serverSessionManager.js} +77 -24
- package/build/auth/serverSessionManager.js.map +1 -0
- package/build/auth/sessionTypes.d.ts +24 -0
- package/build/auth/sessionTypes.d.ts.map +1 -0
- package/build/auth/sessionTypes.js +3 -0
- package/build/auth/sessionTypes.js.map +1 -0
- package/build/capabilities/capabilityManager.d.ts +2 -2
- package/build/capabilities/capabilityManager.d.ts.map +1 -1
- package/build/capabilities/capabilityManager.js +1 -1
- package/build/capabilities/capabilityManager.js.map +1 -1
- package/build/config/{configManager.d.ts → mcpConfigManager.d.ts} +11 -6
- package/build/config/mcpConfigManager.d.ts.map +1 -0
- package/build/config/{configManager.js → mcpConfigManager.js} +26 -8
- package/build/config/mcpConfigManager.js.map +1 -0
- package/build/constants.d.ts +36 -14
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +40 -17
- package/build/constants.js.map +1 -1
- package/build/core/client/clientManager.d.ts +14 -6
- package/build/core/client/clientManager.d.ts.map +1 -1
- package/build/core/client/clientManager.js +90 -28
- package/build/core/client/clientManager.js.map +1 -1
- package/build/core/server/{serverConfig.d.ts → agentConfig.d.ts} +50 -15
- package/build/core/server/agentConfig.d.ts.map +1 -0
- package/build/core/server/agentConfig.js +166 -0
- package/build/core/server/agentConfig.js.map +1 -0
- package/build/core/server/serverManager.d.ts +12 -5
- package/build/core/server/serverManager.d.ts.map +1 -1
- package/build/core/server/serverManager.js +12 -2
- package/build/core/server/serverManager.js.map +1 -1
- package/build/core/types/client.d.ts +22 -9
- package/build/core/types/client.d.ts.map +1 -1
- package/build/core/types/client.js +2 -0
- package/build/core/types/client.js.map +1 -1
- package/build/core/types/server.d.ts +3 -3
- package/build/core/types/server.d.ts.map +1 -1
- package/build/core/types/transport.d.ts +58 -0
- package/build/core/types/transport.d.ts.map +1 -1
- package/build/core/types/transport.js +10 -0
- package/build/core/types/transport.js.map +1 -1
- package/build/handlers/notificationHandlers.d.ts +3 -3
- package/build/handlers/notificationHandlers.d.ts.map +1 -1
- package/build/handlers/notificationHandlers.js +2 -2
- package/build/handlers/notificationHandlers.js.map +1 -1
- package/build/handlers/requestHandlers.d.ts +2 -2
- package/build/handlers/requestHandlers.d.ts.map +1 -1
- package/build/handlers/requestHandlers.js +4 -3
- package/build/handlers/requestHandlers.js.map +1 -1
- package/build/index.js +47 -7
- package/build/index.js.map +1 -1
- package/build/{transport/http/middleware/loggingMiddleware.d.ts → logger/mcpLoggingEnhancer.d.ts} +1 -1
- package/build/logger/mcpLoggingEnhancer.d.ts.map +1 -0
- package/build/{transport/http/middleware/loggingMiddleware.js → logger/mcpLoggingEnhancer.js} +2 -2
- package/build/logger/mcpLoggingEnhancer.js.map +1 -0
- package/build/server.js +4 -4
- package/build/server.js.map +1 -1
- package/build/services/configReloadService.d.ts +2 -2
- package/build/services/configReloadService.d.ts.map +1 -1
- package/build/services/configReloadService.js +4 -4
- package/build/services/configReloadService.js.map +1 -1
- package/build/transport/http/middlewares/errorHandler.d.ts.map +1 -0
- package/build/transport/http/{errorHandler.js → middlewares/errorHandler.js} +1 -1
- package/build/transport/http/middlewares/errorHandler.js.map +1 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.d.ts +42 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.js +136 -0
- package/build/transport/http/middlewares/scopeAuthMiddleware.js.map +1 -0
- package/build/transport/http/middlewares/securityMiddleware.d.ts +30 -0
- package/build/transport/http/middlewares/securityMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/securityMiddleware.js +201 -0
- package/build/transport/http/middlewares/securityMiddleware.js.map +1 -0
- package/build/transport/http/middlewares/tagsExtractor.d.ts.map +1 -0
- package/build/transport/http/middlewares/tagsExtractor.js.map +1 -0
- package/build/transport/http/routes/oauthRoutes.d.ts +3 -13
- package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/oauthRoutes.js +459 -117
- package/build/transport/http/routes/oauthRoutes.js.map +1 -1
- package/build/transport/http/routes/sseRoutes.d.ts +2 -2
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/sseRoutes.js +9 -7
- package/build/transport/http/routes/sseRoutes.js.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +2 -2
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.js +16 -10
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
- package/build/transport/http/server.d.ts +3 -2
- package/build/transport/http/server.d.ts.map +1 -1
- package/build/transport/http/server.js +58 -21
- package/build/transport/http/server.js.map +1 -1
- package/build/transport/transportFactory.d.ts +9 -0
- package/build/transport/transportFactory.d.ts.map +1 -0
- package/build/transport/transportFactory.js +148 -0
- package/build/transport/transportFactory.js.map +1 -0
- package/build/utils/clientFiltering.d.ts +4 -4
- package/build/utils/clientFiltering.d.ts.map +1 -1
- package/build/utils/clientFiltering.js +14 -14
- package/build/utils/clientFiltering.js.map +1 -1
- package/build/utils/errorHandling.d.ts +0 -12
- package/build/utils/errorHandling.d.ts.map +1 -1
- package/build/utils/errorHandling.js +1 -42
- package/build/utils/errorHandling.js.map +1 -1
- package/build/utils/pagination.d.ts +2 -2
- package/build/utils/pagination.d.ts.map +1 -1
- package/build/utils/pagination.js +4 -4
- package/build/utils/pagination.js.map +1 -1
- package/build/utils/parsing.d.ts +13 -0
- package/build/utils/parsing.d.ts.map +1 -0
- package/build/utils/parsing.js +32 -0
- package/build/utils/parsing.js.map +1 -0
- package/build/utils/sanitization.d.ts +60 -0
- package/build/utils/sanitization.d.ts.map +1 -0
- package/build/utils/sanitization.js +149 -0
- package/build/utils/sanitization.js.map +1 -0
- package/build/utils/scopeValidation.d.ts +102 -0
- package/build/utils/scopeValidation.d.ts.map +1 -0
- package/build/utils/scopeValidation.js +244 -0
- package/build/utils/scopeValidation.js.map +1 -0
- package/package.json +20 -11
- package/build/auth/authManager.d.ts +0 -109
- package/build/auth/authManager.d.ts.map +0 -1
- package/build/auth/authManager.js +0 -173
- package/build/auth/authManager.js.map +0 -1
- package/build/auth/authMiddleware.d.ts +0 -16
- package/build/auth/authMiddleware.d.ts.map +0 -1
- package/build/auth/authMiddleware.js +0 -45
- package/build/auth/authMiddleware.js.map +0 -1
- package/build/auth/sessionManager.d.ts.map +0 -1
- package/build/auth/sessionManager.js.map +0 -1
- package/build/config/configManager.d.ts.map +0 -1
- package/build/config/configManager.js.map +0 -1
- package/build/core/server/serverConfig.d.ts.map +0 -1
- package/build/core/server/serverConfig.js +0 -117
- package/build/core/server/serverConfig.js.map +0 -1
- package/build/transport/config.d.ts +0 -7
- package/build/transport/config.d.ts.map +0 -1
- package/build/transport/config.js +0 -90
- package/build/transport/config.js.map +0 -1
- package/build/transport/http/errorHandler.d.ts.map +0 -1
- package/build/transport/http/errorHandler.js.map +0 -1
- package/build/transport/http/middleware/loggingMiddleware.d.ts.map +0 -1
- package/build/transport/http/middleware/loggingMiddleware.js.map +0 -1
- package/build/utils/tagsExtractor.d.ts.map +0 -1
- package/build/utils/tagsExtractor.js.map +0 -1
- /package/build/transport/http/{errorHandler.d.ts → middlewares/errorHandler.d.ts} +0 -0
- /package/build/{utils → transport/http/middlewares}/tagsExtractor.d.ts +0 -0
- /package/build/{utils → transport/http/middlewares}/tagsExtractor.js +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import logger from '../logger/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Security constants for scope validation
|
|
4
|
+
*/
|
|
5
|
+
export const SCOPE_VALIDATION_CONFIG = {
|
|
6
|
+
/** Maximum allowed length for a single scope */
|
|
7
|
+
MAX_SCOPE_LENGTH: 100,
|
|
8
|
+
/** Maximum number of scopes per request */
|
|
9
|
+
MAX_SCOPES_COUNT: 50,
|
|
10
|
+
/** Valid tag name pattern: alphanumeric, underscore, hyphen only */
|
|
11
|
+
TAG_NAME_PATTERN: /^[a-zA-Z0-9_-]+$/,
|
|
12
|
+
/** Valid tag scope pattern: tag: prefix followed by valid tag name */
|
|
13
|
+
TAG_SCOPE_PATTERN: /^tag:[a-zA-Z0-9_-]+$/,
|
|
14
|
+
/** Minimum tag name length */
|
|
15
|
+
MIN_TAG_LENGTH: 1,
|
|
16
|
+
/** Maximum tag name length */
|
|
17
|
+
MAX_TAG_LENGTH: 50,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Validates if a string is a valid tag name
|
|
21
|
+
* @param tagName - The tag name to validate
|
|
22
|
+
* @returns True if valid, false otherwise
|
|
23
|
+
*/
|
|
24
|
+
export function isValidTagName(tagName) {
|
|
25
|
+
if (!tagName || typeof tagName !== 'string') {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
// Check length constraints
|
|
29
|
+
if (tagName.length < SCOPE_VALIDATION_CONFIG.MIN_TAG_LENGTH ||
|
|
30
|
+
tagName.length > SCOPE_VALIDATION_CONFIG.MAX_TAG_LENGTH) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// Check pattern
|
|
34
|
+
return SCOPE_VALIDATION_CONFIG.TAG_NAME_PATTERN.test(tagName);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validates if a string is a valid tag scope
|
|
38
|
+
* @param scope - The scope to validate
|
|
39
|
+
* @returns True if valid, false otherwise
|
|
40
|
+
*/
|
|
41
|
+
export function isValidTagScope(scope) {
|
|
42
|
+
if (!scope || typeof scope !== 'string') {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
// Check length constraints
|
|
46
|
+
if (scope.length > SCOPE_VALIDATION_CONFIG.MAX_SCOPE_LENGTH) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Check pattern
|
|
50
|
+
if (!SCOPE_VALIDATION_CONFIG.TAG_SCOPE_PATTERN.test(scope)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
// Extract and validate tag name
|
|
54
|
+
const tagName = scope.slice(4); // Remove "tag:" prefix
|
|
55
|
+
return isValidTagName(tagName);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Safely extracts tag name from a tag scope
|
|
59
|
+
* @param scope - The scope string (e.g., "tag:web")
|
|
60
|
+
* @returns The tag name if valid, null otherwise
|
|
61
|
+
*/
|
|
62
|
+
export function extractTagFromScope(scope) {
|
|
63
|
+
if (!isValidTagScope(scope)) {
|
|
64
|
+
logger.warn(`Invalid tag scope format: ${scope}`);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return scope.slice(4); // Remove "tag:" prefix
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Parses a scope string into its components
|
|
71
|
+
* @param scope - The scope string to parse
|
|
72
|
+
* @returns Parsed scope object or null if invalid
|
|
73
|
+
*/
|
|
74
|
+
export function parseScope(scope) {
|
|
75
|
+
if (!scope || typeof scope !== 'string') {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// Currently only supporting tag scopes
|
|
79
|
+
if (scope.startsWith('tag:')) {
|
|
80
|
+
const tagName = extractTagFromScope(scope);
|
|
81
|
+
if (!tagName) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return { type: 'tag', value: tagName };
|
|
85
|
+
}
|
|
86
|
+
// Future: Add support for other scope types (capability:, resource:, etc.)
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validates an array of scopes for format and security
|
|
91
|
+
* @param scopes - Array of scope strings to validate
|
|
92
|
+
* @returns Validation result with details
|
|
93
|
+
*/
|
|
94
|
+
export function validateScopes(scopes) {
|
|
95
|
+
const result = {
|
|
96
|
+
isValid: true,
|
|
97
|
+
errors: [],
|
|
98
|
+
validScopes: [],
|
|
99
|
+
invalidScopes: [],
|
|
100
|
+
};
|
|
101
|
+
// Check for null/undefined input
|
|
102
|
+
if (!scopes || !Array.isArray(scopes)) {
|
|
103
|
+
result.isValid = false;
|
|
104
|
+
result.errors.push('Scopes must be an array');
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
// Check count limits
|
|
108
|
+
if (scopes.length > SCOPE_VALIDATION_CONFIG.MAX_SCOPES_COUNT) {
|
|
109
|
+
result.isValid = false;
|
|
110
|
+
result.errors.push(`Too many scopes: ${scopes.length} > ${SCOPE_VALIDATION_CONFIG.MAX_SCOPES_COUNT}`);
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
// Validate each scope
|
|
114
|
+
const seenScopes = new Set();
|
|
115
|
+
for (const scope of scopes) {
|
|
116
|
+
// Check for duplicates
|
|
117
|
+
if (seenScopes.has(scope)) {
|
|
118
|
+
result.errors.push(`Duplicate scope: ${scope}`);
|
|
119
|
+
result.invalidScopes.push(scope);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
seenScopes.add(scope);
|
|
123
|
+
// Validate scope format
|
|
124
|
+
if (isValidTagScope(scope)) {
|
|
125
|
+
result.validScopes.push(scope);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
result.errors.push(`Invalid scope format: ${scope}`);
|
|
129
|
+
result.invalidScopes.push(scope);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Set overall validity
|
|
133
|
+
result.isValid = result.errors.length === 0;
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Validates that requested scopes are available (allowlist approach)
|
|
138
|
+
* @param requestedScopes - Scopes requested by client
|
|
139
|
+
* @param availableTags - Tags available on the server
|
|
140
|
+
* @returns Validation result
|
|
141
|
+
*/
|
|
142
|
+
export function validateScopesAgainstAvailableTags(requestedScopes, availableTags) {
|
|
143
|
+
const result = {
|
|
144
|
+
isValid: true,
|
|
145
|
+
errors: [],
|
|
146
|
+
validScopes: [],
|
|
147
|
+
invalidScopes: [],
|
|
148
|
+
};
|
|
149
|
+
// First validate scope formats
|
|
150
|
+
const formatValidation = validateScopes(requestedScopes);
|
|
151
|
+
if (!formatValidation.isValid) {
|
|
152
|
+
return formatValidation;
|
|
153
|
+
}
|
|
154
|
+
// Create set of available tags for fast lookup
|
|
155
|
+
const availableTagSet = new Set(availableTags);
|
|
156
|
+
// Check each scope against available tags
|
|
157
|
+
for (const scope of requestedScopes) {
|
|
158
|
+
const tagName = extractTagFromScope(scope);
|
|
159
|
+
if (!tagName) {
|
|
160
|
+
result.errors.push(`Invalid scope format: ${scope}`);
|
|
161
|
+
result.invalidScopes.push(scope);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (availableTagSet.has(tagName)) {
|
|
165
|
+
result.validScopes.push(scope);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
result.errors.push(`Scope not available: ${scope} (tag: ${tagName})`);
|
|
169
|
+
result.invalidScopes.push(scope);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
result.isValid = result.errors.length === 0;
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Checks if granted scopes satisfy the requirements for requested tags
|
|
177
|
+
* @param grantedScopes - Scopes granted during OAuth flow
|
|
178
|
+
* @param requestedTags - Tags requested for current operation
|
|
179
|
+
* @returns True if all requested tags are covered by granted scopes
|
|
180
|
+
*/
|
|
181
|
+
export function hasRequiredScopes(grantedScopes, requestedTags) {
|
|
182
|
+
// Fail-secure: deny if inputs are invalid
|
|
183
|
+
if (!grantedScopes || !Array.isArray(grantedScopes) || !requestedTags || !Array.isArray(requestedTags)) {
|
|
184
|
+
logger.warn('Invalid input to hasRequiredScopes', { grantedScopes, requestedTags });
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
// No tags requested means access is allowed
|
|
188
|
+
if (requestedTags.length === 0) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
// Extract tags from granted scopes
|
|
192
|
+
const grantedTags = grantedScopes
|
|
193
|
+
.map((scope) => extractTagFromScope(scope))
|
|
194
|
+
.filter((tag) => tag !== null);
|
|
195
|
+
// Check if all requested tags are in granted tags
|
|
196
|
+
const hasAllTags = requestedTags.every((tag) => grantedTags.includes(tag));
|
|
197
|
+
if (!hasAllTags) {
|
|
198
|
+
logger.warn('Insufficient scopes for requested tags', {
|
|
199
|
+
grantedTags,
|
|
200
|
+
requestedTags,
|
|
201
|
+
missing: requestedTags.filter((tag) => !grantedTags.includes(tag)),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return hasAllTags;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Converts tags to their corresponding scopes
|
|
208
|
+
* @param tags - Array of tag names
|
|
209
|
+
* @returns Array of tag scopes
|
|
210
|
+
*/
|
|
211
|
+
export function tagsToScopes(tags) {
|
|
212
|
+
if (!tags || !Array.isArray(tags)) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
return tags.filter((tag) => isValidTagName(tag)).map((tag) => `tag:${tag}`);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Converts scopes to their corresponding tags
|
|
219
|
+
* @param scopes - Array of scope strings
|
|
220
|
+
* @returns Array of tag names
|
|
221
|
+
*/
|
|
222
|
+
export function scopesToTags(scopes) {
|
|
223
|
+
if (!scopes || !Array.isArray(scopes)) {
|
|
224
|
+
return [];
|
|
225
|
+
}
|
|
226
|
+
return scopes.map((scope) => extractTagFromScope(scope)).filter((tag) => tag !== null);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Security utility to audit scope operations
|
|
230
|
+
* @param operation - The operation being performed
|
|
231
|
+
* @param context - Additional context for logging
|
|
232
|
+
*/
|
|
233
|
+
export function auditScopeOperation(operation, context) {
|
|
234
|
+
logger.info(`Scope operation: ${operation}`, {
|
|
235
|
+
operation,
|
|
236
|
+
clientId: context.clientId,
|
|
237
|
+
requestedScopes: context.requestedScopes,
|
|
238
|
+
grantedScopes: context.grantedScopes,
|
|
239
|
+
success: context.success,
|
|
240
|
+
error: context.error,
|
|
241
|
+
timestamp: new Date().toISOString(),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=scopeValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeValidation.js","sourceRoot":"","sources":["../../src/utils/scopeValidation.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,qBAAqB,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,gDAAgD;IAChD,gBAAgB,EAAE,GAAG;IACrB,2CAA2C;IAC3C,gBAAgB,EAAE,EAAE;IACpB,oEAAoE;IACpE,gBAAgB,EAAE,kBAAkB;IACpC,sEAAsE;IACtE,iBAAiB,EAAE,sBAAsB;IACzC,8BAA8B;IAC9B,cAAc,EAAE,CAAC;IACjB,8BAA8B;IAC9B,cAAc,EAAE,EAAE;CACV,CAAC;AAoBX;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2BAA2B;IAC3B,IACE,OAAO,CAAC,MAAM,GAAG,uBAAuB,CAAC,cAAc;QACvD,OAAO,CAAC,MAAM,GAAG,uBAAuB,CAAC,cAAc,EACvD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gBAAgB;IAChB,OAAO,uBAAuB,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2BAA2B;IAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,uBAAuB,CAAC,gBAAgB,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gBAAgB;IAChB,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gCAAgC;IAChC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;IACvD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uCAAuC;IACvC,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC;IAED,2EAA2E;IAC3E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,MAAM,MAAM,GAA0B;QACpC,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,EAAE;KAClB,CAAC;IAEF,iCAAiC;IACjC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,CAAC,MAAM,GAAG,uBAAuB,CAAC,gBAAgB,EAAE,CAAC;QAC7D,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,MAAM,MAAM,uBAAuB,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACtG,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,sBAAsB;IACtB,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,uBAAuB;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC;YAChD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEtB,wBAAwB;QACxB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;YACrD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAE5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kCAAkC,CAChD,eAAyB,EACzB,aAAuB;IAEvB,MAAM,MAAM,GAA0B;QACpC,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,EAAE;KAClB,CAAC;IAEF,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IACzD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC9B,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAE/C,0CAA0C;IAC1C,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;YACrD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QAED,IAAI,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,KAAK,UAAU,OAAO,GAAG,CAAC,CAAC;YACtE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAE5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAuB,EAAE,aAAuB;IAChF,0CAA0C;IAC1C,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QACvG,MAAM,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC;QACpF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4CAA4C;IAC5C,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mCAAmC;IACnC,MAAM,WAAW,GAAG,aAAa;SAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;SAC1C,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAa,CAAC;IAE7C,kDAAkD;IAClD,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAE3E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;YACpD,WAAW;YACX,aAAa;YACb,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SACnE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAgB;IAC3C,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAa,CAAC;AACrG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,OAMC;IAED,MAAM,CAAC,IAAI,CAAC,oBAAoB,SAAS,EAAE,EAAE;QAC3C,SAAS;QACT,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1mcp/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "One MCP server to aggregate them all - A unified Model Context Protocol server implementation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -42,6 +42,9 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"lint-staged": {
|
|
45
|
+
"*.ts": [
|
|
46
|
+
"bash -c 'tsc --noEmit --project tsconfig.test.json'"
|
|
47
|
+
],
|
|
45
48
|
"*.{js,ts}": [
|
|
46
49
|
"eslint --fix",
|
|
47
50
|
"prettier --write"
|
|
@@ -51,7 +54,7 @@
|
|
|
51
54
|
]
|
|
52
55
|
},
|
|
53
56
|
"dependencies": {
|
|
54
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
57
|
+
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
55
58
|
"body-parser": "^2.2.0",
|
|
56
59
|
"cors": "^2.8.5",
|
|
57
60
|
"express": "^5.1.0",
|
|
@@ -76,6 +79,7 @@
|
|
|
76
79
|
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
|
77
80
|
"@typescript-eslint/parser": "^8.27.0",
|
|
78
81
|
"@vitest/coverage-v8": "^1.4.0",
|
|
82
|
+
"axios": "^1.10.0",
|
|
79
83
|
"eslint": "^9.22.0",
|
|
80
84
|
"eslint-config-prettier": "^10.1.1",
|
|
81
85
|
"eslint-plugin-prettier": "^5.2.3",
|
|
@@ -85,21 +89,26 @@
|
|
|
85
89
|
"lint-staged": "^16.1.2",
|
|
86
90
|
"prettier": "^3.5.3",
|
|
87
91
|
"ts-node": "^10.9.2",
|
|
88
|
-
"tsc-watch": "^
|
|
92
|
+
"tsc-watch": "^7.1.1",
|
|
89
93
|
"typescript": "^5.3.3",
|
|
94
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
90
95
|
"vitest": "^1.4.0"
|
|
91
96
|
},
|
|
92
97
|
"scripts": {
|
|
93
|
-
"dev": "tsc-watch --onSuccess \"node build/index.js --config ./mcp.json --port 3051 --auth\"",
|
|
94
|
-
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
|
95
|
-
"
|
|
96
|
-
"watch": "tsc --watch",
|
|
98
|
+
"dev": "LOG_LEVEL=debug tsc-watch --project tsconfig.build.json --onSuccess \"node build/index.js --config ./mcp.json --port 3051 --enable-auth\"",
|
|
99
|
+
"build": "tsc --project tsconfig.build.json && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
|
100
|
+
"watch": "tsc --watch --project tsconfig.build.json",
|
|
97
101
|
"inspector": "npx -y @modelcontextprotocol/inspector",
|
|
98
102
|
"lint": "eslint . --ext .ts",
|
|
99
103
|
"lint:fix": "eslint . --ext .ts --fix",
|
|
100
|
-
"format": "prettier --write \"src/**/*.{js,ts}\"",
|
|
101
|
-
"
|
|
102
|
-
"test:
|
|
103
|
-
"test:
|
|
104
|
+
"format": "prettier --write \"src/**/*.{js,ts}\" \"test/**/*.{js,ts}\"",
|
|
105
|
+
"typecheck": "tsc --noEmit --project tsconfig.test.json",
|
|
106
|
+
"test": "pnpm test:unit && pnpm test:e2e",
|
|
107
|
+
"test:unit": "vitest run",
|
|
108
|
+
"test:unit:watch": "vitest",
|
|
109
|
+
"test:unit:coverage": "vitest run --coverage",
|
|
110
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
111
|
+
"test:e2e:watch": "vitest --config vitest.e2e.config.ts",
|
|
112
|
+
"test:e2e:coverage": "vitest run --config vitest.e2e.config.ts --coverage"
|
|
104
113
|
}
|
|
105
114
|
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { SessionData } from './sessionManager.js';
|
|
2
|
-
/**
|
|
3
|
-
* AuthManager handles OAuth 2.1 authentication flow and token validation.
|
|
4
|
-
*
|
|
5
|
-
* This class orchestrates the OAuth 2.1 authorization code grant flow,
|
|
6
|
-
* manages access token validation, and provides session information.
|
|
7
|
-
* It integrates with SessionManager for persistent storage and
|
|
8
|
-
* ServerConfigManager for configuration settings.
|
|
9
|
-
*
|
|
10
|
-
* Features:
|
|
11
|
-
* - OAuth 2.1 authorization code grant flow
|
|
12
|
-
* - Access token validation with prefix support
|
|
13
|
-
* - Session information retrieval
|
|
14
|
-
* - Configurable authentication settings
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* const authManager = new AuthManager('/custom/sessions');
|
|
19
|
-
* const token = authManager.exchangeCodeForToken('code-123', 'client-456');
|
|
20
|
-
* const session = authManager.validateAccessToken('tk-sess-789');
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export declare class AuthManager {
|
|
24
|
-
private sessionManager;
|
|
25
|
-
private configManager;
|
|
26
|
-
/**
|
|
27
|
-
* Creates a new AuthManager instance.
|
|
28
|
-
*
|
|
29
|
-
* Initializes the session manager with optional custom storage path
|
|
30
|
-
* and retrieves the server configuration manager instance.
|
|
31
|
-
*
|
|
32
|
-
* @param sessionStoragePath - Optional custom path for session storage
|
|
33
|
-
*/
|
|
34
|
-
constructor(sessionStoragePath?: string);
|
|
35
|
-
/**
|
|
36
|
-
* Checks if authentication is currently enabled.
|
|
37
|
-
*
|
|
38
|
-
* @returns True if OAuth 2.1 authentication is enabled, false otherwise
|
|
39
|
-
*/
|
|
40
|
-
isAuthEnabled(): boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Validates an access token and returns session data.
|
|
43
|
-
*
|
|
44
|
-
* If authentication is disabled, returns null (always valid).
|
|
45
|
-
* For enabled authentication, strips the token prefix if present
|
|
46
|
-
* and validates the underlying session.
|
|
47
|
-
*
|
|
48
|
-
* @param token - The access token to validate (with or without prefix)
|
|
49
|
-
* @returns Session data if token is valid, null otherwise
|
|
50
|
-
*/
|
|
51
|
-
validateAccessToken(token: string): SessionData | null;
|
|
52
|
-
/**
|
|
53
|
-
* Creates an authorization code for OAuth 2.1 flow.
|
|
54
|
-
*
|
|
55
|
-
* Delegates to the session manager to create a prefixed authorization
|
|
56
|
-
* code with the configured time-to-live.
|
|
57
|
-
*
|
|
58
|
-
* @param clientId - The client identifier
|
|
59
|
-
* @param redirectUri - The redirect URI for this code
|
|
60
|
-
* @param resource - The resource this code grants access to
|
|
61
|
-
* @returns The generated authorization code with prefix
|
|
62
|
-
*/
|
|
63
|
-
createAuthCode(clientId: string, redirectUri: string, resource: string): string;
|
|
64
|
-
/**
|
|
65
|
-
* Exchanges an authorization code for an access token.
|
|
66
|
-
*
|
|
67
|
-
* Validates the authorization code, checks client ID and redirect URI
|
|
68
|
-
* matches, then creates a new access token with the configured TTL.
|
|
69
|
-
* The authorization code is deleted after successful exchange.
|
|
70
|
-
*
|
|
71
|
-
* @param code - The authorization code to exchange
|
|
72
|
-
* @param clientId - The client identifier
|
|
73
|
-
* @param redirectUri - Optional redirect URI for validation
|
|
74
|
-
* @param resource - Optional resource for validation
|
|
75
|
-
* @returns Access token with prefix if exchange successful, null otherwise
|
|
76
|
-
*/
|
|
77
|
-
exchangeCodeForToken(code: string, clientId: string, redirectUri?: string, resource?: string): string | null;
|
|
78
|
-
/**
|
|
79
|
-
* Gets information about an access token.
|
|
80
|
-
*
|
|
81
|
-
* Retrieves session data for the token and returns formatted
|
|
82
|
-
* information including client ID, resource, and time until expiration.
|
|
83
|
-
*
|
|
84
|
-
* @param token - The access token to get information for
|
|
85
|
-
* @returns Token information if valid, null otherwise
|
|
86
|
-
*/
|
|
87
|
-
getTokenInfo(token: string): {
|
|
88
|
-
clientId: string;
|
|
89
|
-
resource: string;
|
|
90
|
-
expiresIn: number;
|
|
91
|
-
} | null;
|
|
92
|
-
/**
|
|
93
|
-
* Revokes an access token.
|
|
94
|
-
*
|
|
95
|
-
* Removes the session associated with the token from storage.
|
|
96
|
-
*
|
|
97
|
-
* @param token - The access token to revoke
|
|
98
|
-
* @returns True if token was revoked, false if it didn't exist
|
|
99
|
-
*/
|
|
100
|
-
revokeToken(token: string): boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Performs graceful shutdown of the AuthManager.
|
|
103
|
-
*
|
|
104
|
-
* Delegates shutdown to the session manager to ensure proper
|
|
105
|
-
* cleanup of resources and timers.
|
|
106
|
-
*/
|
|
107
|
-
shutdown(): void;
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=authManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authManager.d.ts","sourceRoot":"","sources":["../../src/auth/authManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKlE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAsB;IAE3C;;;;;;;OAOG;gBACS,kBAAkB,CAAC,EAAE,MAAM;IAKvC;;;;OAIG;IACI,aAAa,IAAI,OAAO;IAI/B;;;;;;;;;OASG;IACI,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAmB7D;;;;;;;;;;OAUG;IACI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKtF;;;;;;;;;;;;OAYG;IACI,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAoCnH;;;;;;;;OAQG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAapG;;;;;;;OAOG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1C;;;;;OAKG;IACI,QAAQ,IAAI,IAAI;CAGxB"}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import logger from '../logger/logger.js';
|
|
2
|
-
import { SessionManager } from './sessionManager.js';
|
|
3
|
-
import { ServerConfigManager } from '../core/server/serverConfig.js';
|
|
4
|
-
import { AUTH_CONFIG } from '../constants.js';
|
|
5
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
-
/**
|
|
7
|
-
* AuthManager handles OAuth 2.1 authentication flow and token validation.
|
|
8
|
-
*
|
|
9
|
-
* This class orchestrates the OAuth 2.1 authorization code grant flow,
|
|
10
|
-
* manages access token validation, and provides session information.
|
|
11
|
-
* It integrates with SessionManager for persistent storage and
|
|
12
|
-
* ServerConfigManager for configuration settings.
|
|
13
|
-
*
|
|
14
|
-
* Features:
|
|
15
|
-
* - OAuth 2.1 authorization code grant flow
|
|
16
|
-
* - Access token validation with prefix support
|
|
17
|
-
* - Session information retrieval
|
|
18
|
-
* - Configurable authentication settings
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* const authManager = new AuthManager('/custom/sessions');
|
|
23
|
-
* const token = authManager.exchangeCodeForToken('code-123', 'client-456');
|
|
24
|
-
* const session = authManager.validateAccessToken('tk-sess-789');
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
export class AuthManager {
|
|
28
|
-
sessionManager;
|
|
29
|
-
configManager;
|
|
30
|
-
/**
|
|
31
|
-
* Creates a new AuthManager instance.
|
|
32
|
-
*
|
|
33
|
-
* Initializes the session manager with optional custom storage path
|
|
34
|
-
* and retrieves the server configuration manager instance.
|
|
35
|
-
*
|
|
36
|
-
* @param sessionStoragePath - Optional custom path for session storage
|
|
37
|
-
*/
|
|
38
|
-
constructor(sessionStoragePath) {
|
|
39
|
-
this.sessionManager = new SessionManager(sessionStoragePath);
|
|
40
|
-
this.configManager = ServerConfigManager.getInstance();
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Checks if authentication is currently enabled.
|
|
44
|
-
*
|
|
45
|
-
* @returns True if OAuth 2.1 authentication is enabled, false otherwise
|
|
46
|
-
*/
|
|
47
|
-
isAuthEnabled() {
|
|
48
|
-
return this.configManager.isAuthEnabled();
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Validates an access token and returns session data.
|
|
52
|
-
*
|
|
53
|
-
* If authentication is disabled, returns null (always valid).
|
|
54
|
-
* For enabled authentication, strips the token prefix if present
|
|
55
|
-
* and validates the underlying session.
|
|
56
|
-
*
|
|
57
|
-
* @param token - The access token to validate (with or without prefix)
|
|
58
|
-
* @returns Session data if token is valid, null otherwise
|
|
59
|
-
*/
|
|
60
|
-
validateAccessToken(token) {
|
|
61
|
-
if (!this.isAuthEnabled()) {
|
|
62
|
-
return null; // Auth disabled, always valid
|
|
63
|
-
}
|
|
64
|
-
if (!token) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
// Strip token prefix if present
|
|
68
|
-
const tokenId = token.startsWith(AUTH_CONFIG.PREFIXES.ACCESS_TOKEN)
|
|
69
|
-
? token.slice(AUTH_CONFIG.PREFIXES.ACCESS_TOKEN.length)
|
|
70
|
-
: token;
|
|
71
|
-
// Session is stored with 'sess-' + tokenId
|
|
72
|
-
const sessionId = AUTH_CONFIG.PREFIXES.SESSION_ID + tokenId;
|
|
73
|
-
return this.sessionManager.getSession(sessionId);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Creates an authorization code for OAuth 2.1 flow.
|
|
77
|
-
*
|
|
78
|
-
* Delegates to the session manager to create a prefixed authorization
|
|
79
|
-
* code with the configured time-to-live.
|
|
80
|
-
*
|
|
81
|
-
* @param clientId - The client identifier
|
|
82
|
-
* @param redirectUri - The redirect URI for this code
|
|
83
|
-
* @param resource - The resource this code grants access to
|
|
84
|
-
* @returns The generated authorization code with prefix
|
|
85
|
-
*/
|
|
86
|
-
createAuthCode(clientId, redirectUri, resource) {
|
|
87
|
-
const ttlMs = this.configManager.getOAuthCodeTtlMs();
|
|
88
|
-
return this.sessionManager.createAuthCode(clientId, redirectUri, resource, ttlMs);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Exchanges an authorization code for an access token.
|
|
92
|
-
*
|
|
93
|
-
* Validates the authorization code, checks client ID and redirect URI
|
|
94
|
-
* matches, then creates a new access token with the configured TTL.
|
|
95
|
-
* The authorization code is deleted after successful exchange.
|
|
96
|
-
*
|
|
97
|
-
* @param code - The authorization code to exchange
|
|
98
|
-
* @param clientId - The client identifier
|
|
99
|
-
* @param redirectUri - Optional redirect URI for validation
|
|
100
|
-
* @param resource - Optional resource for validation
|
|
101
|
-
* @returns Access token with prefix if exchange successful, null otherwise
|
|
102
|
-
*/
|
|
103
|
-
exchangeCodeForToken(code, clientId, redirectUri, resource) {
|
|
104
|
-
const codeData = this.sessionManager.getAuthCode(code);
|
|
105
|
-
if (!codeData) {
|
|
106
|
-
logger.warn(`Invalid or expired auth code: ${code}`);
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
if (codeData.clientId !== clientId) {
|
|
110
|
-
logger.warn(`Client ID mismatch for code ${code}: expected ${codeData.clientId}, got ${clientId}`);
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
if (redirectUri && codeData.redirectUri !== redirectUri) {
|
|
114
|
-
logger.warn(`Redirect URI mismatch for code ${code}: expected ${codeData.redirectUri}, got ${redirectUri}`);
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
if (resource && codeData.resource && codeData.resource !== resource) {
|
|
118
|
-
logger.warn(`Resource mismatch for code ${code}: expected ${codeData.resource}, got ${resource}`);
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
// Delete the auth code after successful exchange
|
|
122
|
-
this.sessionManager.deleteAuthCode(code);
|
|
123
|
-
// Create access token with prefix and a new UUID
|
|
124
|
-
const rawTokenId = uuidv4();
|
|
125
|
-
const accessToken = AUTH_CONFIG.PREFIXES.ACCESS_TOKEN + rawTokenId;
|
|
126
|
-
const ttlMs = this.configManager.getOAuthTokenTtlMs();
|
|
127
|
-
// Store the session using the rawTokenId (not prefixed)
|
|
128
|
-
this.sessionManager.createSessionWithId(rawTokenId, clientId, codeData.resource, ttlMs);
|
|
129
|
-
logger.info(`Exchanged code ${code} for token ${accessToken} for client ${clientId}`);
|
|
130
|
-
return accessToken;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Gets information about an access token.
|
|
134
|
-
*
|
|
135
|
-
* Retrieves session data for the token and returns formatted
|
|
136
|
-
* information including client ID, resource, and time until expiration.
|
|
137
|
-
*
|
|
138
|
-
* @param token - The access token to get information for
|
|
139
|
-
* @returns Token information if valid, null otherwise
|
|
140
|
-
*/
|
|
141
|
-
getTokenInfo(token) {
|
|
142
|
-
const session = this.sessionManager.getSession(token);
|
|
143
|
-
if (!session) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
clientId: session.clientId,
|
|
148
|
-
resource: session.resource,
|
|
149
|
-
expiresIn: Math.max(0, Math.floor((session.expires - Date.now()) / 1000)),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Revokes an access token.
|
|
154
|
-
*
|
|
155
|
-
* Removes the session associated with the token from storage.
|
|
156
|
-
*
|
|
157
|
-
* @param token - The access token to revoke
|
|
158
|
-
* @returns True if token was revoked, false if it didn't exist
|
|
159
|
-
*/
|
|
160
|
-
revokeToken(token) {
|
|
161
|
-
return this.sessionManager.deleteSession(token);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Performs graceful shutdown of the AuthManager.
|
|
165
|
-
*
|
|
166
|
-
* Delegates shutdown to the session manager to ensure proper
|
|
167
|
-
* cleanup of resources and timers.
|
|
168
|
-
*/
|
|
169
|
-
shutdown() {
|
|
170
|
-
this.sessionManager.shutdown();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
//# sourceMappingURL=authManager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authManager.js","sourceRoot":"","sources":["../../src/auth/authManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { AuthManager } from './authManager.js';
|
|
3
|
-
export declare function createAuthMiddleware(authManager: AuthManager): (req: express.Request, res: express.Response, next: express.NextFunction) => void;
|
|
4
|
-
declare global {
|
|
5
|
-
namespace Express {
|
|
6
|
-
interface Request {
|
|
7
|
-
sessionData?: {
|
|
8
|
-
clientId: string;
|
|
9
|
-
resource: string;
|
|
10
|
-
expires: number;
|
|
11
|
-
createdAt: number;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=authMiddleware.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/auth/authMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,WAAW,IACnD,KAAK,OAAO,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,YAAY,UA8ChF;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,WAAW,CAAC,EAAE;gBACZ,QAAQ,EAAE,MAAM,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAC;gBACjB,OAAO,EAAE,MAAM,CAAC;gBAChB,SAAS,EAAE,MAAM,CAAC;aACnB,CAAC;SACH;KACF;CACF"}
|