@kya-os/create-mcpi-app 1.10.1 → 1.10.2
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/.turbo/turbo-build.log +13 -13
- package/dist/bundles/blank.js +465 -131
- package/dist/bundles/ecommerce.js +465 -131
- package/dist/bundles/hardware-world.js +465 -131
- package/dist/bundles/manifest.json +11 -11
- package/dist/bundles/mix-station.js +465 -131
- package/dist/helpers/get-package-versions.js +1 -1
- package/package.json +2 -2
|
@@ -19235,7 +19235,7 @@ var require_base2 = __commonJS({
|
|
|
19235
19235
|
var agentshield_api_1 = require_agentshield_api();
|
|
19236
19236
|
var user_did_manager_1 = require_user_did_manager();
|
|
19237
19237
|
var wire_format_1 = require_wire_format();
|
|
19238
|
-
var
|
|
19238
|
+
var isRecord3 = (value) => typeof value === "object" && value !== null;
|
|
19239
19239
|
var MCPIRuntimeBase3 = class _MCPIRuntimeBase {
|
|
19240
19240
|
crypto;
|
|
19241
19241
|
clock;
|
|
@@ -19535,7 +19535,7 @@ var require_base2 = __commonJS({
|
|
|
19535
19535
|
});
|
|
19536
19536
|
}
|
|
19537
19537
|
const clientInfo = session?.clientInfo;
|
|
19538
|
-
const clientCaps =
|
|
19538
|
+
const clientCaps = isRecord3(clientInfo?.capabilities) ? clientInfo.capabilities : void 0;
|
|
19539
19539
|
const uiResult = this.buildConsentUIResult(toolName, protection.requiredScopes, session, resumeToken, session?.projectId || void 0, session?.serverOrigin || void 0, clientCaps);
|
|
19540
19540
|
if (uiResult) {
|
|
19541
19541
|
return uiResult;
|
|
@@ -20118,7 +20118,7 @@ var require_base2 = __commonJS({
|
|
|
20118
20118
|
async verifyProof(dataOrProof, proofOrSession) {
|
|
20119
20119
|
if (dataOrProof && typeof dataOrProof === "object" && "jws" in dataOrProof && "meta" in dataOrProof) {
|
|
20120
20120
|
const detachedProof = dataOrProof;
|
|
20121
|
-
const session =
|
|
20121
|
+
const session = isRecord3(proofOrSession) ? proofOrSession : void 0;
|
|
20122
20122
|
if (this.proofVerifier) {
|
|
20123
20123
|
try {
|
|
20124
20124
|
const didDoc = await this.fetch.resolveDID(detachedProof.meta.did);
|
|
@@ -20139,10 +20139,10 @@ var require_base2 = __commonJS({
|
|
|
20139
20139
|
}
|
|
20140
20140
|
} else {
|
|
20141
20141
|
console.warn("[MCPIRuntimeBase] ProofVerifier not available, using fallback verification");
|
|
20142
|
-
return this.verifyProofLegacy(dataOrProof,
|
|
20142
|
+
return this.verifyProofLegacy(dataOrProof, isRecord3(proofOrSession) ? proofOrSession : {});
|
|
20143
20143
|
}
|
|
20144
20144
|
} else {
|
|
20145
|
-
return this.verifyProofLegacy(dataOrProof,
|
|
20145
|
+
return this.verifyProofLegacy(dataOrProof, isRecord3(proofOrSession) ? proofOrSession : {});
|
|
20146
20146
|
}
|
|
20147
20147
|
}
|
|
20148
20148
|
/**
|
|
@@ -20537,7 +20537,7 @@ var require_base2 = __commonJS({
|
|
|
20537
20537
|
};
|
|
20538
20538
|
}
|
|
20539
20539
|
extractPublicKey(didDoc) {
|
|
20540
|
-
const verificationMethods =
|
|
20540
|
+
const verificationMethods = isRecord3(didDoc) ? didDoc.verificationMethod : void 0;
|
|
20541
20541
|
const method = Array.isArray(verificationMethods) ? verificationMethods[0] : void 0;
|
|
20542
20542
|
if (method?.publicKeyBase64) {
|
|
20543
20543
|
return String(method.publicKeyBase64);
|
|
@@ -20551,7 +20551,7 @@ var require_base2 = __commonJS({
|
|
|
20551
20551
|
* Extract public key JWK from DID document
|
|
20552
20552
|
*/
|
|
20553
20553
|
extractPublicKeyJwk(didDoc, kid) {
|
|
20554
|
-
const verificationMethods =
|
|
20554
|
+
const verificationMethods = isRecord3(didDoc) ? didDoc.verificationMethod : void 0;
|
|
20555
20555
|
const verificationMethodList = Array.isArray(verificationMethods) ? verificationMethods : [];
|
|
20556
20556
|
const verificationMethod = verificationMethodList.find((vm) => {
|
|
20557
20557
|
const vmType = typeof vm.type === "string" ? vm.type : void 0;
|
|
@@ -20560,7 +20560,7 @@ var require_base2 = __commonJS({
|
|
|
20560
20560
|
const matchesKid = !kid || vmId === kid || vmId?.endsWith(`#${kid}`);
|
|
20561
20561
|
return matchesType && matchesKid;
|
|
20562
20562
|
}) || verificationMethodList[0];
|
|
20563
|
-
if (verificationMethod &&
|
|
20563
|
+
if (verificationMethod && isRecord3(verificationMethod.publicKeyJwk)) {
|
|
20564
20564
|
const jwk = verificationMethod.publicKeyJwk;
|
|
20565
20565
|
if (jwk.kty === "OKP" && jwk.crv === "Ed25519") {
|
|
20566
20566
|
return jwk;
|
|
@@ -80849,7 +80849,7 @@ var init_protocol4 = __esm({
|
|
|
80849
80849
|
const capturedTransport = this._transport;
|
|
80850
80850
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY2]?.taskId;
|
|
80851
80851
|
if (handler === void 0) {
|
|
80852
|
-
const
|
|
80852
|
+
const errorResponse2 = {
|
|
80853
80853
|
jsonrpc: "2.0",
|
|
80854
80854
|
id: request.id,
|
|
80855
80855
|
error: {
|
|
@@ -80860,11 +80860,11 @@ var init_protocol4 = __esm({
|
|
|
80860
80860
|
if (relatedTaskId && this._taskMessageQueue) {
|
|
80861
80861
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
80862
80862
|
type: "error",
|
|
80863
|
-
message:
|
|
80863
|
+
message: errorResponse2,
|
|
80864
80864
|
timestamp: Date.now()
|
|
80865
80865
|
}, capturedTransport?.sessionId).catch((error87) => this._onerror(new Error(`Failed to enqueue error response: ${error87}`)));
|
|
80866
80866
|
} else {
|
|
80867
|
-
capturedTransport?.send(
|
|
80867
|
+
capturedTransport?.send(errorResponse2).catch((error87) => this._onerror(new Error(`Failed to send an error response: ${error87}`)));
|
|
80868
80868
|
}
|
|
80869
80869
|
return;
|
|
80870
80870
|
}
|
|
@@ -80934,7 +80934,7 @@ var init_protocol4 = __esm({
|
|
|
80934
80934
|
if (abortController.signal.aborted) {
|
|
80935
80935
|
return;
|
|
80936
80936
|
}
|
|
80937
|
-
const
|
|
80937
|
+
const errorResponse2 = {
|
|
80938
80938
|
jsonrpc: "2.0",
|
|
80939
80939
|
id: request.id,
|
|
80940
80940
|
error: {
|
|
@@ -80946,11 +80946,11 @@ var init_protocol4 = __esm({
|
|
|
80946
80946
|
if (relatedTaskId && this._taskMessageQueue) {
|
|
80947
80947
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
80948
80948
|
type: "error",
|
|
80949
|
-
message:
|
|
80949
|
+
message: errorResponse2,
|
|
80950
80950
|
timestamp: Date.now()
|
|
80951
80951
|
}, capturedTransport?.sessionId);
|
|
80952
80952
|
} else {
|
|
80953
|
-
await capturedTransport?.send(
|
|
80953
|
+
await capturedTransport?.send(errorResponse2);
|
|
80954
80954
|
}
|
|
80955
80955
|
}).catch((error87) => this._onerror(new Error(`Failed to send response: ${error87}`))).finally(() => {
|
|
80956
80956
|
this._requestHandlerAbortControllers.delete(request.id);
|
|
@@ -141255,6 +141255,11 @@ function resolveHttpChallengeConfig(config4, env2) {
|
|
|
141255
141255
|
if (!enabled)
|
|
141256
141256
|
return null;
|
|
141257
141257
|
const anchorTtlS = Math.min(positiveOrDefault(httpChallenge?.anchorTtlS, ANCHOR_TTL_MAX_S), ANCHOR_TTL_MAX_S);
|
|
141258
|
+
const anchorRegistrationEnvFlag = readHttpChallengeEnvFlag(env2?.MCPI_ANCHOR_REGISTRATION);
|
|
141259
|
+
let remoteAnchorRegistration = httpChallenge?.remoteAnchorRegistration ?? true;
|
|
141260
|
+
if (anchorRegistrationEnvFlag !== void 0) {
|
|
141261
|
+
remoteAnchorRegistration = anchorRegistrationEnvFlag;
|
|
141262
|
+
}
|
|
141258
141263
|
return {
|
|
141259
141264
|
enabled: true,
|
|
141260
141265
|
mode: httpChallenge?.mode ?? "negotiated",
|
|
@@ -141262,7 +141267,8 @@ function resolveHttpChallengeConfig(config4, env2) {
|
|
|
141262
141267
|
pollIntervalS: positiveOrDefault(httpChallenge?.pollIntervalS, 3),
|
|
141263
141268
|
anchorTtlS,
|
|
141264
141269
|
delegationExpiresInS: positiveOrDefault(httpChallenge?.delegationExpiresInS, 900),
|
|
141265
|
-
allowUnverifiedKeyidHolders: httpChallenge?.allowUnverifiedKeyidHolders ?? false
|
|
141270
|
+
allowUnverifiedKeyidHolders: httpChallenge?.allowUnverifiedKeyidHolders ?? false,
|
|
141271
|
+
remoteAnchorRegistration
|
|
141266
141272
|
};
|
|
141267
141273
|
}
|
|
141268
141274
|
|
|
@@ -141325,6 +141331,7 @@ function mapPrefixedEnv(env2, prefix) {
|
|
|
141325
141331
|
MCPI_HTTP_CHALLENGE: typeof env2.MCPI_HTTP_CHALLENGE === "string" ? env2.MCPI_HTTP_CHALLENGE : void 0,
|
|
141326
141332
|
MCPI_TEST_CONSENT: typeof env2.MCPI_TEST_CONSENT === "string" ? env2.MCPI_TEST_CONSENT : void 0,
|
|
141327
141333
|
MCPI_INLINE_CONSENT: typeof env2.MCPI_INLINE_CONSENT === "string" ? env2.MCPI_INLINE_CONSENT : void 0,
|
|
141334
|
+
MCPI_ANCHOR_REGISTRATION: typeof env2.MCPI_ANCHOR_REGISTRATION === "string" ? env2.MCPI_ANCHOR_REGISTRATION : void 0,
|
|
141328
141335
|
// MCP_OBJECT: Durable Object namespace for MCP agent
|
|
141329
141336
|
// Try prefixed first, then fall back to unprefixed (most deployments use unprefixed)
|
|
141330
141337
|
MCP_OBJECT: env2[`${prefixWithUnderscore}_MCP_OBJECT`] || env2[`${prefixWithoutUnderscore}_MCP_OBJECT`] || env2.MCP_OBJECT,
|
|
@@ -141456,6 +141463,7 @@ function sha256Hex(input) {
|
|
|
141456
141463
|
// ../mcp-i-cloudflare/dist/delegation-http/constants.js
|
|
141457
141464
|
var PICKUP_ROUTE = "/api/delegation/pickup/:sid";
|
|
141458
141465
|
var CONSENT_ROUTE = "/consent";
|
|
141466
|
+
var ANCHOR_REGISTRATION_ROUTE = "/api/v1/bouncer/sessions";
|
|
141459
141467
|
var PICKUP_TOKEN_HEADER = "X-KYA-Pickup-Token";
|
|
141460
141468
|
var FALLBACK_DELEGATION_HEADER = "KYA-Delegation";
|
|
141461
141469
|
var CHALLENGE_PARAM_ORDER = [
|
|
@@ -141491,7 +141499,7 @@ var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
|
|
|
141491
141499
|
function reduceCreate(rec, input, now2) {
|
|
141492
141500
|
const i2 = input;
|
|
141493
141501
|
if (rec && now2 <= rec.expiresAt) {
|
|
141494
|
-
return { response: { status: 201, body: { success: true } } };
|
|
141502
|
+
return { response: { status: 201, body: { success: true, reused: true } } };
|
|
141495
141503
|
}
|
|
141496
141504
|
const record4 = {
|
|
141497
141505
|
sid: i2.sid,
|
|
@@ -141501,6 +141509,9 @@ function reduceCreate(rec, input, now2) {
|
|
|
141501
141509
|
pollIntervalS: i2.pollIntervalS,
|
|
141502
141510
|
createdAt: now2,
|
|
141503
141511
|
expiresAt: now2 + i2.anchorTtlS * 1e3,
|
|
141512
|
+
agentDid: typeof i2.agentDid === "string" ? i2.agentDid : void 0,
|
|
141513
|
+
audience: typeof i2.audience === "string" ? i2.audience : void 0,
|
|
141514
|
+
serverDid: typeof i2.serverDid === "string" ? i2.serverDid : void 0,
|
|
141504
141515
|
pin: i2.pin ? {
|
|
141505
141516
|
type: i2.pin.type,
|
|
141506
141517
|
valueSha256: i2.pin.valueSha256,
|
|
@@ -141639,7 +141650,10 @@ async function handlePickupInternal(ctx, request, now2) {
|
|
|
141639
141650
|
status: rec.status,
|
|
141640
141651
|
requiredScopes: rec.requiredScopes,
|
|
141641
141652
|
minAssurance: rec.minAssurance,
|
|
141642
|
-
expiresAt: rec.expiresAt
|
|
141653
|
+
expiresAt: rec.expiresAt,
|
|
141654
|
+
agentDid: rec.agentDid,
|
|
141655
|
+
audience: rec.audience,
|
|
141656
|
+
serverDid: rec.serverDid
|
|
141643
141657
|
}
|
|
141644
141658
|
});
|
|
141645
141659
|
}
|
|
@@ -141649,7 +141663,7 @@ async function handlePickupInternal(ctx, request, now2) {
|
|
|
141649
141663
|
// ../mcp-i-cloudflare/package.json
|
|
141650
141664
|
var package_default = {
|
|
141651
141665
|
name: "@kya-os/mcp-i-cloudflare",
|
|
141652
|
-
version: "1.
|
|
141666
|
+
version: "1.12.0",
|
|
141653
141667
|
description: "Cloudflare Workers adapter for MCP-I framework",
|
|
141654
141668
|
main: "dist/index.js",
|
|
141655
141669
|
types: "dist/index.d.ts",
|
|
@@ -141719,7 +141733,7 @@ var package_default = {
|
|
|
141719
141733
|
|
|
141720
141734
|
// ../mcp-i-cloudflare/dist/delegation-http/well-known-capability.js
|
|
141721
141735
|
var KYA_OS_IDENTITY_WELL_KNOWN_PATH = "/.well-known/kya-os-identity";
|
|
141722
|
-
function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg) {
|
|
141736
|
+
function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg, anchorRegistration) {
|
|
141723
141737
|
if (wellKnownPath !== KYA_OS_IDENTITY_WELL_KNOWN_PATH || !result) {
|
|
141724
141738
|
return result;
|
|
141725
141739
|
}
|
|
@@ -141727,11 +141741,406 @@ function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg) {
|
|
|
141727
141741
|
...result,
|
|
141728
141742
|
delegationHttp: {
|
|
141729
141743
|
enabled: cfg !== null,
|
|
141730
|
-
version: package_default.version
|
|
141744
|
+
version: package_default.version,
|
|
141745
|
+
anchorRegistration
|
|
141746
|
+
}
|
|
141747
|
+
};
|
|
141748
|
+
}
|
|
141749
|
+
|
|
141750
|
+
// ../mcp-i-cloudflare/dist/delegation-http/sid.js
|
|
141751
|
+
var ANCHOR_SID_RE = /^kya-[0-9a-f]{16,64}$/;
|
|
141752
|
+
function isAnchorSid(s5) {
|
|
141753
|
+
return typeof s5 === "string" && ANCHOR_SID_RE.test(s5);
|
|
141754
|
+
}
|
|
141755
|
+
|
|
141756
|
+
// ../mcp-i-cloudflare/dist/delegation-http/challenge.js
|
|
141757
|
+
var CHALLENGE_PROOF_METHOD = "kyaos/challenge";
|
|
141758
|
+
function buildWWWAuthenticateDelegation(i2) {
|
|
141759
|
+
const values = {
|
|
141760
|
+
realm: i2.realm,
|
|
141761
|
+
sid: i2.sid,
|
|
141762
|
+
consent_uri: buildConsentUri(i2),
|
|
141763
|
+
pickup_uri: buildPickupUri(i2),
|
|
141764
|
+
scope: i2.requiredScopes.join(" "),
|
|
141765
|
+
min_assurance: i2.minAssurance,
|
|
141766
|
+
interval: String(i2.pollIntervalS),
|
|
141767
|
+
kind: "delegation"
|
|
141768
|
+
};
|
|
141769
|
+
const params = CHALLENGE_PARAM_ORDER.filter(
|
|
141770
|
+
// min_assurance is the only optional param: omit the whole token when absent.
|
|
141771
|
+
(key) => values[key] !== void 0
|
|
141772
|
+
).map((key) => `${key}="${values[key]}"`);
|
|
141773
|
+
return `Delegation ${params.join(", ")}`;
|
|
141774
|
+
}
|
|
141775
|
+
function buildWWWAuthenticateBearer(realm) {
|
|
141776
|
+
return `Bearer resource_metadata="https://${realm}/.well-known/oauth-protected-resource"`;
|
|
141777
|
+
}
|
|
141778
|
+
function buildConsentUri(i2) {
|
|
141779
|
+
return `https://${i2.authorizationHost}/consent?sid=${i2.sid}`;
|
|
141780
|
+
}
|
|
141781
|
+
function buildPickupUri(i2) {
|
|
141782
|
+
return `https://${i2.authorizationHost}/api/delegation/pickup/${i2.sid}`;
|
|
141783
|
+
}
|
|
141784
|
+
function buildInstructions(i2) {
|
|
141785
|
+
const consentUri = buildConsentUri(i2);
|
|
141786
|
+
const pickupUri = buildPickupUri(i2);
|
|
141787
|
+
return `This action requires human authorization. Show your user this link and ask them to approve: ${consentUri}. Then poll ${pickupUri} every ${i2.pollIntervalS} seconds. If you can sign HTTP requests, sign each poll with an ephemeral did:key; otherwise generate one random 32-byte token and send it as X-KYA-Pickup-Token on EVERY poll. When the response status is 200, take the 'delegation' value and retry your original request with header 'Authorization: Bearer <delegation>'.`;
|
|
141788
|
+
}
|
|
141789
|
+
function buildChallengeBody(i2, challengeProof) {
|
|
141790
|
+
const kyaos = {
|
|
141791
|
+
sid: i2.sid,
|
|
141792
|
+
consent_uri: buildConsentUri(i2),
|
|
141793
|
+
pickup_uri: buildPickupUri(i2),
|
|
141794
|
+
required_scopes: i2.requiredScopes
|
|
141795
|
+
};
|
|
141796
|
+
if (i2.minAssurance !== void 0) {
|
|
141797
|
+
kyaos.min_assurance = i2.minAssurance;
|
|
141798
|
+
}
|
|
141799
|
+
kyaos.poll_interval_s = i2.pollIntervalS;
|
|
141800
|
+
kyaos.challenge_proof = challengeProof;
|
|
141801
|
+
return {
|
|
141802
|
+
error: KYAOS_ERRORS.authorizationRequired,
|
|
141803
|
+
kyaos,
|
|
141804
|
+
instructions: buildInstructions(i2)
|
|
141805
|
+
};
|
|
141806
|
+
}
|
|
141807
|
+
function buildChallengeResponse(i2, challengeProof) {
|
|
141808
|
+
const headers = new Headers();
|
|
141809
|
+
headers.append("WWW-Authenticate", buildWWWAuthenticateDelegation(i2));
|
|
141810
|
+
headers.append("WWW-Authenticate", buildWWWAuthenticateBearer(i2.realm));
|
|
141811
|
+
headers.set("Retry-After", String(i2.pollIntervalS));
|
|
141812
|
+
headers.set("Content-Type", "application/json");
|
|
141813
|
+
headers.set("Cache-Control", "no-store");
|
|
141814
|
+
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
141815
|
+
status: 401,
|
|
141816
|
+
headers
|
|
141817
|
+
});
|
|
141818
|
+
}
|
|
141819
|
+
function buildFetcherChallengeResponse(i2, challengeProof) {
|
|
141820
|
+
const consentUri = buildConsentUri(i2);
|
|
141821
|
+
const headers = new Headers();
|
|
141822
|
+
headers.set("Content-Type", "application/json");
|
|
141823
|
+
headers.set("Cache-Control", "no-store");
|
|
141824
|
+
headers.set("KYA-Auth-Required", "true");
|
|
141825
|
+
headers.set("KYA-Auth-Url", consentUri);
|
|
141826
|
+
headers.set("Link", `<${consentUri}>; rel="kya-authorize"`);
|
|
141827
|
+
headers.set("KYA-Action", "challenge");
|
|
141828
|
+
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
141829
|
+
status: 200,
|
|
141830
|
+
headers
|
|
141831
|
+
});
|
|
141832
|
+
}
|
|
141833
|
+
async function signChallengeProof(gen, payload) {
|
|
141834
|
+
const proof = await gen.generateProof({
|
|
141835
|
+
method: CHALLENGE_PROOF_METHOD,
|
|
141836
|
+
params: {
|
|
141837
|
+
sid: payload.sid,
|
|
141838
|
+
consent_uri: payload.consent_uri,
|
|
141839
|
+
required_scopes: payload.required_scopes
|
|
141840
|
+
}
|
|
141841
|
+
}, { data: { sid: payload.sid } }, {
|
|
141842
|
+
// The session binds the proof to this anchor; sid is the natural nonce.
|
|
141843
|
+
nonce: payload.sid,
|
|
141844
|
+
audience: payload.consent_uri,
|
|
141845
|
+
sessionId: payload.sid
|
|
141846
|
+
});
|
|
141847
|
+
return proof.jws;
|
|
141848
|
+
}
|
|
141849
|
+
|
|
141850
|
+
// ../mcp-i-cloudflare/dist/delegation-http/registrar-auth.js
|
|
141851
|
+
function constantTimeEqualHex(a5, b3) {
|
|
141852
|
+
if (a5.length !== b3.length)
|
|
141853
|
+
return false;
|
|
141854
|
+
let diff = 0;
|
|
141855
|
+
for (let i2 = 0; i2 < a5.length; i2++) {
|
|
141856
|
+
diff |= a5.charCodeAt(i2) ^ b3.charCodeAt(i2);
|
|
141857
|
+
}
|
|
141858
|
+
return diff === 0;
|
|
141859
|
+
}
|
|
141860
|
+
function registrarAuthorized(env2, authorizationHeader) {
|
|
141861
|
+
const expected = env2.AGENTSHIELD_API_KEY;
|
|
141862
|
+
if (!expected || !authorizationHeader)
|
|
141863
|
+
return false;
|
|
141864
|
+
const match2 = /^Bearer\s+(.+)$/i.exec(authorizationHeader.trim());
|
|
141865
|
+
if (!match2)
|
|
141866
|
+
return false;
|
|
141867
|
+
return constantTimeEqualHex(sha256Hex(match2[1]), sha256Hex(expected));
|
|
141868
|
+
}
|
|
141869
|
+
var RATE_WINDOW_MS = 6e4;
|
|
141870
|
+
var RATE_MAX_PER_WINDOW = 60;
|
|
141871
|
+
var rateWindowStart = 0;
|
|
141872
|
+
var rateCount = 0;
|
|
141873
|
+
function registrationRateLimited(now2) {
|
|
141874
|
+
if (now2 - rateWindowStart >= RATE_WINDOW_MS) {
|
|
141875
|
+
rateWindowStart = now2;
|
|
141876
|
+
rateCount = 0;
|
|
141877
|
+
}
|
|
141878
|
+
rateCount += 1;
|
|
141879
|
+
return rateCount > RATE_MAX_PER_WINDOW;
|
|
141880
|
+
}
|
|
141881
|
+
|
|
141882
|
+
// ../mcp-i-cloudflare/dist/delegation-http/anchor-registration-validate.js
|
|
141883
|
+
var DID_RE = /^did:(key|web):.+$/;
|
|
141884
|
+
function isRecord2(value) {
|
|
141885
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
141886
|
+
}
|
|
141887
|
+
function checkString(issues, path, value, max) {
|
|
141888
|
+
if (typeof value !== "string" || value.length < 1 || value.length > max) {
|
|
141889
|
+
issues.push({ path, message: `${path} must be a string (1-${max} chars)` });
|
|
141890
|
+
return false;
|
|
141891
|
+
}
|
|
141892
|
+
return true;
|
|
141893
|
+
}
|
|
141894
|
+
function checkOptionalString(issues, path, value, max) {
|
|
141895
|
+
if (value === void 0)
|
|
141896
|
+
return;
|
|
141897
|
+
checkString(issues, path, value, max);
|
|
141898
|
+
}
|
|
141899
|
+
function validateChallenge(issues, raw2) {
|
|
141900
|
+
if (raw2 === void 0)
|
|
141901
|
+
return void 0;
|
|
141902
|
+
if (!isRecord2(raw2)) {
|
|
141903
|
+
issues.push({ path: "challenge", message: "challenge must be an object" });
|
|
141904
|
+
return void 0;
|
|
141905
|
+
}
|
|
141906
|
+
const issuesBefore = issues.length;
|
|
141907
|
+
const scopes = raw2.required_scopes;
|
|
141908
|
+
if (!Array.isArray(scopes) || scopes.length < 1 || scopes.length > 50 || scopes.some((s5) => typeof s5 !== "string" || s5.length < 1 || s5.length > 200)) {
|
|
141909
|
+
issues.push({
|
|
141910
|
+
path: "challenge.required_scopes",
|
|
141911
|
+
message: "challenge.required_scopes must be 1-50 strings of 1-200 chars each"
|
|
141912
|
+
});
|
|
141913
|
+
}
|
|
141914
|
+
checkOptionalString(issues, "challenge.pep_surface", raw2.pep_surface, 64);
|
|
141915
|
+
checkOptionalString(issues, "challenge.verdict", raw2.verdict, 64);
|
|
141916
|
+
checkOptionalString(issues, "challenge.challenge_pin", raw2.challenge_pin, 512);
|
|
141917
|
+
if (raw2.detected_agent_did !== void 0 && (typeof raw2.detected_agent_did !== "string" || !DID_RE.test(raw2.detected_agent_did))) {
|
|
141918
|
+
issues.push({
|
|
141919
|
+
path: "challenge.detected_agent_did",
|
|
141920
|
+
message: "Invalid DID format. Must be did:key: or did:web:"
|
|
141921
|
+
});
|
|
141922
|
+
}
|
|
141923
|
+
if (raw2.audience !== void 0 && (typeof raw2.audience !== "string" || !DID_RE.test(raw2.audience))) {
|
|
141924
|
+
issues.push({
|
|
141925
|
+
path: "challenge.audience",
|
|
141926
|
+
message: "Invalid DID format. Must be did:key: or did:web:"
|
|
141927
|
+
});
|
|
141928
|
+
}
|
|
141929
|
+
if (issues.length > issuesBefore)
|
|
141930
|
+
return void 0;
|
|
141931
|
+
return {
|
|
141932
|
+
requiredScopes: scopes,
|
|
141933
|
+
pepSurface: raw2.pep_surface,
|
|
141934
|
+
verdict: raw2.verdict,
|
|
141935
|
+
detectedAgentDid: raw2.detected_agent_did,
|
|
141936
|
+
challengePin: raw2.challenge_pin,
|
|
141937
|
+
audience: raw2.audience
|
|
141938
|
+
};
|
|
141939
|
+
}
|
|
141940
|
+
function validateRegistrationBody(raw2) {
|
|
141941
|
+
if (!isRecord2(raw2)) {
|
|
141942
|
+
return {
|
|
141943
|
+
ok: false,
|
|
141944
|
+
issues: [{ path: "", message: "body must be a JSON object" }]
|
|
141945
|
+
};
|
|
141946
|
+
}
|
|
141947
|
+
const issues = [];
|
|
141948
|
+
checkString(issues, "session_id", raw2.session_id, 255);
|
|
141949
|
+
if (typeof raw2.agent_did !== "string" || !DID_RE.test(raw2.agent_did)) {
|
|
141950
|
+
issues.push({
|
|
141951
|
+
path: "agent_did",
|
|
141952
|
+
message: "Invalid DID format. Must be did:key: or did:web:"
|
|
141953
|
+
});
|
|
141954
|
+
}
|
|
141955
|
+
checkString(issues, "project_id", raw2.project_id, 255);
|
|
141956
|
+
if (typeof raw2.created_at !== "number" || !Number.isInteger(raw2.created_at) || raw2.created_at <= 0) {
|
|
141957
|
+
issues.push({
|
|
141958
|
+
path: "created_at",
|
|
141959
|
+
message: "created_at must be a positive unix-ms integer"
|
|
141960
|
+
});
|
|
141961
|
+
}
|
|
141962
|
+
const clientInfo = raw2.client_info;
|
|
141963
|
+
if (!isRecord2(clientInfo)) {
|
|
141964
|
+
issues.push({
|
|
141965
|
+
path: "client_info",
|
|
141966
|
+
message: "client_info must be an object"
|
|
141967
|
+
});
|
|
141968
|
+
} else {
|
|
141969
|
+
checkString(issues, "client_info.name", clientInfo.name, 255);
|
|
141970
|
+
checkOptionalString(issues, "client_info.version", clientInfo.version, 50);
|
|
141971
|
+
}
|
|
141972
|
+
if (raw2.server_did !== void 0 && (typeof raw2.server_did !== "string" || !DID_RE.test(raw2.server_did))) {
|
|
141973
|
+
issues.push({
|
|
141974
|
+
path: "server_did",
|
|
141975
|
+
message: "Invalid DID format. Must be did:key: or did:web:"
|
|
141976
|
+
});
|
|
141977
|
+
}
|
|
141978
|
+
const challenge = validateChallenge(issues, raw2.challenge);
|
|
141979
|
+
if (raw2.challenge !== void 0 && typeof raw2.session_id === "string" && raw2.session_id.length < 22) {
|
|
141980
|
+
issues.push({
|
|
141981
|
+
path: "session_id",
|
|
141982
|
+
message: "session_id must be at least 22 characters (\u2248128-bit) when a challenge is attached"
|
|
141983
|
+
});
|
|
141984
|
+
}
|
|
141985
|
+
if (issues.length > 0)
|
|
141986
|
+
return { ok: false, issues };
|
|
141987
|
+
return {
|
|
141988
|
+
ok: true,
|
|
141989
|
+
input: {
|
|
141990
|
+
sessionId: raw2.session_id,
|
|
141991
|
+
agentDid: raw2.agent_did,
|
|
141992
|
+
projectId: raw2.project_id,
|
|
141993
|
+
createdAt: raw2.created_at,
|
|
141994
|
+
clientName: clientInfo.name,
|
|
141995
|
+
clientVersion: clientInfo.version,
|
|
141996
|
+
serverDid: raw2.server_did,
|
|
141997
|
+
challenge
|
|
141731
141998
|
}
|
|
141732
141999
|
};
|
|
141733
142000
|
}
|
|
141734
142001
|
|
|
142002
|
+
// ../mcp-i-cloudflare/dist/delegation-http/anchor-registration.js
|
|
142003
|
+
var DO_INTERNAL_ORIGIN = "https://do.internal";
|
|
142004
|
+
function isAnchorRegistrationEnabled(cfg, env2) {
|
|
142005
|
+
return cfg !== null && cfg.remoteAnchorRegistration && typeof env2.AGENTSHIELD_API_KEY === "string" && env2.AGENTSHIELD_API_KEY.length > 0;
|
|
142006
|
+
}
|
|
142007
|
+
function deriveRegistrationSid(sessionId) {
|
|
142008
|
+
if (isAnchorSid(sessionId))
|
|
142009
|
+
return sessionId;
|
|
142010
|
+
return `kya-${sha256Hex(sessionId).slice(0, 32)}`;
|
|
142011
|
+
}
|
|
142012
|
+
function errorResponse(status, code, message3, details) {
|
|
142013
|
+
return new Response(JSON.stringify({
|
|
142014
|
+
success: false,
|
|
142015
|
+
error: { code, message: message3, ...details ? { details } : {} }
|
|
142016
|
+
}), {
|
|
142017
|
+
status,
|
|
142018
|
+
headers: {
|
|
142019
|
+
"Content-Type": "application/json",
|
|
142020
|
+
"Cache-Control": "no-store"
|
|
142021
|
+
}
|
|
142022
|
+
});
|
|
142023
|
+
}
|
|
142024
|
+
async function callAnchor(env2, deps, sid, internalPath, body) {
|
|
142025
|
+
const stub = deps.getAnchorStub(env2, sid);
|
|
142026
|
+
const response = await stub.fetch(new URL(internalPath, DO_INTERNAL_ORIGIN).toString(), {
|
|
142027
|
+
method: "POST",
|
|
142028
|
+
headers: { "Content-Type": "application/json" },
|
|
142029
|
+
body: JSON.stringify(body)
|
|
142030
|
+
});
|
|
142031
|
+
return response;
|
|
142032
|
+
}
|
|
142033
|
+
async function ensureAnchor(env2, cfg, deps, sid, challenge, session) {
|
|
142034
|
+
const pin = challenge.challengePin && cfg.allowUnverifiedKeyidHolders ? { type: "keyid", valueSha256: sha256Hex(challenge.challengePin) } : void 0;
|
|
142035
|
+
const created = await callAnchor(env2, deps, sid, INTERNAL_PICKUP_CREATE, {
|
|
142036
|
+
sid,
|
|
142037
|
+
requiredScopes: challenge.requiredScopes,
|
|
142038
|
+
pollIntervalS: cfg.pollIntervalS,
|
|
142039
|
+
anchorTtlS: cfg.anchorTtlS,
|
|
142040
|
+
delegationExpiresInS: cfg.delegationExpiresInS,
|
|
142041
|
+
agentDid: challenge.detectedAgentDid ?? session.agentDid,
|
|
142042
|
+
// Cross-resource claim inputs (drive the minted VC's aud / server_did —
|
|
142043
|
+
// see consent-anchor-bridge's withCrossResourceClaims).
|
|
142044
|
+
...challenge.audience ? { audience: challenge.audience } : {},
|
|
142045
|
+
...session.serverDid ? { serverDid: session.serverDid } : {},
|
|
142046
|
+
...pin ? { pin } : {}
|
|
142047
|
+
});
|
|
142048
|
+
if (created.status !== 201) {
|
|
142049
|
+
return {
|
|
142050
|
+
error: errorResponse(502, "anchor_unavailable", "The anchor store did not accept the registration")
|
|
142051
|
+
};
|
|
142052
|
+
}
|
|
142053
|
+
let reused = false;
|
|
142054
|
+
try {
|
|
142055
|
+
reused = (await created.json()).reused === true;
|
|
142056
|
+
} catch {
|
|
142057
|
+
}
|
|
142058
|
+
const readBack = await callAnchor(env2, deps, sid, INTERNAL_PICKUP_INFO, {
|
|
142059
|
+
sid
|
|
142060
|
+
});
|
|
142061
|
+
if (readBack.status !== 200) {
|
|
142062
|
+
return {
|
|
142063
|
+
error: errorResponse(502, "anchor_unavailable", "The registered anchor could not be read back")
|
|
142064
|
+
};
|
|
142065
|
+
}
|
|
142066
|
+
return {
|
|
142067
|
+
isNew: !reused,
|
|
142068
|
+
snapshot: await readBack.json()
|
|
142069
|
+
};
|
|
142070
|
+
}
|
|
142071
|
+
async function handleAnchorRegistration(c, env2, cfg, deps) {
|
|
142072
|
+
if (!registrarAuthorized(env2, c.req.header("Authorization"))) {
|
|
142073
|
+
return errorResponse(401, "unauthorized", "Invalid or missing API key");
|
|
142074
|
+
}
|
|
142075
|
+
if (registrationRateLimited(Date.now())) {
|
|
142076
|
+
return errorResponse(429, "rate_limited", "Too many anchor registrations; retry shortly");
|
|
142077
|
+
}
|
|
142078
|
+
let raw2;
|
|
142079
|
+
try {
|
|
142080
|
+
raw2 = await c.req.raw.clone().json();
|
|
142081
|
+
} catch {
|
|
142082
|
+
return errorResponse(400, "invalid_request", "Invalid request body", [
|
|
142083
|
+
{ path: "", message: "body must be JSON" }
|
|
142084
|
+
]);
|
|
142085
|
+
}
|
|
142086
|
+
const validated = validateRegistrationBody(raw2);
|
|
142087
|
+
if (!validated.ok) {
|
|
142088
|
+
return errorResponse(400, "invalid_request", "Invalid request body", validated.issues);
|
|
142089
|
+
}
|
|
142090
|
+
const { challenge } = validated.input;
|
|
142091
|
+
if (!challenge) {
|
|
142092
|
+
return errorResponse(401, "unauthorized", "This endpoint only accepts challenge registration");
|
|
142093
|
+
}
|
|
142094
|
+
const sid = deriveRegistrationSid(validated.input.sessionId);
|
|
142095
|
+
const anchor = await ensureAnchor(env2, cfg, deps, sid, challenge, {
|
|
142096
|
+
agentDid: validated.input.agentDid,
|
|
142097
|
+
serverDid: validated.input.serverDid
|
|
142098
|
+
});
|
|
142099
|
+
if ("error" in anchor)
|
|
142100
|
+
return anchor.error;
|
|
142101
|
+
const host = cfg.realm || new URL(c.req.url).host;
|
|
142102
|
+
const verdict = {
|
|
142103
|
+
requiredScopes: anchor.snapshot.requiredScopes,
|
|
142104
|
+
authorizationHost: host,
|
|
142105
|
+
realm: host,
|
|
142106
|
+
sid,
|
|
142107
|
+
pollIntervalS: cfg.pollIntervalS
|
|
142108
|
+
};
|
|
142109
|
+
const consentUri = buildConsentUri(verdict);
|
|
142110
|
+
let challengeProof;
|
|
142111
|
+
try {
|
|
142112
|
+
challengeProof = await signChallengeProof(await deps.proofGenerator(), {
|
|
142113
|
+
sid,
|
|
142114
|
+
consent_uri: consentUri,
|
|
142115
|
+
required_scopes: anchor.snapshot.requiredScopes
|
|
142116
|
+
});
|
|
142117
|
+
} catch (error87) {
|
|
142118
|
+
console.warn(`[kya-http] registration challenge_proof signing failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
|
|
142119
|
+
return errorResponse(502, "proof_unavailable", "The challenge proof could not be signed");
|
|
142120
|
+
}
|
|
142121
|
+
return new Response(JSON.stringify({
|
|
142122
|
+
success: true,
|
|
142123
|
+
data: {
|
|
142124
|
+
session_id: sid,
|
|
142125
|
+
registered: true,
|
|
142126
|
+
created_at: new Date(validated.input.createdAt).toISOString(),
|
|
142127
|
+
challenge: {
|
|
142128
|
+
consent_uri: consentUri,
|
|
142129
|
+
challenge_proof: challengeProof,
|
|
142130
|
+
required_scopes: anchor.snapshot.requiredScopes,
|
|
142131
|
+
issued_at: Date.now()
|
|
142132
|
+
}
|
|
142133
|
+
}
|
|
142134
|
+
}), {
|
|
142135
|
+
status: anchor.isNew ? 201 : 200,
|
|
142136
|
+
headers: {
|
|
142137
|
+
"Content-Type": "application/json",
|
|
142138
|
+
// Checkpoint's route parity (its success responses are private/no-cache).
|
|
142139
|
+
"Cache-Control": "private, no-cache"
|
|
142140
|
+
}
|
|
142141
|
+
});
|
|
142142
|
+
}
|
|
142143
|
+
|
|
141735
142144
|
// ../mcp-i-cloudflare/dist/agent.js
|
|
141736
142145
|
init_storage_keys();
|
|
141737
142146
|
|
|
@@ -144166,7 +144575,7 @@ var MCPICloudflareAgent = class extends McpAgent {
|
|
|
144166
144575
|
const mappedEnv = envPrefix ? mapPrefixedEnv(this.env, envPrefix) : this.env;
|
|
144167
144576
|
const runtimeConfig = this.getRuntimeConfigInternal(mappedEnv);
|
|
144168
144577
|
const httpChallengeCfg = resolveHttpChallengeConfig(runtimeConfig, mappedEnv);
|
|
144169
|
-
const augmented = augmentKyaOsIdentityWellKnown(wellKnownPath, result, httpChallengeCfg);
|
|
144578
|
+
const augmented = augmentKyaOsIdentityWellKnown(wellKnownPath, result, httpChallengeCfg, isAnchorRegistrationEnabled(httpChallengeCfg, mappedEnv));
|
|
144170
144579
|
return new Response(JSON.stringify(augmented), {
|
|
144171
144580
|
status: 200,
|
|
144172
144581
|
headers: { "Content-Type": "application/json" }
|
|
@@ -146908,12 +147317,6 @@ var cors = (options) => {
|
|
|
146908
147317
|
};
|
|
146909
147318
|
};
|
|
146910
147319
|
|
|
146911
|
-
// ../mcp-i-cloudflare/dist/delegation-http/sid.js
|
|
146912
|
-
var ANCHOR_SID_RE = /^kya-[0-9a-f]{16,64}$/;
|
|
146913
|
-
function isAnchorSid(s5) {
|
|
146914
|
-
return typeof s5 === "string" && ANCHOR_SID_RE.test(s5);
|
|
146915
|
-
}
|
|
146916
|
-
|
|
146917
147320
|
// ../mcp-i-cloudflare/dist/delegation-http/anchor-routing.js
|
|
146918
147321
|
function anchorInstanceId(sid) {
|
|
146919
147322
|
return `pickup:${sid}`;
|
|
@@ -146973,10 +147376,10 @@ async function handlePickupGet(c, env2, cfg) {
|
|
|
146973
147376
|
init_dist2();
|
|
146974
147377
|
init_crypto();
|
|
146975
147378
|
init_storage();
|
|
146976
|
-
var
|
|
146977
|
-
async function
|
|
147379
|
+
var DO_INTERNAL_ORIGIN2 = "https://do.internal";
|
|
147380
|
+
async function callAnchor2(env2, sid, internalPath, body) {
|
|
146978
147381
|
const stub = getAnchorStub(env2, sid);
|
|
146979
|
-
const response = await stub.fetch(new URL(internalPath,
|
|
147382
|
+
const response = await stub.fetch(new URL(internalPath, DO_INTERNAL_ORIGIN2).toString(), {
|
|
146980
147383
|
method: "POST",
|
|
146981
147384
|
headers: { "Content-Type": "application/json" },
|
|
146982
147385
|
body: JSON.stringify(body)
|
|
@@ -147109,6 +147512,17 @@ function isTestConsentMode(env2) {
|
|
|
147109
147512
|
const environment = String(bag.ENVIRONMENT ?? bag.MCPI_ENV ?? "").toLowerCase();
|
|
147110
147513
|
return environment === "development";
|
|
147111
147514
|
}
|
|
147515
|
+
function withCrossResourceClaims(unsigned, info, sid) {
|
|
147516
|
+
if (!info.audience)
|
|
147517
|
+
return unsigned.signingInput;
|
|
147518
|
+
const payload = {
|
|
147519
|
+
...unsigned.payload,
|
|
147520
|
+
aud: info.audience,
|
|
147521
|
+
sid,
|
|
147522
|
+
...info.serverDid ? { server_did: info.serverDid } : {}
|
|
147523
|
+
};
|
|
147524
|
+
return `${unsigned.encodedHeader}.${base64UrlEncodeString(JSON.stringify(payload))}`;
|
|
147525
|
+
}
|
|
147112
147526
|
async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
147113
147527
|
const cryptoProvider = new WebCryptoProvider();
|
|
147114
147528
|
const configuredIdentity = getConfiguredIdentity(env2);
|
|
@@ -147125,7 +147539,7 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
|
147125
147539
|
keyId = `${issuerDid}#${didKeyFragment2(issuerDid)}`;
|
|
147126
147540
|
signingPrivateKey = rawKeyPair.privateKey;
|
|
147127
147541
|
}
|
|
147128
|
-
const agentDid = env2.MCP_IDENTITY_AGENT_DID || issuerDid;
|
|
147542
|
+
const agentDid = info.agentDid || env2.MCP_IDENTITY_AGENT_DID || issuerDid;
|
|
147129
147543
|
const nowS = Math.floor(Date.now() / 1e3);
|
|
147130
147544
|
const delegation = {
|
|
147131
147545
|
id: `urn:uuid:${sid}`,
|
|
@@ -147146,13 +147560,14 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
|
147146
147560
|
issuanceDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
147147
147561
|
});
|
|
147148
147562
|
const vcWithIssuer = { ...unsignedVC, issuer: issuerDid };
|
|
147149
|
-
const
|
|
147563
|
+
const unsigned = createUnsignedVCJWT2(vcWithIssuer, { keyId });
|
|
147564
|
+
const signingInput = withCrossResourceClaims(unsigned, info, sid);
|
|
147150
147565
|
const signatureBytes = await cryptoProvider.sign(new TextEncoder().encode(signingInput), signingPrivateKey);
|
|
147151
147566
|
const signature = base64urlEncodeFromBytes2(signatureBytes);
|
|
147152
147567
|
return completeVCJWT2(signingInput, signature);
|
|
147153
147568
|
}
|
|
147154
147569
|
async function handleAnchorConsentGet(c, sid, env2, _cfg) {
|
|
147155
|
-
const infoResponse = await
|
|
147570
|
+
const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
|
|
147156
147571
|
sid
|
|
147157
147572
|
});
|
|
147158
147573
|
if (infoResponse.status === 404)
|
|
@@ -147174,7 +147589,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
|
|
|
147174
147589
|
return htmlResponse(page("Authorization failed", `<main class="kya-consent-failed"><h1>Authorization failed</h1><p>Invalid or missing security token. Please reload and try again.</p></main>`), 403);
|
|
147175
147590
|
}
|
|
147176
147591
|
}
|
|
147177
|
-
const infoResponse = await
|
|
147592
|
+
const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
|
|
147178
147593
|
sid
|
|
147179
147594
|
});
|
|
147180
147595
|
if (infoResponse.status === 404)
|
|
@@ -147193,7 +147608,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
|
|
|
147193
147608
|
console.warn(`[kya-http] delegation mint failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
|
|
147194
147609
|
return approvalFailedPage("We could not complete the authorization. Please start over.", 500);
|
|
147195
147610
|
}
|
|
147196
|
-
const approveResponse = await
|
|
147611
|
+
const approveResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_APPROVE, {
|
|
147197
147612
|
sid,
|
|
147198
147613
|
vcJwt,
|
|
147199
147614
|
expiresInS: cfg.delegationExpiresInS
|
|
@@ -147237,7 +147652,7 @@ function resolveRequest(c, options) {
|
|
|
147237
147652
|
return { env: c.env, cfg: null };
|
|
147238
147653
|
}
|
|
147239
147654
|
}
|
|
147240
|
-
function registerDelegationHttpRoutes(app, options) {
|
|
147655
|
+
function registerDelegationHttpRoutes(app, options, deps) {
|
|
147241
147656
|
app.get(PICKUP_ROUTE, async (c, next) => {
|
|
147242
147657
|
const { env: env2, cfg } = resolveRequest(c, options);
|
|
147243
147658
|
if (!cfg)
|
|
@@ -147258,6 +147673,17 @@ function registerDelegationHttpRoutes(app, options) {
|
|
|
147258
147673
|
return next();
|
|
147259
147674
|
return handleAnchorConsentApprove(c, sid, env2, cfg);
|
|
147260
147675
|
});
|
|
147676
|
+
const proofGenerator = deps?.proofGenerator;
|
|
147677
|
+
app.post(ANCHOR_REGISTRATION_ROUTE, async (c, next) => {
|
|
147678
|
+
const { env: env2, cfg } = resolveRequest(c, options);
|
|
147679
|
+
if (!cfg || !isAnchorRegistrationEnabled(cfg, env2) || !proofGenerator) {
|
|
147680
|
+
return next();
|
|
147681
|
+
}
|
|
147682
|
+
return handleAnchorRegistration(c, env2, cfg, {
|
|
147683
|
+
getAnchorStub,
|
|
147684
|
+
proofGenerator: () => proofGenerator(c)
|
|
147685
|
+
});
|
|
147686
|
+
});
|
|
147261
147687
|
}
|
|
147262
147688
|
|
|
147263
147689
|
// ../mcp-i-cloudflare/dist/delegation-http/bearer-retry.js
|
|
@@ -147360,100 +147786,6 @@ async function applyBearerDelegation(request, env2, _cfg) {
|
|
|
147360
147786
|
return { request: rewritten };
|
|
147361
147787
|
}
|
|
147362
147788
|
|
|
147363
|
-
// ../mcp-i-cloudflare/dist/delegation-http/challenge.js
|
|
147364
|
-
var CHALLENGE_PROOF_METHOD = "kyaos/challenge";
|
|
147365
|
-
function buildWWWAuthenticateDelegation(i2) {
|
|
147366
|
-
const values = {
|
|
147367
|
-
realm: i2.realm,
|
|
147368
|
-
sid: i2.sid,
|
|
147369
|
-
consent_uri: buildConsentUri(i2),
|
|
147370
|
-
pickup_uri: buildPickupUri(i2),
|
|
147371
|
-
scope: i2.requiredScopes.join(" "),
|
|
147372
|
-
min_assurance: i2.minAssurance,
|
|
147373
|
-
interval: String(i2.pollIntervalS),
|
|
147374
|
-
kind: "delegation"
|
|
147375
|
-
};
|
|
147376
|
-
const params = CHALLENGE_PARAM_ORDER.filter(
|
|
147377
|
-
// min_assurance is the only optional param: omit the whole token when absent.
|
|
147378
|
-
(key) => values[key] !== void 0
|
|
147379
|
-
).map((key) => `${key}="${values[key]}"`);
|
|
147380
|
-
return `Delegation ${params.join(", ")}`;
|
|
147381
|
-
}
|
|
147382
|
-
function buildWWWAuthenticateBearer(realm) {
|
|
147383
|
-
return `Bearer resource_metadata="https://${realm}/.well-known/oauth-protected-resource"`;
|
|
147384
|
-
}
|
|
147385
|
-
function buildConsentUri(i2) {
|
|
147386
|
-
return `https://${i2.authorizationHost}/consent?sid=${i2.sid}`;
|
|
147387
|
-
}
|
|
147388
|
-
function buildPickupUri(i2) {
|
|
147389
|
-
return `https://${i2.authorizationHost}/api/delegation/pickup/${i2.sid}`;
|
|
147390
|
-
}
|
|
147391
|
-
function buildInstructions(i2) {
|
|
147392
|
-
const consentUri = buildConsentUri(i2);
|
|
147393
|
-
const pickupUri = buildPickupUri(i2);
|
|
147394
|
-
return `This action requires human authorization. Show your user this link and ask them to approve: ${consentUri}. Then poll ${pickupUri} every ${i2.pollIntervalS} seconds. If you can sign HTTP requests, sign each poll with an ephemeral did:key; otherwise generate one random 32-byte token and send it as X-KYA-Pickup-Token on EVERY poll. When the response status is 200, take the 'delegation' value and retry your original request with header 'Authorization: Bearer <delegation>'.`;
|
|
147395
|
-
}
|
|
147396
|
-
function buildChallengeBody(i2, challengeProof) {
|
|
147397
|
-
const kyaos = {
|
|
147398
|
-
sid: i2.sid,
|
|
147399
|
-
consent_uri: buildConsentUri(i2),
|
|
147400
|
-
pickup_uri: buildPickupUri(i2),
|
|
147401
|
-
required_scopes: i2.requiredScopes
|
|
147402
|
-
};
|
|
147403
|
-
if (i2.minAssurance !== void 0) {
|
|
147404
|
-
kyaos.min_assurance = i2.minAssurance;
|
|
147405
|
-
}
|
|
147406
|
-
kyaos.poll_interval_s = i2.pollIntervalS;
|
|
147407
|
-
kyaos.challenge_proof = challengeProof;
|
|
147408
|
-
return {
|
|
147409
|
-
error: KYAOS_ERRORS.authorizationRequired,
|
|
147410
|
-
kyaos,
|
|
147411
|
-
instructions: buildInstructions(i2)
|
|
147412
|
-
};
|
|
147413
|
-
}
|
|
147414
|
-
function buildChallengeResponse(i2, challengeProof) {
|
|
147415
|
-
const headers = new Headers();
|
|
147416
|
-
headers.append("WWW-Authenticate", buildWWWAuthenticateDelegation(i2));
|
|
147417
|
-
headers.append("WWW-Authenticate", buildWWWAuthenticateBearer(i2.realm));
|
|
147418
|
-
headers.set("Retry-After", String(i2.pollIntervalS));
|
|
147419
|
-
headers.set("Content-Type", "application/json");
|
|
147420
|
-
headers.set("Cache-Control", "no-store");
|
|
147421
|
-
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
147422
|
-
status: 401,
|
|
147423
|
-
headers
|
|
147424
|
-
});
|
|
147425
|
-
}
|
|
147426
|
-
function buildFetcherChallengeResponse(i2, challengeProof) {
|
|
147427
|
-
const consentUri = buildConsentUri(i2);
|
|
147428
|
-
const headers = new Headers();
|
|
147429
|
-
headers.set("Content-Type", "application/json");
|
|
147430
|
-
headers.set("Cache-Control", "no-store");
|
|
147431
|
-
headers.set("KYA-Auth-Required", "true");
|
|
147432
|
-
headers.set("KYA-Auth-Url", consentUri);
|
|
147433
|
-
headers.set("Link", `<${consentUri}>; rel="kya-authorize"`);
|
|
147434
|
-
headers.set("KYA-Action", "challenge");
|
|
147435
|
-
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
147436
|
-
status: 200,
|
|
147437
|
-
headers
|
|
147438
|
-
});
|
|
147439
|
-
}
|
|
147440
|
-
async function signChallengeProof(gen, payload) {
|
|
147441
|
-
const proof = await gen.generateProof({
|
|
147442
|
-
method: CHALLENGE_PROOF_METHOD,
|
|
147443
|
-
params: {
|
|
147444
|
-
sid: payload.sid,
|
|
147445
|
-
consent_uri: payload.consent_uri,
|
|
147446
|
-
required_scopes: payload.required_scopes
|
|
147447
|
-
}
|
|
147448
|
-
}, { data: { sid: payload.sid } }, {
|
|
147449
|
-
// The session binds the proof to this anchor; sid is the natural nonce.
|
|
147450
|
-
nonce: payload.sid,
|
|
147451
|
-
audience: payload.consent_uri,
|
|
147452
|
-
sessionId: payload.sid
|
|
147453
|
-
});
|
|
147454
|
-
return proof.jws;
|
|
147455
|
-
}
|
|
147456
|
-
|
|
147457
147789
|
// ../mcp-i-cloudflare/dist/delegation-http/challenge-middleware.js
|
|
147458
147790
|
async function readAuthorizationRequiredMeta(response) {
|
|
147459
147791
|
let parsed;
|
|
@@ -147656,7 +147988,9 @@ function createMCPIApp(options) {
|
|
|
147656
147988
|
});
|
|
147657
147989
|
}
|
|
147658
147990
|
});
|
|
147659
|
-
registerDelegationHttpRoutes(app, options
|
|
147991
|
+
registerDelegationHttpRoutes(app, options, {
|
|
147992
|
+
proofGenerator: (c) => buildChallengeProofGenerator(c)
|
|
147993
|
+
});
|
|
147660
147994
|
app.get("/consent.js", async (c) => {
|
|
147661
147995
|
const server = await getMcpiServer(c.env);
|
|
147662
147996
|
return server.handleRequest(c.req.raw, c.executionCtx);
|