@fedify/fedify 2.4.0-dev.1531 → 2.4.0-dev.1567

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.
Files changed (48) hide show
  1. package/dist/{builder-CmQLlEE1.mjs → builder-DGWCUaNQ.mjs} +2 -2
  2. package/dist/compat/transformers.test.mjs +1 -1
  3. package/dist/{deno-bSDsva_4.mjs → deno-Dho0TW0X.mjs} +1 -1
  4. package/dist/{docloader-DlmmTFJc.mjs → docloader-DCQSgDOg.mjs} +2 -2
  5. package/dist/federation/builder.test.mjs +1 -1
  6. package/dist/federation/handler.test.mjs +13 -3
  7. package/dist/federation/idempotency.test.mjs +2 -2
  8. package/dist/federation/metrics.test.mjs +1 -1
  9. package/dist/federation/middleware.test.mjs +7 -7
  10. package/dist/federation/mod.cjs +1 -1
  11. package/dist/federation/mod.js +1 -1
  12. package/dist/federation/send.test.mjs +3 -3
  13. package/dist/federation/temporal.test.mjs +1 -1
  14. package/dist/federation/webfinger.test.mjs +1 -1
  15. package/dist/{http-DwsK1LoE.mjs → http-Bf8YhWOi.mjs} +3 -3
  16. package/dist/{http-bsrB-Tun.cjs → http-C7Lot0it.cjs} +75 -9
  17. package/dist/{http-yVXJ4RhY.js → http-sngIMb9S.js} +77 -11
  18. package/dist/{key-C0aqQKRk.mjs → key-3rYgSl9f.mjs} +76 -10
  19. package/dist/{kv-cache-M2xxXg9M.js → kv-cache-B0siRaoZ.js} +1 -1
  20. package/dist/{kv-cache-Dv62PM2B.cjs → kv-cache-CO2IaDJu.cjs} +1 -1
  21. package/dist/{kv-cache-D3EQwzQ4.mjs → kv-cache-P3scUO6t.mjs} +1 -1
  22. package/dist/{ld-CBIxjtov.mjs → ld-CCOPy-Co.mjs} +3 -3
  23. package/dist/{metrics-CwNvxtP6.mjs → metrics-CR4UD_gF.mjs} +3 -3
  24. package/dist/{middleware-BpMbjN9m.js → middleware-BoNiH9CQ.js} +3 -3
  25. package/dist/{middleware-DiTi3jC5.mjs → middleware-CIteB8IS.mjs} +1 -1
  26. package/dist/{middleware-C27Pdo18.cjs → middleware-DUelXs9h.cjs} +3 -3
  27. package/dist/{middleware-BWi34Ga3.mjs → middleware-DfBPuuvp.mjs} +12 -12
  28. package/dist/mod.cjs +4 -4
  29. package/dist/mod.js +4 -4
  30. package/dist/nodeinfo/handler.test.mjs +1 -1
  31. package/dist/{owner-SuWJf5wy.mjs → owner-TUz_H-M9.mjs} +2 -2
  32. package/dist/{proof-DMWr-n3N.js → proof-C5i7MhbD.js} +1 -1
  33. package/dist/{proof-CZI5KQdk.mjs → proof-CrI3UpuA.mjs} +3 -3
  34. package/dist/{proof-BclG-T7h.cjs → proof-DzKUmE7R.cjs} +1 -1
  35. package/dist/{send-1EADALaf.mjs → send-BBs_erdP.mjs} +3 -3
  36. package/dist/sig/http.test.mjs +2 -2
  37. package/dist/sig/key.test.mjs +187 -3
  38. package/dist/sig/ld.test.mjs +2 -2
  39. package/dist/sig/mod.cjs +2 -2
  40. package/dist/sig/mod.js +2 -2
  41. package/dist/sig/owner.test.mjs +1 -1
  42. package/dist/sig/proof.test.mjs +62 -2
  43. package/dist/{temporal-GLaGoMUR.mjs → temporal-bBIy2G-F.mjs} +1 -1
  44. package/dist/utils/docloader.test.mjs +2 -2
  45. package/dist/utils/kv-cache.test.mjs +1 -1
  46. package/dist/utils/mod.cjs +1 -1
  47. package/dist/utils/mod.js +1 -1
  48. package/package.json +6 -6
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-bSDsva_4.mjs";
4
+ import { n as version, t as name } from "./deno-Dho0TW0X.mjs";
5
5
  import { t as ActivityListenerSet } from "./activity-listener-tztVvlNb.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { Router, RouterError, assertPath } from "@fedify/uri-template";
