@kya-os/mcp-i-cloudflare 1.6.25 → 1.6.27
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/constants/storage-keys.d.ts +12 -0
- package/dist/constants/storage-keys.d.ts.map +1 -1
- package/dist/constants/storage-keys.js +12 -0
- package/dist/constants/storage-keys.js.map +1 -1
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -1
- package/dist/runtime/oauth-handler.d.ts.map +1 -1
- package/dist/runtime/oauth-handler.js +64 -0
- package/dist/runtime/oauth-handler.js.map +1 -1
- package/dist/services/admin.service.d.ts.map +1 -1
- package/dist/services/admin.service.js +31 -0
- package/dist/services/admin.service.js.map +1 -1
- package/dist/services/consent-page-renderer.d.ts +55 -0
- package/dist/services/consent-page-renderer.d.ts.map +1 -1
- package/dist/services/consent-page-renderer.js +284 -0
- package/dist/services/consent-page-renderer.js.map +1 -1
- package/dist/services/consent.service.d.ts +85 -15
- package/dist/services/consent.service.d.ts.map +1 -1
- package/dist/services/consent.service.js +530 -37
- package/dist/services/consent.service.js.map +1 -1
- package/dist/services/credential-auth.handler.d.ts +72 -0
- package/dist/services/credential-auth.handler.d.ts.map +1 -0
- package/dist/services/credential-auth.handler.js +203 -0
- package/dist/services/credential-auth.handler.js.map +1 -0
- package/dist/services/idp-token-storage.d.ts +54 -6
- package/dist/services/idp-token-storage.d.ts.map +1 -1
- package/dist/services/idp-token-storage.js +21 -6
- package/dist/services/idp-token-storage.js.map +1 -1
- package/package.json +3 -3
- package/dist/__tests__/e2e/test-config.d.ts +0 -37
- package/dist/__tests__/e2e/test-config.d.ts.map +0 -1
- package/dist/__tests__/e2e/test-config.js +0 -62
- package/dist/__tests__/e2e/test-config.js.map +0 -1
- package/dist/utils/client-info.d.ts +0 -69
- package/dist/utils/client-info.d.ts.map +0 -1
- package/dist/utils/client-info.js +0 -178
- package/dist/utils/client-info.js.map +0 -1
- package/dist/utils/error-formatter.d.ts +0 -103
- package/dist/utils/error-formatter.d.ts.map +0 -1
- package/dist/utils/error-formatter.js +0 -245
- package/dist/utils/error-formatter.js.map +0 -1
- package/dist/utils/initialize-context.d.ts +0 -91
- package/dist/utils/initialize-context.d.ts.map +0 -1
- package/dist/utils/initialize-context.js +0 -169
- package/dist/utils/initialize-context.js.map +0 -1
- package/dist/utils/oauth-identity.d.ts +0 -58
- package/dist/utils/oauth-identity.d.ts.map +0 -1
- package/dist/utils/oauth-identity.js +0 -215
- package/dist/utils/oauth-identity.js.map +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential Auth Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles credential-based authentication (email/password) for customers
|
|
5
|
+
* who don't use OAuth and want direct login to their services.
|
|
6
|
+
*
|
|
7
|
+
* @package @kya-os/mcp-i-cloudflare
|
|
8
|
+
* @see TICKET_CRED-003_XMCPI_CREDENTIAL_HANDLER.md
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Create a credential authentication handler
|
|
12
|
+
*
|
|
13
|
+
* @param config - Handler configuration
|
|
14
|
+
* @returns Credential auth handler instance
|
|
15
|
+
*/
|
|
16
|
+
export function createCredentialAuthHandler(config) {
|
|
17
|
+
const logger = config.logger || (() => { });
|
|
18
|
+
return {
|
|
19
|
+
async authenticate(provider, credentials) {
|
|
20
|
+
logger("[CredentialAuthHandler] Starting authentication", {
|
|
21
|
+
authEndpoint: provider.authEndpoint,
|
|
22
|
+
hasSuccessCheck: !!provider.successCheck,
|
|
23
|
+
});
|
|
24
|
+
// 1. Build request body from template
|
|
25
|
+
const requestBody = {};
|
|
26
|
+
for (const [apiFieldName, template] of Object.entries(provider.requestBodyTemplate)) {
|
|
27
|
+
const match = template.match(/\{\{(\w+)\}\}/);
|
|
28
|
+
if (match) {
|
|
29
|
+
const formFieldName = match[1];
|
|
30
|
+
if (credentials[formFieldName] === undefined) {
|
|
31
|
+
logger("[CredentialAuthHandler] Missing required field", {
|
|
32
|
+
field: formFieldName,
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
success: false,
|
|
36
|
+
error: `Missing required field: ${formFieldName}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
requestBody[apiFieldName] = credentials[formFieldName];
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Static value (no placeholder)
|
|
43
|
+
requestBody[apiFieldName] = template;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// 2. Call auth endpoint
|
|
47
|
+
try {
|
|
48
|
+
logger("[CredentialAuthHandler] Calling auth endpoint", {
|
|
49
|
+
endpoint: provider.authEndpoint,
|
|
50
|
+
bodyKeys: Object.keys(requestBody),
|
|
51
|
+
});
|
|
52
|
+
const response = await config.fetch(provider.authEndpoint, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: {
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
...provider.headers,
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify(requestBody),
|
|
59
|
+
});
|
|
60
|
+
// 3. Parse response body
|
|
61
|
+
const data = (await response.json());
|
|
62
|
+
// 4. Validate success if configured
|
|
63
|
+
if (provider.successCheck) {
|
|
64
|
+
const checkValue = getNestedValue(data, provider.successCheck.path);
|
|
65
|
+
const expectedValue = provider.successCheck.expectedValue;
|
|
66
|
+
// Handle type coercion for comparison (true vs "true")
|
|
67
|
+
const isMatch = String(checkValue) === String(expectedValue) ||
|
|
68
|
+
checkValue === expectedValue;
|
|
69
|
+
if (!isMatch) {
|
|
70
|
+
const errorMsg = getNestedValue(data, "error") ||
|
|
71
|
+
getNestedValue(data, "message") ||
|
|
72
|
+
"Authentication failed";
|
|
73
|
+
logger("[CredentialAuthHandler] Success check failed", {
|
|
74
|
+
path: provider.successCheck.path,
|
|
75
|
+
expected: expectedValue,
|
|
76
|
+
actual: checkValue,
|
|
77
|
+
error: errorMsg,
|
|
78
|
+
});
|
|
79
|
+
return { success: false, error: String(errorMsg) };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (!response.ok) {
|
|
83
|
+
// No success check configured - fall back to HTTP status
|
|
84
|
+
logger("[CredentialAuthHandler] HTTP error", {
|
|
85
|
+
status: response.status,
|
|
86
|
+
});
|
|
87
|
+
return { success: false, error: `HTTP ${response.status}` };
|
|
88
|
+
}
|
|
89
|
+
// 5. Extract session token - handle "cookie" special case
|
|
90
|
+
let sessionToken;
|
|
91
|
+
if (provider.responseFields.sessionToken === "cookie") {
|
|
92
|
+
// Try Set-Cookie header first
|
|
93
|
+
const setCookie = response.headers.get("Set-Cookie");
|
|
94
|
+
if (setCookie) {
|
|
95
|
+
// Try common cookie name patterns
|
|
96
|
+
const cookieMatch = setCookie.match(/(?:CIX|session|token|sid|auth)=([^;]+)/i);
|
|
97
|
+
if (cookieMatch) {
|
|
98
|
+
// Known cookie name pattern - extract value
|
|
99
|
+
sessionToken = cookieMatch[1];
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Unknown cookie name - extract value from first cookie (name=value;...)
|
|
103
|
+
// Split by ";" first to get "name=value", then split by "=" to get just value
|
|
104
|
+
const firstCookie = setCookie.split(";")[0];
|
|
105
|
+
const valueIndex = firstCookie.indexOf("=");
|
|
106
|
+
sessionToken =
|
|
107
|
+
valueIndex > 0 ? firstCookie.substring(valueIndex + 1) : undefined;
|
|
108
|
+
}
|
|
109
|
+
logger("[CredentialAuthHandler] Extracted token from Set-Cookie", {
|
|
110
|
+
hasMatch: !!cookieMatch,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Also check response body for "cookie" field
|
|
114
|
+
if (!sessionToken) {
|
|
115
|
+
sessionToken = getNestedValue(data, "cookie");
|
|
116
|
+
if (sessionToken) {
|
|
117
|
+
logger("[CredentialAuthHandler] Extracted token from response.cookie");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Extract from JSON path
|
|
123
|
+
sessionToken = getNestedValue(data, provider.responseFields.sessionToken);
|
|
124
|
+
}
|
|
125
|
+
if (!sessionToken) {
|
|
126
|
+
logger("[CredentialAuthHandler] Session token not found", {
|
|
127
|
+
path: provider.responseFields.sessionToken,
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
success: false,
|
|
131
|
+
error: `Session token not found at path: ${provider.responseFields.sessionToken}`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// 6. Extract optional user data
|
|
135
|
+
const userId = provider.responseFields.userId
|
|
136
|
+
? getNestedValue(data, provider.responseFields.userId)
|
|
137
|
+
: undefined;
|
|
138
|
+
const userEmail = provider.responseFields.userEmail
|
|
139
|
+
? getNestedValue(data, provider.responseFields.userEmail)
|
|
140
|
+
: undefined;
|
|
141
|
+
const userDisplayName = provider.responseFields.userDisplayName
|
|
142
|
+
? getNestedValue(data, provider.responseFields.userDisplayName)
|
|
143
|
+
: undefined;
|
|
144
|
+
const expiresInStr = provider.responseFields.expiresIn
|
|
145
|
+
? getNestedValue(data, provider.responseFields.expiresIn)
|
|
146
|
+
: undefined;
|
|
147
|
+
const expiresIn = expiresInStr ? parseInt(expiresInStr, 10) : undefined;
|
|
148
|
+
logger("[CredentialAuthHandler] Authentication successful", {
|
|
149
|
+
hasUserId: !!userId,
|
|
150
|
+
hasUserEmail: !!userEmail,
|
|
151
|
+
hasDisplayName: !!userDisplayName,
|
|
152
|
+
expiresIn,
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
success: true,
|
|
156
|
+
sessionToken,
|
|
157
|
+
userId,
|
|
158
|
+
userEmail,
|
|
159
|
+
userDisplayName,
|
|
160
|
+
expiresIn: isNaN(expiresIn ?? NaN) ? undefined : expiresIn,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
165
|
+
logger("[CredentialAuthHandler] Network error", { error: errorMsg });
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
error: `Network error: ${errorMsg}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get nested value from object using dot notation path
|
|
176
|
+
*
|
|
177
|
+
* @param obj - Object to traverse
|
|
178
|
+
* @param path - Dot-notation path (e.g., "customer.Email")
|
|
179
|
+
* @returns Value at path or undefined if not found
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* getNestedValue({ customer: { Email: "test@example.com" } }, "customer.Email")
|
|
183
|
+
* // Returns: "test@example.com"
|
|
184
|
+
*/
|
|
185
|
+
function getNestedValue(obj, path) {
|
|
186
|
+
const parts = path.split(".");
|
|
187
|
+
let current = obj;
|
|
188
|
+
for (const part of parts) {
|
|
189
|
+
if (current && typeof current === "object" && part in current) {
|
|
190
|
+
current = current[part];
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (current === null || current === undefined) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
return typeof current === "string" ? current : String(current);
|
|
200
|
+
}
|
|
201
|
+
// Export getNestedValue for testing
|
|
202
|
+
export { getNestedValue };
|
|
203
|
+
//# sourceMappingURL=credential-auth.handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-auth.handler.js","sourceRoot":"","sources":["../../src/services/credential-auth.handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,12 +6,60 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Storage key format: `idp_token:user:{userDid}:provider:{provider}:scopes:{scopeHash}`
|
|
8
8
|
*
|
|
9
|
+
* Supports both OAuth tokens and credential-based session tokens (CRED-003).
|
|
10
|
+
*
|
|
9
11
|
* @package @kya-os/mcp-i-cloudflare
|
|
10
12
|
*/
|
|
11
13
|
import type { KVNamespace } from "@cloudflare/workers-types";
|
|
12
14
|
import type { IdpTokens } from "@kya-os/contracts/config";
|
|
13
15
|
import type { IIdpTokenStorage } from "@kya-os/mcp-i-core";
|
|
14
16
|
import { OAuthSecurityService } from "./oauth-security.service";
|
|
17
|
+
/**
|
|
18
|
+
* Token usage metadata for credential providers
|
|
19
|
+
*
|
|
20
|
+
* Specifies how the token should be used in subsequent API calls.
|
|
21
|
+
*/
|
|
22
|
+
export interface TokenUsageMetadata {
|
|
23
|
+
/**
|
|
24
|
+
* How to use the token in requests
|
|
25
|
+
* - "cookie": Send as Cookie header
|
|
26
|
+
* - "bearer": Send as Authorization: Bearer xxx
|
|
27
|
+
* - "header": Send as custom header (specify tokenHeader)
|
|
28
|
+
*/
|
|
29
|
+
tokenUsage: "cookie" | "bearer" | "header";
|
|
30
|
+
/** Custom header name when tokenUsage is "header" */
|
|
31
|
+
tokenHeader?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Cookie format template when tokenUsage is "cookie"
|
|
34
|
+
* Use {{token}} placeholder for the token value
|
|
35
|
+
* @example "CIX={{token}}; customerCookie={{token}}"
|
|
36
|
+
*/
|
|
37
|
+
cookieFormat?: string;
|
|
38
|
+
/** Additional headers to include in API calls */
|
|
39
|
+
apiHeaders?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Extended token data that includes usage metadata
|
|
43
|
+
*/
|
|
44
|
+
export interface StoredTokenData extends TokenUsageMetadata {
|
|
45
|
+
/** Access/session token */
|
|
46
|
+
access_token: string;
|
|
47
|
+
/** Refresh token (OAuth only, optional) */
|
|
48
|
+
refresh_token?: string;
|
|
49
|
+
/** Token expiration timestamp (milliseconds since epoch) */
|
|
50
|
+
expires_at: number;
|
|
51
|
+
/** Token type (e.g., "Bearer" for OAuth, or custom for credentials) */
|
|
52
|
+
token_type: string;
|
|
53
|
+
/** Granted scopes */
|
|
54
|
+
scope?: string;
|
|
55
|
+
/** When the token was stored */
|
|
56
|
+
stored_at: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extended IdpTokens with usage metadata
|
|
60
|
+
*/
|
|
61
|
+
export interface IdpTokensWithMetadata extends IdpTokens, Partial<TokenUsageMetadata> {
|
|
62
|
+
}
|
|
15
63
|
export interface IdpTokenStorageConfig {
|
|
16
64
|
/** KV namespace for storing tokens */
|
|
17
65
|
storage: KVNamespace;
|
|
@@ -32,20 +80,20 @@ export declare class IdpTokenStorage implements IIdpTokenStorage {
|
|
|
32
80
|
* Store IDP tokens encrypted in KV storage
|
|
33
81
|
*
|
|
34
82
|
* @param userDid - User DID to associate tokens with
|
|
35
|
-
* @param provider - OAuth provider name (e.g., "github", "google")
|
|
83
|
+
* @param provider - OAuth provider name (e.g., "github", "google") or credential provider
|
|
36
84
|
* @param scopes - Scopes granted for these tokens
|
|
37
|
-
* @param tokens - IDP tokens to store
|
|
85
|
+
* @param tokens - IDP tokens to store (may include usage metadata for credentials)
|
|
38
86
|
*/
|
|
39
|
-
storeToken(userDid: string, provider: string, scopes: string[], tokens:
|
|
87
|
+
storeToken(userDid: string, provider: string, scopes: string[], tokens: IdpTokensWithMetadata): Promise<void>;
|
|
40
88
|
/**
|
|
41
89
|
* Retrieve IDP tokens from KV storage
|
|
42
90
|
*
|
|
43
91
|
* @param userDid - User DID to retrieve tokens for
|
|
44
|
-
* @param provider - OAuth provider name
|
|
92
|
+
* @param provider - OAuth provider name or credential provider
|
|
45
93
|
* @param scopes - Scopes to retrieve tokens for
|
|
46
|
-
* @returns IDP tokens or null if not found
|
|
94
|
+
* @returns IDP tokens with usage metadata or null if not found
|
|
47
95
|
*/
|
|
48
|
-
getToken(userDid: string, provider: string, scopes: string[]): Promise<
|
|
96
|
+
getToken(userDid: string, provider: string, scopes: string[]): Promise<IdpTokensWithMetadata | null>;
|
|
49
97
|
/**
|
|
50
98
|
* Delete IDP tokens from storage
|
|
51
99
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idp-token-storage.d.ts","sourceRoot":"","sources":["../../src/services/idp-token-storage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"idp-token-storage.d.ts","sourceRoot":"","sources":["../../src/services/idp-token-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAE3C,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;IACzD,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAC;IAErB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IAEnB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IAEnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC;CAAG;AAExF,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,OAAO,EAAE,WAAW,CAAC;IAErB,4CAA4C;IAC5C,oBAAoB,EAAE,oBAAoB,CAAC;IAE3C,+CAA+C;IAC/C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAED;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,OAAO,CAAC,MAAM,CAEZ;gBAEU,MAAM,EAAE,qBAAqB;IAQzC;;;;;;;OAOG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAgDhB;;;;;;;OAOG;IACG,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IA2DxC;;;;;;OAMG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC;IAchB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;CAcnB"}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Storage key format: `idp_token:user:{userDid}:provider:{provider}:scopes:{scopeHash}`
|
|
8
8
|
*
|
|
9
|
+
* Supports both OAuth tokens and credential-based session tokens (CRED-003).
|
|
10
|
+
*
|
|
9
11
|
* @package @kya-os/mcp-i-cloudflare
|
|
10
12
|
*/
|
|
11
13
|
/**
|
|
@@ -26,14 +28,14 @@ export class IdpTokenStorage {
|
|
|
26
28
|
* Store IDP tokens encrypted in KV storage
|
|
27
29
|
*
|
|
28
30
|
* @param userDid - User DID to associate tokens with
|
|
29
|
-
* @param provider - OAuth provider name (e.g., "github", "google")
|
|
31
|
+
* @param provider - OAuth provider name (e.g., "github", "google") or credential provider
|
|
30
32
|
* @param scopes - Scopes granted for these tokens
|
|
31
|
-
* @param tokens - IDP tokens to store
|
|
33
|
+
* @param tokens - IDP tokens to store (may include usage metadata for credentials)
|
|
32
34
|
*/
|
|
33
35
|
async storeToken(userDid, provider, scopes, tokens) {
|
|
34
36
|
const scopeHash = this.hashScopes(scopes);
|
|
35
37
|
const key = `idp_token:user:${userDid}:provider:${provider}:scopes:${scopeHash}`;
|
|
36
|
-
// Prepare token data for storage
|
|
38
|
+
// Prepare token data for storage, including credential metadata if present
|
|
37
39
|
const tokenData = {
|
|
38
40
|
access_token: tokens.access_token,
|
|
39
41
|
refresh_token: tokens.refresh_token,
|
|
@@ -41,6 +43,11 @@ export class IdpTokenStorage {
|
|
|
41
43
|
token_type: tokens.token_type,
|
|
42
44
|
scope: tokens.scope,
|
|
43
45
|
stored_at: Date.now(),
|
|
46
|
+
// CRED-003: Include credential provider metadata
|
|
47
|
+
tokenUsage: tokens.tokenUsage || "bearer", // Default to bearer for OAuth
|
|
48
|
+
tokenHeader: tokens.tokenHeader,
|
|
49
|
+
cookieFormat: tokens.cookieFormat,
|
|
50
|
+
apiHeaders: tokens.apiHeaders,
|
|
44
51
|
};
|
|
45
52
|
// Encrypt token data before storage
|
|
46
53
|
const encrypted = await this.config.oauthSecurityService.encryptToken(JSON.stringify(tokenData));
|
|
@@ -58,15 +65,17 @@ export class IdpTokenStorage {
|
|
|
58
65
|
scopeHash,
|
|
59
66
|
expiresAt: new Date(expiresAt).toISOString(),
|
|
60
67
|
ttl,
|
|
68
|
+
tokenUsage: tokenData.tokenUsage,
|
|
69
|
+
hasCookieFormat: !!tokenData.cookieFormat,
|
|
61
70
|
});
|
|
62
71
|
}
|
|
63
72
|
/**
|
|
64
73
|
* Retrieve IDP tokens from KV storage
|
|
65
74
|
*
|
|
66
75
|
* @param userDid - User DID to retrieve tokens for
|
|
67
|
-
* @param provider - OAuth provider name
|
|
76
|
+
* @param provider - OAuth provider name or credential provider
|
|
68
77
|
* @param scopes - Scopes to retrieve tokens for
|
|
69
|
-
* @returns IDP tokens or null if not found
|
|
78
|
+
* @returns IDP tokens with usage metadata or null if not found
|
|
70
79
|
*/
|
|
71
80
|
async getToken(userDid, provider, scopes) {
|
|
72
81
|
const scopeHash = this.hashScopes(scopes);
|
|
@@ -85,7 +94,7 @@ export class IdpTokenStorage {
|
|
|
85
94
|
// Decrypt token data
|
|
86
95
|
const decrypted = await this.config.oauthSecurityService.decryptToken(encrypted);
|
|
87
96
|
const tokenData = JSON.parse(decrypted);
|
|
88
|
-
// Reconstruct IdpTokens object
|
|
97
|
+
// Reconstruct IdpTokens object with usage metadata (CRED-003)
|
|
89
98
|
const tokens = {
|
|
90
99
|
access_token: tokenData.access_token,
|
|
91
100
|
refresh_token: tokenData.refresh_token,
|
|
@@ -95,6 +104,11 @@ export class IdpTokenStorage {
|
|
|
95
104
|
expires_in: tokenData.expires_at
|
|
96
105
|
? Math.floor((tokenData.expires_at - Date.now()) / 1000)
|
|
97
106
|
: undefined,
|
|
107
|
+
// CRED-003: Include credential usage metadata
|
|
108
|
+
tokenUsage: tokenData.tokenUsage,
|
|
109
|
+
tokenHeader: tokenData.tokenHeader,
|
|
110
|
+
cookieFormat: tokenData.cookieFormat,
|
|
111
|
+
apiHeaders: tokenData.apiHeaders,
|
|
98
112
|
};
|
|
99
113
|
this.config.logger("[IdpTokenStorage] Token retrieved", {
|
|
100
114
|
userDid: userDid.substring(0, 20) + "...",
|
|
@@ -102,6 +116,7 @@ export class IdpTokenStorage {
|
|
|
102
116
|
scopes,
|
|
103
117
|
expiresAt: new Date(tokens.expires_at).toISOString(),
|
|
104
118
|
isExpired: tokens.expires_at < Date.now(),
|
|
119
|
+
tokenUsage: tokens.tokenUsage,
|
|
105
120
|
});
|
|
106
121
|
return tokens;
|
|
107
122
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idp-token-storage.js","sourceRoot":"","sources":["../../src/services/idp-token-storage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"idp-token-storage.js","sourceRoot":"","sources":["../../src/services/idp-token-storage.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.27",
|
|
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.5",
|
|
21
|
+
"@kya-os/mcp-i-core": "^1.3.12",
|
|
22
22
|
"@modelcontextprotocol/sdk": "^1.19.1",
|
|
23
23
|
"agents": "^0.2.21",
|
|
24
24
|
"base-x": "^5.0.0",
|
|
@@ -1,37 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,62 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,69 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|