@adcp/sdk 16.0.0-beta.1 → 16.0.0-beta.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/dist/lib/core/SingleAgentClient.d.mts +10 -1
- package/dist/lib/core/SingleAgentClient.d.ts +10 -1
- package/dist/lib/core/SingleAgentClient.js +29 -8
- package/dist/lib/core/SingleAgentClient.mjs +29 -8
- package/dist/lib/identity-3.3/generated-compat.d.mts +34 -0
- package/dist/lib/identity-3.3/generated-compat.d.ts +34 -0
- package/dist/lib/identity-3.3/generated-compat.js +16 -0
- package/dist/lib/identity-3.3/generated-compat.mjs +0 -0
- package/dist/lib/identity-3.3/index.d.mts +2 -2
- package/dist/lib/identity-3.3/index.d.ts +2 -2
- package/dist/lib/identity-3.3/index.js +4 -0
- package/dist/lib/identity-3.3/index.mjs +5 -1
- package/dist/lib/identity-3.3/lifecycle.d.mts +17 -5
- package/dist/lib/identity-3.3/lifecycle.d.ts +17 -5
- package/dist/lib/identity-3.3/lifecycle.js +32 -5
- package/dist/lib/identity-3.3/lifecycle.mjs +38 -6
- package/dist/lib/identity-3.3/revocation.d.mts +39 -3
- package/dist/lib/identity-3.3/revocation.d.ts +39 -3
- package/dist/lib/identity-3.3/revocation.js +88 -18
- package/dist/lib/identity-3.3/revocation.mjs +89 -19
- package/dist/lib/identity-3.3/server.d.mts +12 -0
- package/dist/lib/identity-3.3/server.d.ts +12 -0
- package/dist/lib/identity-3.3/server.js +103 -43
- package/dist/lib/identity-3.3/server.mjs +111 -45
- package/dist/lib/identity-3.3/trust.d.mts +62 -1
- package/dist/lib/identity-3.3/trust.d.ts +62 -1
- package/dist/lib/identity-3.3/trust.js +126 -21
- package/dist/lib/identity-3.3/trust.mjs +124 -21
- package/dist/lib/identity-3.3/types.d.mts +39 -11
- package/dist/lib/identity-3.3/types.d.ts +39 -11
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +2 -0
- package/dist/lib/protocols/index.d.mts +1 -1
- package/dist/lib/protocols/index.d.ts +1 -1
- package/dist/lib/protocols/index.js +2 -2
- package/dist/lib/protocols/index.mjs +2 -2
- package/dist/lib/reporting/bigquery/index.js +8 -0
- package/dist/lib/reporting/bigquery/index.mjs +8 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/auth-signature.d.mts +6 -1
- package/dist/lib/server/auth-signature.d.ts +6 -1
- package/dist/lib/server/auth-signature.js +24 -13
- package/dist/lib/server/auth-signature.mjs +29 -13
- package/dist/lib/server/auth.d.mts +2 -2
- package/dist/lib/server/auth.d.ts +2 -2
- package/dist/lib/server/create-adcp-server.js +31 -10
- package/dist/lib/server/create-adcp-server.mjs +37 -11
- package/dist/lib/signing/crypto.js +8 -0
- package/dist/lib/signing/crypto.mjs +9 -1
- package/dist/lib/signing/fetch-async.js +1 -1
- package/dist/lib/signing/fetch-async.mjs +1 -1
- package/dist/lib/signing/fetch.js +1 -1
- package/dist/lib/signing/fetch.mjs +1 -1
- package/dist/lib/signing/middleware.js +9 -0
- package/dist/lib/signing/middleware.mjs +14 -0
- package/dist/lib/signing/parser.d.mts +8 -5
- package/dist/lib/signing/parser.d.ts +8 -5
- package/dist/lib/signing/parser.js +77 -61
- package/dist/lib/signing/parser.mjs +77 -61
- package/dist/lib/signing/revocation.js +3 -0
- package/dist/lib/signing/revocation.mjs +3 -0
- package/dist/lib/signing/verifier.js +1 -1
- package/dist/lib/signing/verifier.mjs +1 -1
- package/dist/lib/signing/web-bot-auth.d.mts +84 -10
- package/dist/lib/signing/web-bot-auth.d.ts +84 -10
- package/dist/lib/signing/web-bot-auth.js +259 -82
- package/dist/lib/signing/web-bot-auth.mjs +259 -87
- package/dist/lib/signing/webhook-verifier.js +1 -1
- package/dist/lib/signing/webhook-verifier.mjs +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/v2/projection/catalog-snapshot.js +3 -1
- package/dist/lib/v2/projection/catalog-snapshot.mjs +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +31 -9
- package/dist/lib/v2/projection/creative-delivery.d.ts +31 -9
- package/dist/lib/v2/projection/index.d.mts +1 -1
- package/dist/lib/v2/projection/index.d.ts +1 -1
- package/dist/lib/v2/projection/index.js +2 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-routes.d.mts +10 -0
- package/dist/lib/v2/projection/legacy-routes.d.ts +10 -0
- package/dist/lib/v2/projection/legacy-routes.js +7 -0
- package/dist/lib/v2/projection/legacy-routes.mjs +6 -0
- 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/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/REPORTING-LEDGER.md +15 -5
- package/docs/guides/REPORTING-OPERATIONS.md +17 -11
- package/docs/llms.txt +2 -2
- package/docs/migration-12-to-13.md +8 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +150 -11
- package/package.json +3 -1
|
@@ -98,7 +98,16 @@ export type WebhookParseErrorCode = WebhookSignatureErrorCode | 'webhook_signatu
|
|
|
98
98
|
export interface WebhookVerificationConfig {
|
|
99
99
|
webBotAuth?: {
|
|
100
100
|
directory: import('../signing/web-bot-auth.mjs').SignatureDirectoryResolver;
|
|
101
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Seller origin revocation, checked after verification. A revoked key is
|
|
103
|
+
* refused; unknown status is retryable; a seller that serves no list is
|
|
104
|
+
* accepted (webhooks do not spend). Usually an `OriginRevocationResolver`.
|
|
105
|
+
*/
|
|
106
|
+
revocation?: {
|
|
107
|
+
status(origin: string, keyid: string): Promise<import('../identity-3.3/revocation.mjs').OriginRevocationStatus>;
|
|
108
|
+
};
|
|
109
|
+
/** @deprecated Use `revocation`. Conservative: a seller that serves no list is refused. */
|
|
110
|
+
isRevoked?: (origin: string, keyid: string) => Promise<boolean>;
|
|
102
111
|
};
|
|
103
112
|
/** Applicable pins from persisted media-buy records. Reuse refresh callbacks bound to the seller/publisher/tenant across deliveries to share their cooldown. Never use webhook payload fields. */
|
|
104
113
|
publisherPins?: (registration: Readonly<WebhookRegistration>) => Promise<readonly import('../signing/publisher-pins.mjs').PublisherSigningKeyPin[]>;
|
|
@@ -98,7 +98,16 @@ export type WebhookParseErrorCode = WebhookSignatureErrorCode | 'webhook_signatu
|
|
|
98
98
|
export interface WebhookVerificationConfig {
|
|
99
99
|
webBotAuth?: {
|
|
100
100
|
directory: import('../signing/web-bot-auth').SignatureDirectoryResolver;
|
|
101
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Seller origin revocation, checked after verification. A revoked key is
|
|
103
|
+
* refused; unknown status is retryable; a seller that serves no list is
|
|
104
|
+
* accepted (webhooks do not spend). Usually an `OriginRevocationResolver`.
|
|
105
|
+
*/
|
|
106
|
+
revocation?: {
|
|
107
|
+
status(origin: string, keyid: string): Promise<import('../identity-3.3/revocation').OriginRevocationStatus>;
|
|
108
|
+
};
|
|
109
|
+
/** @deprecated Use `revocation`. Conservative: a seller that serves no list is refused. */
|
|
110
|
+
isRevoked?: (origin: string, keyid: string) => Promise<boolean>;
|
|
102
111
|
};
|
|
103
112
|
/** Applicable pins from persisted media-buy records. Reuse refresh callbacks bound to the seller/publisher/tenant across deliveries to share their cooldown. Never use webhook payload fields. */
|
|
104
113
|
publisherPins?: (registration: Readonly<WebhookRegistration>) => Promise<readonly import('../signing/publisher-pins').PublisherSigningKeyPin[]>;
|
|
@@ -2450,7 +2450,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2450
2450
|
}
|
|
2451
2451
|
}
|
|
2452
2452
|
if (registration?.mode === "rfc9421") {
|
|
2453
|
-
const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError } = loadWebBotAuth();
|
|
2453
|
+
const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError, WebBotAuthUnavailableError } = loadWebBotAuth();
|
|
2454
2454
|
const requestMethod = options.requestMethod;
|
|
2455
2455
|
const requestUrl = options.requestUrl;
|
|
2456
2456
|
if (rawBody === void 0 || !options.headers || !trustedOperationId || !requestMethod || !requestUrl) {
|
|
@@ -2474,17 +2474,30 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2474
2474
|
method: requestMethod,
|
|
2475
2475
|
url: requestUrl,
|
|
2476
2476
|
headers: normalizedHeaders.headers,
|
|
2477
|
-
body: typeof rawBody === "string" ? rawBody :
|
|
2477
|
+
body: typeof rawBody === "string" ? rawBody : (
|
|
2478
|
+
// ignoreBOM: Content-Digest covers the exact received bytes.
|
|
2479
|
+
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(rawBody)
|
|
2480
|
+
)
|
|
2478
2481
|
},
|
|
2479
2482
|
{
|
|
2480
2483
|
directory: config.directory,
|
|
2481
2484
|
replayStore: this.webhookReplayStore,
|
|
2482
|
-
isRevoked: config.isRevoked,
|
|
2485
|
+
...config.isRevoked && !config.revocation && { isRevoked: config.isRevoked },
|
|
2483
2486
|
now: this.config.webhookVerification?.now
|
|
2484
2487
|
}
|
|
2485
2488
|
);
|
|
2486
2489
|
if (signers.length !== 1 || signers[0].origin !== (0, import_canonicalize.canonicalAgentOrigin)(registration.agentUrl))
|
|
2487
2490
|
throw new WebBotAuthError(403, "webhook_signer_mismatch");
|
|
2491
|
+
if (config.revocation) {
|
|
2492
|
+
let status;
|
|
2493
|
+
try {
|
|
2494
|
+
status = await config.revocation.status(signers[0].origin, signers[0].keyid);
|
|
2495
|
+
} catch (error) {
|
|
2496
|
+
throw new WebBotAuthUnavailableError("revocation_persistence_failed", error);
|
|
2497
|
+
}
|
|
2498
|
+
if (status === "revoked") throw new WebBotAuthError(403, "key_revoked");
|
|
2499
|
+
if (status === "unknown") throw new WebBotAuthError(403, "identity_unverified");
|
|
2500
|
+
} else if (!config.isRevoked) throw new WebBotAuthError(403, "webhook_revocation_not_configured");
|
|
2488
2501
|
} else {
|
|
2489
2502
|
if (actualProfile === "web-bot-auth") throw new WebBotAuthError(403, "webhook_profile_mismatch");
|
|
2490
2503
|
const delegatedOperatorAuthorization = this.delegatedOperatorAuthorizationForRegistration(registration);
|
|
@@ -2510,14 +2523,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2510
2523
|
);
|
|
2511
2524
|
}
|
|
2512
2525
|
} catch (cause) {
|
|
2526
|
+
if (cause instanceof WebBotAuthUnavailableError)
|
|
2527
|
+
return { ok: false, code: "webhook_verification_unavailable", message: cause.message, cause };
|
|
2513
2528
|
if (cause instanceof WebBotAuthError)
|
|
2514
2529
|
return {
|
|
2515
2530
|
ok: false,
|
|
2516
2531
|
code: [
|
|
2517
2532
|
"directory_unavailable",
|
|
2518
|
-
"
|
|
2519
|
-
"
|
|
2520
|
-
"
|
|
2533
|
+
"directory_fetch_limit",
|
|
2534
|
+
"directory_expired",
|
|
2535
|
+
"identity_unverified",
|
|
2536
|
+
"verification_unavailable"
|
|
2521
2537
|
].includes(cause.reason) ? "webhook_verification_unavailable" : "webhook_signature_invalid",
|
|
2522
2538
|
message: cause.message,
|
|
2523
2539
|
cause
|
|
@@ -4854,6 +4870,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4854
4870
|
const defaultAuth = !signed33Webhooks && this.config.webhookSecret ? { schemes: ["HMAC-SHA256"], credentials: this.config.webhookSecret } : void 0;
|
|
4855
4871
|
const resolvedAuth = consumerAuth !== void 0 ? consumerAuth : consumerUrl === void 0 ? defaultAuth : void 0;
|
|
4856
4872
|
if (!signed33Webhooks && resolvedAuth === void 0 || resolvedAuth === null) {
|
|
4873
|
+
if (consumerReportingWebhook && consumerUrl !== void 0 && consumerAuth === void 0) {
|
|
4874
|
+
throw new Error(
|
|
4875
|
+
"reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks: a caller-supplied `reporting_webhook.url` must bring its own `reporting_webhook.authentication` (the client never pairs `webhookSecret` with a caller-controlled URL). Omit `url` to use the client's webhookUrlTemplate callback, or remove `reporting_webhook` if you do not need automated delivery reports."
|
|
4876
|
+
);
|
|
4877
|
+
}
|
|
4857
4878
|
if (consumerReportingWebhook) {
|
|
4858
4879
|
throw new Error(
|
|
4859
4880
|
"reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks, and no credential is available: set `webhookSecret` on the client, or pass `reporting_webhook.authentication` explicitly. Remove `reporting_webhook` from the request if you do not need automated delivery reports \u2014 the media buy itself does not require it."
|
|
@@ -4876,12 +4897,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4876
4897
|
...resolvedAuth === void 0 && this.selectedWebhookSigningProfile() && { signing_profile: this.selectedWebhookSigningProfile() }
|
|
4877
4898
|
}
|
|
4878
4899
|
};
|
|
4879
|
-
if (signed33Webhooks && resolvedAuth === void 0) {
|
|
4900
|
+
if (signed33Webhooks && resolvedAuth === void 0 && consumerUrl === void 0) {
|
|
4880
4901
|
await this.persistWebhookRegistration({
|
|
4881
4902
|
agent: this.normalizedAgent,
|
|
4882
4903
|
taskType: "media_buy_delivery",
|
|
4883
4904
|
operationId,
|
|
4884
|
-
callbackUrl:
|
|
4905
|
+
callbackUrl: deliveryWebhookUrl,
|
|
4885
4906
|
mode: "rfc9421",
|
|
4886
4907
|
signingProfile: this.selectedWebhookSigningProfile()
|
|
4887
4908
|
});
|
|
@@ -2541,7 +2541,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2541
2541
|
}
|
|
2542
2542
|
}
|
|
2543
2543
|
if (registration?.mode === "rfc9421") {
|
|
2544
|
-
const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError } = loadWebBotAuth();
|
|
2544
|
+
const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError, WebBotAuthUnavailableError } = loadWebBotAuth();
|
|
2545
2545
|
const requestMethod = options.requestMethod;
|
|
2546
2546
|
const requestUrl = options.requestUrl;
|
|
2547
2547
|
if (rawBody === void 0 || !options.headers || !trustedOperationId || !requestMethod || !requestUrl) {
|
|
@@ -2565,17 +2565,30 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2565
2565
|
method: requestMethod,
|
|
2566
2566
|
url: requestUrl,
|
|
2567
2567
|
headers: normalizedHeaders.headers,
|
|
2568
|
-
body: typeof rawBody === "string" ? rawBody :
|
|
2568
|
+
body: typeof rawBody === "string" ? rawBody : (
|
|
2569
|
+
// ignoreBOM: Content-Digest covers the exact received bytes.
|
|
2570
|
+
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(rawBody)
|
|
2571
|
+
)
|
|
2569
2572
|
},
|
|
2570
2573
|
{
|
|
2571
2574
|
directory: config.directory,
|
|
2572
2575
|
replayStore: this.webhookReplayStore,
|
|
2573
|
-
isRevoked: config.isRevoked,
|
|
2576
|
+
...config.isRevoked && !config.revocation && { isRevoked: config.isRevoked },
|
|
2574
2577
|
now: this.config.webhookVerification?.now
|
|
2575
2578
|
}
|
|
2576
2579
|
);
|
|
2577
2580
|
if (signers.length !== 1 || signers[0].origin !== canonicalAgentOrigin(registration.agentUrl))
|
|
2578
2581
|
throw new WebBotAuthError(403, "webhook_signer_mismatch");
|
|
2582
|
+
if (config.revocation) {
|
|
2583
|
+
let status;
|
|
2584
|
+
try {
|
|
2585
|
+
status = await config.revocation.status(signers[0].origin, signers[0].keyid);
|
|
2586
|
+
} catch (error) {
|
|
2587
|
+
throw new WebBotAuthUnavailableError("revocation_persistence_failed", error);
|
|
2588
|
+
}
|
|
2589
|
+
if (status === "revoked") throw new WebBotAuthError(403, "key_revoked");
|
|
2590
|
+
if (status === "unknown") throw new WebBotAuthError(403, "identity_unverified");
|
|
2591
|
+
} else if (!config.isRevoked) throw new WebBotAuthError(403, "webhook_revocation_not_configured");
|
|
2579
2592
|
} else {
|
|
2580
2593
|
if (actualProfile === "web-bot-auth") throw new WebBotAuthError(403, "webhook_profile_mismatch");
|
|
2581
2594
|
const delegatedOperatorAuthorization = this.delegatedOperatorAuthorizationForRegistration(registration);
|
|
@@ -2601,14 +2614,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2601
2614
|
);
|
|
2602
2615
|
}
|
|
2603
2616
|
} catch (cause) {
|
|
2617
|
+
if (cause instanceof WebBotAuthUnavailableError)
|
|
2618
|
+
return { ok: false, code: "webhook_verification_unavailable", message: cause.message, cause };
|
|
2604
2619
|
if (cause instanceof WebBotAuthError)
|
|
2605
2620
|
return {
|
|
2606
2621
|
ok: false,
|
|
2607
2622
|
code: [
|
|
2608
2623
|
"directory_unavailable",
|
|
2609
|
-
"
|
|
2610
|
-
"
|
|
2611
|
-
"
|
|
2624
|
+
"directory_fetch_limit",
|
|
2625
|
+
"directory_expired",
|
|
2626
|
+
"identity_unverified",
|
|
2627
|
+
"verification_unavailable"
|
|
2612
2628
|
].includes(cause.reason) ? "webhook_verification_unavailable" : "webhook_signature_invalid",
|
|
2613
2629
|
message: cause.message,
|
|
2614
2630
|
cause
|
|
@@ -4945,6 +4961,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4945
4961
|
const defaultAuth = !signed33Webhooks && this.config.webhookSecret ? { schemes: ["HMAC-SHA256"], credentials: this.config.webhookSecret } : void 0;
|
|
4946
4962
|
const resolvedAuth = consumerAuth !== void 0 ? consumerAuth : consumerUrl === void 0 ? defaultAuth : void 0;
|
|
4947
4963
|
if (!signed33Webhooks && resolvedAuth === void 0 || resolvedAuth === null) {
|
|
4964
|
+
if (consumerReportingWebhook && consumerUrl !== void 0 && consumerAuth === void 0) {
|
|
4965
|
+
throw new Error(
|
|
4966
|
+
"reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks: a caller-supplied `reporting_webhook.url` must bring its own `reporting_webhook.authentication` (the client never pairs `webhookSecret` with a caller-controlled URL). Omit `url` to use the client's webhookUrlTemplate callback, or remove `reporting_webhook` if you do not need automated delivery reports."
|
|
4967
|
+
);
|
|
4968
|
+
}
|
|
4948
4969
|
if (consumerReportingWebhook) {
|
|
4949
4970
|
throw new Error(
|
|
4950
4971
|
"reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks, and no credential is available: set `webhookSecret` on the client, or pass `reporting_webhook.authentication` explicitly. Remove `reporting_webhook` from the request if you do not need automated delivery reports \u2014 the media buy itself does not require it."
|
|
@@ -4967,12 +4988,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4967
4988
|
...resolvedAuth === void 0 && this.selectedWebhookSigningProfile() && { signing_profile: this.selectedWebhookSigningProfile() }
|
|
4968
4989
|
}
|
|
4969
4990
|
};
|
|
4970
|
-
if (signed33Webhooks && resolvedAuth === void 0) {
|
|
4991
|
+
if (signed33Webhooks && resolvedAuth === void 0 && consumerUrl === void 0) {
|
|
4971
4992
|
await this.persistWebhookRegistration({
|
|
4972
4993
|
agent: this.normalizedAgent,
|
|
4973
4994
|
taskType: "media_buy_delivery",
|
|
4974
4995
|
operationId,
|
|
4975
|
-
callbackUrl:
|
|
4996
|
+
callbackUrl: deliveryWebhookUrl,
|
|
4976
4997
|
mode: "rfc9421",
|
|
4977
4998
|
signingProfile: this.selectedWebhookSigningProfile()
|
|
4978
4999
|
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges the experimental AdCP 3.3 preview types to the generated wire types.
|
|
3
|
+
*
|
|
4
|
+
* The released SDK pins an AdCP schema version that predates the 3.3 identity
|
|
5
|
+
* drafts, so the preview types in `./types` start from hand-written drafts. Once
|
|
6
|
+
* the pinned schemas (or a candidate spec bundle built by the spec repo's
|
|
7
|
+
* "Generate TypeScript SDK" check) define a shape, the generated type wins: the
|
|
8
|
+
* preview type becomes an alias of it, so the two cannot drift apart and a
|
|
9
|
+
* server that accepts the preview shape always emits a generated-valid payload.
|
|
10
|
+
*
|
|
11
|
+
* Internal: not re-exported from `@adcp/sdk/identity-3.3`.
|
|
12
|
+
*/
|
|
13
|
+
import type { GetAdCPCapabilitiesResponse } from '../types/tools.generated.mjs';
|
|
14
|
+
/**
|
|
15
|
+
* The value type of an optional property `K` on `T`, or `unknown` when `T`
|
|
16
|
+
* does not declare it. An object type without `K` is assignable to
|
|
17
|
+
* `{ K?: V }`, so the absent case infers `unknown` rather than failing.
|
|
18
|
+
* Non-distributive, so a union `T` resolves to the property's union rather
|
|
19
|
+
* than silently falling back when one member lacks it.
|
|
20
|
+
*/
|
|
21
|
+
export type OptionalPropertyOf<T, K extends PropertyKey> = [T] extends [{
|
|
22
|
+
[P in K]?: infer V;
|
|
23
|
+
}] ? V : unknown;
|
|
24
|
+
/** `Generated` when the pinned schemas define it, otherwise `Draft`. */
|
|
25
|
+
export type PreferGenerated<Generated, Draft> = unknown extends Generated ? Draft : [NonNullable<Generated>] extends [never] ? Draft : NonNullable<Generated>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves `account.agent_onboarding` from a `get_adcp_capabilities` account
|
|
28
|
+
* shape, falling back to the draft when that shape does not declare it.
|
|
29
|
+
* Parameterised so type tests can exercise it against fixtures of newer
|
|
30
|
+
* generated shapes without regenerating the SDK.
|
|
31
|
+
*/
|
|
32
|
+
export type ResolveAgentOnboarding<Account, Draft> = PreferGenerated<OptionalPropertyOf<NonNullable<Account>, 'agent_onboarding'>, Draft>;
|
|
33
|
+
/** `account` in the pinned `get_adcp_capabilities` response. */
|
|
34
|
+
export type GeneratedAccountCapabilities = NonNullable<GetAdCPCapabilitiesResponse['account']>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges the experimental AdCP 3.3 preview types to the generated wire types.
|
|
3
|
+
*
|
|
4
|
+
* The released SDK pins an AdCP schema version that predates the 3.3 identity
|
|
5
|
+
* drafts, so the preview types in `./types` start from hand-written drafts. Once
|
|
6
|
+
* the pinned schemas (or a candidate spec bundle built by the spec repo's
|
|
7
|
+
* "Generate TypeScript SDK" check) define a shape, the generated type wins: the
|
|
8
|
+
* preview type becomes an alias of it, so the two cannot drift apart and a
|
|
9
|
+
* server that accepts the preview shape always emits a generated-valid payload.
|
|
10
|
+
*
|
|
11
|
+
* Internal: not re-exported from `@adcp/sdk/identity-3.3`.
|
|
12
|
+
*/
|
|
13
|
+
import type { GetAdCPCapabilitiesResponse } from '../types/tools.generated';
|
|
14
|
+
/**
|
|
15
|
+
* The value type of an optional property `K` on `T`, or `unknown` when `T`
|
|
16
|
+
* does not declare it. An object type without `K` is assignable to
|
|
17
|
+
* `{ K?: V }`, so the absent case infers `unknown` rather than failing.
|
|
18
|
+
* Non-distributive, so a union `T` resolves to the property's union rather
|
|
19
|
+
* than silently falling back when one member lacks it.
|
|
20
|
+
*/
|
|
21
|
+
export type OptionalPropertyOf<T, K extends PropertyKey> = [T] extends [{
|
|
22
|
+
[P in K]?: infer V;
|
|
23
|
+
}] ? V : unknown;
|
|
24
|
+
/** `Generated` when the pinned schemas define it, otherwise `Draft`. */
|
|
25
|
+
export type PreferGenerated<Generated, Draft> = unknown extends Generated ? Draft : [NonNullable<Generated>] extends [never] ? Draft : NonNullable<Generated>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves `account.agent_onboarding` from a `get_adcp_capabilities` account
|
|
28
|
+
* shape, falling back to the draft when that shape does not declare it.
|
|
29
|
+
* Parameterised so type tests can exercise it against fixtures of newer
|
|
30
|
+
* generated shapes without regenerating the SDK.
|
|
31
|
+
*/
|
|
32
|
+
export type ResolveAgentOnboarding<Account, Draft> = PreferGenerated<OptionalPropertyOf<NonNullable<Account>, 'agent_onboarding'>, Draft>;
|
|
33
|
+
/** `account` in the pinned `get_adcp_capabilities` response. */
|
|
34
|
+
export type GeneratedAccountCapabilities = NonNullable<GetAdCPCapabilitiesResponse['account']>;
|
|
@@ -0,0 +1,16 @@
|
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var generated_compat_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(generated_compat_exports);
|
|
File without changes
|
|
@@ -2,8 +2,8 @@ export * from './types.mjs';
|
|
|
2
2
|
export * from './trust.mjs';
|
|
3
3
|
export * from './lifecycle.mjs';
|
|
4
4
|
export * from './revocation.mjs';
|
|
5
|
-
export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, } from '../signing/web-bot-auth.mjs';
|
|
6
|
-
export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, } from '../signing/web-bot-auth.mjs';
|
|
5
|
+
export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, verifyKeyDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, WebBotAuthUnavailableError, } from '../signing/web-bot-auth.mjs';
|
|
6
|
+
export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, VerifiedSignatureDirectory, SignatureDirectoryResolverOptions, } from '../signing/web-bot-auth.mjs';
|
|
7
7
|
export { validateIdentity33Payload } from './validation.mjs';
|
|
8
8
|
export { createIdentity33PrincipalResolver, createIdentity33PrincipalScopeResolver, createIdentity33Authorization, withIdentity33PrincipalHandlers, isIdentity33UnboundContext, } from './server.mjs';
|
|
9
9
|
export { createIdentity33StateStores } from './store.mjs';
|
|
@@ -2,8 +2,8 @@ export * from './types';
|
|
|
2
2
|
export * from './trust';
|
|
3
3
|
export * from './lifecycle';
|
|
4
4
|
export * from './revocation';
|
|
5
|
-
export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, } from '../signing/web-bot-auth';
|
|
6
|
-
export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, } from '../signing/web-bot-auth';
|
|
5
|
+
export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, verifyKeyDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, WebBotAuthUnavailableError, } from '../signing/web-bot-auth';
|
|
6
|
+
export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, VerifiedSignatureDirectory, SignatureDirectoryResolverOptions, } from '../signing/web-bot-auth';
|
|
7
7
|
export { validateIdentity33Payload } from './validation';
|
|
8
8
|
export { createIdentity33PrincipalResolver, createIdentity33PrincipalScopeResolver, createIdentity33Authorization, withIdentity33PrincipalHandlers, isIdentity33UnboundContext, } from './server';
|
|
9
9
|
export { createIdentity33StateStores } from './store';
|
|
@@ -22,6 +22,7 @@ __export(identity_3_exports, {
|
|
|
22
22
|
SignatureDirectoryResolver: () => import_web_bot_auth.SignatureDirectoryResolver,
|
|
23
23
|
WEB_BOT_AUTH_DRAFT_REVISION: () => import_web_bot_auth.WEB_BOT_AUTH_DRAFT_REVISION,
|
|
24
24
|
WebBotAuthError: () => import_web_bot_auth.WebBotAuthError,
|
|
25
|
+
WebBotAuthUnavailableError: () => import_web_bot_auth.WebBotAuthUnavailableError,
|
|
25
26
|
createIdentity33Authorization: () => import_server.createIdentity33Authorization,
|
|
26
27
|
createIdentity33PrincipalResolver: () => import_server.createIdentity33PrincipalResolver,
|
|
27
28
|
createIdentity33PrincipalScopeResolver: () => import_server.createIdentity33PrincipalScopeResolver,
|
|
@@ -34,6 +35,7 @@ __export(identity_3_exports, {
|
|
|
34
35
|
selectSignatureProfile: () => import_web_bot_auth.selectSignatureProfile,
|
|
35
36
|
signWebBotAuth: () => import_web_bot_auth.signWebBotAuth,
|
|
36
37
|
validateIdentity33Payload: () => import_validation.validateIdentity33Payload,
|
|
38
|
+
verifyKeyDirectory: () => import_web_bot_auth.verifyKeyDirectory,
|
|
37
39
|
verifySignatureDirectory: () => import_web_bot_auth.verifySignatureDirectory,
|
|
38
40
|
verifyWebBotAuth: () => import_web_bot_auth.verifyWebBotAuth,
|
|
39
41
|
withIdentity33PrincipalHandlers: () => import_server.withIdentity33PrincipalHandlers
|
|
@@ -53,6 +55,7 @@ var import_webhook_registration = require('../core/webhook-registration.js');
|
|
|
53
55
|
SignatureDirectoryResolver,
|
|
54
56
|
WEB_BOT_AUTH_DRAFT_REVISION,
|
|
55
57
|
WebBotAuthError,
|
|
58
|
+
WebBotAuthUnavailableError,
|
|
56
59
|
createIdentity33Authorization,
|
|
57
60
|
createIdentity33PrincipalResolver,
|
|
58
61
|
createIdentity33PrincipalScopeResolver,
|
|
@@ -65,6 +68,7 @@ var import_webhook_registration = require('../core/webhook-registration.js');
|
|
|
65
68
|
selectSignatureProfile,
|
|
66
69
|
signWebBotAuth,
|
|
67
70
|
validateIdentity33Payload,
|
|
71
|
+
verifyKeyDirectory,
|
|
68
72
|
verifySignatureDirectory,
|
|
69
73
|
verifyWebBotAuth,
|
|
70
74
|
withIdentity33PrincipalHandlers,
|
|
@@ -10,9 +10,11 @@ import {
|
|
|
10
10
|
createSignedSignatureDirectory,
|
|
11
11
|
SignatureDirectoryResolver,
|
|
12
12
|
verifySignatureDirectory,
|
|
13
|
+
verifyKeyDirectory,
|
|
13
14
|
selectSignatureProfile,
|
|
14
15
|
jwkThumbprint,
|
|
15
|
-
WebBotAuthError
|
|
16
|
+
WebBotAuthError,
|
|
17
|
+
WebBotAuthUnavailableError
|
|
16
18
|
} from "../signing/web-bot-auth.mjs";
|
|
17
19
|
import { validateIdentity33Payload } from "./validation.mjs";
|
|
18
20
|
import {
|
|
@@ -28,6 +30,7 @@ export {
|
|
|
28
30
|
SignatureDirectoryResolver,
|
|
29
31
|
WEB_BOT_AUTH_DRAFT_REVISION,
|
|
30
32
|
WebBotAuthError,
|
|
33
|
+
WebBotAuthUnavailableError,
|
|
31
34
|
createIdentity33Authorization,
|
|
32
35
|
createIdentity33PrincipalResolver,
|
|
33
36
|
createIdentity33PrincipalScopeResolver,
|
|
@@ -40,6 +43,7 @@ export {
|
|
|
40
43
|
selectSignatureProfile,
|
|
41
44
|
signWebBotAuth,
|
|
42
45
|
validateIdentity33Payload,
|
|
46
|
+
verifyKeyDirectory,
|
|
43
47
|
verifySignatureDirectory,
|
|
44
48
|
verifyWebBotAuth,
|
|
45
49
|
withIdentity33PrincipalHandlers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PrincipalKind } from '../server/principal/types.mjs';
|
|
2
2
|
import { TrustEvaluator } from './trust.mjs';
|
|
3
|
-
import type { AgentOnboarding, AgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types.mjs';
|
|
3
|
+
import type { AgentOnboarding, AgentOnboardingRequirement, ObservedAgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types.mjs';
|
|
4
4
|
export interface OriginBinding {
|
|
5
5
|
origin: string;
|
|
6
6
|
operator: string;
|
|
@@ -47,10 +47,13 @@ export declare class InMemoryOriginIdentityStore implements OriginIdentityStore
|
|
|
47
47
|
getApplication(origin: string): Promise<IdentityApplication | undefined>;
|
|
48
48
|
compareAndSetApplication(origin: string, expectedRevision: number | undefined, application: IdentityApplication): Promise<boolean>;
|
|
49
49
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Wrong-direction gates are ignored; unknown gates remain unsatisfied. Accepts
|
|
52
|
+
* requirements read off the wire, whose `kind` may be one this SDK does not know.
|
|
53
|
+
*/
|
|
54
|
+
export declare function evaluateOnboardingRequirements<R extends ObservedAgentOnboardingRequirement = AgentOnboardingRequirement>(requirements: readonly R[], direction: 'seller' | 'buyer', check: (requirement: R) => Promise<boolean>): Promise<{
|
|
52
55
|
satisfied: boolean;
|
|
53
|
-
unsatisfied:
|
|
56
|
+
unsatisfied: R[];
|
|
54
57
|
}>;
|
|
55
58
|
export declare function validateAgentOnboarding(posture: AgentOnboarding, account: {
|
|
56
59
|
sandbox?: boolean;
|
|
@@ -93,7 +96,16 @@ export declare class OriginIdentityLifecycle {
|
|
|
93
96
|
migrationApproved?: boolean;
|
|
94
97
|
sharedOrigin?: boolean;
|
|
95
98
|
}): Promise<OriginBinding>;
|
|
96
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Cryptographic verification does not call this. Authorization revalidates
|
|
101
|
+
* delisting: the last record read does not list the origin (an empty
|
|
102
|
+
* `agents[]` retires it; a known delisting stays delisted through a failed
|
|
103
|
+
* refresh) and throws {@link TrustMembershipError}. An unreadable record
|
|
104
|
+
* (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
|
|
105
|
+
* read-only and identity-configuration calls continue under the binding only
|
|
106
|
+
* while the last record read listed the origin and is within the evaluator's
|
|
107
|
+
* `maxOutageContinuationSeconds`.
|
|
108
|
+
*/
|
|
97
109
|
authorizeBound(originUrl: string, access?: {
|
|
98
110
|
readOnly?: true;
|
|
99
111
|
identityConfiguration?: true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PrincipalKind } from '../server/principal/types';
|
|
2
2
|
import { TrustEvaluator } from './trust';
|
|
3
|
-
import type { AgentOnboarding, AgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types';
|
|
3
|
+
import type { AgentOnboarding, AgentOnboardingRequirement, ObservedAgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types';
|
|
4
4
|
export interface OriginBinding {
|
|
5
5
|
origin: string;
|
|
6
6
|
operator: string;
|
|
@@ -47,10 +47,13 @@ export declare class InMemoryOriginIdentityStore implements OriginIdentityStore
|
|
|
47
47
|
getApplication(origin: string): Promise<IdentityApplication | undefined>;
|
|
48
48
|
compareAndSetApplication(origin: string, expectedRevision: number | undefined, application: IdentityApplication): Promise<boolean>;
|
|
49
49
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Wrong-direction gates are ignored; unknown gates remain unsatisfied. Accepts
|
|
52
|
+
* requirements read off the wire, whose `kind` may be one this SDK does not know.
|
|
53
|
+
*/
|
|
54
|
+
export declare function evaluateOnboardingRequirements<R extends ObservedAgentOnboardingRequirement = AgentOnboardingRequirement>(requirements: readonly R[], direction: 'seller' | 'buyer', check: (requirement: R) => Promise<boolean>): Promise<{
|
|
52
55
|
satisfied: boolean;
|
|
53
|
-
unsatisfied:
|
|
56
|
+
unsatisfied: R[];
|
|
54
57
|
}>;
|
|
55
58
|
export declare function validateAgentOnboarding(posture: AgentOnboarding, account: {
|
|
56
59
|
sandbox?: boolean;
|
|
@@ -93,7 +96,16 @@ export declare class OriginIdentityLifecycle {
|
|
|
93
96
|
migrationApproved?: boolean;
|
|
94
97
|
sharedOrigin?: boolean;
|
|
95
98
|
}): Promise<OriginBinding>;
|
|
96
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Cryptographic verification does not call this. Authorization revalidates
|
|
101
|
+
* delisting: the last record read does not list the origin (an empty
|
|
102
|
+
* `agents[]` retires it; a known delisting stays delisted through a failed
|
|
103
|
+
* refresh) and throws {@link TrustMembershipError}. An unreadable record
|
|
104
|
+
* (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
|
|
105
|
+
* read-only and identity-configuration calls continue under the binding only
|
|
106
|
+
* while the last record read listed the origin and is within the evaluator's
|
|
107
|
+
* `maxOutageContinuationSeconds`.
|
|
108
|
+
*/
|
|
97
109
|
authorizeBound(originUrl: string, access?: {
|
|
98
110
|
readOnly?: true;
|
|
99
111
|
identityConfiguration?: true;
|
|
@@ -66,14 +66,20 @@ class InMemoryOriginIdentityStore {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
const BUYER_GATES = /* @__PURE__ */ new Set(["aao_verified", "storyboard", "sandbox", "experimental_feature"]);
|
|
69
|
-
const SELLER_GATES = /* @__PURE__ */ new Set([
|
|
69
|
+
const SELLER_GATES = /* @__PURE__ */ new Set([
|
|
70
|
+
"agent_identity",
|
|
71
|
+
"grant",
|
|
72
|
+
"billing_entity",
|
|
73
|
+
"contract",
|
|
74
|
+
"credit_application"
|
|
75
|
+
]);
|
|
70
76
|
async function evaluateOnboardingRequirements(requirements, direction, check) {
|
|
71
77
|
const relevant = direction === "seller" ? SELLER_GATES : BUYER_GATES;
|
|
72
78
|
const wrong = direction === "seller" ? BUYER_GATES : SELLER_GATES;
|
|
73
79
|
const unsatisfied = [];
|
|
74
80
|
for (const requirement of requirements) {
|
|
75
81
|
if (wrong.has(requirement.kind)) continue;
|
|
76
|
-
const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!requirement.specialisms?.length && !!requirement.adcp_version;
|
|
82
|
+
const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!(requirement.verified_specialisms ?? requirement.specialisms)?.length && !!requirement.adcp_version;
|
|
77
83
|
const hasId = !["storyboard", "experimental_feature"].includes(requirement.kind) || !!requirement.id;
|
|
78
84
|
if (!relevant.has(requirement.kind) || !wellFormed || !hasId || !await check(requirement))
|
|
79
85
|
unsatisfied.push(requirement);
|
|
@@ -126,13 +132,34 @@ class OriginIdentityLifecycle {
|
|
|
126
132
|
await this.options.store.bind(binding);
|
|
127
133
|
return binding;
|
|
128
134
|
}
|
|
129
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Cryptographic verification does not call this. Authorization revalidates
|
|
137
|
+
* delisting: the last record read does not list the origin (an empty
|
|
138
|
+
* `agents[]` retires it; a known delisting stays delisted through a failed
|
|
139
|
+
* refresh) and throws {@link TrustMembershipError}. An unreadable record
|
|
140
|
+
* (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
|
|
141
|
+
* read-only and identity-configuration calls continue under the binding only
|
|
142
|
+
* while the last record read listed the origin and is within the evaluator's
|
|
143
|
+
* `maxOutageContinuationSeconds`.
|
|
144
|
+
*/
|
|
130
145
|
async authorizeBound(originUrl, access) {
|
|
131
146
|
const origin = (0, import_canonicalize.canonicalAgentOrigin)(originUrl);
|
|
132
147
|
const binding = await this.options.store.getBinding(origin);
|
|
133
148
|
if (!binding) throw new import_trust.IdentityAuthorizationError();
|
|
134
|
-
|
|
135
|
-
|
|
149
|
+
try {
|
|
150
|
+
let trust;
|
|
151
|
+
try {
|
|
152
|
+
trust = await this.options.trust.match(origin, "adcp:buying");
|
|
153
|
+
} catch (error) {
|
|
154
|
+
if (error instanceof import_trust.TrustMembershipError && error.membership === "absent")
|
|
155
|
+
throw Object.assign(new import_trust.TrustRecordUnavailableError(), { cause: error });
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
if (binding.operator !== trust.operator) throw new import_trust.TrustMembershipError();
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (!(error instanceof import_trust.TrustRecordUnavailableError) || !error.lastKnownListed || !(access?.readOnly || access?.identityConfiguration))
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
136
163
|
const relationship = (await this.options.store.getApplication(origin))?.relationship;
|
|
137
164
|
if (!access?.readOnly && relationship && (relationship.status !== "active" || relationship.expires_at && Date.parse(relationship.expires_at) <= this.now() * 1e3))
|
|
138
165
|
throw new import_trust.IdentityAuthorizationError();
|
|
@@ -2,7 +2,12 @@ import { randomUUID } from "crypto";
|
|
|
2
2
|
import { parse as parseTld } from "tldts";
|
|
3
3
|
import { canonicalAgentOrigin } from "../signing/agent-resolver/canonicalize.mjs";
|
|
4
4
|
import { eTldPlusOne } from "../signing/agent-resolver/etld.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
IdentityAuthorizationError,
|
|
7
|
+
TrustMembershipError,
|
|
8
|
+
TrustRecordUnavailableError,
|
|
9
|
+
validateIdentity33Schema
|
|
10
|
+
} from "./trust.mjs";
|
|
6
11
|
class InMemoryOriginIdentityStore {
|
|
7
12
|
durability = "process-local";
|
|
8
13
|
bindings = /* @__PURE__ */ new Map();
|
|
@@ -40,14 +45,20 @@ class InMemoryOriginIdentityStore {
|
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
const BUYER_GATES = /* @__PURE__ */ new Set(["aao_verified", "storyboard", "sandbox", "experimental_feature"]);
|
|
43
|
-
const SELLER_GATES = /* @__PURE__ */ new Set([
|
|
48
|
+
const SELLER_GATES = /* @__PURE__ */ new Set([
|
|
49
|
+
"agent_identity",
|
|
50
|
+
"grant",
|
|
51
|
+
"billing_entity",
|
|
52
|
+
"contract",
|
|
53
|
+
"credit_application"
|
|
54
|
+
]);
|
|
44
55
|
async function evaluateOnboardingRequirements(requirements, direction, check) {
|
|
45
56
|
const relevant = direction === "seller" ? SELLER_GATES : BUYER_GATES;
|
|
46
57
|
const wrong = direction === "seller" ? BUYER_GATES : SELLER_GATES;
|
|
47
58
|
const unsatisfied = [];
|
|
48
59
|
for (const requirement of requirements) {
|
|
49
60
|
if (wrong.has(requirement.kind)) continue;
|
|
50
|
-
const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!requirement.specialisms?.length && !!requirement.adcp_version;
|
|
61
|
+
const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!(requirement.verified_specialisms ?? requirement.specialisms)?.length && !!requirement.adcp_version;
|
|
51
62
|
const hasId = !["storyboard", "experimental_feature"].includes(requirement.kind) || !!requirement.id;
|
|
52
63
|
if (!relevant.has(requirement.kind) || !wellFormed || !hasId || !await check(requirement))
|
|
53
64
|
unsatisfied.push(requirement);
|
|
@@ -100,13 +111,34 @@ class OriginIdentityLifecycle {
|
|
|
100
111
|
await this.options.store.bind(binding);
|
|
101
112
|
return binding;
|
|
102
113
|
}
|
|
103
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* Cryptographic verification does not call this. Authorization revalidates
|
|
116
|
+
* delisting: the last record read does not list the origin (an empty
|
|
117
|
+
* `agents[]` retires it; a known delisting stays delisted through a failed
|
|
118
|
+
* refresh) and throws {@link TrustMembershipError}. An unreadable record
|
|
119
|
+
* (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
|
|
120
|
+
* read-only and identity-configuration calls continue under the binding only
|
|
121
|
+
* while the last record read listed the origin and is within the evaluator's
|
|
122
|
+
* `maxOutageContinuationSeconds`.
|
|
123
|
+
*/
|
|
104
124
|
async authorizeBound(originUrl, access) {
|
|
105
125
|
const origin = canonicalAgentOrigin(originUrl);
|
|
106
126
|
const binding = await this.options.store.getBinding(origin);
|
|
107
127
|
if (!binding) throw new IdentityAuthorizationError();
|
|
108
|
-
|
|
109
|
-
|
|
128
|
+
try {
|
|
129
|
+
let trust;
|
|
130
|
+
try {
|
|
131
|
+
trust = await this.options.trust.match(origin, "adcp:buying");
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (error instanceof TrustMembershipError && error.membership === "absent")
|
|
134
|
+
throw Object.assign(new TrustRecordUnavailableError(), { cause: error });
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
if (binding.operator !== trust.operator) throw new TrustMembershipError();
|
|
138
|
+
} catch (error) {
|
|
139
|
+
if (!(error instanceof TrustRecordUnavailableError) || !error.lastKnownListed || !(access?.readOnly || access?.identityConfiguration))
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
110
142
|
const relationship = (await this.options.store.getApplication(origin))?.relationship;
|
|
111
143
|
if (!access?.readOnly && relationship && (relationship.status !== "active" || relationship.expires_at && Date.parse(relationship.expires_at) <= this.now() * 1e3))
|
|
112
144
|
throw new IdentityAuthorizationError();
|