@adcp/sdk 15.9.0 → 16.0.0-beta.1
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/bin/adcp-identity.js +74 -0
- package/bin/adcp.js +2 -0
- package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
- package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
- package/dist/lib/adapters/keyed-account-backend.js +121 -0
- package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
- package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
- package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
- package/dist/lib/adapters/keyed-account-store.js +227 -0
- package/dist/lib/adapters/keyed-account-store.mjs +203 -0
- package/dist/lib/core/SingleAgentClient.d.mts +16 -2
- package/dist/lib/core/SingleAgentClient.d.ts +16 -2
- package/dist/lib/core/SingleAgentClient.js +259 -62
- package/dist/lib/core/SingleAgentClient.mjs +261 -57
- package/dist/lib/core/TaskExecutor.d.mts +6 -0
- package/dist/lib/core/TaskExecutor.d.ts +6 -0
- package/dist/lib/core/TaskExecutor.js +66 -5
- package/dist/lib/core/TaskExecutor.mjs +71 -5
- package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
- package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
- package/dist/lib/core/redis-webhook-registration-store.js +23 -1
- package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
- package/dist/lib/core/webhook-registration.d.mts +7 -1
- package/dist/lib/core/webhook-registration.d.ts +7 -1
- package/dist/lib/core/webhook-registration.js +24 -2
- package/dist/lib/core/webhook-registration.mjs +23 -2
- package/dist/lib/identity-3.3/index.d.mts +10 -0
- package/dist/lib/identity-3.3/index.d.ts +10 -0
- package/dist/lib/identity-3.3/index.js +75 -0
- package/dist/lib/identity-3.3/index.mjs +46 -0
- package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
- package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
- package/dist/lib/identity-3.3/lifecycle.js +267 -0
- package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
- package/dist/lib/identity-3.3/revocation.d.mts +50 -0
- package/dist/lib/identity-3.3/revocation.d.ts +50 -0
- package/dist/lib/identity-3.3/revocation.js +238 -0
- package/dist/lib/identity-3.3/revocation.mjs +216 -0
- package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
- package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
- package/dist/lib/identity-3.3/server.d.mts +34 -0
- package/dist/lib/identity-3.3/server.d.ts +34 -0
- package/dist/lib/identity-3.3/server.js +219 -0
- package/dist/lib/identity-3.3/server.mjs +194 -0
- package/dist/lib/identity-3.3/store.d.mts +24 -0
- package/dist/lib/identity-3.3/store.d.ts +24 -0
- package/dist/lib/identity-3.3/store.js +191 -0
- package/dist/lib/identity-3.3/store.mjs +169 -0
- package/dist/lib/identity-3.3/trust.d.mts +94 -0
- package/dist/lib/identity-3.3/trust.d.ts +94 -0
- package/dist/lib/identity-3.3/trust.js +278 -0
- package/dist/lib/identity-3.3/trust.mjs +239 -0
- package/dist/lib/identity-3.3/types.d.mts +127 -0
- package/dist/lib/identity-3.3/types.d.ts +127 -0
- package/dist/lib/identity-3.3/types.js +16 -0
- package/dist/lib/identity-3.3/types.mjs +0 -0
- package/dist/lib/identity-3.3/validation.d.mts +2 -0
- package/dist/lib/identity-3.3/validation.d.ts +2 -0
- package/dist/lib/identity-3.3/validation.js +125 -0
- package/dist/lib/identity-3.3/validation.mjs +91 -0
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/reporting/azure/index.d.mts +5 -0
- package/dist/lib/reporting/azure/index.d.ts +5 -0
- package/dist/lib/reporting/azure/index.js +26 -7
- package/dist/lib/reporting/azure/index.mjs +26 -7
- package/dist/lib/reporting/bigquery/index.d.mts +80 -25
- package/dist/lib/reporting/bigquery/index.d.ts +80 -25
- package/dist/lib/reporting/bigquery/index.js +184 -81
- package/dist/lib/reporting/bigquery/index.mjs +182 -80
- package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
- package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
- package/dist/lib/reporting/gcs/errors.d.mts +6 -0
- package/dist/lib/reporting/gcs/errors.d.ts +6 -0
- package/dist/lib/reporting/gcs/fence.d.mts +5 -0
- package/dist/lib/reporting/gcs/fence.d.ts +5 -0
- package/dist/lib/reporting/gcs/index.d.mts +9 -0
- package/dist/lib/reporting/gcs/index.d.ts +9 -0
- package/dist/lib/reporting/gcs/reader.d.mts +27 -3
- package/dist/lib/reporting/gcs/reader.d.ts +27 -3
- package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
- package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
- package/dist/lib/reporting/gcs/row-provider.js +34 -14
- package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
- package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
- package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
- package/dist/lib/reporting/ledger/index.d.mts +11 -0
- package/dist/lib/reporting/ledger/index.d.ts +11 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
- package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
- package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
- package/dist/lib/reporting/ledger/managed.d.mts +86 -6
- package/dist/lib/reporting/ledger/managed.d.ts +86 -6
- package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
- package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
- package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
- package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
- package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
- package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
- package/dist/lib/reporting/ledger/postgres.js +43 -27
- package/dist/lib/reporting/ledger/postgres.mjs +43 -27
- package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.js +8 -4
- package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
- package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
- package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
- package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
- package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
- package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
- package/dist/lib/reporting/ledger/row-storage.js +126 -66
- package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
- package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
- package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
- package/dist/lib/reporting/ledger/schedule.js +24 -0
- package/dist/lib/reporting/ledger/schedule.mjs +23 -0
- package/dist/lib/reporting/ledger/types.d.mts +23 -1
- package/dist/lib/reporting/ledger/types.d.ts +23 -1
- package/dist/lib/reporting/s3/index.d.mts +5 -0
- package/dist/lib/reporting/s3/index.d.ts +5 -0
- package/dist/lib/reporting/s3/index.js +37 -14
- package/dist/lib/reporting/s3/index.mjs +37 -14
- package/dist/lib/reporting/service/index.d.mts +10 -0
- package/dist/lib/reporting/service/index.d.ts +10 -0
- package/dist/lib/reporting/service/maintenance.d.mts +28 -2
- package/dist/lib/reporting/service/maintenance.d.ts +28 -2
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-sync-contract.d.mts +14 -0
- package/dist/lib/server/account-sync-contract.d.ts +14 -0
- package/dist/lib/server/account-sync-contract.js +225 -0
- package/dist/lib/server/account-sync-contract.mjs +197 -0
- package/dist/lib/server/adcp-server.js +5 -0
- package/dist/lib/server/adcp-server.mjs +10 -0
- package/dist/lib/server/auth-signature.d.mts +10 -0
- package/dist/lib/server/auth-signature.d.ts +10 -0
- package/dist/lib/server/auth-signature.js +61 -2
- package/dist/lib/server/auth-signature.mjs +65 -2
- package/dist/lib/server/auth.d.mts +6 -0
- package/dist/lib/server/auth.d.ts +6 -0
- package/dist/lib/server/auth.js +6 -0
- package/dist/lib/server/auth.mjs +6 -0
- package/dist/lib/server/create-adcp-server.d.mts +19 -5
- package/dist/lib/server/create-adcp-server.d.ts +19 -5
- package/dist/lib/server/create-adcp-server.js +238 -19
- package/dist/lib/server/create-adcp-server.mjs +240 -10
- package/dist/lib/server/decisioning/account.d.mts +24 -1
- package/dist/lib/server/decisioning/account.d.ts +24 -1
- package/dist/lib/server/decisioning/index.d.mts +1 -1
- package/dist/lib/server/decisioning/index.d.ts +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
- package/dist/lib/server/index.d.mts +2 -0
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.js +12 -0
- package/dist/lib/server/index.mjs +12 -0
- package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
- package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
- package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
- package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
- package/dist/lib/server/principal/types.d.mts +1 -1
- package/dist/lib/server/principal/types.d.ts +1 -1
- package/dist/lib/server/serve.js +5 -0
- package/dist/lib/server/serve.mjs +5 -0
- package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.js +4 -0
- package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
- package/dist/lib/server/webhook-emitter.d.mts +10 -0
- package/dist/lib/server/webhook-emitter.d.ts +10 -0
- package/dist/lib/server/webhook-emitter.js +22 -0
- package/dist/lib/server/webhook-emitter.mjs +22 -0
- package/dist/lib/signing/agent-context.d.mts +0 -5
- package/dist/lib/signing/agent-context.d.ts +0 -5
- package/dist/lib/signing/agent-context.js +9 -1
- package/dist/lib/signing/agent-context.mjs +9 -1
- package/dist/lib/signing/agent-fetch.js +27 -2
- package/dist/lib/signing/agent-fetch.mjs +32 -2
- package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
- package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
- package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
- package/dist/lib/signing/agent-resolver/index.js +5 -0
- package/dist/lib/signing/agent-resolver/index.mjs +3 -0
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
- package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
- package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
- package/dist/lib/signing/brand-jwks.d.mts +2 -2
- package/dist/lib/signing/brand-jwks.d.ts +2 -2
- package/dist/lib/signing/brand-jwks.js +4 -4
- package/dist/lib/signing/brand-jwks.mjs +4 -4
- package/dist/lib/signing/client.d.mts +1 -0
- package/dist/lib/signing/client.d.ts +1 -0
- package/dist/lib/signing/client.js +5 -0
- package/dist/lib/signing/client.mjs +3 -0
- package/dist/lib/signing/jwks-https.d.mts +1 -1
- package/dist/lib/signing/jwks-https.d.ts +1 -1
- package/dist/lib/signing/jwks-https.js +1 -1
- package/dist/lib/signing/jwks-https.mjs +1 -1
- package/dist/lib/signing/jwks.d.mts +11 -3
- package/dist/lib/signing/jwks.d.ts +11 -3
- package/dist/lib/signing/jwks.js +1 -1
- package/dist/lib/signing/jwks.mjs +1 -1
- package/dist/lib/signing/parser.d.mts +1 -1
- package/dist/lib/signing/parser.d.ts +1 -1
- package/dist/lib/signing/parser.js +5 -3
- package/dist/lib/signing/parser.mjs +6 -4
- package/dist/lib/signing/revocation.d.mts +4 -1
- package/dist/lib/signing/revocation.d.ts +4 -1
- package/dist/lib/signing/revocation.js +33 -3
- package/dist/lib/signing/revocation.mjs +31 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +4 -0
- package/dist/lib/signing/server.mjs +4 -0
- package/dist/lib/signing/types.d.mts +3 -0
- package/dist/lib/signing/types.d.ts +3 -0
- package/dist/lib/signing/web-bot-auth.d.mts +117 -0
- package/dist/lib/signing/web-bot-auth.d.ts +117 -0
- package/dist/lib/signing/web-bot-auth.js +660 -0
- package/dist/lib/signing/web-bot-auth.mjs +624 -0
- package/dist/lib/testing/client.d.mts +1 -4
- package/dist/lib/testing/client.d.ts +1 -4
- package/dist/lib/testing/client.js +141 -20
- package/dist/lib/testing/client.mjs +137 -19
- package/dist/lib/testing/compliance/comply.js +29 -10
- package/dist/lib/testing/compliance/comply.mjs +37 -11
- package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
- package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
- package/dist/lib/testing/storyboard/default-invariants.js +2 -0
- package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
- package/dist/lib/testing/storyboard/runner.js +23 -8
- package/dist/lib/testing/storyboard/runner.mjs +24 -8
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/adcp.d.mts +4 -0
- package/dist/lib/types/adcp.d.ts +4 -0
- package/dist/lib/types/schemas.generated.d.ts +6 -6
- package/dist/lib/utils/capabilities.d.mts +1 -0
- package/dist/lib/utils/capabilities.d.ts +1 -0
- package/dist/lib/utils/capabilities.js +5 -0
- package/dist/lib/utils/capabilities.mjs +5 -0
- package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
- package/dist/lib/v2/projection/creative-delivery.js +26 -10
- package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
- 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/legacy-routes.d.mts +24 -2
- package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
- package/dist/lib/v2/projection/legacy-routes.js +28 -2
- package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
- package/dist/lib/validation/schema-loader.d.mts +2 -0
- package/dist/lib/validation/schema-loader.d.ts +2 -0
- package/dist/lib/validation/schema-loader.js +43 -4
- package/dist/lib/validation/schema-loader.mjs +39 -3
- 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/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
- package/docs/guides/REPORTING-LEDGER.md +132 -46
- package/docs/guides/REPORTING-OPERATIONS.md +25 -4
- package/docs/guides/REPORTING-STABILITY.md +76 -0
- package/docs/guides/account-resolution.md +101 -0
- package/docs/llms.txt +3 -2
- package/docs/migration-12-to-13.md +7 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +355 -0
- package/docs/migration-agent-resolution-3.3.md +5 -0
- package/docs/migration-reporting-row-storage-alignment.md +137 -0
- package/examples/storyboards/account-sync-contract.yaml +57 -0
- package/package.json +15 -1
|
@@ -0,0 +1,238 @@
|
|
|
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 revocation_exports = {};
|
|
20
|
+
__export(revocation_exports, {
|
|
21
|
+
InMemoryOriginRevocationStore: () => InMemoryOriginRevocationStore,
|
|
22
|
+
OriginRevocationResolver: () => OriginRevocationResolver,
|
|
23
|
+
createSignedOriginRevocationList: () => createSignedOriginRevocationList,
|
|
24
|
+
mergeRevocationDetail: () => import_revocation.mergeRevocationDetails
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(revocation_exports);
|
|
27
|
+
var import_etld = require('../signing/agent-resolver/etld.js');
|
|
28
|
+
var import_jose = require("jose");
|
|
29
|
+
var import_net = require('../net/index.js');
|
|
30
|
+
var import_canonicalize = require('../signing/agent-resolver/canonicalize.js');
|
|
31
|
+
var import_strict_json = require('../signing/agent-resolver/strict-json.js');
|
|
32
|
+
var import_web_bot_auth = require('../signing/web-bot-auth.js');
|
|
33
|
+
var import_revocation = require('../signing/revocation.js');
|
|
34
|
+
var import_revocation2 = require('../signing/revocation.js');
|
|
35
|
+
const REASONS = [
|
|
36
|
+
"removeFromCRL",
|
|
37
|
+
"unspecified",
|
|
38
|
+
"superseded",
|
|
39
|
+
"cessationOfOperation",
|
|
40
|
+
"affiliationChanged",
|
|
41
|
+
"certificateHold",
|
|
42
|
+
"privilegeWithdrawn",
|
|
43
|
+
"aACompromise",
|
|
44
|
+
"cACompromise",
|
|
45
|
+
"keyCompromise"
|
|
46
|
+
];
|
|
47
|
+
class InMemoryOriginRevocationStore {
|
|
48
|
+
constructor(limits = { perOrigin: 16384, total: 1e5 }) {
|
|
49
|
+
this.limits = limits;
|
|
50
|
+
}
|
|
51
|
+
limits;
|
|
52
|
+
durability = "process-local";
|
|
53
|
+
revoked = /* @__PURE__ */ new Map();
|
|
54
|
+
async merge(origin, snapshot) {
|
|
55
|
+
origin = (0, import_canonicalize.canonicalAgentOrigin)(origin);
|
|
56
|
+
const additions = new Set(snapshot.revoked_kids.filter((kid) => !this.revoked.has(JSON.stringify([origin, kid]))));
|
|
57
|
+
const count = [...this.revoked.keys()].filter((key) => JSON.parse(key)[0] === origin).length;
|
|
58
|
+
if (count + additions.size > this.limits.perOrigin || this.revoked.size + additions.size > this.limits.total)
|
|
59
|
+
throw new import_web_bot_auth.WebBotAuthError(403, "revocation_storage_limit");
|
|
60
|
+
for (const kid of snapshot.revoked_kids) {
|
|
61
|
+
const key = JSON.stringify([origin, kid]), prior = this.revoked.get(key), detail = snapshot.revocation_details?.[kid] ?? {};
|
|
62
|
+
this.revoked.set(key, (0, import_revocation2.mergeRevocationDetails)(prior, detail));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async get(origin, keyid) {
|
|
66
|
+
const entry = this.revoked.get(JSON.stringify([(0, import_canonicalize.canonicalAgentOrigin)(origin), keyid]));
|
|
67
|
+
return entry && { ...entry };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class OriginRevocationResolver {
|
|
71
|
+
constructor(options) {
|
|
72
|
+
this.options = options;
|
|
73
|
+
if (!(options.directory instanceof import_web_bot_auth.SignatureDirectoryResolver))
|
|
74
|
+
throw new TypeError("Origin revocation requires a verified SignatureDirectoryResolver");
|
|
75
|
+
if (!Number.isFinite(options.pollingIntervalSeconds ?? 300) || (options.pollingIntervalSeconds ?? 300) < 60 || (options.pollingIntervalSeconds ?? 300) > 1800)
|
|
76
|
+
throw new TypeError("Invalid revocation polling interval");
|
|
77
|
+
}
|
|
78
|
+
options;
|
|
79
|
+
freshness = /* @__PURE__ */ new Map();
|
|
80
|
+
updated = /* @__PURE__ */ new Map();
|
|
81
|
+
graceUntil = /* @__PURE__ */ new Map();
|
|
82
|
+
pending = /* @__PURE__ */ new Map();
|
|
83
|
+
failures = /* @__PURE__ */ new Map();
|
|
84
|
+
persistenceFailures = /* @__PURE__ */ new Set();
|
|
85
|
+
async isRevoked(originUrl, keyid) {
|
|
86
|
+
const origin = (0, import_canonicalize.canonicalAgentOrigin)(originUrl), now = this.now();
|
|
87
|
+
if (await this.readStored(origin, keyid)) return true;
|
|
88
|
+
if ((this.freshness.get(origin) ?? 0) <= now) {
|
|
89
|
+
if ((this.failures.get(origin) ?? 0) > now) {
|
|
90
|
+
if (this.persistenceFailures.has(origin)) throw new import_web_bot_auth.WebBotAuthError(403, "revocation_persistence_failed");
|
|
91
|
+
if ((this.graceUntil.get(origin) ?? 0) > now) return false;
|
|
92
|
+
throw new import_web_bot_auth.WebBotAuthError(403, "revocation_unavailable");
|
|
93
|
+
}
|
|
94
|
+
let promise = this.pending.get(origin);
|
|
95
|
+
if (!promise) {
|
|
96
|
+
if (this.pending.size >= 16 || [...this.pending.keys()].filter((pendingOrigin) => (0, import_etld.eTldPlusOne)(pendingOrigin) === (0, import_etld.eTldPlusOne)(origin)).length >= 2) {
|
|
97
|
+
throw new import_web_bot_auth.WebBotAuthError(403, "revocation_unavailable");
|
|
98
|
+
}
|
|
99
|
+
promise = this.refresh(origin).catch((error) => {
|
|
100
|
+
if (this.failures.size >= (this.options.maxOrigins ?? 1e3)) {
|
|
101
|
+
const oldest = this.failures.keys().next().value;
|
|
102
|
+
this.failures.delete(oldest);
|
|
103
|
+
this.persistenceFailures.delete(oldest);
|
|
104
|
+
}
|
|
105
|
+
this.failures.set(origin, now + 60);
|
|
106
|
+
if (error instanceof import_web_bot_auth.WebBotAuthError && error.reason === "revocation_persistence_failed") {
|
|
107
|
+
this.persistenceFailures.add(origin);
|
|
108
|
+
this.graceUntil.delete(origin);
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
});
|
|
112
|
+
this.pending.set(origin, promise);
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
await promise;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error instanceof import_web_bot_auth.WebBotAuthError && error.reason === "revocation_persistence_failed") throw error;
|
|
118
|
+
if ((this.graceUntil.get(origin) ?? 0) <= now) throw error;
|
|
119
|
+
} finally {
|
|
120
|
+
if (this.pending.get(origin) === promise) this.pending.delete(origin);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return !!await this.readStored(origin, keyid);
|
|
124
|
+
}
|
|
125
|
+
async readStored(origin, keyid) {
|
|
126
|
+
try {
|
|
127
|
+
return await this.options.store.get(origin, keyid);
|
|
128
|
+
} catch (cause) {
|
|
129
|
+
const error = new import_web_bot_auth.WebBotAuthError(403, "revocation_persistence_failed");
|
|
130
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async refresh(origin) {
|
|
135
|
+
try {
|
|
136
|
+
const response = await (0, import_net.ssrfSafeFetch)(origin + "/.well-known/governance-revocations.json", {
|
|
137
|
+
...this.options.fetchOptions,
|
|
138
|
+
maxBodyBytes: 256 * 1024,
|
|
139
|
+
timeoutMs: 1e4
|
|
140
|
+
});
|
|
141
|
+
if (response.status !== 200) throw new Error("Unavailable revocation list");
|
|
142
|
+
const body = new TextDecoder("utf-8", { fatal: true }).decode(response.body);
|
|
143
|
+
let tokens;
|
|
144
|
+
if (body.trim().startsWith("{")) {
|
|
145
|
+
const envelope = (0, import_strict_json.parseStrictJson)(body, 32);
|
|
146
|
+
if (typeof envelope.jws === "string") tokens = [envelope.jws];
|
|
147
|
+
else {
|
|
148
|
+
if ("header" in envelope) throw new Error("Revocation metadata must be protected");
|
|
149
|
+
const signatures = envelope.signatures ?? (envelope.protected && envelope.signature ? [{ protected: envelope.protected, signature: envelope.signature }] : []);
|
|
150
|
+
if (typeof envelope.payload !== "string" || !Array.isArray(signatures) || !signatures.length || signatures.length > 64)
|
|
151
|
+
throw new Error("Invalid JWS revocation envelope");
|
|
152
|
+
tokens = signatures.map((signature) => {
|
|
153
|
+
if (typeof signature.protected !== "string" || typeof signature.signature !== "string" || signature.header !== void 0)
|
|
154
|
+
throw new Error("Revocation metadata must be protected");
|
|
155
|
+
return `${signature.protected}.${envelope.payload}.${signature.signature}`;
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
} else tokens = [body.trim()];
|
|
159
|
+
let verifiedPayload;
|
|
160
|
+
for (const token of tokens) {
|
|
161
|
+
try {
|
|
162
|
+
const header = (0, import_jose.decodeProtectedHeader)(token);
|
|
163
|
+
if (header.typ !== "adcp-gov-revocation+jws" || typeof header.kid !== "string" || typeof header.alg !== "string" || !["EdDSA", "ES256"].includes(header.alg))
|
|
164
|
+
continue;
|
|
165
|
+
await this.options.directory.resolve(header.kid, origin);
|
|
166
|
+
const proof = this.options.directory.getAuditProof(origin);
|
|
167
|
+
if (!proof || new URL(proof.request.url).origin !== origin) continue;
|
|
168
|
+
const checked = (0, import_web_bot_auth.verifySignatureDirectory)(proof, this.now(), this.options.directory.allowsTestKeys);
|
|
169
|
+
const jwk = checked.keys.find((key) => key.kid === header.kid);
|
|
170
|
+
if (!jwk) continue;
|
|
171
|
+
const result = await (0, import_jose.compactVerify)(token, await (0, import_jose.importJWK)(jwk, header.alg), {
|
|
172
|
+
algorithms: ["EdDSA", "ES256"]
|
|
173
|
+
});
|
|
174
|
+
verifiedPayload = result.payload;
|
|
175
|
+
break;
|
|
176
|
+
} catch {
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (!verifiedPayload) throw new Error("No valid protected revocation signature");
|
|
180
|
+
const snapshot = (0, import_strict_json.parseStrictJson)(
|
|
181
|
+
new TextDecoder("utf-8", { fatal: true }).decode(verifiedPayload),
|
|
182
|
+
32
|
|
183
|
+
);
|
|
184
|
+
const updated = Date.parse(snapshot.updated) / 1e3, next = Date.parse(snapshot.next_update) / 1e3, now = this.now();
|
|
185
|
+
if (snapshot.issuer !== origin || !Number.isFinite(updated) || !Number.isFinite(next) || updated > now || next <= now || next <= updated || next > now + 1800 || !Array.isArray(snapshot.revoked_kids) || snapshot.revoked_kids.length > 4096 || snapshot.revoked_kids.some((k) => typeof k !== "string" || k.length > 256) || updated < (this.updated.get(origin) ?? 0))
|
|
186
|
+
throw new Error("Invalid revocation snapshot");
|
|
187
|
+
for (const [kid, detail] of Object.entries(snapshot.revocation_details ?? {}))
|
|
188
|
+
if (!snapshot.revoked_kids.includes(kid) || !detail || detail.reason && !REASONS.includes(detail.reason) || detail.invalidity_date && !Number.isFinite(Date.parse(detail.invalidity_date)))
|
|
189
|
+
throw new Error("Invalid revocation detail");
|
|
190
|
+
try {
|
|
191
|
+
await this.options.store.merge(origin, snapshot);
|
|
192
|
+
} catch (cause) {
|
|
193
|
+
const error = new import_web_bot_auth.WebBotAuthError(403, "revocation_persistence_failed");
|
|
194
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
if (!this.freshness.has(origin) && this.freshness.size >= (this.options.maxOrigins ?? 1e3)) {
|
|
198
|
+
const oldest = this.freshness.keys().next().value;
|
|
199
|
+
this.freshness.delete(oldest);
|
|
200
|
+
this.updated.delete(oldest);
|
|
201
|
+
this.graceUntil.delete(oldest);
|
|
202
|
+
}
|
|
203
|
+
this.graceUntil.set(origin, next + 4 * (this.options.pollingIntervalSeconds ?? 300));
|
|
204
|
+
this.updated.set(origin, updated);
|
|
205
|
+
this.freshness.set(origin, Math.min(next, now + (this.options.pollingIntervalSeconds ?? 300)));
|
|
206
|
+
this.failures.delete(origin);
|
|
207
|
+
this.persistenceFailures.delete(origin);
|
|
208
|
+
} catch (cause) {
|
|
209
|
+
if (cause instanceof import_web_bot_auth.WebBotAuthError && cause.reason === "revocation_persistence_failed") throw cause;
|
|
210
|
+
const error = new import_web_bot_auth.WebBotAuthError(403, "revocation_unavailable");
|
|
211
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
now() {
|
|
216
|
+
const now = (this.options.now ?? (() => Date.now() / 1e3))();
|
|
217
|
+
if (!Number.isFinite(now)) throw new import_web_bot_auth.WebBotAuthError(403, "revocation_unavailable");
|
|
218
|
+
return now;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async function createSignedOriginRevocationList(snapshot, privateKey) {
|
|
222
|
+
const issuer = (0, import_canonicalize.canonicalAgentOrigin)(snapshot.issuer), now = Date.now() / 1e3;
|
|
223
|
+
if (issuer !== snapshot.issuer || !Number.isFinite(Date.parse(snapshot.updated)) || !Number.isFinite(Date.parse(snapshot.next_update)) || Date.parse(snapshot.updated) / 1e3 > now || Date.parse(snapshot.next_update) / 1e3 <= now || Date.parse(snapshot.next_update) / 1e3 > now + 1800 || !Array.isArray(snapshot.revoked_kids))
|
|
224
|
+
throw new TypeError("Invalid origin revocation snapshot");
|
|
225
|
+
const kid = (0, import_web_bot_auth.jwkThumbprint)(privateKey);
|
|
226
|
+
if (privateKey.kid && privateKey.kid !== kid)
|
|
227
|
+
throw new TypeError("Revocation signing kid must be the JWK thumbprint");
|
|
228
|
+
const alg = privateKey.crv === "Ed25519" ? "EdDSA" : privateKey.crv === "P-256" ? "ES256" : void 0;
|
|
229
|
+
if (!alg || !privateKey.d) throw new TypeError("Revocations require a private Ed25519 or P-256 key");
|
|
230
|
+
return new import_jose.CompactSign(Buffer.from(JSON.stringify(snapshot))).setProtectedHeader({ alg, kid, typ: "adcp-gov-revocation+jws" }).sign(await (0, import_jose.importJWK)(privateKey, alg));
|
|
231
|
+
}
|
|
232
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
233
|
+
0 && (module.exports = {
|
|
234
|
+
InMemoryOriginRevocationStore,
|
|
235
|
+
OriginRevocationResolver,
|
|
236
|
+
createSignedOriginRevocationList,
|
|
237
|
+
mergeRevocationDetail
|
|
238
|
+
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { eTldPlusOne } from "../signing/agent-resolver/etld.mjs";
|
|
2
|
+
import { CompactSign, compactVerify, decodeProtectedHeader, importJWK } from "jose";
|
|
3
|
+
import { ssrfSafeFetch } from "../net/index.mjs";
|
|
4
|
+
import { canonicalAgentOrigin } from "../signing/agent-resolver/canonicalize.mjs";
|
|
5
|
+
import { parseStrictJson } from "../signing/agent-resolver/strict-json.mjs";
|
|
6
|
+
import {
|
|
7
|
+
SignatureDirectoryResolver,
|
|
8
|
+
WebBotAuthError,
|
|
9
|
+
verifySignatureDirectory,
|
|
10
|
+
jwkThumbprint
|
|
11
|
+
} from "../signing/web-bot-auth.mjs";
|
|
12
|
+
const REASONS = [
|
|
13
|
+
"removeFromCRL",
|
|
14
|
+
"unspecified",
|
|
15
|
+
"superseded",
|
|
16
|
+
"cessationOfOperation",
|
|
17
|
+
"affiliationChanged",
|
|
18
|
+
"certificateHold",
|
|
19
|
+
"privilegeWithdrawn",
|
|
20
|
+
"aACompromise",
|
|
21
|
+
"cACompromise",
|
|
22
|
+
"keyCompromise"
|
|
23
|
+
];
|
|
24
|
+
import { mergeRevocationDetails } from "../signing/revocation.mjs";
|
|
25
|
+
import { mergeRevocationDetails as mergeRevocationDetail } from "../signing/revocation.mjs";
|
|
26
|
+
class InMemoryOriginRevocationStore {
|
|
27
|
+
constructor(limits = { perOrigin: 16384, total: 1e5 }) {
|
|
28
|
+
this.limits = limits;
|
|
29
|
+
}
|
|
30
|
+
limits;
|
|
31
|
+
durability = "process-local";
|
|
32
|
+
revoked = /* @__PURE__ */ new Map();
|
|
33
|
+
async merge(origin, snapshot) {
|
|
34
|
+
origin = canonicalAgentOrigin(origin);
|
|
35
|
+
const additions = new Set(snapshot.revoked_kids.filter((kid) => !this.revoked.has(JSON.stringify([origin, kid]))));
|
|
36
|
+
const count = [...this.revoked.keys()].filter((key) => JSON.parse(key)[0] === origin).length;
|
|
37
|
+
if (count + additions.size > this.limits.perOrigin || this.revoked.size + additions.size > this.limits.total)
|
|
38
|
+
throw new WebBotAuthError(403, "revocation_storage_limit");
|
|
39
|
+
for (const kid of snapshot.revoked_kids) {
|
|
40
|
+
const key = JSON.stringify([origin, kid]), prior = this.revoked.get(key), detail = snapshot.revocation_details?.[kid] ?? {};
|
|
41
|
+
this.revoked.set(key, mergeRevocationDetail(prior, detail));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async get(origin, keyid) {
|
|
45
|
+
const entry = this.revoked.get(JSON.stringify([canonicalAgentOrigin(origin), keyid]));
|
|
46
|
+
return entry && { ...entry };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
class OriginRevocationResolver {
|
|
50
|
+
constructor(options) {
|
|
51
|
+
this.options = options;
|
|
52
|
+
if (!(options.directory instanceof SignatureDirectoryResolver))
|
|
53
|
+
throw new TypeError("Origin revocation requires a verified SignatureDirectoryResolver");
|
|
54
|
+
if (!Number.isFinite(options.pollingIntervalSeconds ?? 300) || (options.pollingIntervalSeconds ?? 300) < 60 || (options.pollingIntervalSeconds ?? 300) > 1800)
|
|
55
|
+
throw new TypeError("Invalid revocation polling interval");
|
|
56
|
+
}
|
|
57
|
+
options;
|
|
58
|
+
freshness = /* @__PURE__ */ new Map();
|
|
59
|
+
updated = /* @__PURE__ */ new Map();
|
|
60
|
+
graceUntil = /* @__PURE__ */ new Map();
|
|
61
|
+
pending = /* @__PURE__ */ new Map();
|
|
62
|
+
failures = /* @__PURE__ */ new Map();
|
|
63
|
+
persistenceFailures = /* @__PURE__ */ new Set();
|
|
64
|
+
async isRevoked(originUrl, keyid) {
|
|
65
|
+
const origin = canonicalAgentOrigin(originUrl), now = this.now();
|
|
66
|
+
if (await this.readStored(origin, keyid)) return true;
|
|
67
|
+
if ((this.freshness.get(origin) ?? 0) <= now) {
|
|
68
|
+
if ((this.failures.get(origin) ?? 0) > now) {
|
|
69
|
+
if (this.persistenceFailures.has(origin)) throw new WebBotAuthError(403, "revocation_persistence_failed");
|
|
70
|
+
if ((this.graceUntil.get(origin) ?? 0) > now) return false;
|
|
71
|
+
throw new WebBotAuthError(403, "revocation_unavailable");
|
|
72
|
+
}
|
|
73
|
+
let promise = this.pending.get(origin);
|
|
74
|
+
if (!promise) {
|
|
75
|
+
if (this.pending.size >= 16 || [...this.pending.keys()].filter((pendingOrigin) => eTldPlusOne(pendingOrigin) === eTldPlusOne(origin)).length >= 2) {
|
|
76
|
+
throw new WebBotAuthError(403, "revocation_unavailable");
|
|
77
|
+
}
|
|
78
|
+
promise = this.refresh(origin).catch((error) => {
|
|
79
|
+
if (this.failures.size >= (this.options.maxOrigins ?? 1e3)) {
|
|
80
|
+
const oldest = this.failures.keys().next().value;
|
|
81
|
+
this.failures.delete(oldest);
|
|
82
|
+
this.persistenceFailures.delete(oldest);
|
|
83
|
+
}
|
|
84
|
+
this.failures.set(origin, now + 60);
|
|
85
|
+
if (error instanceof WebBotAuthError && error.reason === "revocation_persistence_failed") {
|
|
86
|
+
this.persistenceFailures.add(origin);
|
|
87
|
+
this.graceUntil.delete(origin);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
});
|
|
91
|
+
this.pending.set(origin, promise);
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await promise;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (error instanceof WebBotAuthError && error.reason === "revocation_persistence_failed") throw error;
|
|
97
|
+
if ((this.graceUntil.get(origin) ?? 0) <= now) throw error;
|
|
98
|
+
} finally {
|
|
99
|
+
if (this.pending.get(origin) === promise) this.pending.delete(origin);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return !!await this.readStored(origin, keyid);
|
|
103
|
+
}
|
|
104
|
+
async readStored(origin, keyid) {
|
|
105
|
+
try {
|
|
106
|
+
return await this.options.store.get(origin, keyid);
|
|
107
|
+
} catch (cause) {
|
|
108
|
+
const error = new WebBotAuthError(403, "revocation_persistence_failed");
|
|
109
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async refresh(origin) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await ssrfSafeFetch(origin + "/.well-known/governance-revocations.json", {
|
|
116
|
+
...this.options.fetchOptions,
|
|
117
|
+
maxBodyBytes: 256 * 1024,
|
|
118
|
+
timeoutMs: 1e4
|
|
119
|
+
});
|
|
120
|
+
if (response.status !== 200) throw new Error("Unavailable revocation list");
|
|
121
|
+
const body = new TextDecoder("utf-8", { fatal: true }).decode(response.body);
|
|
122
|
+
let tokens;
|
|
123
|
+
if (body.trim().startsWith("{")) {
|
|
124
|
+
const envelope = parseStrictJson(body, 32);
|
|
125
|
+
if (typeof envelope.jws === "string") tokens = [envelope.jws];
|
|
126
|
+
else {
|
|
127
|
+
if ("header" in envelope) throw new Error("Revocation metadata must be protected");
|
|
128
|
+
const signatures = envelope.signatures ?? (envelope.protected && envelope.signature ? [{ protected: envelope.protected, signature: envelope.signature }] : []);
|
|
129
|
+
if (typeof envelope.payload !== "string" || !Array.isArray(signatures) || !signatures.length || signatures.length > 64)
|
|
130
|
+
throw new Error("Invalid JWS revocation envelope");
|
|
131
|
+
tokens = signatures.map((signature) => {
|
|
132
|
+
if (typeof signature.protected !== "string" || typeof signature.signature !== "string" || signature.header !== void 0)
|
|
133
|
+
throw new Error("Revocation metadata must be protected");
|
|
134
|
+
return `${signature.protected}.${envelope.payload}.${signature.signature}`;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
} else tokens = [body.trim()];
|
|
138
|
+
let verifiedPayload;
|
|
139
|
+
for (const token of tokens) {
|
|
140
|
+
try {
|
|
141
|
+
const header = decodeProtectedHeader(token);
|
|
142
|
+
if (header.typ !== "adcp-gov-revocation+jws" || typeof header.kid !== "string" || typeof header.alg !== "string" || !["EdDSA", "ES256"].includes(header.alg))
|
|
143
|
+
continue;
|
|
144
|
+
await this.options.directory.resolve(header.kid, origin);
|
|
145
|
+
const proof = this.options.directory.getAuditProof(origin);
|
|
146
|
+
if (!proof || new URL(proof.request.url).origin !== origin) continue;
|
|
147
|
+
const checked = verifySignatureDirectory(proof, this.now(), this.options.directory.allowsTestKeys);
|
|
148
|
+
const jwk = checked.keys.find((key) => key.kid === header.kid);
|
|
149
|
+
if (!jwk) continue;
|
|
150
|
+
const result = await compactVerify(token, await importJWK(jwk, header.alg), {
|
|
151
|
+
algorithms: ["EdDSA", "ES256"]
|
|
152
|
+
});
|
|
153
|
+
verifiedPayload = result.payload;
|
|
154
|
+
break;
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!verifiedPayload) throw new Error("No valid protected revocation signature");
|
|
159
|
+
const snapshot = parseStrictJson(
|
|
160
|
+
new TextDecoder("utf-8", { fatal: true }).decode(verifiedPayload),
|
|
161
|
+
32
|
|
162
|
+
);
|
|
163
|
+
const updated = Date.parse(snapshot.updated) / 1e3, next = Date.parse(snapshot.next_update) / 1e3, now = this.now();
|
|
164
|
+
if (snapshot.issuer !== origin || !Number.isFinite(updated) || !Number.isFinite(next) || updated > now || next <= now || next <= updated || next > now + 1800 || !Array.isArray(snapshot.revoked_kids) || snapshot.revoked_kids.length > 4096 || snapshot.revoked_kids.some((k) => typeof k !== "string" || k.length > 256) || updated < (this.updated.get(origin) ?? 0))
|
|
165
|
+
throw new Error("Invalid revocation snapshot");
|
|
166
|
+
for (const [kid, detail] of Object.entries(snapshot.revocation_details ?? {}))
|
|
167
|
+
if (!snapshot.revoked_kids.includes(kid) || !detail || detail.reason && !REASONS.includes(detail.reason) || detail.invalidity_date && !Number.isFinite(Date.parse(detail.invalidity_date)))
|
|
168
|
+
throw new Error("Invalid revocation detail");
|
|
169
|
+
try {
|
|
170
|
+
await this.options.store.merge(origin, snapshot);
|
|
171
|
+
} catch (cause) {
|
|
172
|
+
const error = new WebBotAuthError(403, "revocation_persistence_failed");
|
|
173
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
if (!this.freshness.has(origin) && this.freshness.size >= (this.options.maxOrigins ?? 1e3)) {
|
|
177
|
+
const oldest = this.freshness.keys().next().value;
|
|
178
|
+
this.freshness.delete(oldest);
|
|
179
|
+
this.updated.delete(oldest);
|
|
180
|
+
this.graceUntil.delete(oldest);
|
|
181
|
+
}
|
|
182
|
+
this.graceUntil.set(origin, next + 4 * (this.options.pollingIntervalSeconds ?? 300));
|
|
183
|
+
this.updated.set(origin, updated);
|
|
184
|
+
this.freshness.set(origin, Math.min(next, now + (this.options.pollingIntervalSeconds ?? 300)));
|
|
185
|
+
this.failures.delete(origin);
|
|
186
|
+
this.persistenceFailures.delete(origin);
|
|
187
|
+
} catch (cause) {
|
|
188
|
+
if (cause instanceof WebBotAuthError && cause.reason === "revocation_persistence_failed") throw cause;
|
|
189
|
+
const error = new WebBotAuthError(403, "revocation_unavailable");
|
|
190
|
+
Object.defineProperty(error, "cause", { value: cause });
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
now() {
|
|
195
|
+
const now = (this.options.now ?? (() => Date.now() / 1e3))();
|
|
196
|
+
if (!Number.isFinite(now)) throw new WebBotAuthError(403, "revocation_unavailable");
|
|
197
|
+
return now;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function createSignedOriginRevocationList(snapshot, privateKey) {
|
|
201
|
+
const issuer = canonicalAgentOrigin(snapshot.issuer), now = Date.now() / 1e3;
|
|
202
|
+
if (issuer !== snapshot.issuer || !Number.isFinite(Date.parse(snapshot.updated)) || !Number.isFinite(Date.parse(snapshot.next_update)) || Date.parse(snapshot.updated) / 1e3 > now || Date.parse(snapshot.next_update) / 1e3 <= now || Date.parse(snapshot.next_update) / 1e3 > now + 1800 || !Array.isArray(snapshot.revoked_kids))
|
|
203
|
+
throw new TypeError("Invalid origin revocation snapshot");
|
|
204
|
+
const kid = jwkThumbprint(privateKey);
|
|
205
|
+
if (privateKey.kid && privateKey.kid !== kid)
|
|
206
|
+
throw new TypeError("Revocation signing kid must be the JWK thumbprint");
|
|
207
|
+
const alg = privateKey.crv === "Ed25519" ? "EdDSA" : privateKey.crv === "P-256" ? "ES256" : void 0;
|
|
208
|
+
if (!alg || !privateKey.d) throw new TypeError("Revocations require a private Ed25519 or P-256 key");
|
|
209
|
+
return new CompactSign(Buffer.from(JSON.stringify(snapshot))).setProtectedHeader({ alg, kid, typ: "adcp-gov-revocation+jws" }).sign(await importJWK(privateKey, alg));
|
|
210
|
+
}
|
|
211
|
+
export {
|
|
212
|
+
InMemoryOriginRevocationStore,
|
|
213
|
+
OriginRevocationResolver,
|
|
214
|
+
createSignedOriginRevocationList,
|
|
215
|
+
mergeRevocationDetails as mergeRevocationDetail
|
|
216
|
+
};
|