@@ -80,7 +80,7 @@ var FederationBuilderImpl = class {
80
80
  * specified.
81
81
  */
82
82
  async build(options) {
83
- const { FederationImpl } = await import("./middleware-DiTi3jC5.mjs");
83
+ const { FederationImpl } = await import("./middleware-CIteB8IS.mjs");
84
84
  const f = new FederationImpl(options);
85
85
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
86
86
  f.router = this.router.clone();
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
6
6
  import { t as assert } from "../assert-OguE97r2.mjs";
7
7
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
8
- import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-BWi34Ga3.mjs";
8
+ import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-DfBPuuvp.mjs";
9
9
  import { Follow, Person } from "@fedify/vocab";
10
10
  import { test } from "@fedify/fixture";
11
11
  //#region src/compat/transformers.test.ts
@@ -3,6 +3,6 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  //#region deno.json
5
5
  var name = "@fedify/fedify";
6
- var version = "2.4.0-dev.1531+0896bc51";
6
+ var version = "2.4.0-dev.1567+12e6a3c0";
7
7
  //#endregion
8
8
  export { version as n, name as t };
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { o as validateCryptoKey } from "./key-C0aqQKRk.mjs";
5
- import { n as doubleKnock } from "./http-DwsK1LoE.mjs";
4
+ import { o as validateCryptoKey } from "./key-3rYgSl9f.mjs";
5
+ import { n as doubleKnock } from "./http-Bf8YhWOi.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
8
8
  import { curry } from "es-toolkit";
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import { r as assertExists } from "../std__assert-BBjXFNOb.mjs";
6
6
  import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
7
7
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
8
- import { r as createFederationBuilder } from "../builder-CmQLlEE1.mjs";
8
+ import { r as createFederationBuilder } from "../builder-DGWCUaNQ.mjs";
9
9
  import { DisallowedOperatorError, DisallowedVarSpecModifierError, DuplicateRouteVariableError, RouteTemplateOptionsNotMatchedError, RouterError } from "@fedify/uri-template";
10
10
  import { Activity, Note, Person } from "@fedify/vocab";
11
11
  import { test } from "@fedify/fixture";
@@ -8,11 +8,11 @@ import { n as assertGreaterOrEqual, t as assertRejects } from "../assert_rejects
8
8
  import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
9
9
  import { t as assert } from "../assert-OguE97r2.mjs";
10
10
  import { r as parseAcceptSignature } from "../accept-CPkZzmGN.mjs";
11
- import { s as signRequest } from "../http-DwsK1LoE.mjs";
11
+ import { s as signRequest } from "../http-Bf8YhWOi.mjs";
12
12
  import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-DGu1NFwu.mjs";
13
- import { a as compactJsonLd, p as signJsonLd } from "../ld-CBIxjtov.mjs";
13
+ import { a as compactJsonLd, p as signJsonLd } from "../ld-CCOPy-Co.mjs";
14
14
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
15
- import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-BWi34Ga3.mjs";
15
+ import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-DfBPuuvp.mjs";
16
16
  import { t as ActivityListenerSet } from "../activity-listener-tztVvlNb.mjs";
17
17
  import { Activity, Create, Note, Person, Tombstone } from "@fedify/vocab";
18
18
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
@@ -111,11 +111,16 @@ test("handleActor()", async () => {
111
111
  "https://www.w3.org/ns/did/v1",
112
112
  "https://w3id.org/security/multikey/v1",
113
113
  "https://gotosocial.org/ns",
114
+ "https://w3id.org/fep/7aa9",
114
115
  {
115
116
  alsoKnownAs: {
116
117
  "@id": "as:alsoKnownAs",
117
118
  "@type": "@id"
118
119
  },
120
+ featuredCollections: {
121
+ "@id": "https://w3id.org/fep/7aa9#featuredCollections",
122
+ "@type": "@id"
123
+ },
119
124
  manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
120
125
  movedTo: {
121
126
  "@id": "as:movedTo",
@@ -195,11 +200,16 @@ test("handleActor()", async () => {
195
200
  "https://www.w3.org/ns/did/v1",
196
201
  "https://w3id.org/security/multikey/v1",
197
202
  "https://gotosocial.org/ns",
203
+ "https://w3id.org/fep/7aa9",
198
204
  {
199
205
  alsoKnownAs: {
200
206
  "@id": "as:alsoKnownAs",
201
207
  "@type": "@id"
202
208
  },
209
+ featuredCollections: {
210
+ "@id": "https://w3id.org/fep/7aa9#featuredCollections",
211
+ "@type": "@id"
212
+ },
203
213
  manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
204
214
  movedTo: {
205
215
  "@id": "as:movedTo",
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import "../std__assert-BBjXFNOb.mjs";
6
6
  import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
7
- import { r as signObject } from "../proof-CZI5KQdk.mjs";
7
+ import { r as signObject } from "../proof-CrI3UpuA.mjs";
8
8
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
9
- import { o as createFederation } from "../middleware-BWi34Ga3.mjs";
9
+ import { o as createFederation } from "../middleware-DfBPuuvp.mjs";
10
10
  import { Create, Follow, Person } from "@fedify/vocab";
11
11
  import { mockDocumentLoader, test } from "@fedify/fixture";
12
12
  //#region src/federation/idempotency.test.ts
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
5
  import "../std__assert-BBjXFNOb.mjs";
6
6
  import { t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
7
- import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-CwNvxtP6.mjs";
7
+ import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-CR4UD_gF.mjs";
8
8
  import { createTestMeterProvider, test } from "@fedify/fixture";
9
9
  import { FetchError } from "@fedify/vocab-runtime";
10
10
  import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
@@ -10,15 +10,15 @@ import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
10
10
  import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
11
11
  import { t as assertStrictEquals } from "../assert_strict_equals-XEgZAlrj.mjs";
12
12
  import { t as assert } from "../assert-OguE97r2.mjs";
13
- import { g as recordInboxActivity } from "../metrics-CwNvxtP6.mjs";
14
- import { l as verifyRequest, s as signRequest } from "../http-DwsK1LoE.mjs";
13
+ import { g as recordInboxActivity } from "../metrics-CR4UD_gF.mjs";
14
+ import { l as verifyRequest, s as signRequest } from "../http-Bf8YhWOi.mjs";
15
15
  import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
16
- import { t as getAuthenticatedDocumentLoader } from "../docloader-DlmmTFJc.mjs";
17
- import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-CBIxjtov.mjs";
18
- import { t as doesActorOwnKey } from "../owner-SuWJf5wy.mjs";
19
- import { i as verifyObject, r as signObject } from "../proof-CZI5KQdk.mjs";
16
+ import { t as getAuthenticatedDocumentLoader } from "../docloader-DCQSgDOg.mjs";
17
+ import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-CCOPy-Co.mjs";
18
+ import { t as doesActorOwnKey } from "../owner-TUz_H-M9.mjs";
19
+ import { i as verifyObject, r as signObject } from "../proof-CrI3UpuA.mjs";
20
20
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
21
- import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-BWi34Ga3.mjs";
21
+ import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-DfBPuuvp.mjs";
22
22
  import { t as CircuitBreaker } from "../circuit-breaker-CSWsyoef.mjs";
23
23
  import { configure, reset } from "@logtape/logtape";
24
24
  import { RouterError } from "@fedify/uri-template";
@@ -2,7 +2,7 @@ const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  require("../chunk-DDcVe30Y.cjs");
5
- const require_middleware = require("../middleware-C27Pdo18.cjs");
5
+ const require_middleware = require("../middleware-DUelXs9h.cjs");
6
6
  let _logtape_logtape = require("@logtape/logtape");
7
7
  let _fedify_uri_template = require("@fedify/uri-template");
8
8
  let es_toolkit = require("es-toolkit");
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "../middleware-BpMbjN9m.js";
3
+ import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "../middleware-BoNiH9CQ.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { Router as Router$1, RouterError as RouterError$1, assertPath, isPath } from "@fedify/uri-template";
6
6
  import { isEqual } from "es-toolkit";
@@ -8,10 +8,10 @@ import { n as assertGreaterOrEqual, r as assertFalse, t as assertRejects } from
8
8
  import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
9
9
  import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
10
10
  import { t as assert } from "../assert-OguE97r2.mjs";
11
- import { l as verifyRequest } from "../http-DwsK1LoE.mjs";
11
+ import { l as verifyRequest } from "../http-Bf8YhWOi.mjs";
12
12
  import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
13
- import { t as doesActorOwnKey } from "../owner-SuWJf5wy.mjs";
14
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-1EADALaf.mjs";
13
+ import { t as doesActorOwnKey } from "../owner-TUz_H-M9.mjs";
14
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-BBs_erdP.mjs";
15
15
  import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
16
16
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
17
17
  import { FetchError } from "@fedify/vocab-runtime";
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import "../std__assert-BBjXFNOb.mjs";
5
5
  import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
6
6
  import { t as assert } from "../assert-OguE97r2.mjs";
7
- import { t as hasMalformedKnownTemporalLiteral } from "../temporal-GLaGoMUR.mjs";
7
+ import { t as hasMalformedKnownTemporalLiteral } from "../temporal-bBIy2G-F.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/federation/temporal.test.ts
10
10
  test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
@@ -6,7 +6,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
6
  import "../std__assert-BBjXFNOb.mjs";
7
7
  import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
8
8
  import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
9
- import { o as createFederation, s as handleWebFinger } from "../middleware-BWi34Ga3.mjs";
9
+ import { o as createFederation, s as handleWebFinger } from "../middleware-DfBPuuvp.mjs";
10
10
  import { Image, Link, Person, Tombstone } from "@fedify/vocab";
11
11
  import { createTestMeterProvider, test } from "@fedify/fixture";
12
12
  //#region src/federation/webfinger.test.ts
@@ -1,10 +1,10 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-bSDsva_4.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CwNvxtP6.mjs";
4
+ import { n as version, t as name } from "./deno-Dho0TW0X.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CR4UD_gF.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPkZzmGN.mjs";
7
- import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-C0aqQKRk.mjs";
7
+ import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-3rYgSl9f.mjs";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { CryptographicKey } from "@fedify/vocab";
10
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -11,7 +11,7 @@ let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conve
11
11
  let byte_encodings_base64 = require("byte-encodings/base64");
12
12
  //#region deno.json
13
13
  var name = "@fedify/fedify";
14
- var version = "2.4.0-dev.1531+0896bc51";
14
+ var version = "2.4.0-dev.1567+12e6a3c0";
15
15
  //#endregion
16
16
  //#region src/sig/accept.ts
17
17
  /**
@@ -315,11 +315,11 @@ var FederationMetrics = class {
315
315
  unit: "{change}"
316
316
  });
317
317
  this.keyLookup = meter.createCounter("activitypub.key.lookup", {
318
- description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
318
+ description: "Public-key lookup attempts performed by Fedify, including cache hits, local resolutions, and remote fetches.",
319
319
  unit: "{lookup}"
320
320
  });
321
321
  this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
322
- description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
322
+ description: "Duration of public-key lookups performed by Fedify, including cache hits, local resolutions, and any remote fetch.",
323
323
  unit: "ms",
324
324
  advice: { explicitBucketBoundaries: [
325
325
  5,
@@ -1148,16 +1148,22 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
1148
1148
  async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1149
1149
  if (keyCache == null) return null;
1150
1150
  const cachedKey = await keyCache.get(cacheKey);
1151
- if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1152
- logger.debug("Key {keyId} found in cache.", { keyId });
1151
+ const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
1152
+ if (hit != null) return hit;
1153
+ if (cachedKey === null) {
1154
+ logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1153
1155
  return {
1154
- key: cachedKey,
1156
+ key: null,
1155
1157
  cached: true
1156
1158
  };
1157
- } else if (cachedKey === null) {
1158
- logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1159
+ }
1160
+ return null;
1161
+ }
1162
+ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
1163
+ if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1164
+ logger.debug("Key {keyId} found in cache.", { keyId });
1159
1165
  return {
1160
- key: null,
1166
+ key: cachedKey,
1161
1167
  cached: true
1162
1168
  };
1163
1169
  }
@@ -1166,6 +1172,61 @@ async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1166
1172
  async function clearFetchErrorMetadata(keyId, keyCache) {
1167
1173
  await keyCache?.setFetchError?.(keyId, null);
1168
1174
  }
1175
+ function isDidKeyUrl(keyId) {
1176
+ return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
1177
+ }
1178
+ async function doRawKeysMatch(left, right) {
1179
+ const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
1180
+ if (leftRaw.byteLength !== rightRaw.byteLength) return false;
1181
+ const leftBytes = new Uint8Array(leftRaw);
1182
+ const rightBytes = new Uint8Array(rightRaw);
1183
+ return leftBytes.every((byte, index) => byte === rightBytes[index]);
1184
+ }
1185
+ async function isCachedDidKeyValid(key, verificationMethod) {
1186
+ try {
1187
+ return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
1188
+ } catch {
1189
+ return false;
1190
+ }
1191
+ }
1192
+ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
1193
+ if (!isDidKeyUrl(cacheKey)) return null;
1194
+ const keyId = cacheKey.href;
1195
+ if (!(cls === _fedify_vocab.Multikey)) {
1196
+ logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
1197
+ return {
1198
+ key: null,
1199
+ cached: false
1200
+ };
1201
+ }
1202
+ let verificationMethod;
1203
+ try {
1204
+ verificationMethod = await (0, _fedify_vocab_runtime.parseDidKeyVerificationMethod)(cacheKey);
1205
+ } catch (error) {
1206
+ logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
1207
+ keyId,
1208
+ error
1209
+ });
1210
+ return {
1211
+ key: null,
1212
+ cached: false
1213
+ };
1214
+ }
1215
+ const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
1216
+ if (hit?.key instanceof _fedify_vocab.Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
1217
+ const key = new _fedify_vocab.Multikey({
1218
+ id: verificationMethod.id,
1219
+ controller: verificationMethod.controller,
1220
+ publicKey: verificationMethod.publicKey
1221
+ });
1222
+ await keyCache?.set(cacheKey, key);
1223
+ await clearFetchErrorMetadata(cacheKey, keyCache);
1224
+ logger.debug("Resolved did:key verification method {keyId}.", { keyId });
1225
+ return {
1226
+ key,
1227
+ cached: false
1228
+ };
1229
+ }
1169
1230
  async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
1170
1231
  let object;
1171
1232
  try {
@@ -1280,6 +1341,11 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
1280
1341
  ]);
1281
1342
  const keyId = cacheKey.href;
1282
1343
  const keyCache = options.keyCache;
1344
+ const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
1345
+ if (didKey != null) {
1346
+ outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
1347
+ return didKey;
1348
+ }
1283
1349
  const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
1284
1350
  if (cached?.key === null && cached.cached) {
1285
1351
  const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
@@ -1,16 +1,16 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { getLogger } from "@logtape/logtape";
4
- import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
4
+ import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
5
5
  import { SpanKind, SpanStatusCode, metrics, trace } from "@opentelemetry/api";
6
6
  import { encodeHex } from "byte-encodings/hex";
7
7
  import { Item, decodeDict, encodeDict, encodeItem } from "structured-field-values";
8
- import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
8
+ import { FetchError, getDocumentLoader, parseDidKeyVerificationMethod } from "@fedify/vocab-runtime";
9
9
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
10
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
11
11
  //#region deno.json
12
12
  var name = "@fedify/fedify";
13
- var version = "2.4.0-dev.1531+0896bc51";
13
+ var version = "2.4.0-dev.1567+12e6a3c0";
14
14
  //#endregion
15
15
  //#region src/sig/accept.ts
16
16
  /**
@@ -314,11 +314,11 @@ var FederationMetrics = class {
314
314
  unit: "{change}"
315
315
  });
316
316
  this.keyLookup = meter.createCounter("activitypub.key.lookup", {
317
- description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
317
+ description: "Public-key lookup attempts performed by Fedify, including cache hits, local resolutions, and remote fetches.",
318
318
  unit: "{lookup}"
319
319
  });
320
320
  this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
321
- description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
321
+ description: "Duration of public-key lookups performed by Fedify, including cache hits, local resolutions, and any remote fetch.",
322
322
  unit: "ms",
323
323
  advice: { explicitBucketBoundaries: [
324
324
  5,
@@ -1147,16 +1147,22 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
1147
1147
  async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1148
1148
  if (keyCache == null) return null;
1149
1149
  const cachedKey = await keyCache.get(cacheKey);
1150
- if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1151
- logger.debug("Key {keyId} found in cache.", { keyId });
1150
+ const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
1151
+ if (hit != null) return hit;
1152
+ if (cachedKey === null) {
1153
+ logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1152
1154
  return {
1153
- key: cachedKey,
1155
+ key: null,
1154
1156
  cached: true
1155
1157
  };
1156
- } else if (cachedKey === null) {
1157
- logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1158
+ }
1159
+ return null;
1160
+ }
1161
+ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
1162
+ if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1163
+ logger.debug("Key {keyId} found in cache.", { keyId });
1158
1164
  return {
1159
- key: null,
1165
+ key: cachedKey,
1160
1166
  cached: true
1161
1167
  };
1162
1168
  }
@@ -1165,6 +1171,61 @@ async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1165
1171
  async function clearFetchErrorMetadata(keyId, keyCache) {
1166
1172
  await keyCache?.setFetchError?.(keyId, null);
1167
1173
  }
1174
+ function isDidKeyUrl(keyId) {
1175
+ return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
1176
+ }
1177
+ async function doRawKeysMatch(left, right) {
1178
+ const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
1179
+ if (leftRaw.byteLength !== rightRaw.byteLength) return false;
1180
+ const leftBytes = new Uint8Array(leftRaw);
1181
+ const rightBytes = new Uint8Array(rightRaw);
1182
+ return leftBytes.every((byte, index) => byte === rightBytes[index]);
1183
+ }
1184
+ async function isCachedDidKeyValid(key, verificationMethod) {
1185
+ try {
1186
+ return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
1187
+ } catch {
1188
+ return false;
1189
+ }
1190
+ }
1191
+ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
1192
+ if (!isDidKeyUrl(cacheKey)) return null;
1193
+ const keyId = cacheKey.href;
1194
+ if (!(cls === Multikey)) {
1195
+ logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
1196
+ return {
1197
+ key: null,
1198
+ cached: false
1199
+ };
1200
+ }
1201
+ let verificationMethod;
1202
+ try {
1203
+ verificationMethod = await parseDidKeyVerificationMethod(cacheKey);
1204
+ } catch (error) {
1205
+ logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
1206
+ keyId,
1207
+ error
1208
+ });
1209
+ return {
1210
+ key: null,
1211
+ cached: false
1212
+ };
1213
+ }
1214
+ const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
1215
+ if (hit?.key instanceof Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
1216
+ const key = new Multikey({
1217
+ id: verificationMethod.id,
1218
+ controller: verificationMethod.controller,
1219
+ publicKey: verificationMethod.publicKey
1220
+ });
1221
+ await keyCache?.set(cacheKey, key);
1222
+ await clearFetchErrorMetadata(cacheKey, keyCache);
1223
+ logger.debug("Resolved did:key verification method {keyId}.", { keyId });
1224
+ return {
1225
+ key,
1226
+ cached: false
1227
+ };
1228
+ }
1168
1229
  async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
1169
1230
  let object;
1170
1231
  try {
@@ -1279,6 +1340,11 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
1279
1340
  ]);
1280
1341
  const keyId = cacheKey.href;
1281
1342
  const keyCache = options.keyCache;
1343
+ const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
1344
+ if (didKey != null) {
1345
+ outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
1346
+ return didKey;
1347
+ }
1282
1348
  const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
1283
1349
  if (cached?.key === null && cached.cached) {
1284
1350
  const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
@@ -1,12 +1,12 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-bSDsva_4.mjs";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CwNvxtP6.mjs";
4
+ import { n as version, t as name } from "./deno-Dho0TW0X.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CR4UD_gF.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
- import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
7
+ import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
9
- import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
9
+ import { FetchError, getDocumentLoader, parseDidKeyVerificationMethod } from "@fedify/vocab-runtime";
10
10
  //#region src/sig/key.ts
11
11
  /**
12
12
  * Checks if the given key is valid and supported. No-op if the key is valid,
@@ -195,16 +195,22 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
195
195
  async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
196
196
  if (keyCache == null) return null;
197
197
  const cachedKey = await keyCache.get(cacheKey);
198
- if (cachedKey instanceof cls && cachedKey.publicKey != null) {
199
- logger.debug("Key {keyId} found in cache.", { keyId });
198
+ const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
199
+ if (hit != null) return hit;
200
+ if (cachedKey === null) {
201
+ logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
200
202
  return {
201
- key: cachedKey,
203
+ key: null,
202
204
  cached: true
203
205
  };
204
- } else if (cachedKey === null) {
205
- logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
206
+ }
207
+ return null;
208
+ }
209
+ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
210
+ if (cachedKey instanceof cls && cachedKey.publicKey != null) {
211
+ logger.debug("Key {keyId} found in cache.", { keyId });
206
212
  return {
207
- key: null,
213
+ key: cachedKey,
208
214
  cached: true
209
215
  };
210
216
  }
@@ -213,6 +219,61 @@ async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
213
219
  async function clearFetchErrorMetadata(keyId, keyCache) {
214
220
  await keyCache?.setFetchError?.(keyId, null);
215
221
  }
222
+ function isDidKeyUrl(keyId) {
223
+ return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
224
+ }
225
+ async function doRawKeysMatch(left, right) {
226
+ const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
227
+ if (leftRaw.byteLength !== rightRaw.byteLength) return false;
228
+ const leftBytes = new Uint8Array(leftRaw);
229
+ const rightBytes = new Uint8Array(rightRaw);
230
+ return leftBytes.every((byte, index) => byte === rightBytes[index]);
231
+ }
232
+ async function isCachedDidKeyValid(key, verificationMethod) {
233
+ try {
234
+ return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
235
+ } catch {
236
+ return false;
237
+ }
238
+ }
239
+ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
240
+ if (!isDidKeyUrl(cacheKey)) return null;
241
+ const keyId = cacheKey.href;
242
+ if (!(cls === Multikey)) {
243
+ logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
244
+ return {
245
+ key: null,
246
+ cached: false
247
+ };
248
+ }
249
+ let verificationMethod;
250
+ try {
251
+ verificationMethod = await parseDidKeyVerificationMethod(cacheKey);
252
+ } catch (error) {
253
+ logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
254
+ keyId,
255
+ error
256
+ });
257
+ return {
258
+ key: null,
259
+ cached: false
260
+ };
261
+ }
262
+ const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
263
+ if (hit?.key instanceof Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
264
+ const key = new Multikey({
265
+ id: verificationMethod.id,
266
+ controller: verificationMethod.controller,
267
+ publicKey: verificationMethod.publicKey
268
+ });
269
+ await keyCache?.set(cacheKey, key);
270
+ await clearFetchErrorMetadata(cacheKey, keyCache);
271
+ logger.debug("Resolved did:key verification method {keyId}.", { keyId });
272
+ return {
273
+ key,
274
+ cached: false
275
+ };
276
+ }
216
277
  async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
217
278
  let object;
218
279
  try {
@@ -327,6 +388,11 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
327
388
  ]);
328
389
  const keyId = cacheKey.href;
329
390
  const keyCache = options.keyCache;
391
+ const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
392
+ if (didKey != null) {
393
+ outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
394
+ return didKey;
395
+ }
330
396
  const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
331
397
  if (cached?.key === null && cached.cached) {
332
398
  const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-yVXJ4RhY.js";
3
+ import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-sngIMb9S.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { curry } from "es-toolkit";
6
6
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
@@ -1,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  require("./chunk-DDcVe30Y.cjs");
4
- const require_http = require("./http-bsrB-Tun.cjs");
4
+ const require_http = require("./http-C7Lot0it.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let es_toolkit = require("es-toolkit");
7
7
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-CwNvxtP6.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-CR4UD_gF.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts