mcp4openapi 0.2.4 → 0.2.6
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 +14 -1
- package/dist/scripts/validate-profile.js +3 -1
- package/dist/scripts/validate-profile.js.map +1 -1
- package/dist/src/composite-executor.d.ts.map +1 -1
- package/dist/src/composite-executor.js +1 -3
- package/dist/src/composite-executor.js.map +1 -1
- package/dist/src/errors.js +0 -2
- package/dist/src/errors.js.map +1 -1
- package/dist/src/generated-schemas.d.ts +235 -30
- package/dist/src/generated-schemas.d.ts.map +1 -1
- package/dist/src/generated-schemas.js +16 -2
- package/dist/src/generated-schemas.js.map +1 -1
- package/dist/src/http-client-factory.js +3 -2
- package/dist/src/http-client-factory.js.map +1 -1
- package/dist/src/http-transport.d.ts +9 -2
- package/dist/src/http-transport.d.ts.map +1 -1
- package/dist/src/http-transport.js +133 -36
- package/dist/src/http-transport.js.map +1 -1
- package/dist/src/interceptors.d.ts +34 -0
- package/dist/src/interceptors.d.ts.map +1 -1
- package/dist/src/interceptors.js +90 -6
- package/dist/src/interceptors.js.map +1 -1
- package/dist/src/logger.js +0 -4
- package/dist/src/logger.js.map +1 -1
- package/dist/src/mcp-server.d.ts +7 -0
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +86 -20
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/metrics.js +0 -17
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/oauth-provider.d.ts +29 -0
- package/dist/src/oauth-provider.d.ts.map +1 -1
- package/dist/src/oauth-provider.js +177 -22
- package/dist/src/oauth-provider.js.map +1 -1
- package/dist/src/openapi-parser.d.ts.map +1 -1
- package/dist/src/openapi-parser.js +4 -3
- package/dist/src/openapi-parser.js.map +1 -1
- package/dist/src/profile-loader.d.ts.map +1 -1
- package/dist/src/profile-loader.js +8 -0
- package/dist/src/profile-loader.js.map +1 -1
- package/dist/src/proxy-executor.d.ts +71 -0
- package/dist/src/proxy-executor.d.ts.map +1 -0
- package/dist/src/proxy-executor.js +240 -0
- package/dist/src/proxy-executor.js.map +1 -0
- package/dist/src/testing/fixtures.d.ts +229 -2
- package/dist/src/testing/fixtures.d.ts.map +1 -1
- package/dist/src/testing/fixtures.js +175 -1
- package/dist/src/testing/fixtures.js.map +1 -1
- package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -1
- package/dist/src/testing/mock-gitlab-server.js +356 -1
- package/dist/src/testing/mock-gitlab-server.js.map +1 -1
- package/dist/src/testing/mock-youtrack-server.d.ts +11 -0
- package/dist/src/testing/mock-youtrack-server.d.ts.map +1 -0
- package/dist/src/testing/mock-youtrack-server.js +138 -0
- package/dist/src/testing/mock-youtrack-server.js.map +1 -0
- package/dist/src/testing/test-http-utils.js +1 -3
- package/dist/src/testing/test-http-utils.js.map +1 -1
- package/dist/src/testing/test-types.d.ts +157 -2
- package/dist/src/testing/test-types.d.ts.map +1 -1
- package/dist/src/tool-generator.d.ts +23 -0
- package/dist/src/tool-generator.d.ts.map +1 -1
- package/dist/src/tool-generator.js +55 -5
- package/dist/src/tool-generator.js.map +1 -1
- package/dist/src/types/profile.d.ts +48 -3
- package/dist/src/types/profile.d.ts.map +1 -1
- package/package.json +1 -1
- package/profile-schema.json +90 -6
|
@@ -14,9 +14,22 @@ export const parameterDefinitionSchema = z.object({
|
|
|
14
14
|
items: z.object({
|
|
15
15
|
type: z.string()
|
|
16
16
|
}).optional(),
|
|
17
|
+
properties: z.record(z.string(), z.unknown()).optional(),
|
|
17
18
|
default: z.unknown().optional(),
|
|
18
19
|
example: z.unknown().optional()
|
|
19
20
|
});
|
|
21
|
+
export const proxyDownloadOperationSchema = z.object({
|
|
22
|
+
type: z.literal("proxy_download"),
|
|
23
|
+
metadata_endpoint: z.string(),
|
|
24
|
+
download_endpoint: z.string().optional(),
|
|
25
|
+
url_field: z.string().optional(),
|
|
26
|
+
max_size_bytes: z.number().optional(),
|
|
27
|
+
max_size_bytes_from_env: z.string().optional(),
|
|
28
|
+
timeout_ms: z.number().optional(),
|
|
29
|
+
allowed_mime_types: z.array(z.string()).optional(),
|
|
30
|
+
skip_auth: z.boolean().optional()
|
|
31
|
+
});
|
|
32
|
+
export const operationDefinitionSchema = z.union([z.string(), proxyDownloadOperationSchema]);
|
|
20
33
|
export const baseUrlConfigSchema = z.object({
|
|
21
34
|
value_from_env: z.string(),
|
|
22
35
|
default: z.string().optional()
|
|
@@ -48,13 +61,14 @@ export const oAuthConfigSchema = z.object({
|
|
|
48
61
|
export const toolDefinitionSchema = z.object({
|
|
49
62
|
name: z.string(),
|
|
50
63
|
description: z.string(),
|
|
51
|
-
operations: z.
|
|
64
|
+
operations: z.record(z.string(), operationDefinitionSchema).optional(),
|
|
52
65
|
composite: z.boolean().optional(),
|
|
53
66
|
steps: z.array(compositeStepSchema).optional(),
|
|
54
67
|
partial_results: z.boolean().optional(),
|
|
55
68
|
parameters: z.record(z.string(), parameterDefinitionSchema),
|
|
56
69
|
metadata_params: z.array(z.string()).optional(),
|
|
57
|
-
response_fields: z.record(z.string(), z.array(z.string())).optional()
|
|
70
|
+
response_fields: z.record(z.string(), z.array(z.string())).optional(),
|
|
71
|
+
send_response_fields_as_param: z.boolean().optional()
|
|
58
72
|
});
|
|
59
73
|
export const authInterceptorSchema = z.object({
|
|
60
74
|
type: z.union([z.literal("bearer"), z.literal("query"), z.literal("custom-header"), z.literal("oauth")]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generated-schemas.js","sourceRoot":"","sources":["../../src/generated-schemas.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generated-schemas.js","sourceRoot":"","sources":["../../src/generated-schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,9 @@ import { ConfigurationError, AuthenticationError } from './errors.js';
|
|
|
11
11
|
* Handles both global and session-specific clients
|
|
12
12
|
*/
|
|
13
13
|
export class HttpClientFactory {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
constructor() {
|
|
15
|
+
this.sessionClients = new Map();
|
|
16
|
+
}
|
|
16
17
|
/**
|
|
17
18
|
* Create global HTTP client (for stdio transport)
|
|
18
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client-factory.js","sourceRoot":"","sources":["../../src/http-client-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQtE;;;GAGG;AACH,MAAM,OAAO,iBAAiB;
|
|
1
|
+
{"version":3,"file":"http-client-factory.js","sourceRoot":"","sources":["../../src/http-client-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,9 +50,10 @@ export declare class HttpTransport {
|
|
|
50
50
|
*/
|
|
51
51
|
private matchOrigin;
|
|
52
52
|
/**
|
|
53
|
-
* Check if IP address is within CIDR range
|
|
53
|
+
* Check if IP address is within CIDR range (IPv4 or IPv6)
|
|
54
54
|
*
|
|
55
55
|
* Example: '192.168.1.50' matches '192.168.1.0/24'
|
|
56
|
+
* '2001:db8::1' matches '2001:db8::/32'
|
|
56
57
|
*/
|
|
57
58
|
private matchCIDR;
|
|
58
59
|
/**
|
|
@@ -60,7 +61,13 @@ export declare class HttpTransport {
|
|
|
60
61
|
*
|
|
61
62
|
* Example: '192.168.1.1' -> 3232235777
|
|
62
63
|
*/
|
|
63
|
-
private
|
|
64
|
+
private ipv4ToInt;
|
|
65
|
+
/**
|
|
66
|
+
* Convert IPv6 address to 128-bit BigInt
|
|
67
|
+
*/
|
|
68
|
+
private ipv6ToBigInt;
|
|
69
|
+
private ipv6Mask;
|
|
70
|
+
private stripIpv6Brackets;
|
|
64
71
|
/**
|
|
65
72
|
* Create configured rate limiter or a passthrough handler when disabled
|
|
66
73
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../../src/http-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAIV,mBAAmB,EAEpB,MAAM,2BAA2B,CAAC;AAYnC,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,cAAc,CAA6E;IACnG,OAAO,CAAC,aAAa,CAAsC;IAG3D,OAAO,CAAC,wBAAwB,CAA6G;gBAEjI,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM;IAgCvD;;;;OAIG;IACH,OAAO,CAAC,eAAe;IA6HvB,OAAO,CAAC,qBAAqB,CAAS;IAEtC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IA0CvB;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAuBnB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAgDjB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAmBjB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6EpB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,iBAAiB;IAIzB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,sBAAsB;IAI9B;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAqcnB;;;;OAIG;YACW,aAAa;IAoB3B;;;;;OAKG;IACH;;;OAGG;IACH,OAAO,CAAC,QAAQ;YAkBF,iBAAiB;IAqE/B;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IA4CxB;;;;OAIG;YACW,UAAU;IAqNxB;;;;OAIG;YACW,SAAS;IAkDvB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAmCpB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6CtB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAatB;;;;OAIG;IACI,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IA6B9D;;OAEG;IACH,OAAO,CAAC,cAAc;IAuBtB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAoCtB;;OAEG;IACH,OAAO,CAAC,yBAAyB,CAA0C;IAE3E;;;;OAIG;IACI,kBAAkB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAItE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAoC9B;;;;OAIG;IACI,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK7D;;;;;OAKG;IACU,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BzE;;;;;OAKG;YACW,kBAAkB;IA+EhC;;OAEG;IACI,iBAAiB,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAInG;;OAEG;IACI,gBAAgB,IAAI,OAAO;IAIlC;;OAEG;IACI,YAAY,IAAI,MAAM;IAmB7B;;OAEG;IACI,wBAAwB,IAAI,MAAM;IAIzC;;OAEG;IACI,cAAc,IAAI,MAAM,EAAE;IAIjC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqEnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBnC"}
|
|
@@ -11,6 +11,7 @@ import express from 'express';
|
|
|
11
11
|
import https from 'https';
|
|
12
12
|
import fs from 'fs';
|
|
13
13
|
import crypto from 'crypto';
|
|
14
|
+
import { isIP } from 'node:net';
|
|
14
15
|
import rateLimit from 'express-rate-limit';
|
|
15
16
|
import { isInitializeRequest } from './jsonrpc-validator.js';
|
|
16
17
|
import { MetricsCollector } from './metrics.js';
|
|
@@ -20,19 +21,21 @@ import { escapeHtmlSafe } from './validation-utils.js';
|
|
|
20
21
|
// Default maximum token length (1000 characters)
|
|
21
22
|
const DEFAULT_MAX_TOKEN_LENGTH = 1000;
|
|
22
23
|
export class HttpTransport {
|
|
23
|
-
app;
|
|
24
|
-
server = null;
|
|
25
|
-
sessions = new Map();
|
|
26
|
-
config;
|
|
27
|
-
logger;
|
|
28
|
-
metrics = null;
|
|
29
|
-
cleanupInterval = null;
|
|
30
|
-
messageHandler = null;
|
|
31
|
-
oauthProvider = null;
|
|
32
|
-
// Map access_token -> { refreshToken, expiresAt, clientId, scopes }
|
|
33
|
-
// Used to bridge /oauth/token endpoint (where we see OAuthTokens) and session initialization (where we only see access token)
|
|
34
|
-
oauthTokensByAccessToken = new Map();
|
|
35
24
|
constructor(config, logger) {
|
|
25
|
+
this.server = null;
|
|
26
|
+
this.sessions = new Map();
|
|
27
|
+
this.metrics = null;
|
|
28
|
+
this.cleanupInterval = null;
|
|
29
|
+
this.messageHandler = null;
|
|
30
|
+
this.oauthProvider = null;
|
|
31
|
+
// Map access_token -> { refreshToken, expiresAt, clientId, scopes }
|
|
32
|
+
// Used to bridge /oauth/token endpoint (where we see OAuthTokens) and session initialization (where we only see access token)
|
|
33
|
+
this.oauthTokensByAccessToken = new Map();
|
|
34
|
+
this.hasWarnedAboutBinding = false;
|
|
35
|
+
/**
|
|
36
|
+
* Session destruction listeners for cleanup in other components
|
|
37
|
+
*/
|
|
38
|
+
this.sessionDestroyedListeners = [];
|
|
36
39
|
// Freeze config to prevent runtime mutation of security-critical settings (allowedOrigins, rate limits, etc.)
|
|
37
40
|
this.config = Object.freeze({ ...config });
|
|
38
41
|
this.logger = logger;
|
|
@@ -176,7 +179,6 @@ export class HttpTransport {
|
|
|
176
179
|
next();
|
|
177
180
|
});
|
|
178
181
|
}
|
|
179
|
-
hasWarnedAboutBinding = false;
|
|
180
182
|
/**
|
|
181
183
|
* Check if origin is allowed
|
|
182
184
|
*
|
|
@@ -235,43 +237,64 @@ export class HttpTransport {
|
|
|
235
237
|
* - CIDR: '192.168.1.0/24' matches '192.168.1.1' through '192.168.1.254'
|
|
236
238
|
*/
|
|
237
239
|
matchOrigin(hostname, pattern) {
|
|
240
|
+
const normalizedHost = this.stripIpv6Brackets(hostname);
|
|
241
|
+
const normalizedPattern = this.stripIpv6Brackets(pattern);
|
|
238
242
|
// Exact match
|
|
239
|
-
if (
|
|
243
|
+
if (normalizedHost === normalizedPattern) {
|
|
240
244
|
return true;
|
|
241
245
|
}
|
|
242
246
|
// Wildcard subdomain match (*.example.com)
|
|
243
|
-
if (
|
|
244
|
-
const domain =
|
|
245
|
-
return
|
|
247
|
+
if (normalizedPattern.startsWith('*.')) {
|
|
248
|
+
const domain = normalizedPattern.substring(2); // Remove '*.'
|
|
249
|
+
return normalizedHost.endsWith('.' + domain) || normalizedHost === domain;
|
|
246
250
|
}
|
|
247
|
-
// CIDR match (IPv4
|
|
248
|
-
if (
|
|
249
|
-
return this.matchCIDR(
|
|
251
|
+
// CIDR match (IPv4/IPv6)
|
|
252
|
+
if (normalizedPattern.includes('/')) {
|
|
253
|
+
return this.matchCIDR(normalizedHost, normalizedPattern);
|
|
250
254
|
}
|
|
251
255
|
return false;
|
|
252
256
|
}
|
|
253
257
|
/**
|
|
254
|
-
* Check if IP address is within CIDR range
|
|
258
|
+
* Check if IP address is within CIDR range (IPv4 or IPv6)
|
|
255
259
|
*
|
|
256
260
|
* Example: '192.168.1.50' matches '192.168.1.0/24'
|
|
261
|
+
* '2001:db8::1' matches '2001:db8::/32'
|
|
257
262
|
*/
|
|
258
263
|
matchCIDR(ip, cidr) {
|
|
259
|
-
|
|
260
|
-
const
|
|
264
|
+
const [rawRange, bits] = cidr.split('/');
|
|
265
|
+
const range = this.stripIpv6Brackets(rawRange);
|
|
261
266
|
const maskBits = parseInt(bits, 10);
|
|
262
|
-
if (isNaN(maskBits)
|
|
263
|
-
this.logger.warn('Invalid CIDR mask bits', { cidr });
|
|
267
|
+
if (isNaN(maskBits)) {
|
|
264
268
|
return false;
|
|
265
269
|
}
|
|
266
|
-
|
|
267
|
-
const
|
|
268
|
-
|
|
270
|
+
const ipVersion = isIP(ip);
|
|
271
|
+
const rangeVersion = isIP(range);
|
|
272
|
+
if (ipVersion === 0 || rangeVersion === 0 || ipVersion !== rangeVersion) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
if (ipVersion === 4) {
|
|
276
|
+
if (maskBits < 0 || maskBits > 32) {
|
|
277
|
+
this.logger.warn('Invalid CIDR mask bits', { cidr });
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
const ipInt = this.ipv4ToInt(ip);
|
|
281
|
+
const rangeInt = this.ipv4ToInt(range);
|
|
282
|
+
if (ipInt === null || rangeInt === null) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const mask = (0xFFFFFFFF << (32 - maskBits)) >>> 0;
|
|
286
|
+
return (ipInt & mask) === (rangeInt & mask);
|
|
287
|
+
}
|
|
288
|
+
if (maskBits < 0 || maskBits > 128) {
|
|
289
|
+
this.logger.warn('Invalid IPv6 CIDR mask bits', { cidr });
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
const ipInt = this.ipv6ToBigInt(ip);
|
|
293
|
+
const rangeInt = this.ipv6ToBigInt(range);
|
|
269
294
|
if (ipInt === null || rangeInt === null) {
|
|
270
295
|
return false;
|
|
271
296
|
}
|
|
272
|
-
|
|
273
|
-
const mask = (0xFFFFFFFF << (32 - maskBits)) >>> 0;
|
|
274
|
-
// Compare network portions
|
|
297
|
+
const mask = this.ipv6Mask(maskBits);
|
|
275
298
|
return (ipInt & mask) === (rangeInt & mask);
|
|
276
299
|
}
|
|
277
300
|
/**
|
|
@@ -279,7 +302,7 @@ export class HttpTransport {
|
|
|
279
302
|
*
|
|
280
303
|
* Example: '192.168.1.1' -> 3232235777
|
|
281
304
|
*/
|
|
282
|
-
|
|
305
|
+
ipv4ToInt(ip) {
|
|
283
306
|
const parts = ip.split('.');
|
|
284
307
|
if (parts.length !== 4) {
|
|
285
308
|
return null;
|
|
@@ -294,6 +317,83 @@ export class HttpTransport {
|
|
|
294
317
|
}
|
|
295
318
|
return result >>> 0; // Unsigned
|
|
296
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Convert IPv6 address to 128-bit BigInt
|
|
322
|
+
*/
|
|
323
|
+
ipv6ToBigInt(ip) {
|
|
324
|
+
const cleaned = this.stripIpv6Brackets(ip);
|
|
325
|
+
// Handle IPv4-mapped IPv6 (e.g., ::ffff:192.168.0.1)
|
|
326
|
+
let ipv4Tail = null;
|
|
327
|
+
let base = cleaned;
|
|
328
|
+
if (cleaned.includes('.')) {
|
|
329
|
+
const lastColon = cleaned.lastIndexOf(':');
|
|
330
|
+
if (lastColon === -1)
|
|
331
|
+
return null;
|
|
332
|
+
const ipv4Part = cleaned.slice(lastColon + 1);
|
|
333
|
+
ipv4Tail = this.ipv4ToInt(ipv4Part);
|
|
334
|
+
if (ipv4Tail === null)
|
|
335
|
+
return null;
|
|
336
|
+
base = cleaned.slice(0, lastColon);
|
|
337
|
+
}
|
|
338
|
+
const parts = base.split('::');
|
|
339
|
+
if (parts.length > 2) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
const head = parts[0] ? parts[0].split(':') : [];
|
|
343
|
+
const tail = parts.length === 2 && parts[1] ? parts[1].split(':') : [];
|
|
344
|
+
if (head.some(p => p === '') || tail.some(p => p === '')) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const totalSegmentsNeeded = 8 - (ipv4Tail !== null ? 2 : 0);
|
|
348
|
+
let segments = [];
|
|
349
|
+
const parseHextets = (items) => {
|
|
350
|
+
const result = [];
|
|
351
|
+
for (const part of items) {
|
|
352
|
+
const num = parseInt(part || '0', 16);
|
|
353
|
+
if (isNaN(num) || num < 0 || num > 0xFFFF) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
result.push(num);
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
};
|
|
360
|
+
const headVals = parseHextets(head);
|
|
361
|
+
const tailVals = parseHextets(tail);
|
|
362
|
+
if (!headVals || !tailVals) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const missing = totalSegmentsNeeded - (headVals.length + tailVals.length);
|
|
366
|
+
if (missing < 0) {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
segments = [...headVals, ...Array(missing).fill(0), ...tailVals];
|
|
370
|
+
if (segments.length !== totalSegmentsNeeded) {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
if (ipv4Tail !== null) {
|
|
374
|
+
const high = (ipv4Tail >>> 16) & 0xFFFF;
|
|
375
|
+
const low = ipv4Tail & 0xFFFF;
|
|
376
|
+
segments.push(high, low);
|
|
377
|
+
}
|
|
378
|
+
if (segments.length !== 8) {
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
let value = 0n;
|
|
382
|
+
for (const part of segments) {
|
|
383
|
+
value = (value << 16n) + BigInt(part);
|
|
384
|
+
}
|
|
385
|
+
return value;
|
|
386
|
+
}
|
|
387
|
+
ipv6Mask(maskBits) {
|
|
388
|
+
if (maskBits === 0) {
|
|
389
|
+
return 0n;
|
|
390
|
+
}
|
|
391
|
+
const ones = (1n << BigInt(maskBits)) - 1n;
|
|
392
|
+
return BigInt.asUintN(128, ones << BigInt(128 - maskBits));
|
|
393
|
+
}
|
|
394
|
+
stripIpv6Brackets(value) {
|
|
395
|
+
return value.replace(/^\[/, '').replace(/\]$/, '');
|
|
396
|
+
}
|
|
297
397
|
/**
|
|
298
398
|
* Create configured rate limiter or a passthrough handler when disabled
|
|
299
399
|
*
|
|
@@ -667,6 +767,7 @@ export class HttpTransport {
|
|
|
667
767
|
const origin = req.headers.origin;
|
|
668
768
|
// Only send CORS headers for explicitly allowed origins; otherwise reject
|
|
669
769
|
if (origin && this.isAllowedOrigin(origin)) {
|
|
770
|
+
// nosemgrep: javascript.express.security.cors-misconfiguration.cors-misconfiguration
|
|
670
771
|
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
671
772
|
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
|
672
773
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept, Mcp-Session-Id');
|
|
@@ -1394,10 +1495,6 @@ export class HttpTransport {
|
|
|
1394
1495
|
}
|
|
1395
1496
|
}
|
|
1396
1497
|
}
|
|
1397
|
-
/**
|
|
1398
|
-
* Session destruction listeners for cleanup in other components
|
|
1399
|
-
*/
|
|
1400
|
-
sessionDestroyedListeners = [];
|
|
1401
1498
|
/**
|
|
1402
1499
|
* Register listener for session destruction events
|
|
1403
1500
|
*
|