@adcp/sdk 14.0.0 → 14.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/adapters/implicit-account-store.d.mts +12 -7
- package/dist/lib/adapters/implicit-account-store.d.ts +12 -7
- package/dist/lib/adapters/implicit-account-store.js +69 -15
- package/dist/lib/adapters/implicit-account-store.mjs +69 -15
- package/dist/lib/core/AgentClient.d.mts +1 -0
- package/dist/lib/core/AgentClient.d.ts +1 -0
- package/dist/lib/core/AgentClient.js +3 -0
- package/dist/lib/core/AgentClient.mjs +3 -0
- package/dist/lib/core/SingleAgentClient.d.mts +35 -2
- package/dist/lib/core/SingleAgentClient.d.ts +35 -2
- package/dist/lib/core/SingleAgentClient.js +377 -36
- package/dist/lib/core/SingleAgentClient.mjs +387 -38
- package/dist/lib/core/TaskExecutor.d.mts +3 -1
- package/dist/lib/core/TaskExecutor.d.ts +3 -1
- package/dist/lib/core/TaskExecutor.js +17 -12
- package/dist/lib/core/TaskExecutor.mjs +17 -12
- package/dist/lib/core/account-key.d.mts +3 -0
- package/dist/lib/core/account-key.d.ts +3 -0
- package/dist/lib/core/account-key.js +41 -0
- package/dist/lib/core/account-key.mjs +17 -0
- package/dist/lib/core/account-resolution.d.mts +2 -0
- package/dist/lib/core/account-resolution.d.ts +2 -0
- package/dist/lib/core/buyer-account-registry.d.mts +93 -0
- package/dist/lib/core/buyer-account-registry.d.ts +93 -0
- package/dist/lib/core/buyer-account-registry.js +602 -0
- package/dist/lib/core/buyer-account-registry.mjs +578 -0
- package/dist/lib/core/product-cache.d.mts +18 -0
- package/dist/lib/core/product-cache.d.ts +18 -0
- package/dist/lib/core/product-cache.js +137 -0
- package/dist/lib/core/product-cache.mjs +112 -0
- package/dist/lib/errors/index.d.mts +40 -1
- package/dist/lib/errors/index.d.ts +40 -1
- package/dist/lib/errors/index.js +69 -3
- package/dist/lib/errors/index.mjs +64 -3
- package/dist/lib/governance/authorization.d.mts +17 -1
- package/dist/lib/governance/authorization.d.ts +17 -1
- package/dist/lib/governance/authorization.js +55 -7
- package/dist/lib/governance/authorization.mjs +59 -7
- package/dist/lib/governance/index.d.mts +2 -2
- package/dist/lib/governance/index.d.ts +2 -2
- package/dist/lib/governance/index.js +2 -0
- package/dist/lib/governance/index.mjs +3 -1
- package/dist/lib/index.d.mts +7 -4
- package/dist/lib/index.d.ts +7 -4
- package/dist/lib/index.js +29 -0
- package/dist/lib/index.mjs +31 -1
- package/dist/lib/net/agent-transport-fetch.d.mts +4 -0
- package/dist/lib/net/agent-transport-fetch.d.ts +4 -0
- package/dist/lib/net/agent-transport-fetch.js +18 -5
- package/dist/lib/net/agent-transport-fetch.mjs +17 -5
- package/dist/lib/protocols/a2a.js +9 -1
- package/dist/lib/protocols/a2a.mjs +9 -1
- package/dist/lib/protocols/index.js +9 -2
- package/dist/lib/protocols/index.mjs +9 -2
- package/dist/lib/protocols/mcp-modern.js +2 -1
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +5 -2
- package/dist/lib/protocols/mcp.mjs +5 -2
- package/dist/lib/protocols/rawResponseCapture.d.mts +6 -0
- package/dist/lib/protocols/rawResponseCapture.d.ts +6 -0
- package/dist/lib/protocols/rawResponseCapture.js +41 -29
- package/dist/lib/protocols/rawResponseCapture.mjs +40 -29
- package/dist/lib/protocols/signedRequestRejection.d.mts +9 -0
- package/dist/lib/protocols/signedRequestRejection.d.ts +9 -0
- package/dist/lib/protocols/signedRequestRejection.js +209 -0
- package/dist/lib/protocols/signedRequestRejection.mjs +189 -0
- package/dist/lib/protocols/transportDiagnostics.d.mts +1 -0
- package/dist/lib/protocols/transportDiagnostics.d.ts +1 -0
- package/dist/lib/protocols/transportDiagnostics.js +2 -0
- package/dist/lib/protocols/transportDiagnostics.mjs +1 -0
- package/dist/lib/registry/types.generated.d.mts +112 -45
- package/dist/lib/registry/types.generated.d.ts +112 -45
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-provisioning.d.mts +2 -0
- package/dist/lib/server/account-provisioning.d.ts +2 -0
- package/dist/lib/server/account-provisioning.js +30 -0
- package/dist/lib/server/account-provisioning.mjs +6 -0
- package/dist/lib/server/account-reference-warnings.d.mts +12 -0
- package/dist/lib/server/account-reference-warnings.d.ts +12 -0
- package/dist/lib/server/account-reference-warnings.js +48 -0
- package/dist/lib/server/account-reference-warnings.mjs +23 -0
- package/dist/lib/server/auth-signature.js +1 -0
- package/dist/lib/server/auth-signature.mjs +1 -0
- package/dist/lib/server/create-adcp-server.d.mts +34 -0
- package/dist/lib/server/create-adcp-server.d.ts +34 -0
- package/dist/lib/server/create-adcp-server.js +225 -14
- package/dist/lib/server/create-adcp-server.mjs +225 -14
- package/dist/lib/server/decisioning/account.d.mts +2 -0
- package/dist/lib/server/decisioning/account.d.ts +2 -0
- package/dist/lib/server/decisioning/runtime/from-platform.js +49 -10
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +49 -10
- package/dist/lib/server/index.d.mts +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.mjs +3 -1
- package/dist/lib/signing/agent-resolver/consistency.d.mts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.d.ts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.js +0 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -1
- package/dist/lib/signing/agent-resolver/errors.d.mts +3 -1
- package/dist/lib/signing/agent-resolver/errors.d.ts +3 -1
- package/dist/lib/signing/agent-resolver/errors.js +6 -0
- package/dist/lib/signing/agent-resolver/errors.mjs +6 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.js +37 -2
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +40 -3
- package/dist/lib/signing/agent-resolver/jwks-set.js +24 -3
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +24 -3
- package/dist/lib/signing/agent-resolver/legacy-brand.d.mts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.d.ts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.js +60 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.mjs +36 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.mts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.ts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.js +108 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.mjs +84 -0
- package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.js +148 -137
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +157 -139
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +50 -17
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +50 -17
- package/dist/lib/signing/agent-resolver/select-agent.d.mts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.d.ts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.js +98 -13
- package/dist/lib/signing/agent-resolver/select-agent.mjs +95 -13
- package/dist/lib/signing/brand-jwks.d.mts +29 -75
- package/dist/lib/signing/brand-jwks.d.ts +29 -75
- package/dist/lib/signing/brand-jwks.js +120 -182
- package/dist/lib/signing/brand-jwks.mjs +120 -182
- package/dist/lib/signing/errors.d.mts +7 -3
- package/dist/lib/signing/errors.d.ts +7 -3
- package/dist/lib/signing/errors.js +7 -2
- package/dist/lib/signing/errors.mjs +7 -2
- package/dist/lib/signing/jwks-https.d.mts +7 -0
- package/dist/lib/signing/jwks-https.d.ts +7 -0
- package/dist/lib/signing/jwks-https.js +31 -8
- package/dist/lib/signing/jwks-https.mjs +31 -8
- package/dist/lib/signing/jwks.d.mts +8 -0
- package/dist/lib/signing/jwks.d.ts +8 -0
- package/dist/lib/signing/middleware.js +2 -1
- package/dist/lib/signing/middleware.mjs +2 -1
- package/dist/lib/signing/publisher-pins.d.mts +11 -0
- package/dist/lib/signing/publisher-pins.d.ts +11 -0
- package/dist/lib/signing/publisher-pins.js +125 -0
- package/dist/lib/signing/publisher-pins.mjs +101 -0
- package/dist/lib/signing/server.d.mts +1 -0
- package/dist/lib/signing/server.d.ts +1 -0
- package/dist/lib/signing/types.d.mts +5 -0
- package/dist/lib/signing/types.d.ts +5 -0
- package/dist/lib/signing/verifier.js +50 -5
- package/dist/lib/signing/verifier.mjs +50 -5
- package/dist/lib/signing/webhook-verifier.d.mts +7 -2
- package/dist/lib/signing/webhook-verifier.d.ts +7 -2
- package/dist/lib/signing/webhook-verifier.js +42 -2
- package/dist/lib/signing/webhook-verifier.mjs +42 -2
- package/dist/lib/testing/storyboard/account-policy.d.mts +2 -0
- package/dist/lib/testing/storyboard/account-policy.d.ts +2 -0
- package/dist/lib/testing/storyboard/account-policy.js +35 -0
- package/dist/lib/testing/storyboard/account-policy.mjs +11 -0
- package/dist/lib/testing/storyboard/context.js +6 -0
- package/dist/lib/testing/storyboard/context.mjs +6 -0
- package/dist/lib/testing/storyboard/request-builder.js +12 -2
- package/dist/lib/testing/storyboard/request-builder.mjs +12 -2
- package/dist/lib/testing/storyboard/runner.js +3 -2
- package/dist/lib/testing/storyboard/runner.mjs +3 -2
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/accept-proposal.d.ts +19 -1
- package/dist/lib/types/buy-products.d.ts +19 -1
- package/dist/lib/types/check-governance.d.ts +19 -1
- package/dist/lib/types/comply-test-controller.d.ts +19 -1
- package/dist/lib/types/control-media-buy.d.ts +19 -1
- package/dist/lib/types/core.generated.d.mts +14 -1
- package/dist/lib/types/core.generated.d.ts +14 -1
- package/dist/lib/types/create-media-buy.d.ts +14 -1
- package/dist/lib/types/get-media-buys.d.ts +14 -1
- package/dist/lib/types/get-products.d.ts +19 -1
- package/dist/lib/types/list-products.d.ts +19 -1
- package/dist/lib/types/refine-proposals.d.ts +19 -1
- package/dist/lib/types/request-proposals.d.ts +19 -1
- package/dist/lib/types/schemas.generated.d.ts +12 -3
- package/dist/lib/types/schemas.generated.js +4 -1
- package/dist/lib/types/schemas.generated.mjs +4 -1
- package/dist/lib/types/tools.generated.d.mts +14 -1
- package/dist/lib/types/tools.generated.d.ts +14 -1
- package/dist/lib/types/update-media-buy.d.ts +14 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/webhooks/index.d.mts +24 -0
- package/dist/lib/webhooks/index.d.ts +24 -0
- package/dist/lib/webhooks/index.js +50 -24
- package/dist/lib/webhooks/index.mjs +49 -24
- package/dist/lib/wholesale-feed-sync/index.d.mts +2 -0
- package/dist/lib/wholesale-feed-sync/index.d.ts +2 -0
- package/dist/lib/wholesale-feed-sync/index.js +7 -0
- package/dist/lib/wholesale-feed-sync/index.mjs +4 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.mts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.ts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.js +350 -0
- package/dist/lib/wholesale-feed-sync/mirror.mjs +322 -0
- package/dist/lib/wholesale-feed-sync/sync.d.mts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.d.ts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.js +208 -281
- package/dist/lib/wholesale-feed-sync/sync.mjs +213 -281
- package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
- package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
- package/docs/README.md +6 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/BUILD-AN-AGENT.md +2 -2
- package/docs/guides/BUYER-QUICKSTART-3.2.md +2 -0
- package/docs/guides/BUYER-STORAGE.md +3 -0
- package/docs/guides/FIRST-CALL-TO-A-SELLER.md +106 -0
- package/docs/guides/SIGNING-GUIDE.md +16 -7
- package/docs/guides/account-resolution.md +132 -10
- package/docs/llms.txt +3 -2
- package/docs/migration-14.0-to-14.1.md +85 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-4.x-to-5.x.md +1 -0
- package/docs/migration-agent-resolution-3.3.md +125 -0
- package/docs/recipes/verifying-inbound-webhooks.md +60 -15
- package/package.json +3 -2
- package/skills/adcp-brand.previous/SKILL.md +0 -200
- package/skills/adcp-creative.previous/SKILL.md +0 -305
- package/skills/adcp-governance.previous/SKILL.md +0 -566
- package/skills/adcp-measurement.previous/SKILL.md +0 -136
- package/skills/adcp-media-buy.previous/SKILL.md +0 -556
- package/skills/adcp-si.previous/SKILL.md +0 -206
- package/skills/adcp-signals.previous/SKILL.md +0 -204
|
@@ -22,10 +22,14 @@ __export(resolve_agent_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(resolve_agent_exports);
|
|
24
24
|
var import_tldts = require("tldts");
|
|
25
|
+
var import_node_net = require("node:net");
|
|
25
26
|
var import_protocols = require('../../protocols/index.js');
|
|
26
27
|
var import_domain = require('../../brand/domain.js');
|
|
27
28
|
var import_capabilities_types = require('./capabilities-types.js');
|
|
28
|
-
var
|
|
29
|
+
var import_net = require('../../net/index.js');
|
|
30
|
+
var import_agent_transport_fetch = require('../../net/agent-transport-fetch.js');
|
|
31
|
+
var import_operator_authorization = require('./operator-authorization.js');
|
|
32
|
+
var import_legacy_brand = require('./legacy-brand.js');
|
|
29
33
|
var import_consistency = require('./consistency.js');
|
|
30
34
|
var import_errors = require('./errors.js');
|
|
31
35
|
var import_etld = require('./etld.js');
|
|
@@ -41,7 +45,7 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
41
45
|
const caps = options.bodyCaps ?? {};
|
|
42
46
|
const brandJsonCap = caps.brandJsonBytes ?? import_fetch_helpers.MAX_BRAND_JSON_BYTES;
|
|
43
47
|
const jwksCap = caps.jwksBytes ?? import_fetch_helpers.MAX_JWKS_BYTES;
|
|
44
|
-
const fetchCapabilities = options.fetchCapabilities ?? defaultFetchCapabilities(agentUrl, options.protocol ?? "mcp");
|
|
48
|
+
const fetchCapabilities = options.fetchCapabilities ?? defaultFetchCapabilities(agentUrl, options.protocol ?? "mcp", allowPrivateIp, timeoutMs);
|
|
45
49
|
let capabilitiesPayload;
|
|
46
50
|
let capabilitiesFetchedAt;
|
|
47
51
|
try {
|
|
@@ -58,7 +62,7 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
58
62
|
} catch (err) {
|
|
59
63
|
const detail = {
|
|
60
64
|
agent_url: agentUrl,
|
|
61
|
-
|
|
65
|
+
...(0, import_fetch_helpers.classifyDiscoveryFailure)(err),
|
|
62
66
|
last_attempt_at: now()
|
|
63
67
|
};
|
|
64
68
|
pushTrace(trace, { step: 1, name: "fetch_capabilities", ok: false, url: agentUrl, detail });
|
|
@@ -69,7 +73,10 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
69
73
|
["agent_url"]
|
|
70
74
|
);
|
|
71
75
|
}
|
|
72
|
-
|
|
76
|
+
let brandJsonUrl = (0, import_capabilities_types.readBrandJsonUrl)(capabilitiesPayload);
|
|
77
|
+
const identity = capabilitiesPayload?.identity;
|
|
78
|
+
const legacyFallback = options.legacyWebhookFallback === true && identity?.brand_json_url === void 0 && permitsLegacyWebhookDiscovery(capabilitiesPayload);
|
|
79
|
+
if (legacyFallback) brandJsonUrl = `${new URL(agentUrl).origin}/.well-known/brand.json`;
|
|
73
80
|
const identityPosture = (0, import_capabilities_types.readIdentityPosture)(capabilitiesPayload);
|
|
74
81
|
const acceptsScheme = (url) => {
|
|
75
82
|
if (!url) return false;
|
|
@@ -87,24 +94,43 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
87
94
|
["agent_url"]
|
|
88
95
|
);
|
|
89
96
|
}
|
|
97
|
+
if (!legacyFallback && options.expectedBrandJsonUrl !== void 0 && (0, import_select_agent.canonicalAgentUrl)(brandJsonUrl) !== (0, import_select_agent.canonicalAgentUrl)(options.expectedBrandJsonUrl)) {
|
|
98
|
+
throw new import_errors.AgentResolverError(
|
|
99
|
+
"request_signature_brand_origin_mismatch",
|
|
100
|
+
"Cached operator mapping disagrees with identity.brand_json_url",
|
|
101
|
+
{ agent_url: agentUrl },
|
|
102
|
+
["agent_url"]
|
|
103
|
+
);
|
|
104
|
+
}
|
|
90
105
|
pushTrace(trace, { step: 2, name: "read_brand_json_url", ok: true, detail: { brand_json_url: brandJsonUrl } });
|
|
91
|
-
let agentEtld1;
|
|
92
|
-
let brandEtld1;
|
|
93
|
-
let sameOrigin;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
let agentEtld1 = "";
|
|
107
|
+
let brandEtld1 = "";
|
|
108
|
+
let sameOrigin = true;
|
|
109
|
+
if (!legacyFallback) {
|
|
110
|
+
try {
|
|
111
|
+
agentEtld1 = (0, import_etld.eTldPlusOne)(agentUrl);
|
|
112
|
+
brandEtld1 = (0, import_etld.eTldPlusOne)(brandJsonUrl);
|
|
113
|
+
sameOrigin = (0, import_etld.sameEtldPlusOne)(agentUrl, brandJsonUrl);
|
|
114
|
+
} catch {
|
|
115
|
+
if (allowPrivateIp) {
|
|
116
|
+
const agentHost = new URL(agentUrl).hostname;
|
|
117
|
+
const brandHost = new URL(brandJsonUrl).hostname;
|
|
118
|
+
const agentIsExplicitDevelopmentHost = agentHost === "localhost" || (0, import_domain.isDevelopmentBrandDomain)(agentHost) || (0, import_tldts.parse)(agentHost, { extractHostname: false }).isIp;
|
|
119
|
+
const brandIsExplicitDevelopmentHost = brandHost === "localhost" || (0, import_domain.isDevelopmentBrandDomain)(brandHost) || (0, import_tldts.parse)(brandHost, { extractHostname: false }).isIp;
|
|
120
|
+
if (agentIsExplicitDevelopmentHost && brandIsExplicitDevelopmentHost) {
|
|
121
|
+
agentEtld1 = agentHost;
|
|
122
|
+
brandEtld1 = brandHost;
|
|
123
|
+
sameOrigin = agentHost === brandHost;
|
|
124
|
+
} else {
|
|
125
|
+
const detail = { agent_url: agentUrl, brand_json_url: brandJsonUrl };
|
|
126
|
+
pushTrace(trace, { step: 3, name: "etld1_binding", ok: false, detail });
|
|
127
|
+
throw new import_errors.AgentResolverError(
|
|
128
|
+
"request_signature_brand_origin_mismatch",
|
|
129
|
+
`Cannot compute eTLD+1 for agent or brand.json host`,
|
|
130
|
+
detail,
|
|
131
|
+
["agent_url", "brand_json_url"]
|
|
132
|
+
);
|
|
133
|
+
}
|
|
108
134
|
} else {
|
|
109
135
|
const detail = { agent_url: agentUrl, brand_json_url: brandJsonUrl };
|
|
110
136
|
pushTrace(trace, { step: 3, name: "etld1_binding", ok: false, detail });
|
|
@@ -115,25 +141,24 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
115
141
|
["agent_url", "brand_json_url"]
|
|
116
142
|
);
|
|
117
143
|
}
|
|
118
|
-
} else {
|
|
119
|
-
const detail = { agent_url: agentUrl, brand_json_url: brandJsonUrl };
|
|
120
|
-
pushTrace(trace, { step: 3, name: "etld1_binding", ok: false, detail });
|
|
121
|
-
throw new import_errors.AgentResolverError(
|
|
122
|
-
"request_signature_brand_origin_mismatch",
|
|
123
|
-
`Cannot compute eTLD+1 for agent or brand.json host`,
|
|
124
|
-
detail,
|
|
125
|
-
["agent_url", "brand_json_url"]
|
|
126
|
-
);
|
|
127
144
|
}
|
|
128
145
|
}
|
|
129
146
|
let brandJson;
|
|
130
147
|
let brandJsonFetchedAt;
|
|
148
|
+
let brandJsonCacheControl;
|
|
131
149
|
try {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
})
|
|
150
|
+
const fetchOptions = { allowPrivateIp, timeoutMs, maxBodyBytes: brandJsonCap, lookup: options.lookup };
|
|
151
|
+
const fetched = legacyFallback ? await (0, import_legacy_brand.fetchLegacyBrandJson)(agentUrl, fetchOptions) : await (0, import_fetch_helpers.safeFetchJson)(brandJsonUrl, "brand.json", fetchOptions);
|
|
152
|
+
if (legacyFallback && "url" in fetched) brandJsonUrl = fetched.url;
|
|
153
|
+
brandJsonCacheControl = fetched.headers["cache-control"];
|
|
154
|
+
if (legacyFallback && options.expectedBrandJsonUrl !== void 0 && (0, import_select_agent.canonicalAgentUrl)(brandJsonUrl) !== (0, import_select_agent.canonicalAgentUrl)(options.expectedBrandJsonUrl) && (0, import_select_agent.canonicalAgentUrl)(`${new URL(agentUrl).origin}/.well-known/brand.json`) !== (0, import_select_agent.canonicalAgentUrl)(options.expectedBrandJsonUrl)) {
|
|
155
|
+
throw new import_errors.AgentResolverError(
|
|
156
|
+
"request_signature_brand_origin_mismatch",
|
|
157
|
+
"Cached mapping disagrees with legacy discovery",
|
|
158
|
+
{ agent_url: agentUrl },
|
|
159
|
+
["agent_url"]
|
|
160
|
+
);
|
|
161
|
+
}
|
|
137
162
|
brandJson = fetched.body;
|
|
138
163
|
brandJsonFetchedAt = fetched.fetchedAt;
|
|
139
164
|
pushTrace(trace, {
|
|
@@ -144,6 +169,7 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
144
169
|
url: brandJsonUrl
|
|
145
170
|
});
|
|
146
171
|
} catch (err) {
|
|
172
|
+
if (err instanceof import_errors.AgentResolverError) throw err;
|
|
147
173
|
if (err instanceof import_fetch_helpers.SafeFetchError && /strict-JSON parse/.test(err.message)) {
|
|
148
174
|
const detail2 = {
|
|
149
175
|
brand_json_url: brandJsonUrl,
|
|
@@ -187,7 +213,17 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
187
213
|
["agent_url"]
|
|
188
214
|
);
|
|
189
215
|
}
|
|
190
|
-
|
|
216
|
+
if (options.requiredOperatorBrand !== void 0 || options.requiredOperatorScope !== void 0 || options.requiredOperatorCountry !== void 0) {
|
|
217
|
+
const authorization = (0, import_operator_authorization.checkDelegatedOperatorAuthorization)(brandJson, agentEtld1, now(), options);
|
|
218
|
+
if (!authorization)
|
|
219
|
+
throw new import_errors.AgentResolverError(
|
|
220
|
+
"request_signature_brand_origin_mismatch",
|
|
221
|
+
"Delegated operator does not satisfy the receiver account authorization policy",
|
|
222
|
+
{ agent_url: agentUrl },
|
|
223
|
+
["agent_url"]
|
|
224
|
+
);
|
|
225
|
+
operatorAuthorizationValidUntil = authorization.validUntil;
|
|
226
|
+
}
|
|
191
227
|
pushTrace(trace, {
|
|
192
228
|
step: 3,
|
|
193
229
|
name: "etld1_binding",
|
|
@@ -204,7 +240,7 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
204
240
|
}
|
|
205
241
|
let agentEntry;
|
|
206
242
|
try {
|
|
207
|
-
agentEntry = (0, import_select_agent.selectAgentByUrl)(brandJson, agentUrl);
|
|
243
|
+
agentEntry = (0, import_select_agent.selectAgentByUrl)(brandJson, agentUrl, options);
|
|
208
244
|
pushTrace(trace, { step: 5, name: "select_agent", ok: true, detail: { url: agentEntry.url } });
|
|
209
245
|
} catch (err) {
|
|
210
246
|
if (err instanceof import_select_agent.AgentSelectorError) {
|
|
@@ -227,17 +263,19 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
227
263
|
pushTrace(trace, { step: 5, name: "select_agent", ok: false, detail });
|
|
228
264
|
throw new import_errors.AgentResolverError(code, err.message, detail, attacker);
|
|
229
265
|
}
|
|
230
|
-
throw
|
|
266
|
+
throw new import_errors.AgentResolverError(
|
|
267
|
+
"request_signature_brand_json_malformed",
|
|
268
|
+
"Matched agent has an invalid URL or JWKS source",
|
|
269
|
+
{ brand_json_url: brandJsonUrl },
|
|
270
|
+
["brand_json_url"]
|
|
271
|
+
);
|
|
231
272
|
}
|
|
232
|
-
const
|
|
233
|
-
const jwksUriFromEntry = typeof declaredJwksUri === "string" && acceptsScheme(declaredJwksUri) ? declaredJwksUri : void 0;
|
|
234
|
-
const jwksUri = jwksUriFromEntry ?? `${originOf(agentUrl)}/.well-known/jwks.json`;
|
|
273
|
+
const jwksUri = (0, import_select_agent.agentJwksUri)(agentEntry);
|
|
235
274
|
pushTrace(trace, { step: 6, name: "resolve_jwks_uri", ok: true, detail: { jwks_uri: jwksUri } });
|
|
236
|
-
const consistencyResults = runConsistencyChecks({
|
|
275
|
+
const consistencyResults = legacyFallback ? [] : runConsistencyChecks({
|
|
237
276
|
capabilitiesPayload,
|
|
238
277
|
identityPosture,
|
|
239
278
|
jwksUri,
|
|
240
|
-
publisherPinnedWebhookSigning: options.publisherPinned?.webhook_signing === true,
|
|
241
279
|
extraDeclaredPurposes: options.declaredPurposes ?? []
|
|
242
280
|
});
|
|
243
281
|
const failedConsistency = consistencyResults.filter((r) => r.ok === false);
|
|
@@ -270,7 +308,8 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
270
308
|
const fetched = await (0, import_fetch_helpers.safeFetchJson)(jwksUri, "jwks", {
|
|
271
309
|
allowPrivateIp,
|
|
272
310
|
timeoutMs,
|
|
273
|
-
maxBodyBytes: jwksCap
|
|
311
|
+
maxBodyBytes: jwksCap,
|
|
312
|
+
lookup: options.lookup
|
|
274
313
|
});
|
|
275
314
|
if (!fetched.body || typeof fetched.body !== "object" || !Array.isArray(fetched.body.keys)) {
|
|
276
315
|
throw new import_fetch_helpers.SafeFetchError("jwks", "fetch_failed", "JWKS document has no keys[] array");
|
|
@@ -307,8 +346,11 @@ async function resolveAgent(agentUrl, options = {}) {
|
|
|
307
346
|
);
|
|
308
347
|
}
|
|
309
348
|
return {
|
|
310
|
-
agentUrl,
|
|
349
|
+
agentUrl: (0, import_select_agent.canonicalAgentUrl)(agentEntry.url),
|
|
311
350
|
brandJsonUrl,
|
|
351
|
+
brandJson,
|
|
352
|
+
...legacyFallback && { legacyWebhookFallback: true },
|
|
353
|
+
...brandJsonCacheControl !== void 0 && { brandJsonCacheControl },
|
|
312
354
|
agentEntry,
|
|
313
355
|
jwksUri,
|
|
314
356
|
jwks,
|
|
@@ -329,101 +371,59 @@ function checkAllowPrivateIp(requested) {
|
|
|
329
371
|
"resolveAgent: allowPrivateIp=true refused outside {NODE_ENV=test, NODE_ENV=development}. Set NODE_ENV appropriately for dev/test, or set ADCP_RESOLVER_ALLOW_PRIVATE_IP=1 as an explicit ops acknowledgment if you genuinely need private-IP discovery in this process."
|
|
330
372
|
);
|
|
331
373
|
}
|
|
332
|
-
function defaultFetchCapabilities(agentUrl, protocol) {
|
|
374
|
+
function defaultFetchCapabilities(agentUrl, protocol, allowPrivateIp, timeoutMs) {
|
|
333
375
|
return async () => {
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
if (typeof domain !== "string" || !AUTHORIZED_OPERATOR_DOMAIN.test(domain) || !isValidBrandGrant(brands)) {
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
if ((0, import_etld.eTldPlusOne)(domain) !== agentEtld1) continue;
|
|
364
|
-
} catch {
|
|
365
|
-
if (!(options.allowPrivateIp && (0, import_domain.isDevelopmentBrandDomain)(domain) && domain === agentEtld1)) {
|
|
366
|
-
continue;
|
|
376
|
+
const url = new URL(agentUrl);
|
|
377
|
+
const hostname = url.hostname.replace(/^\[|\]$/g, "");
|
|
378
|
+
if (!allowPrivateIp && url.protocol !== "https:" || (0, import_node_net.isIP)(hostname) && ((0, import_net.isAlwaysBlocked)(hostname) || !allowPrivateIp && (0, import_net.isPrivateIp)(hostname)))
|
|
379
|
+
throw new import_agent_transport_fetch.AgentTransportPolicyError("Signing discovery URL refused by address or HTTPS policy.");
|
|
380
|
+
let failure;
|
|
381
|
+
const upstream = (0, import_agent_transport_fetch.createAgentTransportFetch)(agentUrl, {
|
|
382
|
+
allowPrivateIp,
|
|
383
|
+
allowPrivateInitialOrigin: false,
|
|
384
|
+
requireHttps: true
|
|
385
|
+
});
|
|
386
|
+
let postSucceeded = false;
|
|
387
|
+
const trustedFetchFn = async (input, init) => {
|
|
388
|
+
const method = init?.method ?? (input instanceof Request ? input.method : "GET");
|
|
389
|
+
try {
|
|
390
|
+
const response = await upstream(input, init);
|
|
391
|
+
const isGet = method.toUpperCase() === "GET";
|
|
392
|
+
const observed = response.status >= 400 ? { dns_error: "fetch_failed", http_status: response.status } : void 0;
|
|
393
|
+
if (protocol === "mcp" && method.toUpperCase() === "POST" && response.ok) postSucceeded = true;
|
|
394
|
+
if (!(protocol === "mcp" && isGet && (postSucceeded || response.status === 405)) && !(isGet && observed && failure && !(0, import_fetch_helpers.isPermanentDiscoveryFailure)(failure) && (0, import_fetch_helpers.isPermanentDiscoveryFailure)(observed)))
|
|
395
|
+
failure = observed;
|
|
396
|
+
return response;
|
|
397
|
+
} catch (error) {
|
|
398
|
+
if (!(protocol === "mcp" && method.toUpperCase() === "GET" && postSucceeded))
|
|
399
|
+
failure = (0, import_fetch_helpers.classifyDiscoveryFailure)(error);
|
|
400
|
+
throw error;
|
|
367
401
|
}
|
|
402
|
+
};
|
|
403
|
+
const transport = { trustedFetchFn, requestTimeoutMs: timeoutMs };
|
|
404
|
+
const client = protocol === "a2a" ? (0, import_protocols.createA2AClient)(agentUrl, void 0, void 0, void 0, void 0, transport) : (0, import_protocols.createMCPClient)(agentUrl, void 0, void 0, void 0, void 0, transport);
|
|
405
|
+
try {
|
|
406
|
+
return await client.callTool("get_adcp_capabilities", {});
|
|
407
|
+
} catch (error) {
|
|
408
|
+
if (failure)
|
|
409
|
+
throw new import_fetch_helpers.SafeFetchError(
|
|
410
|
+
"capabilities",
|
|
411
|
+
failure.dns_error,
|
|
412
|
+
"Capabilities fetch failed",
|
|
413
|
+
failure.http_status
|
|
414
|
+
);
|
|
415
|
+
throw error;
|
|
368
416
|
}
|
|
369
|
-
|
|
370
|
-
if (scopes !== void 0 && !isValidScopeGrant(scopes)) continue;
|
|
371
|
-
const countries = candidate.countries;
|
|
372
|
-
if (countries !== void 0 && !isValidCountryGrant(countries)) continue;
|
|
373
|
-
const validFrom = parseOptionalRfc3339(candidate.valid_from);
|
|
374
|
-
const validUntil = parseOptionalRfc3339(candidate.valid_until);
|
|
375
|
-
if (validFrom === null || validUntil === null) continue;
|
|
376
|
-
if (validFrom !== void 0 && validUntil !== void 0 && validFrom >= validUntil) continue;
|
|
377
|
-
if (validFrom !== void 0 && now < validFrom) continue;
|
|
378
|
-
if (validUntil !== void 0 && now >= validUntil) continue;
|
|
379
|
-
if (!matchesGrant(brands, options.requiredOperatorBrand, "*")) continue;
|
|
380
|
-
if (scopes !== void 0 && !matchesGrant(scopes, options.requiredOperatorScope, "all")) continue;
|
|
381
|
-
if (countries !== void 0 && !matchesGrant(countries, options.requiredOperatorCountry)) continue;
|
|
382
|
-
matched = true;
|
|
383
|
-
if (validUntil === void 0) return {};
|
|
384
|
-
latestValidUntil = Math.max(latestValidUntil ?? Number.NEGATIVE_INFINITY, validUntil);
|
|
385
|
-
}
|
|
386
|
-
return matched ? { validUntil: latestValidUntil } : void 0;
|
|
387
|
-
}
|
|
388
|
-
function isValidBrandGrant(value) {
|
|
389
|
-
return Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === "string" && (item === "*" || /^[a-z0-9_]+$/.test(item)));
|
|
390
|
-
}
|
|
391
|
-
function isValidScopeGrant(value) {
|
|
392
|
-
return Array.isArray(value) && value.length > 0 && new Set(value).size === value.length && value.every((item) => typeof item === "string" && AUTHORIZED_OPERATOR_SCOPES.has(item));
|
|
393
|
-
}
|
|
394
|
-
function isValidCountryGrant(value) {
|
|
395
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string" && /^[A-Z]{2}$/.test(item));
|
|
396
|
-
}
|
|
397
|
-
function matchesGrant(grants, required, wildcard) {
|
|
398
|
-
if (wildcard !== void 0 && grants.includes(wildcard)) return true;
|
|
399
|
-
return required !== void 0 && grants.includes(required);
|
|
417
|
+
};
|
|
400
418
|
}
|
|
401
|
-
function
|
|
402
|
-
if (
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
);
|
|
407
|
-
if (!match) return null;
|
|
408
|
-
const year = Number(match[1]);
|
|
409
|
-
const month = Number(match[2]);
|
|
410
|
-
const day = Number(match[3]);
|
|
411
|
-
const hour = Number(match[4]);
|
|
412
|
-
const minute = Number(match[5]);
|
|
413
|
-
const second = Number(match[6]);
|
|
414
|
-
const offsetHour = match[10] === void 0 ? 0 : Number(match[10]);
|
|
415
|
-
const offsetMinute = match[11] === void 0 ? 0 : Number(match[11]);
|
|
416
|
-
if (month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month) || hour > 23 || minute > 59 || second > 59 || offsetHour > 23 || offsetMinute > 59) {
|
|
417
|
-
return null;
|
|
419
|
+
function findAuthorizedOperator(brandJson, agentEtld1, _now, _options) {
|
|
420
|
+
if (!brandJson || typeof brandJson !== "object") return void 0;
|
|
421
|
+
const obj = brandJson;
|
|
422
|
+
if (!obj.house || typeof obj.house !== "object" || Array.isArray(obj.house) || !Array.isArray(obj.brands)) {
|
|
423
|
+
return void 0;
|
|
418
424
|
}
|
|
419
|
-
|
|
420
|
-
return
|
|
421
|
-
}
|
|
422
|
-
function daysInMonth(year, month) {
|
|
423
|
-
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
424
|
-
}
|
|
425
|
-
function originOf(url) {
|
|
426
|
-
return (0, import_canonicalize.canonicalizeOrigin)(url);
|
|
425
|
+
if (!Array.isArray(obj.authorized_operators)) return void 0;
|
|
426
|
+
return obj.authorized_operators.some((op) => op && typeof op === "object" && op.domain === agentEtld1) ? {} : void 0;
|
|
427
427
|
}
|
|
428
428
|
function pushTrace(trace, step) {
|
|
429
429
|
trace.push(step);
|
|
@@ -445,14 +445,25 @@ function runConsistencyChecks(args) {
|
|
|
445
445
|
const result = (0, import_consistency.checkOriginConsistency)({
|
|
446
446
|
purpose,
|
|
447
447
|
declaredOrigin,
|
|
448
|
-
resolvedJwksUri: args.jwksUri
|
|
449
|
-
publisherPinned: purpose === "webhook_signing" && args.publisherPinnedWebhookSigning
|
|
448
|
+
resolvedJwksUri: args.jwksUri
|
|
450
449
|
});
|
|
451
450
|
if (result.ok === false) results.push(result);
|
|
452
451
|
}
|
|
453
452
|
}
|
|
454
453
|
return results;
|
|
455
454
|
}
|
|
455
|
+
function permitsLegacyWebhookDiscovery(payload) {
|
|
456
|
+
if (!payload || typeof payload !== "object") return true;
|
|
457
|
+
const caps = payload;
|
|
458
|
+
const major = (value) => typeof value === "string" ? Number(/^(\d+)\./.exec(value)?.[1]) : value;
|
|
459
|
+
if (Number(major(caps.adcp_version)) >= 4 || Array.isArray(caps.adcp?.supported_versions) && caps.adcp.supported_versions.some((v) => Number(major(v)) >= 4) || Array.isArray(caps.adcp?.major_versions) && caps.adcp.major_versions.some((v) => typeof v === "number" && v >= 4))
|
|
460
|
+
return false;
|
|
461
|
+
if (caps.adcp_version !== void 0) return typeof caps.adcp_version === "string" && /^3\./.test(caps.adcp_version);
|
|
462
|
+
if (Array.isArray(caps.adcp?.supported_versions))
|
|
463
|
+
return caps.adcp.supported_versions.some((v) => typeof v === "string" && /^3\./.test(v));
|
|
464
|
+
if (Array.isArray(caps.adcp?.major_versions)) return caps.adcp.major_versions.includes(3);
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
456
467
|
// Annotate the CommonJS export names for ESM import in node:
|
|
457
468
|
0 && (module.exports = {
|
|
458
469
|
resolveAgent
|