@vfarcic/dot-ai 1.21.1 → 1.23.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.
Files changed (34) hide show
  1. package/dist/core/git-utils.d.ts +46 -0
  2. package/dist/core/git-utils.d.ts.map +1 -1
  3. package/dist/core/git-utils.js +192 -1
  4. package/dist/core/user-prompts-loader.d.ts +129 -1
  5. package/dist/core/user-prompts-loader.d.ts.map +1 -1
  6. package/dist/core/user-prompts-loader.js +654 -68
  7. package/dist/interfaces/cors-headers.d.ts +41 -0
  8. package/dist/interfaces/cors-headers.d.ts.map +1 -0
  9. package/dist/interfaces/cors-headers.js +43 -0
  10. package/dist/interfaces/header-redaction.d.ts +28 -0
  11. package/dist/interfaces/header-redaction.d.ts.map +1 -0
  12. package/dist/interfaces/header-redaction.js +48 -0
  13. package/dist/interfaces/mcp.d.ts +22 -0
  14. package/dist/interfaces/mcp.d.ts.map +1 -1
  15. package/dist/interfaces/mcp.js +131 -7
  16. package/dist/interfaces/openapi-generator.d.ts.map +1 -1
  17. package/dist/interfaces/openapi-generator.js +11 -5
  18. package/dist/interfaces/rest-api.d.ts +59 -15
  19. package/dist/interfaces/rest-api.d.ts.map +1 -1
  20. package/dist/interfaces/rest-api.js +288 -52
  21. package/dist/interfaces/routes/index.d.ts.map +1 -1
  22. package/dist/interfaces/routes/index.js +35 -0
  23. package/dist/interfaces/schemas/common.d.ts +33 -0
  24. package/dist/interfaces/schemas/common.d.ts.map +1 -1
  25. package/dist/interfaces/schemas/common.js +20 -1
  26. package/dist/interfaces/schemas/index.d.ts +2 -2
  27. package/dist/interfaces/schemas/index.d.ts.map +1 -1
  28. package/dist/interfaces/schemas/index.js +14 -3
  29. package/dist/interfaces/schemas/prompts.d.ts +155 -0
  30. package/dist/interfaces/schemas/prompts.d.ts.map +1 -1
  31. package/dist/interfaces/schemas/prompts.js +134 -1
  32. package/dist/tools/prompts.d.ts.map +1 -1
  33. package/dist/tools/prompts.js +37 -2
  34. package/package.json +6 -4
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared CORS allow-header lists (PRD #621 M2, Decision 1).
3
+ *
4
+ * The REST (src/interfaces/rest-api.ts) and front HTTP (src/interfaces/mcp.ts)
5
+ * layers each answer CORS preflight with their own `Access-Control-Allow-Headers`
6
+ * value, and the two were historically OUT OF SYNC. Centralizing the credential
7
+ * header name here guarantees the new `X-Dot-AI-Git-Token` header is advertised
8
+ * by BOTH preflight responses (Decision 1) and that the two lists can never
9
+ * silently drift apart on this header again.
10
+ *
11
+ * The two lists intentionally differ on the OTHER headers (mcp.ts also allows
12
+ * X-Session-Id / X-Dot-AI-Authorization), which is preserved.
13
+ */
14
+ /**
15
+ * Per-request git credential header (PRD #621 M2/M3, Decision 1). The CLI
16
+ * forwards its `DOT_AI_GIT_TOKEN` here so the server can authenticate an
17
+ * overridden (`?repo=`) clone against a second auth realm. Always a request
18
+ * header — never a query param or body field.
19
+ */
20
+ export declare const GIT_TOKEN_HEADER = "X-Dot-AI-Git-Token";
21
+ /**
22
+ * Lowercased form for reading the header off Node's `req.headers` (Node
23
+ * lowercases all incoming header names).
24
+ */
25
+ export declare const GIT_TOKEN_HEADER_LC: string;
26
+ /**
27
+ * `Access-Control-Allow-Headers` value for the REST API layer
28
+ * (rest-api.ts `setCorsHeaders`).
29
+ */
30
+ export declare const REST_CORS_ALLOW_HEADERS = "Content-Type, Authorization, X-Dot-AI-Git-Token";
31
+ /**
32
+ * `Access-Control-Allow-Headers` value for the front HTTP layer (mcp.ts).
33
+ * Retains X-Session-Id and X-Dot-AI-Authorization from the pre-existing list.
34
+ *
35
+ * Includes `Mcp-Session-Id` because the MCP session router in mcp.ts routes
36
+ * requests by `req.headers['mcp-session-id']` (the Streamable HTTP transport's
37
+ * session header); without it a browser preflight requesting that header would
38
+ * fail (CodeRabbit Finding 3). `X-Session-Id` is kept for backward compat.
39
+ */
40
+ export declare const MCP_CORS_ALLOW_HEADERS = "Content-Type, X-Session-Id, Mcp-Session-Id, Authorization, X-Dot-AI-Authorization, X-Dot-AI-Git-Token";
41
+ //# sourceMappingURL=cors-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors-headers.d.ts","sourceRoot":"","sources":["../../src/interfaces/cors-headers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAAiC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,uBAAuB,oDAAqD,CAAC;AAE1F;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,0GAA2G,CAAC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /**
3
+ * Shared CORS allow-header lists (PRD #621 M2, Decision 1).
4
+ *
5
+ * The REST (src/interfaces/rest-api.ts) and front HTTP (src/interfaces/mcp.ts)
6
+ * layers each answer CORS preflight with their own `Access-Control-Allow-Headers`
7
+ * value, and the two were historically OUT OF SYNC. Centralizing the credential
8
+ * header name here guarantees the new `X-Dot-AI-Git-Token` header is advertised
9
+ * by BOTH preflight responses (Decision 1) and that the two lists can never
10
+ * silently drift apart on this header again.
11
+ *
12
+ * The two lists intentionally differ on the OTHER headers (mcp.ts also allows
13
+ * X-Session-Id / X-Dot-AI-Authorization), which is preserved.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.MCP_CORS_ALLOW_HEADERS = exports.REST_CORS_ALLOW_HEADERS = exports.GIT_TOKEN_HEADER_LC = exports.GIT_TOKEN_HEADER = void 0;
17
+ /**
18
+ * Per-request git credential header (PRD #621 M2/M3, Decision 1). The CLI
19
+ * forwards its `DOT_AI_GIT_TOKEN` here so the server can authenticate an
20
+ * overridden (`?repo=`) clone against a second auth realm. Always a request
21
+ * header — never a query param or body field.
22
+ */
23
+ exports.GIT_TOKEN_HEADER = 'X-Dot-AI-Git-Token';
24
+ /**
25
+ * Lowercased form for reading the header off Node's `req.headers` (Node
26
+ * lowercases all incoming header names).
27
+ */
28
+ exports.GIT_TOKEN_HEADER_LC = exports.GIT_TOKEN_HEADER.toLowerCase();
29
+ /**
30
+ * `Access-Control-Allow-Headers` value for the REST API layer
31
+ * (rest-api.ts `setCorsHeaders`).
32
+ */
33
+ exports.REST_CORS_ALLOW_HEADERS = `Content-Type, Authorization, ${exports.GIT_TOKEN_HEADER}`;
34
+ /**
35
+ * `Access-Control-Allow-Headers` value for the front HTTP layer (mcp.ts).
36
+ * Retains X-Session-Id and X-Dot-AI-Authorization from the pre-existing list.
37
+ *
38
+ * Includes `Mcp-Session-Id` because the MCP session router in mcp.ts routes
39
+ * requests by `req.headers['mcp-session-id']` (the Streamable HTTP transport's
40
+ * session header); without it a browser preflight requesting that header would
41
+ * fail (CodeRabbit Finding 3). `X-Session-Id` is kept for backward compat.
42
+ */
43
+ exports.MCP_CORS_ALLOW_HEADERS = `Content-Type, X-Session-Id, Mcp-Session-Id, Authorization, X-Dot-AI-Authorization, ${exports.GIT_TOKEN_HEADER}`;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Redaction of credential-bearing request headers before they are logged.
3
+ *
4
+ * The front HTTP layer (mcp.ts) logs incoming requests at debug level. Logging
5
+ * `req.headers` verbatim would leak credentials — `Authorization`,
6
+ * `X-Dot-AI-Authorization`, and (PRD #621) the per-request `X-Dot-AI-Git-Token`
7
+ * — bypassing the loader-level scrubbing. PRD #621 requires the forwarded token
8
+ * NEVER appear in logs, so these header values are replaced with a fixed
9
+ * placeholder before logging.
10
+ *
11
+ * Kept in its own module so the redaction is unit-testable without importing
12
+ * the heavy mcp.ts server module.
13
+ */
14
+ /** Fixed placeholder substituted for a redacted header value. */
15
+ export declare const REDACTED_PLACEHOLDER = "***REDACTED***";
16
+ /**
17
+ * Lowercased names of headers whose values are credential-bearing and must be
18
+ * redacted before logging. Node lowercases all incoming header names, so the
19
+ * comparison is done in lowercase.
20
+ */
21
+ export declare const SENSITIVE_HEADER_NAMES: ReadonlySet<string>;
22
+ /**
23
+ * Return a shallow copy of `headers` with the value of every credential-bearing
24
+ * header replaced by REDACTED_PLACEHOLDER. Non-sensitive headers are preserved
25
+ * verbatim. The input object is never mutated.
26
+ */
27
+ export declare function redactSensitiveHeaders(headers: Record<string, unknown> | undefined): Record<string, unknown>;
28
+ //# sourceMappingURL=header-redaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-redaction.d.ts","sourceRoot":"","sources":["../../src/interfaces/header-redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAMrD,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Redaction of credential-bearing request headers before they are logged.
4
+ *
5
+ * The front HTTP layer (mcp.ts) logs incoming requests at debug level. Logging
6
+ * `req.headers` verbatim would leak credentials — `Authorization`,
7
+ * `X-Dot-AI-Authorization`, and (PRD #621) the per-request `X-Dot-AI-Git-Token`
8
+ * — bypassing the loader-level scrubbing. PRD #621 requires the forwarded token
9
+ * NEVER appear in logs, so these header values are replaced with a fixed
10
+ * placeholder before logging.
11
+ *
12
+ * Kept in its own module so the redaction is unit-testable without importing
13
+ * the heavy mcp.ts server module.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.SENSITIVE_HEADER_NAMES = exports.REDACTED_PLACEHOLDER = void 0;
17
+ exports.redactSensitiveHeaders = redactSensitiveHeaders;
18
+ const cors_headers_1 = require("./cors-headers");
19
+ /** Fixed placeholder substituted for a redacted header value. */
20
+ exports.REDACTED_PLACEHOLDER = '***REDACTED***';
21
+ /**
22
+ * Lowercased names of headers whose values are credential-bearing and must be
23
+ * redacted before logging. Node lowercases all incoming header names, so the
24
+ * comparison is done in lowercase.
25
+ */
26
+ exports.SENSITIVE_HEADER_NAMES = new Set([
27
+ 'authorization',
28
+ 'x-dot-ai-authorization',
29
+ cors_headers_1.GIT_TOKEN_HEADER_LC,
30
+ 'cookie',
31
+ 'proxy-authorization',
32
+ ]);
33
+ /**
34
+ * Return a shallow copy of `headers` with the value of every credential-bearing
35
+ * header replaced by REDACTED_PLACEHOLDER. Non-sensitive headers are preserved
36
+ * verbatim. The input object is never mutated.
37
+ */
38
+ function redactSensitiveHeaders(headers) {
39
+ if (!headers)
40
+ return {};
41
+ const redacted = {};
42
+ for (const [name, value] of Object.entries(headers)) {
43
+ redacted[name] = exports.SENSITIVE_HEADER_NAMES.has(name.toLowerCase())
44
+ ? exports.REDACTED_PLACEHOLDER
45
+ : value;
46
+ }
47
+ return redacted;
48
+ }
@@ -73,7 +73,29 @@ export declare class MCPServer {
73
73
  private generateRequestId;
74
74
  start(): Promise<void>;
75
75
  private startHttpTransport;
76
+ /**
77
+ * Buffer and JSON-parse the request body.
78
+ *
79
+ * PRD #647 F1: when `maxBytes` is supplied (the untrusted ingest route), the
80
+ * body is rejected with RequestBodyTooLargeError as soon as the declared
81
+ * Content-Length OR the accumulated bytes exceed the ceiling — so an
82
+ * authenticated multi-GB POST can't buffer unbounded and OOM the shared
83
+ * process. When `maxBytes` is omitted (every other endpoint), behavior is
84
+ * exactly as before: no cap.
85
+ */
76
86
  private parseRequestBody;
87
+ /**
88
+ * PRD #647 F1: true only for the prompts source ingest endpoint, the one
89
+ * untrusted route the raw-body cap is scoped to. Parses the pathname so a
90
+ * query string can't bypass (or wrongly trip) the cap.
91
+ *
92
+ * PRD #647 C2 (CodeRabbit): the cap check runs BEFORE route dispatch, so a
93
+ * non-canonical pathname must be normalized here or it slips past the cap and
94
+ * buffers an uncapped body (DoS). A strict `===` let `POST /api/v1/prompts/
95
+ * sources/` (trailing slash) — the same ingest surface — skip `maxBytes`.
96
+ * Collapse trailing slashes (keeping a bare "/" intact) before comparing.
97
+ */
98
+ private isPromptsIngestRequest;
77
99
  stop(): Promise<void>;
78
100
  isReady(): boolean;
79
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AA8EtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAcvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAmBD,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAC,CAAkC;IACrD,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAM;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IA6BjD;;;OAGG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAQ7C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA2CvB;;OAEG;IACH,OAAO,CAAC,WAAW;IA8KnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;;OAIG;YACW,mBAAmB;IA6CjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAed,kBAAkB;YAwRlB,gBAAgB;IAexB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3B,OAAO,IAAI,OAAO;CAGnB"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/interfaces/mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAgFtC,OAAO,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAcvD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAqDD,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,UAAU,CAAC,CAAkC;IACrD,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,cAAc,CAAC,CAAiC;IACxD,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAA6B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAM;gBAEZ,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IA6BjD;;;OAGG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAQ7C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA2CvB;;OAEG;IACH,OAAO,CAAC,WAAW;IA8KnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;;;OAIG;YACW,mBAAmB;IA6CjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,iBAAiB;IAInB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAed,kBAAkB;IA0ThC;;;;;;;;;OASG;YACW,gBAAgB;IAgD9B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,sBAAsB;IAWxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3B,OAAO,IAAI,OAAO;CAGnB"}
@@ -28,6 +28,8 @@ const impact_analysis_1 = require("../tools/impact-analysis");
28
28
  const prompts_1 = require("../tools/prompts");
29
29
  const rest_registry_1 = require("./rest-registry");
30
30
  const rest_api_1 = require("./rest-api");
31
+ const cors_headers_1 = require("./cors-headers");
32
+ const header_redaction_1 = require("./header-redaction");
31
33
  const oauth_1 = require("./oauth");
32
34
  const request_context_1 = require("./request-context");
33
35
  const rbac_1 = require("../core/rbac");
@@ -42,6 +44,37 @@ const plugin_registry_1 = require("../core/plugin-registry");
42
44
  const SESSION_TTL_MS = 60 * 60 * 1000;
43
45
  /** How often to check for expired sessions. */
44
46
  const SESSION_GC_INTERVAL_MS = 5 * 60 * 1000;
47
+ /**
48
+ * PRD #647 F1 — hard raw-body byte ceiling for the untrusted prompts source
49
+ * ingest endpoint (POST /api/v1/prompts/sources).
50
+ *
51
+ * parseRequestBody buffers the whole body before JSON.parse + per-file
52
+ * base64-decode, all of which allocate fully BEFORE the 256 KiB *decoded* cap
53
+ * in ingestPromptsSource — so without a raw ceiling a multi-GB authenticated
54
+ * POST OOMs the shared process. 512 KiB is:
55
+ * - comfortably ABOVE the largest valid manifest: 256 KiB decoded ≈ ~342 KiB
56
+ * base64 + JSON/path/mode overhead (~350 KiB raw), and
57
+ * - testably BELOW the ~1 MiB nginx-ingress limit the integration suite
58
+ * traverses, so the app returns 413 before the proxy would.
59
+ * The cap is scoped to the ingest route only (see parseRequestBody's maxBytes
60
+ * argument); every other endpoint keeps today's uncapped behavior.
61
+ */
62
+ const INGEST_MAX_RAW_BODY_BYTES = 512 * 1024;
63
+ /** Pathname of the prompts source ingest endpoint the raw-body cap is scoped to. */
64
+ const PROMPTS_INGEST_PATHNAME = '/api/v1/prompts/sources';
65
+ /**
66
+ * PRD #647 F1 — thrown by parseRequestBody when the raw request body exceeds the
67
+ * per-route ceiling, so the HTTP handler can map it to a 413 (matching the mock
68
+ * server's read-json-body.ts) instead of buffering an unbounded body.
69
+ */
70
+ class RequestBodyTooLargeError extends Error {
71
+ limit;
72
+ constructor(limit) {
73
+ super(`Request body exceeds ${limit} bytes`);
74
+ this.name = 'RequestBodyTooLargeError';
75
+ this.limit = limit;
76
+ }
77
+ }
45
78
  class MCPServer {
46
79
  dotAI;
47
80
  initialized = false;
@@ -423,15 +456,23 @@ class MCPServer {
423
456
  // Execute entire request within the span's context for proper propagation
424
457
  await api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), async () => {
425
458
  try {
459
+ // PRD #621: the forwarded token must never appear in logs. Redact
460
+ // credential-bearing headers (HIGH-1) AND scrub credentials from the
461
+ // request URL — a ?repo=https://user:token@host or a
462
+ // credential-bearing query param would otherwise leak verbatim
463
+ // (CodeRabbit Finding 1). sanitizeRequestUrlForLogging is the shared
464
+ // helper already used by the REST layer.
426
465
  this.logger.debug('HTTP request received', {
427
466
  method: req.method,
428
- url: req.url,
429
- headers: req.headers,
467
+ url: (0, rest_api_1.sanitizeRequestUrlForLogging)(req.url),
468
+ headers: (0, header_redaction_1.redactSensitiveHeaders)(req.headers),
430
469
  });
431
470
  // Handle CORS for browser-based clients
432
471
  res.setHeader('Access-Control-Allow-Origin', '*');
433
472
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
434
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Session-Id, Authorization, X-Dot-AI-Authorization');
473
+ // PRD #621 M2 / Decision 1: includes X-Dot-AI-Git-Token, kept in
474
+ // sync with the REST allowlist via cors-headers.ts.
475
+ res.setHeader('Access-Control-Allow-Headers', cors_headers_1.MCP_CORS_ALLOW_HEADERS);
435
476
  if (req.method === 'OPTIONS') {
436
477
  res.writeHead(204);
437
478
  res.end();
@@ -486,12 +527,34 @@ class MCPServer {
486
527
  // Parse request body for POST requests
487
528
  let body = undefined;
488
529
  if (req.method === 'POST') {
489
- body = await this.parseRequestBody(req);
530
+ // PRD #647 F1: cap the raw body for the untrusted ingest route
531
+ // only (default = today's uncapped behavior elsewhere) and map
532
+ // an oversize body to 413 (matches the mock server).
533
+ const maxBytes = this.isPromptsIngestRequest(req.url)
534
+ ? INGEST_MAX_RAW_BODY_BYTES
535
+ : undefined;
536
+ try {
537
+ body = await this.parseRequestBody(req, maxBytes);
538
+ }
539
+ catch (error) {
540
+ if (error instanceof RequestBodyTooLargeError) {
541
+ this.logger.warn('Request body too large', {
542
+ url: (0, rest_api_1.sanitizeRequestUrlForLogging)(req.url),
543
+ limit: error.limit,
544
+ });
545
+ (0, error_response_1.sendErrorResponse)(res, 413, 'PAYLOAD_TOO_LARGE', error.message);
546
+ endSpan(413);
547
+ return;
548
+ }
549
+ throw error;
550
+ }
490
551
  }
491
552
  // Check if this is a REST API request
492
553
  if (this.restApiRouter.isApiRequest(req.url || '')) {
493
554
  this.logger.debug('Routing to REST API handler', {
494
- url: req.url,
555
+ // PRD #647 M5 (F2): scrub credential-bearing ?repo=/?source=
556
+ // values before they reach the log (matches the REST handler).
557
+ url: (0, rest_api_1.sanitizeRequestUrlForLogging)(req.url),
495
558
  });
496
559
  // Mark span as REST API request
497
560
  span.setAttribute('request.type', 'rest-api');
@@ -593,11 +656,49 @@ class MCPServer {
593
656
  }).on('error', reject);
594
657
  });
595
658
  }
596
- async parseRequestBody(req) {
659
+ /**
660
+ * Buffer and JSON-parse the request body.
661
+ *
662
+ * PRD #647 F1: when `maxBytes` is supplied (the untrusted ingest route), the
663
+ * body is rejected with RequestBodyTooLargeError as soon as the declared
664
+ * Content-Length OR the accumulated bytes exceed the ceiling — so an
665
+ * authenticated multi-GB POST can't buffer unbounded and OOM the shared
666
+ * process. When `maxBytes` is omitted (every other endpoint), behavior is
667
+ * exactly as before: no cap.
668
+ */
669
+ async parseRequestBody(req, maxBytes) {
597
670
  return new Promise((resolve, reject) => {
671
+ // Reject up front on a declared Content-Length over the cap, so we never
672
+ // start buffering a body we already know is too large.
673
+ if (maxBytes !== undefined) {
674
+ const declaredLen = parseInt(req.headers['content-length'] || '0', 10);
675
+ if (!Number.isNaN(declaredLen) && declaredLen > maxBytes) {
676
+ reject(new RequestBodyTooLargeError(maxBytes));
677
+ return;
678
+ }
679
+ }
598
680
  let body = '';
599
- req.on('data', chunk => (body += chunk.toString()));
681
+ let received = 0;
682
+ let aborted = false;
683
+ req.on('data', chunk => {
684
+ if (aborted)
685
+ return;
686
+ // Defense-in-depth: enforce the cap against actual bytes in case the
687
+ // Content-Length header is absent or lies.
688
+ if (maxBytes !== undefined) {
689
+ received += chunk.length;
690
+ if (received > maxBytes) {
691
+ aborted = true;
692
+ req.destroy();
693
+ reject(new RequestBodyTooLargeError(maxBytes));
694
+ return;
695
+ }
696
+ }
697
+ body += chunk.toString();
698
+ });
600
699
  req.on('end', () => {
700
+ if (aborted)
701
+ return;
601
702
  try {
602
703
  resolve(body ? JSON.parse(body) : undefined);
603
704
  }
@@ -608,6 +709,29 @@ class MCPServer {
608
709
  req.on('error', reject);
609
710
  });
610
711
  }
712
+ /**
713
+ * PRD #647 F1: true only for the prompts source ingest endpoint, the one
714
+ * untrusted route the raw-body cap is scoped to. Parses the pathname so a
715
+ * query string can't bypass (or wrongly trip) the cap.
716
+ *
717
+ * PRD #647 C2 (CodeRabbit): the cap check runs BEFORE route dispatch, so a
718
+ * non-canonical pathname must be normalized here or it slips past the cap and
719
+ * buffers an uncapped body (DoS). A strict `===` let `POST /api/v1/prompts/
720
+ * sources/` (trailing slash) — the same ingest surface — skip `maxBytes`.
721
+ * Collapse trailing slashes (keeping a bare "/" intact) before comparing.
722
+ */
723
+ isPromptsIngestRequest(url) {
724
+ if (!url)
725
+ return false;
726
+ try {
727
+ const pathname = new URL(url, 'http://internal.invalid').pathname;
728
+ const normalized = pathname.replace(/\/+$/, '') || '/';
729
+ return normalized === PROMPTS_INGEST_PATHNAME;
730
+ }
731
+ catch {
732
+ return false;
733
+ }
734
+ }
611
735
  async stop() {
612
736
  // Stop OAuth provider pruning timer
613
737
  if (this.oauthProvider) {
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-generator.d.ts","sourceRoot":"","sources":["../../src/interfaces/openapi-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openapi-generator.d.ts","sourceRoot":"","sources":["../../src/interfaces/openapi-generator.ts"],"names":[],"mappings":"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"}
@@ -26,7 +26,13 @@ class OpenApiGenerator {
26
26
  specCache;
27
27
  lastCacheUpdate = 0;
28
28
  cacheValidityMs = 60000; // 1 minute
29
- schemaCache = new Map();
29
+ // Keyed on the Zod schema OBJECT identity, not a structural stringify: two
30
+ // distinct schemas that differ only in their `.describe()` text serialize to
31
+ // the same string, so a string key would conflate them and leak one schema's
32
+ // descriptions into the other's endpoint (e.g. the prompts list vs. render
33
+ // `?source=` query). Identity keying gives each schema object its own entry
34
+ // while a schema reused across routes still hits the cache.
35
+ schemaCache = new WeakMap();
30
36
  constructor(toolRegistry, logger, config = {}, routeRegistry) {
31
37
  this.toolRegistry = toolRegistry;
32
38
  this.routeRegistry = routeRegistry;
@@ -472,6 +478,7 @@ class OpenApiGenerator {
472
478
  404: 'Not found',
473
479
  405: 'Method not allowed',
474
480
  409: 'Conflict',
481
+ 413: 'Payload too large',
475
482
  422: 'Unprocessable entity',
476
483
  500: 'Internal server error',
477
484
  502: 'Bad gateway',
@@ -483,16 +490,15 @@ class OpenApiGenerator {
483
490
  * Convert Zod schema to JSON Schema with caching
484
491
  */
485
492
  zodSchemaToJsonSchema(schema) {
486
- const cacheKey = JSON.stringify(schema);
487
- if (this.schemaCache.has(cacheKey)) {
488
- return this.schemaCache.get(cacheKey);
493
+ if (this.schemaCache.has(schema)) {
494
+ return this.schemaCache.get(schema);
489
495
  }
490
496
  try {
491
497
  const result = zod_1.z.toJSONSchema(schema);
492
498
  // Remove $schema and additionalProperties (not valid in OpenAPI component schemas)
493
499
  delete result.$schema;
494
500
  delete result.additionalProperties;
495
- this.schemaCache.set(cacheKey, result);
501
+ this.schemaCache.set(schema, result);
496
502
  return result;
497
503
  }
498
504
  catch (error) {
@@ -9,6 +9,7 @@ import { RestToolRegistry, ToolInfo } from './rest-registry';
9
9
  import { RestRouteRegistry } from './rest-route-registry';
10
10
  import { Logger } from '../core/error-handling';
11
11
  import { DotAI } from '../core/index';
12
+ import { UserPromptsOverride } from '../core/user-prompts-loader';
12
13
  import { PluginManager } from '../core/plugin-manager';
13
14
  /**
14
15
  * Constant placeholder used when the request URL fails to parse and the
@@ -19,9 +20,11 @@ import { PluginManager } from '../core/plugin-manager';
19
20
  export declare const UNPARSEABLE_QUERY_PLACEHOLDER = "?<redacted-unparseable>";
20
21
  /**
21
22
  * F3: req.url is logged on every request; with PRD #581 the query string may
22
- * carry `?repo=<user-supplied-url>` whose value can include credentials. This
23
- * helper rewrites the `repo` value to its credential-scrubbed form so the
24
- * raw token doesn't reach the log. Everything else is preserved verbatim.
23
+ * carry `?repo=<user-supplied-url>` whose value can include credentials, and
24
+ * PRD #647 adds `?source=<identifier>` which is equally credential-bearing (it
25
+ * may be a `https://user:tok@host` git URL). This helper rewrites BOTH values
26
+ * to their credential-scrubbed form so the raw token doesn't reach the log.
27
+ * Everything else is preserved verbatim.
25
28
  *
26
29
  * CodeRabbit Major B: on parse failure, we no longer return the input
27
30
  * verbatim — an unparseable URL is more likely than a parseable one to hide
@@ -31,6 +34,47 @@ export declare const UNPARSEABLE_QUERY_PLACEHOLDER = "?<redacted-unparseable>";
31
34
  * '?' are pass-through (no risk).
32
35
  */
33
36
  export declare function sanitizeRequestUrlForLogging(url: string | undefined): string | undefined;
37
+ /**
38
+ * Extract and validate the per-request prompts override.
39
+ *
40
+ * Threads three optional, additive inputs from the request into a
41
+ * UserPromptsOverride (PRD #581 introduced `repo`; PRD #621 M1 adds `path`
42
+ * and `branch`):
43
+ * - repoParam → override.repoUrl (GET ?repo= / POST body `repo`)
44
+ * - pathParam → override.subPath (GET ?path= / POST body `path`)
45
+ * - branchParam → override.branch (GET ?branch= / POST body `branch`)
46
+ * - gitToken → override.gitToken (X-Dot-AI-Git-Token request header; M2)
47
+ *
48
+ * Returns:
49
+ * - { ok: true, override } when no `repo` is supplied (override undefined;
50
+ * any path/branch/token are ignored, since they only qualify an override —
51
+ * this keeps the no-`repo` / env-var-configured path unchanged).
52
+ * - { ok: true, override } when a syntactically valid override is supplied.
53
+ * - { ok: false, message } when the override fails validation (HTTP 400).
54
+ *
55
+ * The validation message is run through scrubCredentials so embedded tokens
56
+ * never reach the wire response.
57
+ *
58
+ * Backward compatibility (PRD #621, non-negotiable): when path/branch are
59
+ * absent or empty, the override carries `repoUrl` only — byte-identical to
60
+ * the PRD #581 behavior (same clone target: repo root, `main`). subPath and
61
+ * branch are populated ONLY for a non-empty value, so downstream defaults are
62
+ * untouched. The credential header is INERT unless a `?repo=` override is
63
+ * present: without a repo this returns `override: undefined` before the token
64
+ * is ever read, so the env-var path is unaffected by a forwarded header.
65
+ *
66
+ * Validation is delegated to getUserPromptsConfigFromOverride (scheme,
67
+ * sanitizeRelativePath for subPath, isValidGitBranch for branch) and happens
68
+ * BEFORE any clone or shared-cache mutation, so a rejected override can never
69
+ * corrupt the env-var-configured cache.
70
+ */
71
+ export declare function extractPromptsOverride(repoParam: unknown, pathParam?: unknown, branchParam?: unknown, gitToken?: string, sourceParam?: unknown): {
72
+ ok: true;
73
+ override?: UserPromptsOverride;
74
+ } | {
75
+ ok: false;
76
+ message: string;
77
+ };
34
78
  /**
35
79
  * HTTP status codes for REST responses
36
80
  */
@@ -233,18 +277,6 @@ export declare class RestApiRouter {
233
277
  * Returns container logs for a pod
234
278
  */
235
279
  private handleGetLogs;
236
- /**
237
- * Extract and validate the per-request `repo` override (PRD #581).
238
- *
239
- * Returns:
240
- * - { ok: true, override } when no repo param is supplied, override is undefined.
241
- * - { ok: true, override } when a syntactically valid override URL is supplied.
242
- * - { ok: false, message } when the override fails validation (HTTP 400).
243
- *
244
- * The validation message is run through scrubCredentials so embedded tokens
245
- * never reach the wire response.
246
- */
247
- private extractPromptsOverride;
248
280
  /**
249
281
  * Handle prompts list requests
250
282
  */
@@ -257,6 +289,18 @@ export declare class RestApiRouter {
257
289
  * Handle prompts cache refresh requests (PRD #386, extended PRD #581)
258
290
  */
259
291
  private handlePromptsCacheRefresh;
292
+ /**
293
+ * Handle prompts source ingestion (PRD #647 M2).
294
+ *
295
+ * Accepts a JSON manifest { source, contentHash, files:[{path, content(base64),
296
+ * mode}] }, base64-decodes and caches the uploaded skill source keyed by its
297
+ * `source` identifier in the in-memory ingested cache. A later
298
+ * POST /api/v1/prompts/:promptName?source=<identifier> renders it through the
299
+ * existing render path with no git operation. The (scrubbed) source is echoed
300
+ * back. Bearer-gated by the same checkBearerAuth path as every non-OpenAPI
301
+ * request.
302
+ */
303
+ private handlePromptsSourceIngest;
260
304
  /**
261
305
  * Handle visualization requests (PRD #317)
262
306
  * Returns structured visualization data for a query session
@@ -1 +1 @@
1
- {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/rest-api.ts"],"names":[],"mappings":"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"}