@1mcp/agent 0.11.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 +45 -50
- 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/{server/auth/sessionManager.d.ts → auth/serverSessionManager.d.ts} +26 -37
- package/build/auth/serverSessionManager.d.ts.map +1 -0
- package/build/{server/auth/sessionManager.js → auth/serverSessionManager.js} +104 -19
- 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 +40 -7
- package/build/capabilities/capabilityManager.js.map +1 -1
- package/build/config/{configManager.d.ts → mcpConfigManager.d.ts} +18 -7
- package/build/config/mcpConfigManager.d.ts.map +1 -0
- package/build/config/{configManager.js → mcpConfigManager.js} +50 -10
- 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/{client.d.ts → core/client/clientFactory.d.ts} +1 -1
- package/build/core/client/clientFactory.d.ts.map +1 -0
- package/build/{client.js → core/client/clientFactory.js} +2 -2
- package/build/core/client/clientFactory.js.map +1 -0
- package/build/{clients → core/client}/clientManager.d.ts +14 -6
- package/build/core/client/clientManager.d.ts.map +1 -0
- package/build/core/client/clientManager.js +209 -0
- package/build/core/client/clientManager.js.map +1 -0
- package/build/{server/config/serverConfig.d.ts → core/server/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 +39 -0
- package/build/core/server/serverManager.d.ts.map +1 -0
- package/build/core/server/serverManager.js +169 -0
- package/build/core/server/serverManager.js.map +1 -0
- package/build/core/types/client.d.ts +51 -0
- package/build/core/types/client.d.ts.map +1 -0
- package/build/core/types/client.js +15 -0
- package/build/core/types/client.js.map +1 -0
- package/build/core/types/index.d.ts +4 -0
- package/build/core/types/index.d.ts.map +1 -0
- package/build/core/types/index.js +5 -0
- package/build/core/types/index.js.map +1 -0
- package/build/core/types/server.d.ts +14 -0
- package/build/core/types/server.d.ts.map +1 -0
- package/build/core/types/server.js +2 -0
- package/build/core/types/server.js.map +1 -0
- package/build/{types.d.ts → core/types/transport.d.ts} +59 -49
- package/build/core/types/transport.d.ts.map +1 -0
- package/build/{types.js → core/types/transport.js} +11 -13
- package/build/core/types/transport.js.map +1 -0
- package/build/handlers/notificationHandlers.d.ts +3 -3
- package/build/handlers/notificationHandlers.d.ts.map +1 -1
- package/build/handlers/notificationHandlers.js +13 -9
- 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 +25 -3
- package/build/handlers/requestHandlers.js.map +1 -1
- package/build/index.js +48 -8
- package/build/index.js.map +1 -1
- package/build/logger/logger.js +1 -1
- package/build/logger/logger.js.map +1 -1
- package/build/{middleware/loggingMiddleware.d.ts → logger/mcpLoggingEnhancer.d.ts} +1 -1
- package/build/logger/mcpLoggingEnhancer.d.ts.map +1 -0
- package/build/{middleware/loggingMiddleware.js → logger/mcpLoggingEnhancer.js} +2 -2
- package/build/logger/mcpLoggingEnhancer.js.map +1 -0
- package/build/server.d.ts +1 -1
- package/build/server.d.ts.map +1 -1
- package/build/server.js +9 -6
- package/build/server.js.map +1 -1
- package/build/services/configReloadService.d.ts +15 -5
- package/build/services/configReloadService.d.ts.map +1 -1
- package/build/services/configReloadService.js +31 -14
- package/build/services/configReloadService.js.map +1 -1
- package/build/transport/http/middlewares/errorHandler.d.ts.map +1 -0
- package/build/{server → transport/http/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 +4 -0
- package/build/transport/http/routes/oauthRoutes.d.ts.map +1 -0
- package/build/transport/http/routes/oauthRoutes.js +474 -0
- package/build/transport/http/routes/oauthRoutes.js.map +1 -0
- package/build/transport/http/routes/sseRoutes.d.ts +4 -0
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -0
- package/build/{server → transport/http}/routes/sseRoutes.js +12 -10
- package/build/transport/http/routes/sseRoutes.js.map +1 -0
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +4 -0
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -0
- package/build/{server → transport/http}/routes/streamableHttpRoutes.js +46 -13
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -0
- package/build/{server/expressServer.d.ts → transport/http/server.d.ts} +5 -4
- package/build/transport/http/server.d.ts.map +1 -0
- package/build/{server/expressServer.js → transport/http/server.js} +60 -23
- package/build/transport/http/server.js.map +1 -0
- 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 -11
- package/build/utils/errorHandling.d.ts.map +1 -1
- package/build/utils/errorHandling.js +1 -18
- package/build/utils/errorHandling.js.map +1 -1
- package/build/utils/errorTypes.js +4 -4
- package/build/utils/errorTypes.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 +87 -8
- 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 +23 -9
- package/build/client.d.ts.map +0 -1
- package/build/client.js.map +0 -1
- package/build/clients/clientManager.d.ts.map +0 -1
- package/build/clients/clientManager.js +0 -147
- package/build/clients/clientManager.js.map +0 -1
- package/build/config/configManager.d.ts.map +0 -1
- package/build/config/configManager.js.map +0 -1
- package/build/config/transportConfig.d.ts +0 -7
- package/build/config/transportConfig.d.ts.map +0 -1
- package/build/config/transportConfig.js +0 -90
- package/build/config/transportConfig.js.map +0 -1
- package/build/middleware/loggingMiddleware.d.ts.map +0 -1
- package/build/middleware/loggingMiddleware.js.map +0 -1
- package/build/server/auth/authManager.d.ts +0 -109
- package/build/server/auth/authManager.d.ts.map +0 -1
- package/build/server/auth/authManager.js +0 -173
- package/build/server/auth/authManager.js.map +0 -1
- package/build/server/auth/authMiddleware.d.ts +0 -16
- package/build/server/auth/authMiddleware.d.ts.map +0 -1
- package/build/server/auth/authMiddleware.js +0 -45
- package/build/server/auth/authMiddleware.js.map +0 -1
- package/build/server/auth/sessionManager.d.ts.map +0 -1
- package/build/server/auth/sessionManager.js.map +0 -1
- package/build/server/config/serverConfig.d.ts.map +0 -1
- package/build/server/config/serverConfig.js +0 -117
- package/build/server/config/serverConfig.js.map +0 -1
- package/build/server/errorHandler.d.ts.map +0 -1
- package/build/server/errorHandler.js.map +0 -1
- package/build/server/expressServer.d.ts.map +0 -1
- package/build/server/expressServer.js.map +0 -1
- package/build/server/routes/oauthRoutes.d.ts +0 -14
- package/build/server/routes/oauthRoutes.d.ts.map +0 -1
- package/build/server/routes/oauthRoutes.js +0 -132
- package/build/server/routes/oauthRoutes.js.map +0 -1
- package/build/server/routes/sseRoutes.d.ts +0 -4
- package/build/server/routes/sseRoutes.d.ts.map +0 -1
- package/build/server/routes/sseRoutes.js.map +0 -1
- package/build/server/routes/streamableHttpRoutes.d.ts +0 -4
- package/build/server/routes/streamableHttpRoutes.d.ts.map +0 -1
- package/build/server/routes/streamableHttpRoutes.js.map +0 -1
- package/build/server/tagsExtractor.d.ts.map +0 -1
- package/build/server/tagsExtractor.js.map +0 -1
- package/build/serverManager.d.ts +0 -27
- package/build/serverManager.d.ts.map +0 -1
- package/build/serverManager.js +0 -87
- package/build/serverManager.js.map +0 -1
- package/build/types.d.ts.map +0 -1
- package/build/types.js.map +0 -1
- /package/build/{server → transport/http/middlewares}/errorHandler.d.ts +0 -0
- /package/build/{server → transport/http/middlewares}/tagsExtractor.d.ts +0 -0
- /package/build/{server → transport/http/middlewares}/tagsExtractor.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandling.d.ts","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"errorHandling.d.ts","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,SAAS,GAAG,EAAE,EACrD,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACjC,YAAY,EAAE,MAAM,GACnB,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAkB/B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CAUjF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAE/G;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKnD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKtD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAK/D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,CAAA;CAAE,CAa7F"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import logger from '../logger/logger.js';
|
|
3
|
-
import { MCPError
|
|
3
|
+
import { MCPError } from './errorTypes.js';
|
|
4
4
|
/**
|
|
5
5
|
* Wraps a function with error handling
|
|
6
6
|
* @param fn The function to wrap
|
|
@@ -100,21 +100,4 @@ export function formatErrorResponse(error) {
|
|
|
100
100
|
message: error instanceof Error ? error.message : String(error),
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Extracts client name and resource name from a URI
|
|
105
|
-
* @param uri The URI to parse
|
|
106
|
-
* @param separator The separator used in the URI
|
|
107
|
-
* @returns An object with clientName and resourceName
|
|
108
|
-
* @throws InvalidRequestError if the URI is invalid
|
|
109
|
-
*/
|
|
110
|
-
export function parseUri(uri, separator) {
|
|
111
|
-
const parts = uri.split(separator);
|
|
112
|
-
if (parts.length !== 2) {
|
|
113
|
-
throw new InvalidRequestError(`Invalid URI format: ${uri}`);
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
clientName: parts[0],
|
|
117
|
-
resourceName: parts[1],
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
103
|
//# sourceMappingURL=errorHandling.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAgB,
|
|
1
|
+
{"version":3,"file":"errorHandling.js","sourceRoot":"","sources":["../../src/utils/errorHandling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAgB,MAAM,iBAAiB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAiC,EACjC,YAAoB;IAEpB,OAAO,KAAK,EAAE,GAAG,IAAU,EAAc,EAAE;QACzC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,KAAK,EAAE,CAAC,CAAC;YAE1C,0BAA0B;YAC1B,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,mCAAmC;YACnC,MAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,aAAa,EAAE;gBACxD,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aACzE,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,YAAoB;IACjE,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,IAAI,YAAY,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,IAAI,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAqB,KAAc,EAAE,SAAoC;IACjG,OAAO,KAAK,YAAY,SAAS,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,SAAS,CAAC,aAAa,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,YAAY,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAC,KAAc,CAAC;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAU;IAC5C,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,aAAa;QAC7B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAChE,CAAC;AACJ,CAAC"}
|
|
@@ -11,13 +11,13 @@ export class MCPError extends Error {
|
|
|
11
11
|
}
|
|
12
12
|
export class ClientConnectionError extends MCPError {
|
|
13
13
|
constructor(clientName, cause) {
|
|
14
|
-
super(`Failed to connect to client ${clientName}: ${cause.message}`, ErrorCode.
|
|
14
|
+
super(`Failed to connect to client ${clientName}: ${cause.message}`, ErrorCode.ConnectionClosed, { cause });
|
|
15
15
|
this.name = 'ClientConnectionError';
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
export class ClientNotFoundError extends MCPError {
|
|
19
19
|
constructor(clientName) {
|
|
20
|
-
super(`Client '${clientName}' not found`, ErrorCode.
|
|
20
|
+
super(`Client '${clientName}' not found`, ErrorCode.MethodNotFound, { clientName });
|
|
21
21
|
this.name = 'ClientNotFoundError';
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -38,13 +38,13 @@ export class ValidationError extends MCPError {
|
|
|
38
38
|
}
|
|
39
39
|
export class TransportError extends MCPError {
|
|
40
40
|
constructor(transportName, cause) {
|
|
41
|
-
super(`Transport error for ${transportName}: ${cause.message}`, ErrorCode.
|
|
41
|
+
super(`Transport error for ${transportName}: ${cause.message}`, ErrorCode.InternalError, { cause });
|
|
42
42
|
this.name = 'TransportError';
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
export class InvalidRequestError extends MCPError {
|
|
46
46
|
constructor(message, data) {
|
|
47
|
-
super(message, ErrorCode.
|
|
47
|
+
super(message, ErrorCode.InvalidRequest, data);
|
|
48
48
|
this.name = 'InvalidRequestError';
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorTypes.js","sourceRoot":"","sources":["../../src/utils/errorTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAE/D,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,IAAI,CAAS;IACb,IAAI,CAAO;IAEX,YAAY,OAAe,EAAE,IAAY,EAAE,IAAU;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;IACjD,YAAY,UAAkB,EAAE,KAAY;QAC1C,KAAK,CAAC,+BAA+B,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"errorTypes.js","sourceRoot":"","sources":["../../src/utils/errorTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAE/D,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,IAAI,CAAS;IACb,IAAI,CAAO;IAEX,YAAY,OAAe,EAAE,IAAY,EAAE,IAAU;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,QAAQ;IACjD,YAAY,UAAkB,EAAE,KAAY;QAC1C,KAAK,CAAC,+BAA+B,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5G,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAC/C,YAAY,UAAkB;QAC5B,KAAK,CAAC,WAAW,UAAU,aAAa,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IAChD,YAAY,UAAkB,EAAE,SAAiB,EAAE,KAAY,EAAE,OAAiC;QAChG,KAAK,CAAC,aAAa,SAAS,qBAAqB,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,aAAa,EAAE;YACxG,KAAK;YACL,OAAO;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,OAAe,EAAE,gBAAqB;QAChD,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,aAAa,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAC1C,YAAY,aAAqB,EAAE,KAAY;QAC7C,KAAK,CAAC,uBAAuB,aAAa,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;IAC/C,YAAY,OAAe,EAAE,IAAU;QACrC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,QAAQ;IAC3C,YAAY,UAAkB,EAAE,UAAkB;QAChD,KAAK,CAAC,WAAW,UAAU,2BAA2B,UAAU,cAAc,EAAE,SAAS,CAAC,cAAc,EAAE;YACxG,UAAU;YACV,UAAU;SACX,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
2
|
import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
3
3
|
import { Resource, ResourceTemplate, Tool, Prompt } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
-
import {
|
|
4
|
+
import { OutboundConnection, OutboundConnections } from '../core/types/index.js';
|
|
5
5
|
interface PaginationParams {
|
|
6
6
|
[x: string]: unknown;
|
|
7
7
|
_meta?: {
|
|
@@ -26,6 +26,6 @@ export declare function parseCursor(cursor?: string): {
|
|
|
26
26
|
actualCursor?: string;
|
|
27
27
|
};
|
|
28
28
|
export declare function encodeCursor(clientName: string, nextCursor?: string): string | undefined;
|
|
29
|
-
export declare function handlePagination<T>(clients:
|
|
29
|
+
export declare function handlePagination<T>(clients: OutboundConnections, params: PaginationParams, callClientMethod: (client: Client, params: unknown, opts: RequestOptions) => Promise<PaginationResponse>, transformResult: (client: OutboundConnection, result: PaginationResponse) => T[], enablePagination: boolean): Promise<PaginationResult<T>>;
|
|
30
30
|
export {};
|
|
31
31
|
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGjF,UAAU,gBAAgB;IACxB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACrB,KAAK,CAAC,EACF;QACE,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KAC7C,GACD,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CA+C1F;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,GAAG,SAAS,CA+B5F;AAiCD,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,kBAAkB,CAAC,EACxG,eAAe,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,KAAK,CAAC,EAAE,EAChF,gBAAgB,EAAE,OAAO,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CA0D9B"}
|
|
@@ -1,13 +1,75 @@
|
|
|
1
1
|
import logger from '../logger/logger.js';
|
|
2
2
|
export function parseCursor(cursor) {
|
|
3
|
-
if (!cursor) {
|
|
3
|
+
if (!cursor || typeof cursor !== 'string') {
|
|
4
|
+
return { clientName: '' };
|
|
5
|
+
}
|
|
6
|
+
// Validate base64 format
|
|
7
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cursor)) {
|
|
8
|
+
logger.warn(`Invalid cursor format: not valid base64`);
|
|
9
|
+
return { clientName: '' };
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
// Decode the base64 cursor
|
|
13
|
+
const decoded = Buffer.from(cursor, 'base64').toString('utf-8');
|
|
14
|
+
// Validate decoded content (should be clientName:actualCursor format)
|
|
15
|
+
if (!decoded || decoded.length > 1000) {
|
|
16
|
+
// Reasonable length limit
|
|
17
|
+
logger.warn(`Invalid cursor: decoded content too long or empty`);
|
|
18
|
+
return { clientName: '' };
|
|
19
|
+
}
|
|
20
|
+
// Split on first colon only to handle cursors that might contain colons
|
|
21
|
+
const colonIndex = decoded.indexOf(':');
|
|
22
|
+
let clientName;
|
|
23
|
+
let actualCursor;
|
|
24
|
+
if (colonIndex === -1) {
|
|
25
|
+
// No colon found, treat entire string as client name
|
|
26
|
+
clientName = decoded;
|
|
27
|
+
actualCursor = undefined;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
clientName = decoded.substring(0, colonIndex);
|
|
31
|
+
actualCursor = decoded.substring(colonIndex + 1);
|
|
32
|
+
}
|
|
33
|
+
// Validate client name (basic alphanumeric and common symbols)
|
|
34
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(clientName) || clientName.length > 100) {
|
|
35
|
+
logger.warn(`Invalid cursor: invalid client name format`);
|
|
36
|
+
return { clientName: '' };
|
|
37
|
+
}
|
|
38
|
+
return { clientName, actualCursor: actualCursor || undefined };
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.warn(`Failed to parse cursor: ${error}`);
|
|
4
42
|
return { clientName: '' };
|
|
5
43
|
}
|
|
6
|
-
const [clientName, actualCursor] = Buffer.from(cursor, 'base64').toString('utf-8').split(':');
|
|
7
|
-
return { clientName, actualCursor };
|
|
8
44
|
}
|
|
9
45
|
export function encodeCursor(clientName, nextCursor = '') {
|
|
10
|
-
|
|
46
|
+
// Validate inputs
|
|
47
|
+
if (!clientName || typeof clientName !== 'string') {
|
|
48
|
+
logger.warn('Cannot encode cursor: invalid client name');
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (typeof nextCursor !== 'string') {
|
|
52
|
+
logger.warn('Cannot encode cursor: invalid next cursor');
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
// Validate client name format
|
|
56
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(clientName) || clientName.length > 100) {
|
|
57
|
+
logger.warn('Cannot encode cursor: client name contains invalid characters or is too long');
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
// Reasonable length limit for the full cursor
|
|
61
|
+
const fullCursor = `${clientName}:${nextCursor}`;
|
|
62
|
+
if (fullCursor.length > 1000) {
|
|
63
|
+
logger.warn('Cannot encode cursor: combined cursor length exceeds limit');
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
return Buffer.from(fullCursor).toString('base64');
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.warn(`Failed to encode cursor: ${error}`);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
11
73
|
}
|
|
12
74
|
async function fetchAllItemsForClient(clientInfo, params, callClientMethod, transformResult) {
|
|
13
75
|
logger.info(`Fetching all items for client ${clientInfo.name}`);
|
|
@@ -28,16 +90,33 @@ function getNextClientCursor(currentClientName, clientNames) {
|
|
|
28
90
|
}
|
|
29
91
|
export async function handlePagination(clients, params, callClientMethod, transformResult, enablePagination) {
|
|
30
92
|
const { cursor, ...clientParams } = params;
|
|
31
|
-
const clientNames =
|
|
93
|
+
const clientNames = Array.from(clients.keys());
|
|
32
94
|
if (!enablePagination) {
|
|
33
|
-
const allItems = await Promise.all(clientNames.map((clientName) => fetchAllItemsForClient(clients
|
|
95
|
+
const allItems = await Promise.all(clientNames.map((clientName) => fetchAllItemsForClient(clients.get(clientName), clientParams, callClientMethod, transformResult)));
|
|
34
96
|
return { items: allItems.flat() };
|
|
35
97
|
}
|
|
36
98
|
const { clientName, actualCursor } = parseCursor(cursor);
|
|
99
|
+
// If cursor parsing failed or clientName is empty, start from first client
|
|
37
100
|
const targetClientName = clientName || clientNames[0];
|
|
38
|
-
|
|
101
|
+
// Validate that the target client exists
|
|
102
|
+
const clientInfo = clients.get(targetClientName);
|
|
39
103
|
if (!clientInfo) {
|
|
40
|
-
|
|
104
|
+
logger.warn(`Client '${targetClientName}' not found, falling back to first available client`);
|
|
105
|
+
// Fallback to first available client if the target doesn't exist
|
|
106
|
+
const fallbackClientName = clientNames[0];
|
|
107
|
+
const fallbackClient = fallbackClientName ? clients.get(fallbackClientName) : null;
|
|
108
|
+
if (!fallbackClient) {
|
|
109
|
+
logger.warn('No clients available for pagination');
|
|
110
|
+
return { items: [] };
|
|
111
|
+
}
|
|
112
|
+
// Use fallback client and reset cursor since the original target was invalid
|
|
113
|
+
const result = await callClientMethod(fallbackClient.client, clientParams, // Don't pass the invalid cursor
|
|
114
|
+
{ timeout: fallbackClient.transport.timeout });
|
|
115
|
+
const transformedItems = transformResult(fallbackClient, result);
|
|
116
|
+
const nextCursor = result.nextCursor
|
|
117
|
+
? encodeCursor(fallbackClientName, result.nextCursor)
|
|
118
|
+
: getNextClientCursor(fallbackClientName, clientNames);
|
|
119
|
+
return { items: transformedItems, nextCursor };
|
|
41
120
|
}
|
|
42
121
|
const result = await callClientMethod(clientInfo.client, { ...clientParams, cursor: actualCursor }, { timeout: clientInfo.transport.timeout });
|
|
43
122
|
const transformedItems = transformResult(clientInfo, result);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"AAIA,OAAO,MAAM,MAAM,qBAAqB,CAAC;AA0BzC,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/utils/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts client name and resource name from a URI
|
|
3
|
+
* Uses split with limit to handle separators in resource names correctly.
|
|
4
|
+
* @param uri The URI to parse
|
|
5
|
+
* @param separator The separator used in the URI
|
|
6
|
+
* @returns An object with clientName and resourceName
|
|
7
|
+
* @throws InvalidRequestError if the URI is invalid
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseUri(uri: string, separator: string): {
|
|
10
|
+
clientName: string;
|
|
11
|
+
resourceName: string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=parsing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsing.d.ts","sourceRoot":"","sources":["../../src/utils/parsing.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA4BrG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { InvalidRequestError } from './errorTypes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts client name and resource name from a URI
|
|
4
|
+
* Uses split with limit to handle separators in resource names correctly.
|
|
5
|
+
* @param uri The URI to parse
|
|
6
|
+
* @param separator The separator used in the URI
|
|
7
|
+
* @returns An object with clientName and resourceName
|
|
8
|
+
* @throws InvalidRequestError if the URI is invalid
|
|
9
|
+
*/
|
|
10
|
+
export function parseUri(uri, separator) {
|
|
11
|
+
if (typeof uri !== 'string' || !uri?.trim()) {
|
|
12
|
+
throw new InvalidRequestError('URI must be a non-empty string');
|
|
13
|
+
}
|
|
14
|
+
if (!separator || typeof separator !== 'string') {
|
|
15
|
+
throw new InvalidRequestError('Separator must be a non-empty string');
|
|
16
|
+
}
|
|
17
|
+
// Split only on the first occurrence of separator
|
|
18
|
+
const parts = uri.split(separator, 2);
|
|
19
|
+
if (parts.length < 2 || !uri.includes(separator)) {
|
|
20
|
+
throw new InvalidRequestError(`Invalid URI format: missing separator '${separator}' in '${uri}'`);
|
|
21
|
+
}
|
|
22
|
+
const clientName = parts[0].trim();
|
|
23
|
+
const resourceName = uri.substring(parts[0].length + separator.length).trim();
|
|
24
|
+
if (!clientName) {
|
|
25
|
+
throw new InvalidRequestError('Client name cannot be empty');
|
|
26
|
+
}
|
|
27
|
+
if (!resourceName) {
|
|
28
|
+
throw new InvalidRequestError('Resource name cannot be empty');
|
|
29
|
+
}
|
|
30
|
+
return { clientName, resourceName };
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=parsing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsing.js","sourceRoot":"","sources":["../../src/utils/parsing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,SAAiB;IACrD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,IAAI,mBAAmB,CAAC,gCAAgC,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,mBAAmB,CAAC,sCAAsC,CAAC,CAAC;IACxE,CAAC;IAED,kDAAkD;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAEtC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,mBAAmB,CAAC,0CAA0C,SAAS,SAAS,GAAG,GAAG,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAE9E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAAC,+BAA+B,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitization utilities for various use cases
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* HTML escape function to prevent XSS attacks
|
|
6
|
+
* Escapes HTML entities in user-provided strings
|
|
7
|
+
*
|
|
8
|
+
* @param unsafe - The string to escape
|
|
9
|
+
* @returns HTML-escaped string safe for display
|
|
10
|
+
*/
|
|
11
|
+
export declare function escapeHtml(unsafe: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Sanitizes server name for use as filename by replacing special characters.
|
|
14
|
+
* Based on the existing implementation in clientSessionManager.ts
|
|
15
|
+
*
|
|
16
|
+
* @param serverName - The server name to sanitize
|
|
17
|
+
* @returns Sanitized server name safe for use as filename
|
|
18
|
+
*/
|
|
19
|
+
export declare function sanitizeServerName(serverName: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Sanitizes server name for display purposes
|
|
22
|
+
* Similar to filename sanitization but preserves more characters for readability
|
|
23
|
+
*
|
|
24
|
+
* @param serverName - The server name to sanitize
|
|
25
|
+
* @returns Sanitized server name safe for display
|
|
26
|
+
*/
|
|
27
|
+
export declare function sanitizeServerNameForDisplay(serverName: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Sanitizes URL parameter values to prevent injection attacks
|
|
30
|
+
*
|
|
31
|
+
* @param param - The parameter value to sanitize
|
|
32
|
+
* @returns URL-safe parameter value
|
|
33
|
+
*/
|
|
34
|
+
export declare function sanitizeUrlParam(param: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Sanitizes error messages for safe display
|
|
37
|
+
* Removes potentially sensitive information and escapes HTML
|
|
38
|
+
*
|
|
39
|
+
* @param error - The error message to sanitize
|
|
40
|
+
* @returns Sanitized error message safe for display
|
|
41
|
+
*/
|
|
42
|
+
export declare function sanitizeErrorMessage(error: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Sanitizes HTTP headers for safe logging
|
|
45
|
+
* Redacts sensitive authentication and authorization headers
|
|
46
|
+
*
|
|
47
|
+
* @param headers - The headers object to sanitize
|
|
48
|
+
* @returns Sanitized headers object safe for logging
|
|
49
|
+
*/
|
|
50
|
+
export declare function sanitizeHeaders(headers: Record<string, any>): Record<string, any>;
|
|
51
|
+
/**
|
|
52
|
+
* Comprehensive sanitization for server configuration data
|
|
53
|
+
* Applies appropriate sanitization based on the context
|
|
54
|
+
*
|
|
55
|
+
* @param serverName - The server name to sanitize
|
|
56
|
+
* @param context - The context where this will be used ('filename' | 'display' | 'url' | 'html')
|
|
57
|
+
* @returns Sanitized server name appropriate for the context
|
|
58
|
+
*/
|
|
59
|
+
export declare function sanitizeServerNameForContext(serverName: string, context: 'filename' | 'display' | 'url' | 'html'): string;
|
|
60
|
+
//# sourceMappingURL=sanitization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/utils/sanitization.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASjD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAkB7D;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqBvE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAkBjF;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,GAC/C,MAAM,CAaR"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitization utilities for various use cases
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* HTML escape function to prevent XSS attacks
|
|
6
|
+
* Escapes HTML entities in user-provided strings
|
|
7
|
+
*
|
|
8
|
+
* @param unsafe - The string to escape
|
|
9
|
+
* @returns HTML-escaped string safe for display
|
|
10
|
+
*/
|
|
11
|
+
export function escapeHtml(unsafe) {
|
|
12
|
+
if (!unsafe)
|
|
13
|
+
return '';
|
|
14
|
+
return unsafe
|
|
15
|
+
.replace(/&/g, '&')
|
|
16
|
+
.replace(/</g, '<')
|
|
17
|
+
.replace(/>/g, '>')
|
|
18
|
+
.replace(/"/g, '"')
|
|
19
|
+
.replace(/'/g, ''');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sanitizes server name for use as filename by replacing special characters.
|
|
23
|
+
* Based on the existing implementation in clientSessionManager.ts
|
|
24
|
+
*
|
|
25
|
+
* @param serverName - The server name to sanitize
|
|
26
|
+
* @returns Sanitized server name safe for use as filename
|
|
27
|
+
*/
|
|
28
|
+
export function sanitizeServerName(serverName) {
|
|
29
|
+
if (!serverName) {
|
|
30
|
+
return 'default';
|
|
31
|
+
}
|
|
32
|
+
// Replace special characters with safe equivalents
|
|
33
|
+
let sanitized = serverName
|
|
34
|
+
.replace(/[^a-zA-Z0-9_-]/g, '_') // Replace any non-alphanumeric, underscore, or hyphen with underscore
|
|
35
|
+
.replace(/_{2,}/g, '_') // Replace multiple consecutive underscores with single underscore
|
|
36
|
+
.replace(/^_+|_+$/g, '') // Remove leading/trailing underscores
|
|
37
|
+
.substring(0, 100); // Limit length to prevent filesystem issues
|
|
38
|
+
// If result is empty or only underscores, use default
|
|
39
|
+
if (!sanitized || sanitized.length === 0) {
|
|
40
|
+
return 'default';
|
|
41
|
+
}
|
|
42
|
+
return sanitized;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Sanitizes server name for display purposes
|
|
46
|
+
* Similar to filename sanitization but preserves more characters for readability
|
|
47
|
+
*
|
|
48
|
+
* @param serverName - The server name to sanitize
|
|
49
|
+
* @returns Sanitized server name safe for display
|
|
50
|
+
*/
|
|
51
|
+
export function sanitizeServerNameForDisplay(serverName) {
|
|
52
|
+
if (!serverName) {
|
|
53
|
+
return 'default';
|
|
54
|
+
}
|
|
55
|
+
// Allow more characters for display but still escape dangerous ones
|
|
56
|
+
// Create regex pattern for dangerous characters (including control characters)
|
|
57
|
+
const controlChars = Array.from({ length: 32 }, (_, i) => String.fromCharCode(i)).join('');
|
|
58
|
+
const dangerousChars = new RegExp(`[<>"/\\|?*${controlChars}\x7f]`, 'g');
|
|
59
|
+
let sanitized = serverName
|
|
60
|
+
.replace(dangerousChars, '_') // Replace dangerous characters
|
|
61
|
+
.replace(/_{2,}/g, '_') // Replace multiple consecutive underscores with single underscore
|
|
62
|
+
.replace(/^_+|_+$/g, '') // Remove leading/trailing underscores
|
|
63
|
+
.substring(0, 200); // Longer limit for display
|
|
64
|
+
// If result is empty, use default
|
|
65
|
+
if (!sanitized || sanitized.length === 0) {
|
|
66
|
+
return 'default';
|
|
67
|
+
}
|
|
68
|
+
return sanitized;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Sanitizes URL parameter values to prevent injection attacks
|
|
72
|
+
*
|
|
73
|
+
* @param param - The parameter value to sanitize
|
|
74
|
+
* @returns URL-safe parameter value
|
|
75
|
+
*/
|
|
76
|
+
export function sanitizeUrlParam(param) {
|
|
77
|
+
if (!param)
|
|
78
|
+
return '';
|
|
79
|
+
// Use built-in encodeURIComponent but also limit length
|
|
80
|
+
return encodeURIComponent(param).substring(0, 500);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Sanitizes error messages for safe display
|
|
84
|
+
* Removes potentially sensitive information and escapes HTML
|
|
85
|
+
*
|
|
86
|
+
* @param error - The error message to sanitize
|
|
87
|
+
* @returns Sanitized error message safe for display
|
|
88
|
+
*/
|
|
89
|
+
export function sanitizeErrorMessage(error) {
|
|
90
|
+
if (!error)
|
|
91
|
+
return '';
|
|
92
|
+
// Remove common sensitive patterns - preserve original case in replacement
|
|
93
|
+
let sanitized = error
|
|
94
|
+
.replace(/(password[s]?[:\s=]+)[^\s]+/gi, (_match, prefix) => `${prefix}[REDACTED]`)
|
|
95
|
+
.replace(/(token[s]?[:\s=]+)[^\s]+/gi, (_match, prefix) => `${prefix}[REDACTED]`)
|
|
96
|
+
.replace(/(key[s]?[:\s=]+)[^\s]+/gi, (_match, prefix) => `${prefix}[REDACTED]`)
|
|
97
|
+
.replace(/(secret[s]?[:\s=]+)[^\s]+/gi, (_match, prefix) => `${prefix}[REDACTED]`)
|
|
98
|
+
.replace(/(auth[=][^\s]+)/gi, (_match, _prefix) => `auth=[REDACTED]`)
|
|
99
|
+
.substring(0, 1000); // Limit length
|
|
100
|
+
// HTML escape the result
|
|
101
|
+
return escapeHtml(sanitized);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Sanitizes HTTP headers for safe logging
|
|
105
|
+
* Redacts sensitive authentication and authorization headers
|
|
106
|
+
*
|
|
107
|
+
* @param headers - The headers object to sanitize
|
|
108
|
+
* @returns Sanitized headers object safe for logging
|
|
109
|
+
*/
|
|
110
|
+
export function sanitizeHeaders(headers) {
|
|
111
|
+
if (!headers || typeof headers !== 'object') {
|
|
112
|
+
return {};
|
|
113
|
+
}
|
|
114
|
+
const sanitized = {};
|
|
115
|
+
const sensitiveHeaders = ['authorization', 'auth', 'x-auth-token', 'x-api-key', 'cookie', 'set-cookie'];
|
|
116
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
117
|
+
const lowerKey = key.toLowerCase();
|
|
118
|
+
if (sensitiveHeaders.includes(lowerKey)) {
|
|
119
|
+
sanitized[key] = '[REDACTED]';
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
sanitized[key] = value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return sanitized;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Comprehensive sanitization for server configuration data
|
|
129
|
+
* Applies appropriate sanitization based on the context
|
|
130
|
+
*
|
|
131
|
+
* @param serverName - The server name to sanitize
|
|
132
|
+
* @param context - The context where this will be used ('filename' | 'display' | 'url' | 'html')
|
|
133
|
+
* @returns Sanitized server name appropriate for the context
|
|
134
|
+
*/
|
|
135
|
+
export function sanitizeServerNameForContext(serverName, context) {
|
|
136
|
+
switch (context) {
|
|
137
|
+
case 'filename':
|
|
138
|
+
return sanitizeServerName(serverName);
|
|
139
|
+
case 'display':
|
|
140
|
+
return sanitizeServerNameForDisplay(serverName);
|
|
141
|
+
case 'url':
|
|
142
|
+
return sanitizeUrlParam(serverName);
|
|
143
|
+
case 'html':
|
|
144
|
+
return escapeHtml(sanitizeServerNameForDisplay(serverName));
|
|
145
|
+
default:
|
|
146
|
+
return sanitizeServerName(serverName);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=sanitization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitization.js","sourceRoot":"","sources":["../../src/utils/sanitization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security constants for scope validation
|
|
3
|
+
*/
|
|
4
|
+
export declare const SCOPE_VALIDATION_CONFIG: {
|
|
5
|
+
/** Maximum allowed length for a single scope */
|
|
6
|
+
readonly MAX_SCOPE_LENGTH: 100;
|
|
7
|
+
/** Maximum number of scopes per request */
|
|
8
|
+
readonly MAX_SCOPES_COUNT: 50;
|
|
9
|
+
/** Valid tag name pattern: alphanumeric, underscore, hyphen only */
|
|
10
|
+
readonly TAG_NAME_PATTERN: RegExp;
|
|
11
|
+
/** Valid tag scope pattern: tag: prefix followed by valid tag name */
|
|
12
|
+
readonly TAG_SCOPE_PATTERN: RegExp;
|
|
13
|
+
/** Minimum tag name length */
|
|
14
|
+
readonly MIN_TAG_LENGTH: 1;
|
|
15
|
+
/** Maximum tag name length */
|
|
16
|
+
readonly MAX_TAG_LENGTH: 50;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Parsed scope structure
|
|
20
|
+
*/
|
|
21
|
+
export interface ParsedScope {
|
|
22
|
+
type: 'tag';
|
|
23
|
+
value: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Scope validation result
|
|
27
|
+
*/
|
|
28
|
+
export interface ScopeValidationResult {
|
|
29
|
+
isValid: boolean;
|
|
30
|
+
errors: string[];
|
|
31
|
+
validScopes: string[];
|
|
32
|
+
invalidScopes: string[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates if a string is a valid tag name
|
|
36
|
+
* @param tagName - The tag name to validate
|
|
37
|
+
* @returns True if valid, false otherwise
|
|
38
|
+
*/
|
|
39
|
+
export declare function isValidTagName(tagName: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Validates if a string is a valid tag scope
|
|
42
|
+
* @param scope - The scope to validate
|
|
43
|
+
* @returns True if valid, false otherwise
|
|
44
|
+
*/
|
|
45
|
+
export declare function isValidTagScope(scope: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Safely extracts tag name from a tag scope
|
|
48
|
+
* @param scope - The scope string (e.g., "tag:web")
|
|
49
|
+
* @returns The tag name if valid, null otherwise
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractTagFromScope(scope: string): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Parses a scope string into its components
|
|
54
|
+
* @param scope - The scope string to parse
|
|
55
|
+
* @returns Parsed scope object or null if invalid
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseScope(scope: string): ParsedScope | null;
|
|
58
|
+
/**
|
|
59
|
+
* Validates an array of scopes for format and security
|
|
60
|
+
* @param scopes - Array of scope strings to validate
|
|
61
|
+
* @returns Validation result with details
|
|
62
|
+
*/
|
|
63
|
+
export declare function validateScopes(scopes: string[]): ScopeValidationResult;
|
|
64
|
+
/**
|
|
65
|
+
* Validates that requested scopes are available (allowlist approach)
|
|
66
|
+
* @param requestedScopes - Scopes requested by client
|
|
67
|
+
* @param availableTags - Tags available on the server
|
|
68
|
+
* @returns Validation result
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateScopesAgainstAvailableTags(requestedScopes: string[], availableTags: string[]): ScopeValidationResult;
|
|
71
|
+
/**
|
|
72
|
+
* Checks if granted scopes satisfy the requirements for requested tags
|
|
73
|
+
* @param grantedScopes - Scopes granted during OAuth flow
|
|
74
|
+
* @param requestedTags - Tags requested for current operation
|
|
75
|
+
* @returns True if all requested tags are covered by granted scopes
|
|
76
|
+
*/
|
|
77
|
+
export declare function hasRequiredScopes(grantedScopes: string[], requestedTags: string[]): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Converts tags to their corresponding scopes
|
|
80
|
+
* @param tags - Array of tag names
|
|
81
|
+
* @returns Array of tag scopes
|
|
82
|
+
*/
|
|
83
|
+
export declare function tagsToScopes(tags: string[]): string[];
|
|
84
|
+
/**
|
|
85
|
+
* Converts scopes to their corresponding tags
|
|
86
|
+
* @param scopes - Array of scope strings
|
|
87
|
+
* @returns Array of tag names
|
|
88
|
+
*/
|
|
89
|
+
export declare function scopesToTags(scopes: string[]): string[];
|
|
90
|
+
/**
|
|
91
|
+
* Security utility to audit scope operations
|
|
92
|
+
* @param operation - The operation being performed
|
|
93
|
+
* @param context - Additional context for logging
|
|
94
|
+
*/
|
|
95
|
+
export declare function auditScopeOperation(operation: string, context: {
|
|
96
|
+
clientId?: string;
|
|
97
|
+
requestedScopes?: string[];
|
|
98
|
+
grantedScopes?: string[];
|
|
99
|
+
success?: boolean;
|
|
100
|
+
error?: string;
|
|
101
|
+
}): void;
|
|
102
|
+
//# sourceMappingURL=scopeValidation.d.ts.map
|