@kya-os/mcp-i-cloudflare 1.7.24 → 1.7.26
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.d.ts +12 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +17 -14
- package/dist/constants.js.map +1 -1
- package/dist/services/consent-templates/modes/credentials.template.d.ts.map +1 -1
- package/dist/services/consent-templates/modes/credentials.template.js +12 -5
- package/dist/services/consent-templates/modes/credentials.template.js.map +1 -1
- package/dist/services/consent-templates/template-renderer.d.ts +5 -1
- package/dist/services/consent-templates/template-renderer.d.ts.map +1 -1
- package/dist/services/consent-templates/template-renderer.js +12 -3
- package/dist/services/consent-templates/template-renderer.js.map +1 -1
- package/dist/services/consent-templates/types.d.ts +7 -0
- package/dist/services/consent-templates/types.d.ts.map +1 -1
- package/dist/services/consent.service.d.ts.map +1 -1
- package/dist/services/consent.service.js +178 -36
- package/dist/services/consent.service.js.map +1 -1
- package/dist/services/credential-auth.handler.d.ts.map +1 -1
- package/dist/services/credential-auth.handler.js +6 -2
- package/dist/services/credential-auth.handler.js.map +1 -1
- package/package.json +3 -3
|
@@ -1345,6 +1345,10 @@ export class ConsentService {
|
|
|
1345
1345
|
// When credential auth completes, userDid is passed through redirect URL
|
|
1346
1346
|
// This ensures storeDelegationToken can use the correct user+agent key immediately
|
|
1347
1347
|
const userDidFromParams = params.get("user_did");
|
|
1348
|
+
// ✅ Extract user info from credential provider for delegation metadata
|
|
1349
|
+
// These are used for human-readable display in AgentShield dashboard
|
|
1350
|
+
const credentialUserEmail = params.get("credential_user_email");
|
|
1351
|
+
const credentialProviderUserId = params.get("credential_provider_user_id");
|
|
1348
1352
|
// ✅ Extract mode param for post-credential clickwrap detection
|
|
1349
1353
|
// When credential auth completes, user is redirected to /consent?mode=consent-only&credential_provider_type=password
|
|
1350
1354
|
const mode = params.get("mode");
|
|
@@ -1684,22 +1688,32 @@ export class ConsentService {
|
|
|
1684
1688
|
// ✅ CRITICAL: Pass userDid to bypass KV eventual consistency issues
|
|
1685
1689
|
// This is passed through the redirect URL from credential auth
|
|
1686
1690
|
userDid: userDidFromParams || undefined,
|
|
1691
|
+
// ✅ Pass user info from credential provider for delegation metadata
|
|
1692
|
+
credentialUserEmail: credentialUserEmail || undefined,
|
|
1693
|
+
credentialProviderUserId: credentialProviderUserId || undefined,
|
|
1687
1694
|
};
|
|
1688
1695
|
// CRED-003: Render credential form if this is a credential provider
|
|
1689
1696
|
// Guard conditions:
|
|
1690
1697
|
// 1. credentialProviderConfig must exist (already fetched above)
|
|
1691
1698
|
// 2. Must NOT be in post-credential clickwrap mode (would cause infinite loop)
|
|
1692
1699
|
if (credentialProviderConfig && !isPostCredentialClickwrap) {
|
|
1700
|
+
// Determine authorization type from tool protection config
|
|
1701
|
+
// Default to 'password' for credential flows (matches AgentShield expectations)
|
|
1702
|
+
// The authorization.type from tool protection tells us what type of auth the tool expects
|
|
1703
|
+
const authorizationType = protection?.authorization?.type ?? "password";
|
|
1693
1704
|
logger.debug("[ConsentService] Credential provider detected, rendering credential page", {
|
|
1694
1705
|
projectId,
|
|
1695
1706
|
provider,
|
|
1696
1707
|
providerType: credentialProviderConfig.type,
|
|
1697
1708
|
displayName: credentialProviderConfig.displayName,
|
|
1709
|
+
authorizationType, // Log the authorization type being used
|
|
1698
1710
|
});
|
|
1699
1711
|
// Generate and store CSRF token for form security
|
|
1700
1712
|
const csrfToken = await this.storeCredentialCsrfToken(sessionId);
|
|
1701
1713
|
// Render credential login page instead of OAuth consent
|
|
1702
|
-
|
|
1714
|
+
// Pass authorizationType from tool protection config for dynamic provider_type
|
|
1715
|
+
const html = this.renderer.renderCredentialPage(pageConfig, credentialProviderConfig, provider, csrfToken, authorizationType // Dynamic authorization type from tool protection
|
|
1716
|
+
);
|
|
1703
1717
|
return new Response(html, {
|
|
1704
1718
|
status: 200,
|
|
1705
1719
|
headers: {
|
|
@@ -2879,23 +2893,33 @@ export class ConsentService {
|
|
|
2879
2893
|
// Ensure userDid is in bodyObj for createDelegation and storeDelegationToken
|
|
2880
2894
|
bodyObj.user_did = userDidFromRedirect;
|
|
2881
2895
|
}
|
|
2882
|
-
// Read
|
|
2883
|
-
//
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2896
|
+
// Read user info from redirect URL params
|
|
2897
|
+
// Field mapping (clear naming):
|
|
2898
|
+
// credential_user_email → user_identifier (human-readable for display)
|
|
2899
|
+
// credential_provider_user_id → user_id (provider's internal ID)
|
|
2900
|
+
const credentialUserEmailFromRedirect = bodyObj.credential_user_email;
|
|
2901
|
+
const credentialProviderUserIdFromRedirect = bodyObj.credential_provider_user_id;
|
|
2902
|
+
if (credentialUserEmailFromRedirect ||
|
|
2903
|
+
credentialProviderUserIdFromRedirect) {
|
|
2904
|
+
logger.debug("[ConsentService] ✅ Using credential user info from redirect:", {
|
|
2887
2905
|
sessionId: sessionId?.substring(0, 20) + "...",
|
|
2888
|
-
|
|
2906
|
+
credential_user_email: credentialUserEmailFromRedirect
|
|
2907
|
+
? credentialUserEmailFromRedirect.substring(0, 20) + "..."
|
|
2908
|
+
: undefined,
|
|
2909
|
+
credential_provider_user_id: credentialProviderUserIdFromRedirect
|
|
2910
|
+
? credentialProviderUserIdFromRedirect.substring(0, 20) +
|
|
2911
|
+
"..."
|
|
2912
|
+
: undefined,
|
|
2889
2913
|
source: "redirect-param",
|
|
2890
2914
|
});
|
|
2891
|
-
// credential_user_id is already in bodyObj from form, no need to reassign
|
|
2892
2915
|
}
|
|
2893
2916
|
logger.debug("[ConsentService] ✅ Using credential auth provider_type for delegation:", {
|
|
2894
2917
|
sessionId: sessionId?.substring(0, 20) + "...",
|
|
2895
2918
|
providerType: CONSENT_PROVIDER_TYPES.PASSWORD,
|
|
2896
2919
|
provider: credentialProvider,
|
|
2897
2920
|
hasUserDid: !!userDidFromRedirect,
|
|
2898
|
-
|
|
2921
|
+
hasCredentialUserEmail: !!credentialUserEmailFromRedirect,
|
|
2922
|
+
hasProviderUserId: !!credentialProviderUserIdFromRedirect,
|
|
2899
2923
|
note: "Delegation will have authorization.type='password' to match tool protection",
|
|
2900
2924
|
});
|
|
2901
2925
|
// The userDid is passed via redirect URL - no need to read from KV
|
|
@@ -3743,12 +3767,18 @@ export class ConsentService {
|
|
|
3743
3767
|
if (Array.isArray(scopes) && scopes.length > 0) {
|
|
3744
3768
|
clickwrapUrl.searchParams.set("scopes", scopes.join(","));
|
|
3745
3769
|
}
|
|
3746
|
-
// Include user info for
|
|
3770
|
+
// Include user info for delegation request
|
|
3771
|
+
// Field mapping (clear naming):
|
|
3772
|
+
// credential_user_email → user_identifier (human-readable for display)
|
|
3773
|
+
// credential_provider_user_id → user_id (provider's internal ID for business reference)
|
|
3774
|
+
// user_did → user_did (cryptographic identity, always present)
|
|
3747
3775
|
if (authResult.userEmail) {
|
|
3776
|
+
// Email for human-readable display in AgentShield dashboard
|
|
3748
3777
|
clickwrapUrl.searchParams.set("credential_user_email", authResult.userEmail);
|
|
3749
3778
|
}
|
|
3750
3779
|
if (authResult.userId) {
|
|
3751
|
-
|
|
3780
|
+
// Provider's internal ID (e.g., customer ID 696395) for business reference
|
|
3781
|
+
clickwrapUrl.searchParams.set("credential_provider_user_id", authResult.userId);
|
|
3752
3782
|
}
|
|
3753
3783
|
// CRITICAL FIX: Pass userDid through redirect to avoid KV eventual consistency issues
|
|
3754
3784
|
// Without this, the clickwrap approval might read stale session data from KV
|
|
@@ -4158,30 +4188,98 @@ export class ConsentService {
|
|
|
4158
4188
|
// CRITICAL: user_did is required for proper user identification in dashboard
|
|
4159
4189
|
// user_identifier is for display purposes (email, username, etc.)
|
|
4160
4190
|
// user_id is the provider-specific ID from credential auth (for UX metadata)
|
|
4191
|
+
//
|
|
4192
|
+
// Fallback Strategy:
|
|
4193
|
+
// 1. If email available → user_identifier = email (preferred)
|
|
4194
|
+
// 2. If no email → user_identifier = userDid (fallback so AgentShield has something to display)
|
|
4195
|
+
// AgentShield will also check metadata.user_email for extraction
|
|
4161
4196
|
if (userDid) {
|
|
4162
4197
|
// user_did is the primary identifier - the actual DID
|
|
4163
4198
|
result.user_did = userDid;
|
|
4164
|
-
// user_identifier:
|
|
4165
|
-
//
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4199
|
+
// user_identifier: Human-readable identifier (email/username) for AgentShield dashboard display
|
|
4200
|
+
// user_id: Provider's internal ID (e.g., customer ID 696395) for business reference
|
|
4201
|
+
// user_did: Cryptographic DID for identity verification
|
|
4202
|
+
if (request.credential_user_email) {
|
|
4203
|
+
// Have email - use it as human-readable identifier
|
|
4204
|
+
result.user_identifier = request.credential_user_email;
|
|
4205
|
+
}
|
|
4206
|
+
else {
|
|
4207
|
+
// No email - fall back to DID so dashboard has something to display
|
|
4208
|
+
// AgentShield will detect this is a DID and may display differently
|
|
4209
|
+
result.user_identifier = userDid;
|
|
4210
|
+
}
|
|
4211
|
+
// user_id is the provider's internal ID (separate from email)
|
|
4212
|
+
// Use credential_provider_user_id if available
|
|
4213
|
+
const fullFormatProviderId = request.credential_provider_user_id;
|
|
4214
|
+
if (fullFormatProviderId) {
|
|
4215
|
+
result.user_id = fullFormatProviderId;
|
|
4216
|
+
logger.debug("[ConsentService] Full format: Including provider user_id from credential auth:", {
|
|
4217
|
+
user_id: fullFormatProviderId.substring(0, 20) + "...",
|
|
4218
|
+
user_identifier: request.credential_user_email?.substring(0, 20) + "...",
|
|
4173
4219
|
});
|
|
4174
4220
|
}
|
|
4175
4221
|
logger.debug("[ConsentService] Full format: Including user identity fields:", {
|
|
4176
4222
|
user_did: userDid.substring(0, 20) + "...",
|
|
4177
|
-
user_identifier:
|
|
4178
|
-
|
|
4223
|
+
user_identifier: request.credential_user_email
|
|
4224
|
+
? request.credential_user_email.substring(0, 20) + "..."
|
|
4225
|
+
: "(fallback to DID)",
|
|
4226
|
+
has_user_id: !!fullFormatProviderId,
|
|
4227
|
+
source: request.credential_user_email ? "email" : "did-fallback",
|
|
4179
4228
|
});
|
|
4180
4229
|
}
|
|
4181
4230
|
// Phase 2 VC-Only: Include credential_jwt if available
|
|
4182
4231
|
if (credentialJwt) {
|
|
4183
4232
|
result.credential_jwt = credentialJwt;
|
|
4184
4233
|
}
|
|
4234
|
+
// MCP-I Compatibility: Include user_email and user_id in custom_fields (becomes metadata)
|
|
4235
|
+
// This matches buildSimplifiedFormatRequest behavior for consistency
|
|
4236
|
+
// AgentShield extracts these from metadata when user_identifier is not provided
|
|
4237
|
+
//
|
|
4238
|
+
// user_email = human-readable email (for display)
|
|
4239
|
+
// user_id = provider's internal ID (for business reference)
|
|
4240
|
+
const fullFormatUserEmail = request.credential_user_email || null;
|
|
4241
|
+
const fullFormatProviderUserId = request
|
|
4242
|
+
.credential_provider_user_id || null;
|
|
4243
|
+
const providerType = request.provider_type || "none";
|
|
4244
|
+
const customFieldsFromRequest = request.customFields || {};
|
|
4245
|
+
if (userDid || fullFormatUserEmail || providerType !== "none") {
|
|
4246
|
+
result.custom_fields = {
|
|
4247
|
+
...(userDid
|
|
4248
|
+
? {
|
|
4249
|
+
issuer_did: userDid,
|
|
4250
|
+
subject_did: request.agent_did,
|
|
4251
|
+
}
|
|
4252
|
+
: {}),
|
|
4253
|
+
format_version: "full_v1",
|
|
4254
|
+
...(providerType ? { provider_type: providerType } : {}),
|
|
4255
|
+
// MCP-I Compatibility: Include user_email and user_id in metadata
|
|
4256
|
+
// AgentShield will extract these if user_identifier is not provided
|
|
4257
|
+
// user_email = human-readable email (for display)
|
|
4258
|
+
// user_id = provider's internal ID (for business reference, e.g., customer ID 696395)
|
|
4259
|
+
...(fullFormatUserEmail ? { user_email: fullFormatUserEmail } : {}),
|
|
4260
|
+
...(fullFormatProviderUserId
|
|
4261
|
+
? { user_id: fullFormatProviderUserId }
|
|
4262
|
+
: {}),
|
|
4263
|
+
// Merge with any existing custom_fields from request
|
|
4264
|
+
...customFieldsFromRequest,
|
|
4265
|
+
};
|
|
4266
|
+
if (fullFormatUserEmail || fullFormatProviderUserId) {
|
|
4267
|
+
logger.debug("[ConsentService] Full format: Including user info in custom_fields for AgentShield compatibility:", {
|
|
4268
|
+
user_email: fullFormatUserEmail
|
|
4269
|
+
? fullFormatUserEmail.substring(0, 20) + "..."
|
|
4270
|
+
: undefined,
|
|
4271
|
+
user_id: fullFormatProviderUserId
|
|
4272
|
+
? fullFormatProviderUserId.substring(0, 20) + "..."
|
|
4273
|
+
: undefined,
|
|
4274
|
+
});
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
else if (request.customFields &&
|
|
4278
|
+
Object.keys(request.customFields).length > 0) {
|
|
4279
|
+
// Include custom_fields from request even if no userDid (matches buildSimplifiedFormatRequest)
|
|
4280
|
+
result.custom_fields = request.customFields;
|
|
4281
|
+
}
|
|
4282
|
+
// If no userDid, no customFields, and no provider info, custom_fields is omitted (valid)
|
|
4185
4283
|
return result;
|
|
4186
4284
|
}
|
|
4187
4285
|
/**
|
|
@@ -4221,25 +4319,44 @@ export class ConsentService {
|
|
|
4221
4319
|
// CRITICAL: user_did is required for proper user identification in dashboard
|
|
4222
4320
|
// user_identifier is for display purposes (email, username, etc.)
|
|
4223
4321
|
// user_id is the provider-specific ID from credential auth (for UX metadata)
|
|
4322
|
+
//
|
|
4323
|
+
// Fallback Strategy:
|
|
4324
|
+
// 1. If email available → user_identifier = email (preferred)
|
|
4325
|
+
// 2. If no email → user_identifier = userDid (fallback so AgentShield has something to display)
|
|
4326
|
+
// AgentShield will also check metadata.user_email for extraction
|
|
4224
4327
|
if (userDid) {
|
|
4225
4328
|
// user_did is the primary identifier - the actual DID
|
|
4226
4329
|
simplifiedRequest.user_did = userDid;
|
|
4227
|
-
// user_identifier:
|
|
4228
|
-
//
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4330
|
+
// user_identifier: Human-readable identifier (email/username) for AgentShield dashboard display
|
|
4331
|
+
// user_id: Provider's internal ID (e.g., customer ID 696395) for business reference
|
|
4332
|
+
// user_did: Cryptographic DID for identity verification
|
|
4333
|
+
if (request.credential_user_email) {
|
|
4334
|
+
// Have email - use it as human-readable identifier
|
|
4335
|
+
simplifiedRequest.user_identifier = request.credential_user_email;
|
|
4336
|
+
}
|
|
4337
|
+
else {
|
|
4338
|
+
// No email - fall back to DID so dashboard has something to display
|
|
4339
|
+
// AgentShield will detect this is a DID and may display differently
|
|
4340
|
+
simplifiedRequest.user_identifier = userDid;
|
|
4341
|
+
}
|
|
4342
|
+
// user_id is the provider's internal ID (separate from email)
|
|
4343
|
+
// Use credential_provider_user_id if available
|
|
4344
|
+
const providerId = request
|
|
4345
|
+
.credential_provider_user_id;
|
|
4346
|
+
if (providerId) {
|
|
4347
|
+
simplifiedRequest.user_id = providerId;
|
|
4348
|
+
logger.debug("[ConsentService] Including provider user_id from credential auth:", {
|
|
4349
|
+
user_id: providerId.substring(0, 20) + "...",
|
|
4350
|
+
user_identifier: request.credential_user_email?.substring(0, 20) + "...",
|
|
4237
4351
|
});
|
|
4238
4352
|
}
|
|
4239
|
-
logger.debug("[ConsentService] Including
|
|
4353
|
+
logger.debug("[ConsentService] Including user info in delegation request:", {
|
|
4240
4354
|
user_did: userDid.substring(0, 20) + "...",
|
|
4241
|
-
user_identifier:
|
|
4242
|
-
|
|
4355
|
+
user_identifier: request.credential_user_email
|
|
4356
|
+
? request.credential_user_email.substring(0, 20) + "..."
|
|
4357
|
+
: "(fallback to DID)",
|
|
4358
|
+
has_user_id: !!providerId,
|
|
4359
|
+
source: request.credential_user_email ? "email" : "did-fallback",
|
|
4243
4360
|
});
|
|
4244
4361
|
}
|
|
4245
4362
|
else {
|
|
@@ -4264,7 +4381,16 @@ export class ConsentService {
|
|
|
4264
4381
|
const providerType = request.provider_type || customFieldsFromRequest.provider_type;
|
|
4265
4382
|
const provider = customFieldsFromRequest.provider;
|
|
4266
4383
|
const hasProviderInfo = providerType || provider;
|
|
4267
|
-
|
|
4384
|
+
// MCP-I Compatibility: Include user_email and user_id in custom_fields (becomes metadata)
|
|
4385
|
+
// AgentShield extracts these from metadata when user_identifier is a DID or not provided
|
|
4386
|
+
// This ensures human-readable identifiers are always available for dashboard display
|
|
4387
|
+
//
|
|
4388
|
+
// user_email = human-readable email (for display)
|
|
4389
|
+
// user_id = provider's internal ID (for business reference)
|
|
4390
|
+
const userEmail = request.credential_user_email || null;
|
|
4391
|
+
const providerUserId = request
|
|
4392
|
+
.credential_provider_user_id || null;
|
|
4393
|
+
if (userDid || hasProviderInfo || userEmail) {
|
|
4268
4394
|
// Include issuer_did and subject_did in custom_fields when we have userDid
|
|
4269
4395
|
// Also include provider_type and provider for AgentShield dashboard
|
|
4270
4396
|
// CRITICAL: AgentShield derives authorization from metadata.provider_type:
|
|
@@ -4282,6 +4408,12 @@ export class ConsentService {
|
|
|
4282
4408
|
format_version: "simplified_v1",
|
|
4283
4409
|
// Include provider_type at the custom_fields level (where AgentShield reads it)
|
|
4284
4410
|
...(providerType ? { provider_type: providerType } : {}),
|
|
4411
|
+
// MCP-I Compatibility: Include user_email and user_id in metadata
|
|
4412
|
+
// AgentShield will extract these if user_identifier is not provided or is a DID
|
|
4413
|
+
// user_email = human-readable email (for display)
|
|
4414
|
+
// user_id = provider's internal ID (for business reference, e.g., customer ID 696395)
|
|
4415
|
+
...(userEmail ? { user_email: userEmail } : {}),
|
|
4416
|
+
...(providerUserId ? { user_id: providerUserId } : {}),
|
|
4285
4417
|
// Merge with any existing custom_fields from request
|
|
4286
4418
|
...customFieldsFromRequest,
|
|
4287
4419
|
};
|
|
@@ -4294,6 +4426,16 @@ export class ConsentService {
|
|
|
4294
4426
|
: "customFields",
|
|
4295
4427
|
});
|
|
4296
4428
|
}
|
|
4429
|
+
if (userEmail || providerUserId) {
|
|
4430
|
+
logger.debug("[ConsentService] Including user info in custom_fields for AgentShield compatibility:", {
|
|
4431
|
+
user_email: userEmail
|
|
4432
|
+
? userEmail.substring(0, 20) + "..."
|
|
4433
|
+
: undefined,
|
|
4434
|
+
user_id: providerUserId
|
|
4435
|
+
? providerUserId.substring(0, 20) + "..."
|
|
4436
|
+
: undefined,
|
|
4437
|
+
});
|
|
4438
|
+
}
|
|
4297
4439
|
}
|
|
4298
4440
|
else if (request.customFields &&
|
|
4299
4441
|
Object.keys(request.customFields).length > 0) {
|