@adcp/sdk 14.0.0 → 14.1.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 +31 -1
- package/dist/lib/core/SingleAgentClient.d.ts +31 -1
- package/dist/lib/core/SingleAgentClient.js +355 -35
- package/dist/lib/core/SingleAgentClient.mjs +365 -37
- package/dist/lib/core/TaskExecutor.js +2 -1
- package/dist/lib/core/TaskExecutor.mjs +2 -1
- 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 +65 -0
- package/dist/lib/core/buyer-account-registry.d.ts +65 -0
- package/dist/lib/core/buyer-account-registry.js +518 -0
- package/dist/lib/core/buyer-account-registry.mjs +494 -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 +5 -3
- package/dist/lib/index.d.ts +5 -3
- package/dist/lib/index.js +20 -0
- package/dist/lib/index.mjs +19 -0
- 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 +1 -1
- package/dist/lib/signing/agent-resolver/errors.d.ts +1 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +2 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +2 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.js +2 -1
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +2 -1
- 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 +101 -132
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +102 -133
- 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 +27 -75
- package/dist/lib/signing/brand-jwks.d.ts +27 -75
- package/dist/lib/signing/brand-jwks.js +112 -182
- package/dist/lib/signing/brand-jwks.mjs +112 -182
- package/dist/lib/signing/errors.d.mts +3 -1
- package/dist/lib/signing/errors.d.ts +3 -1
- package/dist/lib/signing/errors.js +4 -1
- package/dist/lib/signing/errors.mjs +4 -1
- 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 +49 -4
- package/dist/lib/signing/verifier.mjs +49 -4
- 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 +43 -3
- 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/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/wholesale-feed-sync/sync.d.mts +1 -0
- package/dist/lib/wholesale-feed-sync/sync.d.ts +1 -0
- package/dist/lib/wholesale-feed-sync/sync.js +92 -21
- package/dist/lib/wholesale-feed-sync/sync.mjs +92 -21
- package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
- package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
- 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/FIRST-CALL-TO-A-SELLER.md +104 -0
- package/docs/guides/SIGNING-GUIDE.md +16 -7
- package/docs/guides/account-resolution.md +86 -0
- package/docs/llms.txt +3 -2
- 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 +123 -0
- package/docs/recipes/verifying-inbound-webhooks.md +56 -15
- package/package.json +2 -2
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var signedRequestRejection_exports = {};
|
|
20
|
+
__export(signedRequestRejection_exports, {
|
|
21
|
+
getSignedRequestRejection: () => getSignedRequestRejection,
|
|
22
|
+
wrapFetchWithSignedRequestRejection: () => wrapFetchWithSignedRequestRejection
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(signedRequestRejection_exports);
|
|
25
|
+
var import_errors = require('../errors/index.js');
|
|
26
|
+
var import_enums = require('../types/enums.generated.js');
|
|
27
|
+
var import_diagnostics = require('../auth/oauth/diagnostics.js');
|
|
28
|
+
var import_transportDiagnostics = require('./transportDiagnostics.js');
|
|
29
|
+
var import_rawResponseCapture = require('./rawResponseCapture.js');
|
|
30
|
+
const CAPTURE_BYTES = 16 * 1024;
|
|
31
|
+
const EXCERPT_LENGTH = 2048;
|
|
32
|
+
const CAPTURE_TIMEOUT_MS = 1e3;
|
|
33
|
+
const PUBLIC_HEADERS = /* @__PURE__ */ new Set([
|
|
34
|
+
"accept",
|
|
35
|
+
"content-type",
|
|
36
|
+
"content-length",
|
|
37
|
+
"user-agent",
|
|
38
|
+
"host",
|
|
39
|
+
"a2a-version",
|
|
40
|
+
"a2a-extensions",
|
|
41
|
+
"adcp-version",
|
|
42
|
+
"mcp-protocol-version",
|
|
43
|
+
"mcp-session-id",
|
|
44
|
+
"traceparent",
|
|
45
|
+
"tracestate",
|
|
46
|
+
"signature",
|
|
47
|
+
"signature-input",
|
|
48
|
+
"content-digest"
|
|
49
|
+
]);
|
|
50
|
+
function wrapFetchWithSignedRequestRejection(upstream, agentUrl) {
|
|
51
|
+
return async (input, init) => {
|
|
52
|
+
const startedAt = Date.now();
|
|
53
|
+
const response = await upstream(input, init);
|
|
54
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
55
|
+
if (response.status !== 401 || !headers.has("signature")) return response;
|
|
56
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
57
|
+
const parsed = (0, import_diagnostics.parseWWWAuthenticate)(response.headers.get("www-authenticate"));
|
|
58
|
+
if (parsed && parsed.scheme !== "signature") return response;
|
|
59
|
+
const knownCode = parsed?.scheme === "signature" && parsed.error && Object.prototype.hasOwnProperty.call(import_enums.RequestSigningErrorCodeMetadata, parsed.error);
|
|
60
|
+
const challenge = parsed ? { scheme: parsed.scheme.slice(0, 64), ...knownCode && { error: parsed.error } } : void 0;
|
|
61
|
+
const secrets = getHeaderSecrets(headers);
|
|
62
|
+
const captured = await captureBody(response, secrets, init?.signal);
|
|
63
|
+
const captureHeaders = (0, import_transportDiagnostics.sanitizeTransportHeaders)(response.headers);
|
|
64
|
+
for (const key of Object.keys(captureHeaders)) {
|
|
65
|
+
captureHeaders[key] = redactReflected(captureHeaders[key], secrets);
|
|
66
|
+
}
|
|
67
|
+
if (parsed) captureHeaders["www-authenticate"] = knownCode ? `Signature error="${parsed.error}"` : "Signature";
|
|
68
|
+
(0, import_rawResponseCapture.recordRawResponseCapture)(input, init, response, captured?.body ?? "", captured?.truncated ?? true, startedAt, {
|
|
69
|
+
url: (0, import_transportDiagnostics.sanitizeTransportUrl)(url),
|
|
70
|
+
headers: captureHeaders
|
|
71
|
+
});
|
|
72
|
+
const body = captured?.body;
|
|
73
|
+
let excerpt = body;
|
|
74
|
+
if (body && body.length > EXCERPT_LENGTH) {
|
|
75
|
+
let end = EXCERPT_LENGTH - 1;
|
|
76
|
+
if (/[\uD800-\uDBFF]/.test(body[end - 1])) end--;
|
|
77
|
+
excerpt = body.slice(0, end) + "\u2026";
|
|
78
|
+
}
|
|
79
|
+
throw new import_errors.AuthenticationRequiredError((0, import_transportDiagnostics.sanitizeTransportUrl)(agentUrl ?? url), void 0, void 0, challenge, {
|
|
80
|
+
status: response.status,
|
|
81
|
+
responseBody: excerpt
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function getSignedRequestRejection(error) {
|
|
86
|
+
const seen = /* @__PURE__ */ new Set();
|
|
87
|
+
while (error && typeof error === "object" && !seen.has(error)) {
|
|
88
|
+
seen.add(error);
|
|
89
|
+
if (error instanceof import_errors.AuthenticationRequiredError && error.requestSigned) return error;
|
|
90
|
+
error = error.cause;
|
|
91
|
+
}
|
|
92
|
+
return void 0;
|
|
93
|
+
}
|
|
94
|
+
function getHeaderSecrets(headers) {
|
|
95
|
+
const secrets = [];
|
|
96
|
+
headers.forEach((value, name) => {
|
|
97
|
+
if (value && !PUBLIC_HEADERS.has(name)) {
|
|
98
|
+
secrets.push(value);
|
|
99
|
+
if (/^(authorization|proxy-authorization)$/i.test(name)) {
|
|
100
|
+
const credential = value.replace(/^\S+\s+/, "");
|
|
101
|
+
if (credential) secrets.push(credential);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return secrets;
|
|
106
|
+
}
|
|
107
|
+
function redactReflected(value, secrets) {
|
|
108
|
+
const mask = new Uint8Array(value.length);
|
|
109
|
+
for (const secret of secrets) {
|
|
110
|
+
for (let from = 0; from < value.length; ) {
|
|
111
|
+
const at = value.indexOf(secret, from);
|
|
112
|
+
if (at < 0) break;
|
|
113
|
+
mask.fill(1, at, at + secret.length);
|
|
114
|
+
from = at + 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
let out = "";
|
|
118
|
+
let cursor = 0;
|
|
119
|
+
for (let at = 0; at < value.length; ) {
|
|
120
|
+
if (!mask[at]) {
|
|
121
|
+
at++;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
out += value.slice(cursor, at) + "[redacted]";
|
|
125
|
+
while (at < value.length && mask[at]) at++;
|
|
126
|
+
cursor = at;
|
|
127
|
+
}
|
|
128
|
+
return out + value.slice(cursor);
|
|
129
|
+
}
|
|
130
|
+
async function captureBody(response, secrets, signal) {
|
|
131
|
+
if (!response.body) return void 0;
|
|
132
|
+
const reader = response.body.getReader();
|
|
133
|
+
let timer;
|
|
134
|
+
let cancelled = false;
|
|
135
|
+
const cancel = () => {
|
|
136
|
+
cancelled = true;
|
|
137
|
+
void reader.cancel().catch(() => {
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
141
|
+
if (signal?.aborted) cancel();
|
|
142
|
+
try {
|
|
143
|
+
return await Promise.race([
|
|
144
|
+
(async () => {
|
|
145
|
+
const chunks = [];
|
|
146
|
+
let bytes = 0;
|
|
147
|
+
while (true) {
|
|
148
|
+
const { value, done } = await reader.read();
|
|
149
|
+
if (done) break;
|
|
150
|
+
if (bytes + value.byteLength > CAPTURE_BYTES) {
|
|
151
|
+
return { body: "[seller response exceeds diagnostic capture limit]", truncated: true };
|
|
152
|
+
}
|
|
153
|
+
chunks.push(value);
|
|
154
|
+
bytes += value.byteLength;
|
|
155
|
+
}
|
|
156
|
+
if (cancelled) return void 0;
|
|
157
|
+
let text = Buffer.concat(chunks).toString("utf8");
|
|
158
|
+
const redact = (value) => redactReflected(value, secrets);
|
|
159
|
+
if (/^\s*[{["]/.test(text)) {
|
|
160
|
+
try {
|
|
161
|
+
const valueRedacted = JSON.stringify(
|
|
162
|
+
JSON.parse(text, (_key, value) => {
|
|
163
|
+
if (typeof value === "string") return redact(value);
|
|
164
|
+
if ((typeof value === "boolean" || value === null) && secrets.includes(String(value)))
|
|
165
|
+
return "[redacted]";
|
|
166
|
+
if (typeof value === "number" && secrets.some((secret) => /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(secret) && Number(secret) === value))
|
|
167
|
+
return "[redacted]";
|
|
168
|
+
return value;
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
text = JSON.stringify(
|
|
172
|
+
JSON.parse((0, import_transportDiagnostics.redactSensitiveJsonOrText)(valueRedacted), (_key, value) => {
|
|
173
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
174
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
175
|
+
for (const key of Object.keys(value)) out[redact(key)] = value[key];
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
178
|
+
return value;
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
} catch {
|
|
182
|
+
return { body: "[seller response is not valid diagnostic JSON]", truncated: true };
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
text = redact(text);
|
|
186
|
+
}
|
|
187
|
+
text = (0, import_transportDiagnostics.redactSensitiveJsonOrText)(text).replace(/[\u0000-\u001f\u007f]/g, " ");
|
|
188
|
+
return { body: text, truncated: false };
|
|
189
|
+
})(),
|
|
190
|
+
new Promise((resolve) => {
|
|
191
|
+
timer = setTimeout(() => {
|
|
192
|
+
cancel();
|
|
193
|
+
resolve(void 0);
|
|
194
|
+
}, CAPTURE_TIMEOUT_MS);
|
|
195
|
+
})
|
|
196
|
+
]);
|
|
197
|
+
} catch {
|
|
198
|
+
return void 0;
|
|
199
|
+
} finally {
|
|
200
|
+
if (timer) clearTimeout(timer);
|
|
201
|
+
signal?.removeEventListener("abort", cancel);
|
|
202
|
+
cancel();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
206
|
+
0 && (module.exports = {
|
|
207
|
+
getSignedRequestRejection,
|
|
208
|
+
wrapFetchWithSignedRequestRejection
|
|
209
|
+
});
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { fileURLToPath as __adcpFileURLToPath } from "node:url";
|
|
2
|
+
import { dirname as __adcpDirname } from "node:path";
|
|
3
|
+
import { createRequire as __adcpCreateRequire } from "node:module";
|
|
4
|
+
const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
|
|
5
|
+
const require2 = __adcpCreateRequire(import.meta.url);
|
|
6
|
+
import { AuthenticationRequiredError } from "../errors/index.mjs";
|
|
7
|
+
import { RequestSigningErrorCodeMetadata } from "../types/enums.generated.mjs";
|
|
8
|
+
import { parseWWWAuthenticate } from "../auth/oauth/diagnostics.mjs";
|
|
9
|
+
import { redactSensitiveJsonOrText, sanitizeTransportHeaders, sanitizeTransportUrl } from "./transportDiagnostics.mjs";
|
|
10
|
+
import { recordRawResponseCapture } from "./rawResponseCapture.mjs";
|
|
11
|
+
const CAPTURE_BYTES = 16 * 1024;
|
|
12
|
+
const EXCERPT_LENGTH = 2048;
|
|
13
|
+
const CAPTURE_TIMEOUT_MS = 1e3;
|
|
14
|
+
const PUBLIC_HEADERS = /* @__PURE__ */ new Set([
|
|
15
|
+
"accept",
|
|
16
|
+
"content-type",
|
|
17
|
+
"content-length",
|
|
18
|
+
"user-agent",
|
|
19
|
+
"host",
|
|
20
|
+
"a2a-version",
|
|
21
|
+
"a2a-extensions",
|
|
22
|
+
"adcp-version",
|
|
23
|
+
"mcp-protocol-version",
|
|
24
|
+
"mcp-session-id",
|
|
25
|
+
"traceparent",
|
|
26
|
+
"tracestate",
|
|
27
|
+
"signature",
|
|
28
|
+
"signature-input",
|
|
29
|
+
"content-digest"
|
|
30
|
+
]);
|
|
31
|
+
function wrapFetchWithSignedRequestRejection(upstream, agentUrl) {
|
|
32
|
+
return async (input, init) => {
|
|
33
|
+
const startedAt = Date.now();
|
|
34
|
+
const response = await upstream(input, init);
|
|
35
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
36
|
+
if (response.status !== 401 || !headers.has("signature")) return response;
|
|
37
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
38
|
+
const parsed = parseWWWAuthenticate(response.headers.get("www-authenticate"));
|
|
39
|
+
if (parsed && parsed.scheme !== "signature") return response;
|
|
40
|
+
const knownCode = parsed?.scheme === "signature" && parsed.error && Object.prototype.hasOwnProperty.call(RequestSigningErrorCodeMetadata, parsed.error);
|
|
41
|
+
const challenge = parsed ? { scheme: parsed.scheme.slice(0, 64), ...knownCode && { error: parsed.error } } : void 0;
|
|
42
|
+
const secrets = getHeaderSecrets(headers);
|
|
43
|
+
const captured = await captureBody(response, secrets, init?.signal);
|
|
44
|
+
const captureHeaders = sanitizeTransportHeaders(response.headers);
|
|
45
|
+
for (const key of Object.keys(captureHeaders)) {
|
|
46
|
+
captureHeaders[key] = redactReflected(captureHeaders[key], secrets);
|
|
47
|
+
}
|
|
48
|
+
if (parsed) captureHeaders["www-authenticate"] = knownCode ? `Signature error="${parsed.error}"` : "Signature";
|
|
49
|
+
recordRawResponseCapture(input, init, response, captured?.body ?? "", captured?.truncated ?? true, startedAt, {
|
|
50
|
+
url: sanitizeTransportUrl(url),
|
|
51
|
+
headers: captureHeaders
|
|
52
|
+
});
|
|
53
|
+
const body = captured?.body;
|
|
54
|
+
let excerpt = body;
|
|
55
|
+
if (body && body.length > EXCERPT_LENGTH) {
|
|
56
|
+
let end = EXCERPT_LENGTH - 1;
|
|
57
|
+
if (/[\uD800-\uDBFF]/.test(body[end - 1])) end--;
|
|
58
|
+
excerpt = body.slice(0, end) + "\u2026";
|
|
59
|
+
}
|
|
60
|
+
throw new AuthenticationRequiredError(sanitizeTransportUrl(agentUrl ?? url), void 0, void 0, challenge, {
|
|
61
|
+
status: response.status,
|
|
62
|
+
responseBody: excerpt
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function getSignedRequestRejection(error) {
|
|
67
|
+
const seen = /* @__PURE__ */ new Set();
|
|
68
|
+
while (error && typeof error === "object" && !seen.has(error)) {
|
|
69
|
+
seen.add(error);
|
|
70
|
+
if (error instanceof AuthenticationRequiredError && error.requestSigned) return error;
|
|
71
|
+
error = error.cause;
|
|
72
|
+
}
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
75
|
+
function getHeaderSecrets(headers) {
|
|
76
|
+
const secrets = [];
|
|
77
|
+
headers.forEach((value, name) => {
|
|
78
|
+
if (value && !PUBLIC_HEADERS.has(name)) {
|
|
79
|
+
secrets.push(value);
|
|
80
|
+
if (/^(authorization|proxy-authorization)$/i.test(name)) {
|
|
81
|
+
const credential = value.replace(/^\S+\s+/, "");
|
|
82
|
+
if (credential) secrets.push(credential);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return secrets;
|
|
87
|
+
}
|
|
88
|
+
function redactReflected(value, secrets) {
|
|
89
|
+
const mask = new Uint8Array(value.length);
|
|
90
|
+
for (const secret of secrets) {
|
|
91
|
+
for (let from = 0; from < value.length; ) {
|
|
92
|
+
const at = value.indexOf(secret, from);
|
|
93
|
+
if (at < 0) break;
|
|
94
|
+
mask.fill(1, at, at + secret.length);
|
|
95
|
+
from = at + 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
let out = "";
|
|
99
|
+
let cursor = 0;
|
|
100
|
+
for (let at = 0; at < value.length; ) {
|
|
101
|
+
if (!mask[at]) {
|
|
102
|
+
at++;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
out += value.slice(cursor, at) + "[redacted]";
|
|
106
|
+
while (at < value.length && mask[at]) at++;
|
|
107
|
+
cursor = at;
|
|
108
|
+
}
|
|
109
|
+
return out + value.slice(cursor);
|
|
110
|
+
}
|
|
111
|
+
async function captureBody(response, secrets, signal) {
|
|
112
|
+
if (!response.body) return void 0;
|
|
113
|
+
const reader = response.body.getReader();
|
|
114
|
+
let timer;
|
|
115
|
+
let cancelled = false;
|
|
116
|
+
const cancel = () => {
|
|
117
|
+
cancelled = true;
|
|
118
|
+
void reader.cancel().catch(() => {
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
122
|
+
if (signal?.aborted) cancel();
|
|
123
|
+
try {
|
|
124
|
+
return await Promise.race([
|
|
125
|
+
(async () => {
|
|
126
|
+
const chunks = [];
|
|
127
|
+
let bytes = 0;
|
|
128
|
+
while (true) {
|
|
129
|
+
const { value, done } = await reader.read();
|
|
130
|
+
if (done) break;
|
|
131
|
+
if (bytes + value.byteLength > CAPTURE_BYTES) {
|
|
132
|
+
return { body: "[seller response exceeds diagnostic capture limit]", truncated: true };
|
|
133
|
+
}
|
|
134
|
+
chunks.push(value);
|
|
135
|
+
bytes += value.byteLength;
|
|
136
|
+
}
|
|
137
|
+
if (cancelled) return void 0;
|
|
138
|
+
let text = Buffer.concat(chunks).toString("utf8");
|
|
139
|
+
const redact = (value) => redactReflected(value, secrets);
|
|
140
|
+
if (/^\s*[{["]/.test(text)) {
|
|
141
|
+
try {
|
|
142
|
+
const valueRedacted = JSON.stringify(
|
|
143
|
+
JSON.parse(text, (_key, value) => {
|
|
144
|
+
if (typeof value === "string") return redact(value);
|
|
145
|
+
if ((typeof value === "boolean" || value === null) && secrets.includes(String(value)))
|
|
146
|
+
return "[redacted]";
|
|
147
|
+
if (typeof value === "number" && secrets.some((secret) => /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(secret) && Number(secret) === value))
|
|
148
|
+
return "[redacted]";
|
|
149
|
+
return value;
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
text = JSON.stringify(
|
|
153
|
+
JSON.parse(redactSensitiveJsonOrText(valueRedacted), (_key, value) => {
|
|
154
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
155
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
156
|
+
for (const key of Object.keys(value)) out[redact(key)] = value[key];
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
} catch {
|
|
163
|
+
return { body: "[seller response is not valid diagnostic JSON]", truncated: true };
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
text = redact(text);
|
|
167
|
+
}
|
|
168
|
+
text = redactSensitiveJsonOrText(text).replace(/[\u0000-\u001f\u007f]/g, " ");
|
|
169
|
+
return { body: text, truncated: false };
|
|
170
|
+
})(),
|
|
171
|
+
new Promise((resolve) => {
|
|
172
|
+
timer = setTimeout(() => {
|
|
173
|
+
cancel();
|
|
174
|
+
resolve(void 0);
|
|
175
|
+
}, CAPTURE_TIMEOUT_MS);
|
|
176
|
+
})
|
|
177
|
+
]);
|
|
178
|
+
} catch {
|
|
179
|
+
return void 0;
|
|
180
|
+
} finally {
|
|
181
|
+
if (timer) clearTimeout(timer);
|
|
182
|
+
signal?.removeEventListener("abort", cancel);
|
|
183
|
+
cancel();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export {
|
|
187
|
+
getSignedRequestRejection,
|
|
188
|
+
wrapFetchWithSignedRequestRejection
|
|
189
|
+
};
|
|
@@ -53,4 +53,5 @@ export declare function withTransportDiagnostics<T>(context: TransportActivityCo
|
|
|
53
53
|
export declare function sanitizeTransportUrl(value: string): string;
|
|
54
54
|
export declare function sanitizeTransportHeaders(headers: HeadersInit | undefined): Record<string, string>;
|
|
55
55
|
export declare function wrapFetchWithTransportDiagnostics(upstream: typeof fetch): typeof fetch;
|
|
56
|
+
export declare function redactSensitiveJsonOrText(text: string): string;
|
|
56
57
|
export {};
|
|
@@ -53,4 +53,5 @@ export declare function withTransportDiagnostics<T>(context: TransportActivityCo
|
|
|
53
53
|
export declare function sanitizeTransportUrl(value: string): string;
|
|
54
54
|
export declare function sanitizeTransportHeaders(headers: HeadersInit | undefined): Record<string, string>;
|
|
55
55
|
export declare function wrapFetchWithTransportDiagnostics(upstream: typeof fetch): typeof fetch;
|
|
56
|
+
export declare function redactSensitiveJsonOrText(text: string): string;
|
|
56
57
|
export {};
|
|
@@ -20,6 +20,7 @@ var transportDiagnostics_exports = {};
|
|
|
20
20
|
__export(transportDiagnostics_exports, {
|
|
21
21
|
BODY_SNIPPET_TIMEOUT_MS: () => BODY_SNIPPET_TIMEOUT_MS,
|
|
22
22
|
OBSERVER_FLUSH_TIMEOUT_MS: () => OBSERVER_FLUSH_TIMEOUT_MS,
|
|
23
|
+
redactSensitiveJsonOrText: () => redactSensitiveJsonOrText,
|
|
23
24
|
sanitizeTransportHeaders: () => sanitizeTransportHeaders,
|
|
24
25
|
sanitizeTransportUrl: () => sanitizeTransportUrl,
|
|
25
26
|
transportDiagnosticsStorage: () => transportDiagnosticsStorage,
|
|
@@ -385,6 +386,7 @@ function fingerprintDiagnosticValue(value) {
|
|
|
385
386
|
0 && (module.exports = {
|
|
386
387
|
BODY_SNIPPET_TIMEOUT_MS,
|
|
387
388
|
OBSERVER_FLUSH_TIMEOUT_MS,
|
|
389
|
+
redactSensitiveJsonOrText,
|
|
388
390
|
sanitizeTransportHeaders,
|
|
389
391
|
sanitizeTransportUrl,
|
|
390
392
|
transportDiagnosticsStorage,
|