@kya-os/mcp-i-cloudflare 1.6.23 → 1.6.25
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/dist/__tests__/e2e/test-config.d.ts +37 -0
- package/dist/__tests__/e2e/test-config.d.ts.map +1 -0
- package/dist/__tests__/e2e/test-config.js +62 -0
- package/dist/__tests__/e2e/test-config.js.map +1 -0
- package/dist/utils/client-info.d.ts +69 -0
- package/dist/utils/client-info.d.ts.map +1 -0
- package/dist/utils/client-info.js +178 -0
- package/dist/utils/client-info.js.map +1 -0
- package/dist/utils/error-formatter.d.ts +103 -0
- package/dist/utils/error-formatter.d.ts.map +1 -0
- package/dist/utils/error-formatter.js +245 -0
- package/dist/utils/error-formatter.js.map +1 -0
- package/dist/utils/initialize-context.d.ts +91 -0
- package/dist/utils/initialize-context.d.ts.map +1 -0
- package/dist/utils/initialize-context.js +169 -0
- package/dist/utils/initialize-context.js.map +1 -0
- package/dist/utils/oauth-identity.d.ts +58 -0
- package/dist/utils/oauth-identity.d.ts.map +1 -0
- package/dist/utils/oauth-identity.js +215 -0
- package/dist/utils/oauth-identity.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E Test Configuration
|
|
3
|
+
*
|
|
4
|
+
* This file contains configuration for end-to-end tests that use real AgentShield API.
|
|
5
|
+
* Set these environment variables before running E2E tests:
|
|
6
|
+
*
|
|
7
|
+
* ```bash
|
|
8
|
+
* export E2E_AGENTSHIELD_API_KEY="sk_test_..."
|
|
9
|
+
* export E2E_AGENTSHIELD_PROJECT_ID="test-project-id"
|
|
10
|
+
* export E2E_AGENTSHIELD_API_URL="https://kya.vouched.id" # Optional, defaults to production
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Or create a `.env.e2e` file in the package root:
|
|
14
|
+
* ```
|
|
15
|
+
* E2E_AGENTSHIELD_API_KEY=sk_test_...
|
|
16
|
+
* E2E_AGENTSHIELD_PROJECT_ID=test-project-id
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export interface E2ETestConfig {
|
|
20
|
+
apiKey: string;
|
|
21
|
+
projectId: string;
|
|
22
|
+
apiUrl: string;
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load E2E test configuration from environment variables
|
|
27
|
+
*/
|
|
28
|
+
export declare function loadE2EConfig(): E2ETestConfig | null;
|
|
29
|
+
/**
|
|
30
|
+
* Check if E2E tests should run
|
|
31
|
+
*/
|
|
32
|
+
export declare function shouldRunE2ETests(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get E2E test configuration or throw if not configured
|
|
35
|
+
*/
|
|
36
|
+
export declare function getE2EConfig(): E2ETestConfig;
|
|
37
|
+
//# sourceMappingURL=test-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-config.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/test-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAWH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,aAAa,GAAG,IAAI,CAyBpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,aAAa,CAU5C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E Test Configuration
|
|
3
|
+
*
|
|
4
|
+
* This file contains configuration for end-to-end tests that use real AgentShield API.
|
|
5
|
+
* Set these environment variables before running E2E tests:
|
|
6
|
+
*
|
|
7
|
+
* ```bash
|
|
8
|
+
* export E2E_AGENTSHIELD_API_KEY="sk_test_..."
|
|
9
|
+
* export E2E_AGENTSHIELD_PROJECT_ID="test-project-id"
|
|
10
|
+
* export E2E_AGENTSHIELD_API_URL="https://kya.vouched.id" # Optional, defaults to production
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Or create a `.env.e2e` file in the package root:
|
|
14
|
+
* ```
|
|
15
|
+
* E2E_AGENTSHIELD_API_KEY=sk_test_...
|
|
16
|
+
* E2E_AGENTSHIELD_PROJECT_ID=test-project-id
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Load E2E test configuration from environment variables
|
|
21
|
+
*/
|
|
22
|
+
export function loadE2EConfig() {
|
|
23
|
+
// Access environment variables - works in Node.js (vitest) environment
|
|
24
|
+
const apiKey = typeof process !== "undefined" && process.env
|
|
25
|
+
? process.env.E2E_AGENTSHIELD_API_KEY
|
|
26
|
+
: undefined;
|
|
27
|
+
const projectId = typeof process !== "undefined" && process.env
|
|
28
|
+
? process.env.E2E_AGENTSHIELD_PROJECT_ID
|
|
29
|
+
: undefined;
|
|
30
|
+
const apiUrl = typeof process !== "undefined" && process.env
|
|
31
|
+
? process.env.E2E_AGENTSHIELD_API_URL || "https://kya.vouched.id"
|
|
32
|
+
: "https://kya.vouched.id";
|
|
33
|
+
if (!apiKey || !projectId) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
apiKey,
|
|
38
|
+
projectId,
|
|
39
|
+
apiUrl,
|
|
40
|
+
enabled: true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if E2E tests should run
|
|
45
|
+
*/
|
|
46
|
+
export function shouldRunE2ETests() {
|
|
47
|
+
const config = loadE2EConfig();
|
|
48
|
+
return config !== null && config.enabled;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get E2E test configuration or throw if not configured
|
|
52
|
+
*/
|
|
53
|
+
export function getE2EConfig() {
|
|
54
|
+
const config = loadE2EConfig();
|
|
55
|
+
if (!config) {
|
|
56
|
+
throw new Error("E2E tests require E2E_AGENTSHIELD_API_KEY and E2E_AGENTSHIELD_PROJECT_ID environment variables.\n" +
|
|
57
|
+
"Set them in your environment or create a .env.e2e file.\n" +
|
|
58
|
+
"See packages/mcp-i-cloudflare/src/__tests__/e2e/test-config.ts for details.");
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=test-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-config.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/test-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAkBH;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,uEAAuE;IACvE,MAAM,MAAM,GACV,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG;QAC3C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACrC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,SAAS,GACb,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG;QAC3C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B;QACxC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,MAAM,GACV,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG;QAC3C,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,wBAAwB;QACjE,CAAC,CAAC,wBAAwB,CAAC;IAE/B,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,MAAM;QACN,SAAS;QACT,MAAM;QACN,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,mGAAmG;YACjG,2DAA2D;YAC3D,6EAA6E,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Info Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles MCP client information extraction, normalization, and handshake payload preparation.
|
|
5
|
+
* This consolidates logic for working with client metadata across initialize and handshake.
|
|
6
|
+
*/
|
|
7
|
+
import type { HandshakeRequest, MCPClientCapabilities } from "@kya-os/contracts/handshake";
|
|
8
|
+
import type { MCPClientInfo as SessionClientInfo } from "../types/client";
|
|
9
|
+
/**
|
|
10
|
+
* Initialize context with client information
|
|
11
|
+
*/
|
|
12
|
+
export interface InitializeContext {
|
|
13
|
+
timestamp: number;
|
|
14
|
+
protocolVersion?: string;
|
|
15
|
+
capabilities?: MCPClientCapabilities;
|
|
16
|
+
clientInfo?: Partial<SessionClientInfo>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Normalize client info from various formats
|
|
20
|
+
*
|
|
21
|
+
* @param value Client info from request (could be from initialize or handshake)
|
|
22
|
+
* @returns Normalized client info or undefined if invalid
|
|
23
|
+
*/
|
|
24
|
+
export declare function normalizeClientInfo(value: unknown): Partial<SessionClientInfo> | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Extract MCP client information from handshake request and initialize context
|
|
27
|
+
*
|
|
28
|
+
* @param request Handshake request
|
|
29
|
+
* @param initializeContext Optional context from previous initialize call
|
|
30
|
+
* @returns Extracted and normalized client info or undefined
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractMCPClient(request: HandshakeRequest, initializeContext?: InitializeContext): SessionClientInfo | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Prepare handshake payload with client information from initialize context
|
|
35
|
+
*
|
|
36
|
+
* @param params Original handshake request parameters
|
|
37
|
+
* @param initializeContext Optional context from previous initialize call
|
|
38
|
+
* @returns Enhanced handshake request with client info
|
|
39
|
+
*/
|
|
40
|
+
export declare function prepareHandshakePayload(params: HandshakeRequest, initializeContext?: InitializeContext): HandshakeRequest;
|
|
41
|
+
/**
|
|
42
|
+
* Clone capabilities object (deep copy)
|
|
43
|
+
*
|
|
44
|
+
* @param capabilities Capabilities to clone
|
|
45
|
+
* @returns Cloned capabilities or undefined
|
|
46
|
+
*/
|
|
47
|
+
export declare function cloneCapabilities(capabilities: unknown): MCPClientCapabilities | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Type guard for record objects
|
|
50
|
+
*
|
|
51
|
+
* @param value Value to check
|
|
52
|
+
* @returns true if value is a record object
|
|
53
|
+
*/
|
|
54
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* Extract client ID from client info if available
|
|
57
|
+
*
|
|
58
|
+
* @param clientInfo Client info object
|
|
59
|
+
* @returns Client ID or undefined
|
|
60
|
+
*/
|
|
61
|
+
export declare function extractClientId(clientInfo: unknown): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Merge client info from multiple sources
|
|
64
|
+
*
|
|
65
|
+
* @param sources Array of potential client info sources (later sources override earlier)
|
|
66
|
+
* @returns Merged client info
|
|
67
|
+
*/
|
|
68
|
+
export declare function mergeClientInfo(...sources: (Partial<SessionClientInfo> | undefined)[]): Partial<SessionClientInfo>;
|
|
69
|
+
//# sourceMappingURL=client-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-info.d.ts","sourceRoot":"","sources":["../../src/utils/client-info.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAuCxC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EACzB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,iBAAiB,GAAG,SAAS,CAkD/B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,gBAAgB,CA8BlB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,OAAO,GACpB,qBAAqB,GAAG,SAAS,CAMnC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAWvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,OAAO,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC,EAAE,GACrD,OAAO,CAAC,iBAAiB,CAAC,CAU5B"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Info Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles MCP client information extraction, normalization, and handshake payload preparation.
|
|
5
|
+
* This consolidates logic for working with client metadata across initialize and handshake.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Normalize client info from various formats
|
|
9
|
+
*
|
|
10
|
+
* @param value Client info from request (could be from initialize or handshake)
|
|
11
|
+
* @returns Normalized client info or undefined if invalid
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeClientInfo(value) {
|
|
14
|
+
if (!isRecord(value)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const normalized = {};
|
|
18
|
+
const record = value;
|
|
19
|
+
const name = record.name;
|
|
20
|
+
if (typeof name === "string" && name.trim().length > 0) {
|
|
21
|
+
normalized.name = name.trim();
|
|
22
|
+
}
|
|
23
|
+
const title = record.title;
|
|
24
|
+
if (typeof title === "string" && title.trim().length > 0) {
|
|
25
|
+
normalized.title = title.trim();
|
|
26
|
+
}
|
|
27
|
+
const version = record.version;
|
|
28
|
+
if (typeof version === "string" && version.trim().length > 0) {
|
|
29
|
+
normalized.version = version.trim();
|
|
30
|
+
}
|
|
31
|
+
const platform = record.platform;
|
|
32
|
+
if (typeof platform === "string" && platform.trim().length > 0) {
|
|
33
|
+
normalized.platform = platform.trim();
|
|
34
|
+
}
|
|
35
|
+
const vendor = record.vendor;
|
|
36
|
+
if (typeof vendor === "string" && vendor.trim().length > 0) {
|
|
37
|
+
normalized.vendor = vendor.trim();
|
|
38
|
+
}
|
|
39
|
+
const persistentId = record.persistentId;
|
|
40
|
+
if (typeof persistentId === "string" && persistentId.trim().length > 0) {
|
|
41
|
+
normalized.persistentId = persistentId.trim();
|
|
42
|
+
}
|
|
43
|
+
return Object.keys(normalized).length > 0 ? normalized : undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Extract MCP client information from handshake request and initialize context
|
|
47
|
+
*
|
|
48
|
+
* @param request Handshake request
|
|
49
|
+
* @param initializeContext Optional context from previous initialize call
|
|
50
|
+
* @returns Extracted and normalized client info or undefined
|
|
51
|
+
*/
|
|
52
|
+
export function extractMCPClient(request, initializeContext) {
|
|
53
|
+
const fromHandshake = normalizeClientInfo(request.clientInfo);
|
|
54
|
+
const merged = {
|
|
55
|
+
...(initializeContext?.clientInfo ?? {}),
|
|
56
|
+
...(fromHandshake ?? {}),
|
|
57
|
+
};
|
|
58
|
+
const handshakeClientId = isRecord(request.clientInfo) &&
|
|
59
|
+
typeof request.clientInfo.clientId === "string" &&
|
|
60
|
+
request.clientInfo.clientId.trim().length > 0
|
|
61
|
+
? request.clientInfo.clientId.trim()
|
|
62
|
+
: undefined;
|
|
63
|
+
const hasClientMetadata = Object.keys(merged).length > 0 ||
|
|
64
|
+
handshakeClientId ||
|
|
65
|
+
typeof request.clientProtocolVersion === "string" ||
|
|
66
|
+
isRecord(request.clientCapabilities);
|
|
67
|
+
if (!hasClientMetadata) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
const nameValue = merged.name;
|
|
71
|
+
const name = typeof nameValue === "string" && nameValue.trim().length > 0
|
|
72
|
+
? nameValue.trim()
|
|
73
|
+
: "unknown";
|
|
74
|
+
const clientId = handshakeClientId || crypto.randomUUID();
|
|
75
|
+
const capabilities = isRecord(request.clientCapabilities)
|
|
76
|
+
? request.clientCapabilities
|
|
77
|
+
: initializeContext?.capabilities;
|
|
78
|
+
return {
|
|
79
|
+
name,
|
|
80
|
+
title: merged.title,
|
|
81
|
+
version: merged.version,
|
|
82
|
+
platform: merged.platform,
|
|
83
|
+
vendor: merged.vendor,
|
|
84
|
+
persistentId: merged.persistentId,
|
|
85
|
+
protocolVersion: request.clientProtocolVersion ??
|
|
86
|
+
initializeContext?.protocolVersion ??
|
|
87
|
+
merged.protocolVersion,
|
|
88
|
+
capabilities,
|
|
89
|
+
clientId,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Prepare handshake payload with client information from initialize context
|
|
94
|
+
*
|
|
95
|
+
* @param params Original handshake request parameters
|
|
96
|
+
* @param initializeContext Optional context from previous initialize call
|
|
97
|
+
* @returns Enhanced handshake request with client info
|
|
98
|
+
*/
|
|
99
|
+
export function prepareHandshakePayload(params, initializeContext) {
|
|
100
|
+
const payload = {
|
|
101
|
+
...params,
|
|
102
|
+
};
|
|
103
|
+
if (!payload.clientProtocolVersion && initializeContext?.protocolVersion) {
|
|
104
|
+
payload.clientProtocolVersion = initializeContext.protocolVersion;
|
|
105
|
+
}
|
|
106
|
+
if (!payload.clientCapabilities && initializeContext?.capabilities) {
|
|
107
|
+
payload.clientCapabilities = initializeContext.capabilities;
|
|
108
|
+
}
|
|
109
|
+
if (!payload.clientInfo && initializeContext?.clientInfo?.name) {
|
|
110
|
+
const source = initializeContext.clientInfo;
|
|
111
|
+
const name = source.name;
|
|
112
|
+
if (!name) {
|
|
113
|
+
return payload;
|
|
114
|
+
}
|
|
115
|
+
payload.clientInfo = {
|
|
116
|
+
name,
|
|
117
|
+
...(source.title ? { title: source.title } : {}),
|
|
118
|
+
...(source.version ? { version: source.version } : {}),
|
|
119
|
+
...(source.platform ? { platform: source.platform } : {}),
|
|
120
|
+
...(source.vendor ? { vendor: source.vendor } : {}),
|
|
121
|
+
...(source.persistentId ? { persistentId: source.persistentId } : {}),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return payload;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Clone capabilities object (deep copy)
|
|
128
|
+
*
|
|
129
|
+
* @param capabilities Capabilities to clone
|
|
130
|
+
* @returns Cloned capabilities or undefined
|
|
131
|
+
*/
|
|
132
|
+
export function cloneCapabilities(capabilities) {
|
|
133
|
+
if (!isRecord(capabilities)) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
return JSON.parse(JSON.stringify(capabilities));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Type guard for record objects
|
|
140
|
+
*
|
|
141
|
+
* @param value Value to check
|
|
142
|
+
* @returns true if value is a record object
|
|
143
|
+
*/
|
|
144
|
+
export function isRecord(value) {
|
|
145
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Extract client ID from client info if available
|
|
149
|
+
*
|
|
150
|
+
* @param clientInfo Client info object
|
|
151
|
+
* @returns Client ID or undefined
|
|
152
|
+
*/
|
|
153
|
+
export function extractClientId(clientInfo) {
|
|
154
|
+
if (!isRecord(clientInfo)) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
const clientId = clientInfo.clientId;
|
|
158
|
+
if (typeof clientId === "string" && clientId.trim().length > 0) {
|
|
159
|
+
return clientId.trim();
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Merge client info from multiple sources
|
|
165
|
+
*
|
|
166
|
+
* @param sources Array of potential client info sources (later sources override earlier)
|
|
167
|
+
* @returns Merged client info
|
|
168
|
+
*/
|
|
169
|
+
export function mergeClientInfo(...sources) {
|
|
170
|
+
const merged = {};
|
|
171
|
+
for (const source of sources) {
|
|
172
|
+
if (source) {
|
|
173
|
+
Object.assign(merged, source);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return merged;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=client-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-info.js","sourceRoot":"","sources":["../../src/utils/client-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Formatter Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent JSON-RPC error response formatting for all error types.
|
|
5
|
+
* Handles special cases like DelegationRequiredError and OAuthRequiredError.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* JSON-RPC error response structure
|
|
9
|
+
*/
|
|
10
|
+
export interface JsonRpcErrorResponse {
|
|
11
|
+
jsonrpc: string;
|
|
12
|
+
id: unknown;
|
|
13
|
+
error: {
|
|
14
|
+
code: number;
|
|
15
|
+
message: string;
|
|
16
|
+
data?: any;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error codes for different error types
|
|
21
|
+
*/
|
|
22
|
+
export declare const ERROR_CODES: {
|
|
23
|
+
readonly PARSE_ERROR: -32700;
|
|
24
|
+
readonly INVALID_REQUEST: -32600;
|
|
25
|
+
readonly METHOD_NOT_FOUND: -32601;
|
|
26
|
+
readonly INVALID_PARAMS: -32602;
|
|
27
|
+
readonly INTERNAL_ERROR: -32603;
|
|
28
|
+
readonly DELEGATION_REQUIRED: -32001;
|
|
29
|
+
readonly OAUTH_REQUIRED: -32002;
|
|
30
|
+
readonly AUTHORIZATION_REQUIRED: -32003;
|
|
31
|
+
readonly SESSION_EXPIRED: -32004;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Format a generic error into JSON-RPC response
|
|
35
|
+
*
|
|
36
|
+
* @param error The error to format
|
|
37
|
+
* @param id Request ID from JSON-RPC request
|
|
38
|
+
* @returns Formatted JSON-RPC error response
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatJsonRpcError(error: unknown, id: unknown): JsonRpcErrorResponse;
|
|
41
|
+
/**
|
|
42
|
+
* Format DelegationRequiredError into JSON-RPC response
|
|
43
|
+
*
|
|
44
|
+
* @param error Delegation required error
|
|
45
|
+
* @param id Request ID
|
|
46
|
+
* @returns Formatted error response with consent URL
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatDelegationError(error: any, id: unknown): JsonRpcErrorResponse;
|
|
49
|
+
/**
|
|
50
|
+
* Format OAuthRequiredError into JSON-RPC response
|
|
51
|
+
*
|
|
52
|
+
* @param error OAuth required error
|
|
53
|
+
* @param id Request ID
|
|
54
|
+
* @returns Formatted error response with OAuth URL
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatOAuthError(error: any, id: unknown): JsonRpcErrorResponse;
|
|
57
|
+
/**
|
|
58
|
+
* Check if error is a DelegationRequiredError
|
|
59
|
+
*
|
|
60
|
+
* @param error Error to check
|
|
61
|
+
* @returns true if it's a delegation required error
|
|
62
|
+
*/
|
|
63
|
+
export declare function isDelegationRequiredError(error: unknown): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Check if error is an OAuthRequiredError
|
|
66
|
+
*
|
|
67
|
+
* @param error Error to check
|
|
68
|
+
* @returns true if it's an OAuth required error
|
|
69
|
+
*/
|
|
70
|
+
export declare function isOAuthRequiredError(error: unknown): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Format method not found error
|
|
73
|
+
*
|
|
74
|
+
* @param method The method that was not found
|
|
75
|
+
* @param id Request ID
|
|
76
|
+
* @returns Formatted error response
|
|
77
|
+
*/
|
|
78
|
+
export declare function formatMethodNotFoundError(method: string, id: unknown): JsonRpcErrorResponse;
|
|
79
|
+
/**
|
|
80
|
+
* Format tool not found error
|
|
81
|
+
*
|
|
82
|
+
* @param toolName The tool that was not found
|
|
83
|
+
* @param id Request ID
|
|
84
|
+
* @returns Formatted error response
|
|
85
|
+
*/
|
|
86
|
+
export declare function formatToolNotFoundError(toolName: string, id: unknown): JsonRpcErrorResponse;
|
|
87
|
+
/**
|
|
88
|
+
* Format session expired error
|
|
89
|
+
*
|
|
90
|
+
* @param sessionId The expired session ID
|
|
91
|
+
* @param id Request ID
|
|
92
|
+
* @returns Formatted error response
|
|
93
|
+
*/
|
|
94
|
+
export declare function formatSessionExpiredError(sessionId: string, id: unknown): JsonRpcErrorResponse;
|
|
95
|
+
/**
|
|
96
|
+
* Create a success response wrapper
|
|
97
|
+
*
|
|
98
|
+
* @param result The result to wrap
|
|
99
|
+
* @param id Request ID
|
|
100
|
+
* @returns JSON-RPC success response
|
|
101
|
+
*/
|
|
102
|
+
export declare function formatSuccessResponse(result: any, id: unknown): any;
|
|
103
|
+
//# sourceMappingURL=error-formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/error-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,GAAG,CAAC;KACZ,CAAC;CACH;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;CAad,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CAoDpF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CA4BnF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CA8B9E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAW5D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CAS3F;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CAS3F;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,oBAAoB,CAY9F;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,GAAG,GAAG,CAMnE"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Formatter Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent JSON-RPC error response formatting for all error types.
|
|
5
|
+
* Handles special cases like DelegationRequiredError and OAuthRequiredError.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error codes for different error types
|
|
9
|
+
*/
|
|
10
|
+
export const ERROR_CODES = {
|
|
11
|
+
// Standard JSON-RPC error codes
|
|
12
|
+
PARSE_ERROR: -32700,
|
|
13
|
+
INVALID_REQUEST: -32600,
|
|
14
|
+
METHOD_NOT_FOUND: -32601,
|
|
15
|
+
INVALID_PARAMS: -32602,
|
|
16
|
+
INTERNAL_ERROR: -32603,
|
|
17
|
+
// Custom error codes for MCP-I
|
|
18
|
+
DELEGATION_REQUIRED: -32001,
|
|
19
|
+
OAUTH_REQUIRED: -32002,
|
|
20
|
+
AUTHORIZATION_REQUIRED: -32003,
|
|
21
|
+
SESSION_EXPIRED: -32004,
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Format a generic error into JSON-RPC response
|
|
25
|
+
*
|
|
26
|
+
* @param error The error to format
|
|
27
|
+
* @param id Request ID from JSON-RPC request
|
|
28
|
+
* @returns Formatted JSON-RPC error response
|
|
29
|
+
*/
|
|
30
|
+
export function formatJsonRpcError(error, id) {
|
|
31
|
+
// Check if this is a special error type
|
|
32
|
+
if (isDelegationRequiredError(error)) {
|
|
33
|
+
return formatDelegationError(error, id);
|
|
34
|
+
}
|
|
35
|
+
if (isOAuthRequiredError(error)) {
|
|
36
|
+
return formatOAuthError(error, id);
|
|
37
|
+
}
|
|
38
|
+
// Generic error handling
|
|
39
|
+
let errorMessage = "Internal error";
|
|
40
|
+
let errorCode = ERROR_CODES.INTERNAL_ERROR;
|
|
41
|
+
let errorData = undefined;
|
|
42
|
+
if (error) {
|
|
43
|
+
// Check if it's an Error object with a message
|
|
44
|
+
if (typeof error === "object" && error instanceof Error && error.message) {
|
|
45
|
+
errorMessage = error.message;
|
|
46
|
+
}
|
|
47
|
+
// Check for custom error properties
|
|
48
|
+
else if (typeof error === "object" && "message" in error) {
|
|
49
|
+
errorMessage = String(error.message);
|
|
50
|
+
}
|
|
51
|
+
// For non-Error objects (strings, etc.), try to convert to string
|
|
52
|
+
else if (typeof error === "string") {
|
|
53
|
+
errorMessage = error;
|
|
54
|
+
}
|
|
55
|
+
// Extract additional error data if available
|
|
56
|
+
if (typeof error === "object" && "data" in error) {
|
|
57
|
+
errorData = error.data;
|
|
58
|
+
}
|
|
59
|
+
// Check for custom error code
|
|
60
|
+
if (typeof error === "object" && "code" in error) {
|
|
61
|
+
const customCode = error.code;
|
|
62
|
+
if (typeof customCode === "number") {
|
|
63
|
+
errorCode = customCode;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
jsonrpc: "2.0",
|
|
69
|
+
id,
|
|
70
|
+
error: {
|
|
71
|
+
code: errorCode,
|
|
72
|
+
message: errorMessage,
|
|
73
|
+
...(errorData !== undefined && { data: errorData }),
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Format DelegationRequiredError into JSON-RPC response
|
|
79
|
+
*
|
|
80
|
+
* @param error Delegation required error
|
|
81
|
+
* @param id Request ID
|
|
82
|
+
* @returns Formatted error response with consent URL
|
|
83
|
+
*/
|
|
84
|
+
export function formatDelegationError(error, id) {
|
|
85
|
+
const toolName = error.toolName || "unknown";
|
|
86
|
+
const requiredScopes = error.requiredScopes || [];
|
|
87
|
+
const consentUrl = error.consentUrl;
|
|
88
|
+
const resumeToken = error.resumeToken;
|
|
89
|
+
// Format message with consent URL in MCP format
|
|
90
|
+
let message = error.message || `Delegation required for tool "${toolName}"`;
|
|
91
|
+
if (consentUrl) {
|
|
92
|
+
message = `${message}. <authorization_url>${consentUrl}</authorization_url>`;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
jsonrpc: "2.0",
|
|
96
|
+
id,
|
|
97
|
+
error: {
|
|
98
|
+
code: ERROR_CODES.DELEGATION_REQUIRED,
|
|
99
|
+
message,
|
|
100
|
+
data: {
|
|
101
|
+
toolName,
|
|
102
|
+
requiredScopes,
|
|
103
|
+
consentUrl,
|
|
104
|
+
resumeToken,
|
|
105
|
+
// MCP-I specific: provide authorization URL for client to display
|
|
106
|
+
authorizationUrl: consentUrl,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Format OAuthRequiredError into JSON-RPC response
|
|
113
|
+
*
|
|
114
|
+
* @param error OAuth required error
|
|
115
|
+
* @param id Request ID
|
|
116
|
+
* @returns Formatted error response with OAuth URL
|
|
117
|
+
*/
|
|
118
|
+
export function formatOAuthError(error, id) {
|
|
119
|
+
const toolName = error.toolName || "unknown";
|
|
120
|
+
const requiredScopes = error.requiredScopes || [];
|
|
121
|
+
const provider = error.provider;
|
|
122
|
+
const oauthUrl = error.oauthUrl;
|
|
123
|
+
const resumeToken = error.resumeToken;
|
|
124
|
+
// Format message with OAuth URL in MCP format
|
|
125
|
+
let message = error.message || `OAuth required for tool "${toolName}"`;
|
|
126
|
+
if (oauthUrl) {
|
|
127
|
+
message = `${message}. <authorization_url>${oauthUrl}</authorization_url>`;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
jsonrpc: "2.0",
|
|
131
|
+
id,
|
|
132
|
+
error: {
|
|
133
|
+
code: ERROR_CODES.OAUTH_REQUIRED,
|
|
134
|
+
message,
|
|
135
|
+
data: {
|
|
136
|
+
toolName,
|
|
137
|
+
requiredScopes,
|
|
138
|
+
provider,
|
|
139
|
+
oauthUrl,
|
|
140
|
+
resumeToken,
|
|
141
|
+
// MCP-I specific: provide authorization URL for client to display
|
|
142
|
+
authorizationUrl: oauthUrl,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Check if error is a DelegationRequiredError
|
|
149
|
+
*
|
|
150
|
+
* @param error Error to check
|
|
151
|
+
* @returns true if it's a delegation required error
|
|
152
|
+
*/
|
|
153
|
+
export function isDelegationRequiredError(error) {
|
|
154
|
+
if (!error || typeof error !== "object") {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
const err = error;
|
|
158
|
+
return (err.name === "DelegationRequiredError" ||
|
|
159
|
+
err.constructor?.name === "DelegationRequiredError" ||
|
|
160
|
+
(err.code === ERROR_CODES.DELEGATION_REQUIRED && err.consentUrl));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Check if error is an OAuthRequiredError
|
|
164
|
+
*
|
|
165
|
+
* @param error Error to check
|
|
166
|
+
* @returns true if it's an OAuth required error
|
|
167
|
+
*/
|
|
168
|
+
export function isOAuthRequiredError(error) {
|
|
169
|
+
if (!error || typeof error !== "object") {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const err = error;
|
|
173
|
+
return (err.name === "OAuthRequiredError" ||
|
|
174
|
+
err.constructor?.name === "OAuthRequiredError" ||
|
|
175
|
+
(err.code === ERROR_CODES.OAUTH_REQUIRED && err.oauthUrl));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Format method not found error
|
|
179
|
+
*
|
|
180
|
+
* @param method The method that was not found
|
|
181
|
+
* @param id Request ID
|
|
182
|
+
* @returns Formatted error response
|
|
183
|
+
*/
|
|
184
|
+
export function formatMethodNotFoundError(method, id) {
|
|
185
|
+
return {
|
|
186
|
+
jsonrpc: "2.0",
|
|
187
|
+
id,
|
|
188
|
+
error: {
|
|
189
|
+
code: ERROR_CODES.METHOD_NOT_FOUND,
|
|
190
|
+
message: `Unknown method: ${method}`,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Format tool not found error
|
|
196
|
+
*
|
|
197
|
+
* @param toolName The tool that was not found
|
|
198
|
+
* @param id Request ID
|
|
199
|
+
* @returns Formatted error response
|
|
200
|
+
*/
|
|
201
|
+
export function formatToolNotFoundError(toolName, id) {
|
|
202
|
+
return {
|
|
203
|
+
jsonrpc: "2.0",
|
|
204
|
+
id,
|
|
205
|
+
error: {
|
|
206
|
+
code: ERROR_CODES.INVALID_PARAMS,
|
|
207
|
+
message: `Tool not found: ${toolName}`,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Format session expired error
|
|
213
|
+
*
|
|
214
|
+
* @param sessionId The expired session ID
|
|
215
|
+
* @param id Request ID
|
|
216
|
+
* @returns Formatted error response
|
|
217
|
+
*/
|
|
218
|
+
export function formatSessionExpiredError(sessionId, id) {
|
|
219
|
+
return {
|
|
220
|
+
jsonrpc: "2.0",
|
|
221
|
+
id,
|
|
222
|
+
error: {
|
|
223
|
+
code: ERROR_CODES.SESSION_EXPIRED,
|
|
224
|
+
message: "Session has expired",
|
|
225
|
+
data: {
|
|
226
|
+
sessionId,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create a success response wrapper
|
|
233
|
+
*
|
|
234
|
+
* @param result The result to wrap
|
|
235
|
+
* @param id Request ID
|
|
236
|
+
* @returns JSON-RPC success response
|
|
237
|
+
*/
|
|
238
|
+
export function formatSuccessResponse(result, id) {
|
|
239
|
+
return {
|
|
240
|
+
jsonrpc: "2.0",
|
|
241
|
+
id,
|
|
242
|
+
result,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=error-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-formatter.js","sourceRoot":"","sources":["../../src/utils/error-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initialize Context Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages MCP initialize context storage and retrieval for cross-request state.
|
|
5
|
+
* This allows us to preserve client info between initialize and handshake calls.
|
|
6
|
+
*/
|
|
7
|
+
import type { MCPClientCapabilities } from "@kya-os/contracts/handshake";
|
|
8
|
+
import type { MCPClientInfo as SessionClientInfo } from "../types/client";
|
|
9
|
+
/**
|
|
10
|
+
* Context stored from initialize request
|
|
11
|
+
*/
|
|
12
|
+
export interface InitializeContext {
|
|
13
|
+
timestamp: number;
|
|
14
|
+
protocolVersion?: string;
|
|
15
|
+
capabilities?: MCPClientCapabilities;
|
|
16
|
+
clientInfo?: Partial<SessionClientInfo>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Request metadata for fingerprinting
|
|
20
|
+
*/
|
|
21
|
+
export interface RequestMeta {
|
|
22
|
+
fingerprint?: string;
|
|
23
|
+
userAgent?: string;
|
|
24
|
+
ip?: string;
|
|
25
|
+
cfRay?: string;
|
|
26
|
+
request?: Request;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Manages initialize contexts for session continuity
|
|
30
|
+
*/
|
|
31
|
+
export declare class InitializeContextManager {
|
|
32
|
+
private contexts;
|
|
33
|
+
constructor();
|
|
34
|
+
/**
|
|
35
|
+
* Store initialize context for later use in handshake
|
|
36
|
+
*
|
|
37
|
+
* @param meta Request metadata for fingerprinting
|
|
38
|
+
* @param params Initialize request parameters
|
|
39
|
+
*/
|
|
40
|
+
store(meta: RequestMeta | undefined, params: unknown): void;
|
|
41
|
+
/**
|
|
42
|
+
* Consume initialize context (removes it after retrieval)
|
|
43
|
+
*
|
|
44
|
+
* @param meta Request metadata for fingerprinting
|
|
45
|
+
* @returns Initialize context if found and valid, undefined otherwise
|
|
46
|
+
*/
|
|
47
|
+
consume(meta: RequestMeta | undefined): InitializeContext | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Prune expired contexts
|
|
50
|
+
*/
|
|
51
|
+
private prune;
|
|
52
|
+
/**
|
|
53
|
+
* Normalize client info from various formats
|
|
54
|
+
*
|
|
55
|
+
* @param value Client info from request
|
|
56
|
+
* @returns Normalized client info or undefined
|
|
57
|
+
*/
|
|
58
|
+
private normalizeClientInfo;
|
|
59
|
+
/**
|
|
60
|
+
* Clone capabilities object (deep copy)
|
|
61
|
+
*
|
|
62
|
+
* @param capabilities Capabilities to clone
|
|
63
|
+
* @returns Cloned capabilities or undefined
|
|
64
|
+
*/
|
|
65
|
+
private cloneCapabilities;
|
|
66
|
+
/**
|
|
67
|
+
* Type guard for record objects
|
|
68
|
+
*
|
|
69
|
+
* @param value Value to check
|
|
70
|
+
* @returns true if value is a record object
|
|
71
|
+
*/
|
|
72
|
+
private isRecord;
|
|
73
|
+
/**
|
|
74
|
+
* Get current size of context cache (for monitoring)
|
|
75
|
+
*
|
|
76
|
+
* @returns Number of stored contexts
|
|
77
|
+
*/
|
|
78
|
+
size(): number;
|
|
79
|
+
/**
|
|
80
|
+
* Clear all contexts (for testing)
|
|
81
|
+
*/
|
|
82
|
+
clear(): void;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build request metadata from HTTP request
|
|
86
|
+
*
|
|
87
|
+
* @param request HTTP request
|
|
88
|
+
* @returns Request metadata with fingerprint
|
|
89
|
+
*/
|
|
90
|
+
export declare function buildRequestMeta(request: Request): RequestMeta;
|
|
91
|
+
//# sourceMappingURL=initialize-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize-context.d.ts","sourceRoot":"","sources":["../../src/utils/initialize-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAKD;;GAEG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAiC;;IAMjD;;;;;OAKG;IACH,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAqB3D;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS;IAoBrE;;OAEG;IACH,OAAO,CAAC,KAAK;IASb;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IA2C3B;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAIhB;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAsB9D"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initialize Context Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages MCP initialize context storage and retrieval for cross-request state.
|
|
5
|
+
* This allows us to preserve client info between initialize and handshake calls.
|
|
6
|
+
*/
|
|
7
|
+
// TTL for initialize contexts (60 seconds)
|
|
8
|
+
const INITIALIZE_CONTEXT_TTL_MS = 60_000;
|
|
9
|
+
/**
|
|
10
|
+
* Manages initialize contexts for session continuity
|
|
11
|
+
*/
|
|
12
|
+
export class InitializeContextManager {
|
|
13
|
+
contexts;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.contexts = new Map();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Store initialize context for later use in handshake
|
|
19
|
+
*
|
|
20
|
+
* @param meta Request metadata for fingerprinting
|
|
21
|
+
* @param params Initialize request parameters
|
|
22
|
+
*/
|
|
23
|
+
store(meta, params) {
|
|
24
|
+
if (!meta?.fingerprint || !this.isRecord(params)) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const protocolVersion = params.protocolVersion;
|
|
28
|
+
const capabilities = params.capabilities;
|
|
29
|
+
const clientInfo = this.normalizeClientInfo(params.clientInfo);
|
|
30
|
+
const context = {
|
|
31
|
+
timestamp: Date.now(),
|
|
32
|
+
protocolVersion: typeof protocolVersion === "string" ? protocolVersion : undefined,
|
|
33
|
+
capabilities: this.cloneCapabilities(capabilities),
|
|
34
|
+
clientInfo,
|
|
35
|
+
};
|
|
36
|
+
this.contexts.set(meta.fingerprint, context);
|
|
37
|
+
this.prune();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Consume initialize context (removes it after retrieval)
|
|
41
|
+
*
|
|
42
|
+
* @param meta Request metadata for fingerprinting
|
|
43
|
+
* @returns Initialize context if found and valid, undefined otherwise
|
|
44
|
+
*/
|
|
45
|
+
consume(meta) {
|
|
46
|
+
if (!meta?.fingerprint) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const context = this.contexts.get(meta.fingerprint);
|
|
50
|
+
if (!context) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
if (Date.now() - context.timestamp > INITIALIZE_CONTEXT_TTL_MS) {
|
|
54
|
+
this.contexts.delete(meta.fingerprint);
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
// Remove after consumption to prevent cross-session leakage
|
|
58
|
+
this.contexts.delete(meta.fingerprint);
|
|
59
|
+
return context;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Prune expired contexts
|
|
63
|
+
*/
|
|
64
|
+
prune() {
|
|
65
|
+
const now = Date.now();
|
|
66
|
+
for (const [key, context] of this.contexts.entries()) {
|
|
67
|
+
if (now - context.timestamp > INITIALIZE_CONTEXT_TTL_MS) {
|
|
68
|
+
this.contexts.delete(key);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Normalize client info from various formats
|
|
74
|
+
*
|
|
75
|
+
* @param value Client info from request
|
|
76
|
+
* @returns Normalized client info or undefined
|
|
77
|
+
*/
|
|
78
|
+
normalizeClientInfo(value) {
|
|
79
|
+
if (!this.isRecord(value)) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
const normalized = {};
|
|
83
|
+
const record = value;
|
|
84
|
+
const name = record.name;
|
|
85
|
+
if (typeof name === "string" && name.trim().length > 0) {
|
|
86
|
+
normalized.name = name.trim();
|
|
87
|
+
}
|
|
88
|
+
const title = record.title;
|
|
89
|
+
if (typeof title === "string" && title.trim().length > 0) {
|
|
90
|
+
normalized.title = title.trim();
|
|
91
|
+
}
|
|
92
|
+
const version = record.version;
|
|
93
|
+
if (typeof version === "string" && version.trim().length > 0) {
|
|
94
|
+
normalized.version = version.trim();
|
|
95
|
+
}
|
|
96
|
+
const platform = record.platform;
|
|
97
|
+
if (typeof platform === "string" && platform.trim().length > 0) {
|
|
98
|
+
normalized.platform = platform.trim();
|
|
99
|
+
}
|
|
100
|
+
const vendor = record.vendor;
|
|
101
|
+
if (typeof vendor === "string" && vendor.trim().length > 0) {
|
|
102
|
+
normalized.vendor = vendor.trim();
|
|
103
|
+
}
|
|
104
|
+
const persistentId = record.persistentId;
|
|
105
|
+
if (typeof persistentId === "string" && persistentId.trim().length > 0) {
|
|
106
|
+
normalized.persistentId = persistentId.trim();
|
|
107
|
+
}
|
|
108
|
+
return Object.keys(normalized).length > 0 ? normalized : undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Clone capabilities object (deep copy)
|
|
112
|
+
*
|
|
113
|
+
* @param capabilities Capabilities to clone
|
|
114
|
+
* @returns Cloned capabilities or undefined
|
|
115
|
+
*/
|
|
116
|
+
cloneCapabilities(capabilities) {
|
|
117
|
+
if (!this.isRecord(capabilities)) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return JSON.parse(JSON.stringify(capabilities));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Type guard for record objects
|
|
124
|
+
*
|
|
125
|
+
* @param value Value to check
|
|
126
|
+
* @returns true if value is a record object
|
|
127
|
+
*/
|
|
128
|
+
isRecord(value) {
|
|
129
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get current size of context cache (for monitoring)
|
|
133
|
+
*
|
|
134
|
+
* @returns Number of stored contexts
|
|
135
|
+
*/
|
|
136
|
+
size() {
|
|
137
|
+
return this.contexts.size;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Clear all contexts (for testing)
|
|
141
|
+
*/
|
|
142
|
+
clear() {
|
|
143
|
+
this.contexts.clear();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Build request metadata from HTTP request
|
|
148
|
+
*
|
|
149
|
+
* @param request HTTP request
|
|
150
|
+
* @returns Request metadata with fingerprint
|
|
151
|
+
*/
|
|
152
|
+
export function buildRequestMeta(request) {
|
|
153
|
+
const ip = request.headers.get("cf-connecting-ip") ??
|
|
154
|
+
request.headers.get("x-forwarded-for") ??
|
|
155
|
+
undefined;
|
|
156
|
+
const userAgent = request.headers.get("user-agent") ?? undefined;
|
|
157
|
+
const cfRay = request.headers.get("cf-ray") ?? undefined;
|
|
158
|
+
const origin = request.headers.get("origin") ?? undefined;
|
|
159
|
+
const secChUa = request.headers.get("sec-ch-ua") ?? undefined;
|
|
160
|
+
const fingerprintParts = [ip, userAgent, cfRay, origin, secChUa].filter((value) => typeof value === "string" && value.length > 0);
|
|
161
|
+
return {
|
|
162
|
+
fingerprint: fingerprintParts.length > 0 ? fingerprintParts.join("|") : undefined,
|
|
163
|
+
ip,
|
|
164
|
+
userAgent,
|
|
165
|
+
cfRay,
|
|
166
|
+
request, // Include request for cookie access
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=initialize-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialize-context.js","sourceRoot":"","sources":["../../src/utils/initialize-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH,2CAA2C;AAC3C,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAC3B,QAAQ,CAAiC;IAEjD;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAA6B,EAAE,MAAe;QAClD,IAAI,CAAC,IAAI,EAAE,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAC/C,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE/D,MAAM,OAAO,GAAsB;YACjC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,eAAe,EACb,OAAO,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;YACnE,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC;YAClD,UAAU;SACX,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAA6B;QACnC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,yBAAyB,EAAE,CAAC;YAC/D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,4DAA4D;QAC5D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,IAAI,GAAG,GAAG,OAAO,CAAC,SAAS,GAAG,yBAAyB,EAAE,CAAC;gBACxD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,mBAAmB,CACzB,KAAc;QAEd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,UAAU,GAA+B,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,KAAgC,CAAC;QAEhD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzD,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAClC,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QACtC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3D,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACzC,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvE,UAAU,CAAC,YAAY,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACK,iBAAiB,CACvB,YAAqB;QAErB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAA0B,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACK,QAAQ,CAAC,KAAc;QAC7B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC;IAED;;;;OAIG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,EAAE,GACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACvC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACtC,SAAS,CAAC;IACZ,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC;IAE9D,MAAM,gBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,CACrE,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAC1E,CAAC;IAEF,OAAO;QACL,WAAW,EACT,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QACtE,EAAE;QACF,SAAS;QACT,KAAK;QACL,OAAO,EAAE,oCAAoC;KAC9C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Identity Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles OAuth identity extraction and validation from HTTP requests.
|
|
5
|
+
* This module consolidates OAuth-related logic that was previously in the adapter.
|
|
6
|
+
*/
|
|
7
|
+
import type { OAuthIdentity } from "@kya-os/contracts/consent";
|
|
8
|
+
/**
|
|
9
|
+
* OAuth identity validation result
|
|
10
|
+
*/
|
|
11
|
+
export interface OAuthValidationResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extract OAuth identity from request cookies
|
|
17
|
+
*
|
|
18
|
+
* @param request - HTTP Request object
|
|
19
|
+
* @returns OAuthIdentity or null if not found/invalid
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractOAuthIdentityFromRequest(request: Request): OAuthIdentity | null;
|
|
22
|
+
/**
|
|
23
|
+
* Validate OAuth identity format and content
|
|
24
|
+
*
|
|
25
|
+
* Ensures:
|
|
26
|
+
* - Provider is non-empty string (1-50 chars)
|
|
27
|
+
* - Subject is non-empty string (1-255 chars)
|
|
28
|
+
* - Provider matches expected format (alphanumeric, hyphens, underscores)
|
|
29
|
+
* - Subject matches expected format (non-empty, reasonable length)
|
|
30
|
+
*
|
|
31
|
+
* @param identity - Parsed OAuth identity object
|
|
32
|
+
* @returns Validation result
|
|
33
|
+
*/
|
|
34
|
+
export declare function validateOAuthIdentity(identity: unknown): OAuthValidationResult;
|
|
35
|
+
/**
|
|
36
|
+
* Lookup User DID from OAuth identity mapping
|
|
37
|
+
*
|
|
38
|
+
* @param oauthIdentity OAuth identity to lookup
|
|
39
|
+
* @param delegationStorage KV namespace for storage
|
|
40
|
+
* @returns User DID or null if not found
|
|
41
|
+
*/
|
|
42
|
+
export declare function lookupUserDidFromOAuth(oauthIdentity: OAuthIdentity, delegationStorage: any): Promise<string | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Create a redacted OAuth identity for storage (PII protection)
|
|
45
|
+
*
|
|
46
|
+
* @param oauthIdentity Original OAuth identity
|
|
47
|
+
* @returns Redacted identity safe for storage
|
|
48
|
+
*/
|
|
49
|
+
export declare function redactOAuthIdentityForStorage(oauthIdentity: OAuthIdentity | null): any;
|
|
50
|
+
/**
|
|
51
|
+
* Test if an OAuth cookie value is valid
|
|
52
|
+
* Helper function for testing and debugging
|
|
53
|
+
*
|
|
54
|
+
* @param cookieValue Encoded cookie value
|
|
55
|
+
* @returns true if valid OAuth identity, false otherwise
|
|
56
|
+
*/
|
|
57
|
+
export declare function isValidOAuthCookie(cookieValue: string): boolean;
|
|
58
|
+
//# sourceMappingURL=oauth-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-identity.d.ts","sourceRoot":"","sources":["../../src/utils/oauth-identity.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAoCtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,qBAAqB,CAkH9E;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,GAAG,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BxB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,GAAG,GAAG,CAUtF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ/D"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Identity Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles OAuth identity extraction and validation from HTTP requests.
|
|
5
|
+
* This module consolidates OAuth-related logic that was previously in the adapter.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Extract OAuth identity from request cookies
|
|
9
|
+
*
|
|
10
|
+
* @param request - HTTP Request object
|
|
11
|
+
* @returns OAuthIdentity or null if not found/invalid
|
|
12
|
+
*/
|
|
13
|
+
export function extractOAuthIdentityFromRequest(request) {
|
|
14
|
+
try {
|
|
15
|
+
const cookieHeader = request.headers.get("Cookie");
|
|
16
|
+
if (!cookieHeader)
|
|
17
|
+
return null;
|
|
18
|
+
const cookies = cookieHeader.split("; ").map((c) => c.trim());
|
|
19
|
+
const oauthCookie = cookies.find((c) => c.startsWith("oauth_identity="));
|
|
20
|
+
if (!oauthCookie)
|
|
21
|
+
return null;
|
|
22
|
+
// Extract cookie value properly handling cases where value contains '='
|
|
23
|
+
// Find the first '=' which separates key from value, then take everything after it
|
|
24
|
+
const equalsIndex = oauthCookie.indexOf("=");
|
|
25
|
+
if (equalsIndex === -1)
|
|
26
|
+
return null;
|
|
27
|
+
const cookieValue = oauthCookie.substring(equalsIndex + 1);
|
|
28
|
+
const parsed = JSON.parse(decodeURIComponent(cookieValue));
|
|
29
|
+
// ✅ SECURITY: Validate OAuth identity format and content
|
|
30
|
+
const validationResult = validateOAuthIdentity(parsed);
|
|
31
|
+
if (!validationResult.valid) {
|
|
32
|
+
console.warn("[OAuth] ⚠️ OAuth identity validation failed:", validationResult.reason, { parsed });
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.warn("[OAuth] Failed to extract OAuth identity from cookies:", error);
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate OAuth identity format and content
|
|
44
|
+
*
|
|
45
|
+
* Ensures:
|
|
46
|
+
* - Provider is non-empty string (1-50 chars)
|
|
47
|
+
* - Subject is non-empty string (1-255 chars)
|
|
48
|
+
* - Provider matches expected format (alphanumeric, hyphens, underscores)
|
|
49
|
+
* - Subject matches expected format (non-empty, reasonable length)
|
|
50
|
+
*
|
|
51
|
+
* @param identity - Parsed OAuth identity object
|
|
52
|
+
* @returns Validation result
|
|
53
|
+
*/
|
|
54
|
+
export function validateOAuthIdentity(identity) {
|
|
55
|
+
// Check if identity is an object
|
|
56
|
+
if (!identity || typeof identity !== "object") {
|
|
57
|
+
return { valid: false, reason: "OAuth identity must be an object" };
|
|
58
|
+
}
|
|
59
|
+
const oauth = identity;
|
|
60
|
+
// Validate provider
|
|
61
|
+
if (!oauth.provider || typeof oauth.provider !== "string") {
|
|
62
|
+
return {
|
|
63
|
+
valid: false,
|
|
64
|
+
reason: "OAuth provider is required and must be a string",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const provider = oauth.provider.trim();
|
|
68
|
+
if (provider.length === 0) {
|
|
69
|
+
return { valid: false, reason: "OAuth provider cannot be empty" };
|
|
70
|
+
}
|
|
71
|
+
if (provider.length > 50) {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
reason: "OAuth provider must be 50 characters or less",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Provider format: alphanumeric, hyphens, underscores, dots (e.g., "google", "microsoft", "github", "custom-provider")
|
|
78
|
+
const providerPattern = /^[a-zA-Z0-9._-]+$/;
|
|
79
|
+
if (!providerPattern.test(provider)) {
|
|
80
|
+
return {
|
|
81
|
+
valid: false,
|
|
82
|
+
reason: `OAuth provider must match pattern [a-zA-Z0-9._-]: "${provider}"`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Validate subject
|
|
86
|
+
if (!oauth.subject || typeof oauth.subject !== "string") {
|
|
87
|
+
return {
|
|
88
|
+
valid: false,
|
|
89
|
+
reason: "OAuth subject is required and must be a string",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const subject = oauth.subject.trim();
|
|
93
|
+
if (subject.length === 0) {
|
|
94
|
+
return { valid: false, reason: "OAuth subject cannot be empty" };
|
|
95
|
+
}
|
|
96
|
+
if (subject.length > 255) {
|
|
97
|
+
return {
|
|
98
|
+
valid: false,
|
|
99
|
+
reason: "OAuth subject must be 255 characters or less",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Subject format: non-empty, reasonable characters (allows most Unicode, but prevents control chars)
|
|
103
|
+
// OAuth subjects can be numeric IDs, email-like strings, or other identifiers
|
|
104
|
+
const subjectPattern = /^[\S]+$/; // At least one non-whitespace character
|
|
105
|
+
if (!subjectPattern.test(subject)) {
|
|
106
|
+
return {
|
|
107
|
+
valid: false,
|
|
108
|
+
reason: `OAuth subject contains invalid characters: "${subject.substring(0, 20)}..."`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Validate optional email if present
|
|
112
|
+
if (oauth.email !== undefined) {
|
|
113
|
+
if (typeof oauth.email !== "string") {
|
|
114
|
+
return {
|
|
115
|
+
valid: false,
|
|
116
|
+
reason: "OAuth email must be a string if provided",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const email = oauth.email.trim();
|
|
120
|
+
if (email.length > 0) {
|
|
121
|
+
// Basic email format validation
|
|
122
|
+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
123
|
+
if (!emailPattern.test(email)) {
|
|
124
|
+
return {
|
|
125
|
+
valid: false,
|
|
126
|
+
reason: `OAuth email format invalid: "${email}"`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (email.length > 255) {
|
|
130
|
+
return {
|
|
131
|
+
valid: false,
|
|
132
|
+
reason: "OAuth email must be 255 characters or less",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Validate optional name if present
|
|
138
|
+
if (oauth.name !== undefined) {
|
|
139
|
+
if (typeof oauth.name !== "string") {
|
|
140
|
+
return {
|
|
141
|
+
valid: false,
|
|
142
|
+
reason: "OAuth name must be a string if provided",
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (oauth.name.length > 255) {
|
|
146
|
+
return {
|
|
147
|
+
valid: false,
|
|
148
|
+
reason: "OAuth name must be 255 characters or less",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { valid: true };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Lookup User DID from OAuth identity mapping
|
|
156
|
+
*
|
|
157
|
+
* @param oauthIdentity OAuth identity to lookup
|
|
158
|
+
* @param delegationStorage KV namespace for storage
|
|
159
|
+
* @returns User DID or null if not found
|
|
160
|
+
*/
|
|
161
|
+
export async function lookupUserDidFromOAuth(oauthIdentity, delegationStorage) {
|
|
162
|
+
if (!delegationStorage || !oauthIdentity?.provider || !oauthIdentity?.subject) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const { STORAGE_KEYS } = await import("../constants/storage-keys");
|
|
167
|
+
const oauthKey = STORAGE_KEYS.oauthIdentity(oauthIdentity.provider, oauthIdentity.subject);
|
|
168
|
+
const userDid = await delegationStorage.get(oauthKey, "text");
|
|
169
|
+
if (userDid) {
|
|
170
|
+
console.log("[OAuth] ✅ Retrieved persistent userDid from OAuth mapping:", {
|
|
171
|
+
provider: oauthIdentity.provider,
|
|
172
|
+
userDid: userDid.slice(0, 20) + "...",
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return userDid;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.warn("[OAuth] Failed to lookup userDid from OAuth mapping:", error);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Create a redacted OAuth identity for storage (PII protection)
|
|
184
|
+
*
|
|
185
|
+
* @param oauthIdentity Original OAuth identity
|
|
186
|
+
* @returns Redacted identity safe for storage
|
|
187
|
+
*/
|
|
188
|
+
export function redactOAuthIdentityForStorage(oauthIdentity) {
|
|
189
|
+
if (!oauthIdentity) {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
provider: oauthIdentity.provider,
|
|
194
|
+
subjectHash: oauthIdentity.subject.substring(0, 8), // Redact full subject
|
|
195
|
+
// Don't store email, name, or full subject for PII protection
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Test if an OAuth cookie value is valid
|
|
200
|
+
* Helper function for testing and debugging
|
|
201
|
+
*
|
|
202
|
+
* @param cookieValue Encoded cookie value
|
|
203
|
+
* @returns true if valid OAuth identity, false otherwise
|
|
204
|
+
*/
|
|
205
|
+
export function isValidOAuthCookie(cookieValue) {
|
|
206
|
+
try {
|
|
207
|
+
const parsed = JSON.parse(decodeURIComponent(cookieValue));
|
|
208
|
+
const result = validateOAuthIdentity(parsed);
|
|
209
|
+
return result.valid;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=oauth-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-identity.js","sourceRoot":"","sources":["../../src/utils/oauth-identity.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kya-os/mcp-i-cloudflare",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.25",
|
|
4
4
|
"description": "Cloudflare Workers adapter for MCP-I framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"prepublishOnly": "npm run build && node ../create-mcpi-app/scripts/validate-no-workspace.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@kya-os/contracts": "^1.6.
|
|
21
|
-
"@kya-os/mcp-i-core": "^1.3.
|
|
20
|
+
"@kya-os/contracts": "^1.6.4",
|
|
21
|
+
"@kya-os/mcp-i-core": "^1.3.10",
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.19.1",
|
|
23
23
|
"agents": "^0.2.21",
|
|
24
24
|
"base-x": "^5.0.0",
|