@fedify/fedify 2.4.0-dev.1570 → 2.4.0-dev.1573

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 (51) hide show
  1. package/README.md +0 -4
  2. package/dist/{builder-CJnWbgbj.mjs → builder-DRvTk1DV.mjs} +2 -2
  3. package/dist/compat/transformers.test.mjs +1 -1
  4. package/dist/{deno-klNxGW7W.mjs → deno-NNtxIQMN.mjs} +1 -1
  5. package/dist/{docloader-CuFH35j1.mjs → docloader-B3zJcGV1.mjs} +2 -2
  6. package/dist/federation/builder.test.mjs +1 -1
  7. package/dist/federation/handler.test.mjs +13 -3
  8. package/dist/federation/idempotency.test.mjs +2 -2
  9. package/dist/federation/metrics.test.mjs +1 -1
  10. package/dist/federation/middleware.test.mjs +7 -7
  11. package/dist/federation/mod.cjs +1 -1
  12. package/dist/federation/mod.js +1 -1
  13. package/dist/federation/send.test.mjs +3 -3
  14. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  15. package/dist/federation/tasks/tasks.test.mjs +2 -2
  16. package/dist/federation/temporal.test.mjs +1 -1
  17. package/dist/federation/webfinger.test.mjs +1 -1
  18. package/dist/{http-D0jH0kco.js → http-B7tuUJIL.js} +77 -11
  19. package/dist/{http-JdRPUYku.mjs → http-Bz2dzdDd.mjs} +3 -3
  20. package/dist/{http-DeuPW1Oh.cjs → http-DTLIxKTx.cjs} +75 -9
  21. package/dist/{key-o0_ipvUR.mjs → key-DRzXlJqV.mjs} +76 -10
  22. package/dist/{kv-cache-DSWq2JHU.js → kv-cache-CtSufpZ1.js} +1 -1
  23. package/dist/{kv-cache-CM7w20U5.mjs → kv-cache-DCxdceYC.mjs} +1 -1
  24. package/dist/{kv-cache-C3rqzQvu.cjs → kv-cache-FrvAhESd.cjs} +1 -1
  25. package/dist/{ld-C__CEgQH.mjs → ld-Fg4L4ACx.mjs} +3 -3
  26. package/dist/{metrics-CLSPm4dZ.mjs → metrics-BcukmbIq.mjs} +3 -3
  27. package/dist/{middleware-zuLSkPIk.js → middleware-Bq3xO08m.js} +3 -3
  28. package/dist/{middleware-CdMiavoh.mjs → middleware-DIkD3qG1.mjs} +1 -1
  29. package/dist/{middleware-B502nwxx.cjs → middleware-DluTV87a.cjs} +3 -3
  30. package/dist/{middleware-CjHqy-1i.mjs → middleware-eIA8GL1A.mjs} +12 -12
  31. package/dist/mod.cjs +4 -4
  32. package/dist/mod.js +4 -4
  33. package/dist/nodeinfo/handler.test.mjs +1 -1
  34. package/dist/{owner-gz4TUfKG.mjs → owner-BuTQfsLw.mjs} +2 -2
  35. package/dist/{proof-CiDzRtr0.cjs → proof-0kBkKeh3.cjs} +1 -1
  36. package/dist/{proof-DQWTf6oB.js → proof-BZxwbdof.js} +1 -1
  37. package/dist/{proof-CuQpZ_AT.mjs → proof-CYRfoVyl.mjs} +3 -3
  38. package/dist/{send-B60teucv.mjs → send-CUsSH2KQ.mjs} +3 -3
  39. package/dist/sig/http.test.mjs +2 -2
  40. package/dist/sig/key.test.mjs +187 -3
  41. package/dist/sig/ld.test.mjs +2 -2
  42. package/dist/sig/mod.cjs +2 -2
  43. package/dist/sig/mod.js +2 -2
  44. package/dist/sig/owner.test.mjs +1 -1
  45. package/dist/sig/proof.test.mjs +62 -2
  46. package/dist/{temporal-CvVMrvJJ.mjs → temporal-uleCkDIj.mjs} +1 -1
  47. package/dist/utils/docloader.test.mjs +2 -2
  48. package/dist/utils/kv-cache.test.mjs +1 -1
  49. package/dist/utils/mod.cjs +1 -1
  50. package/dist/utils/mod.js +1 -1
  51. package/package.json +6 -6
package/README.md CHANGED
@@ -9,9 +9,6 @@
9
9
  [![Matrix][Matrix badge]][Matrix]
10
10
  [![@fedify@hackers.pub][@fedify@hackers.pub badge]][@fedify@hackers.pub]
11
11
 
12
- > [!NOTE]
13
- > Looking for a quick demo? Here it is: [Fedify Demo] on Deno Playground.
14
-
15
12
  Fedify is a TypeScript library for building federated server apps
16
13
  powered by [ActivityPub] and other standards, so-called [fediverse].[^1]
17
14
  It aims to eliminate the complexity and boilerplate code when
@@ -63,7 +60,6 @@ in the fediverse!
63
60
  [Matrix]: https://matrix.to/#/#fedify:matrix.org
64
61
  [@fedify@hackers.pub badge]: https://fedi-badge.minhee.org/@fedify@hackers.pub/followers.svg
65
62
  [@fedify@hackers.pub]: https://hackers.pub/@fedify
66
- [Fedify Demo]: https://dash.deno.com/playground/fedify-demo
67
63
  [ActivityPub]: https://www.w3.org/TR/activitypub/
68
64
  [fediverse]: https://en.wikipedia.org/wiki/Fediverse
69
65
  [Activity Vocabulary]: https://www.w3.org/TR/activitystreams-vocabulary/
@@ -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-klNxGW7W.mjs";
4
+ import { n as version, t as name } from "./deno-NNtxIQMN.mjs";
5
5
  import { t as ActivityListenerSet } from "./activity-listener-BeTGV3wc.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { Router, RouterError, assertPath } from "@fedify/uri-template";
@@ -82,7 +82,7 @@ var FederationBuilderImpl = class {
82
82
  * specified.
83
83
  */
84
84
  async build(options) {
85
- const { FederationImpl } = await import("./middleware-CdMiavoh.mjs");
85
+ const { FederationImpl } = await import("./middleware-DIkD3qG1.mjs");
86
86
  const f = new FederationImpl(options);
87
87
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
88
88
  f.router = this.router.clone();
@@ -5,7 +5,7 @@ import { t as MemoryKvStore } from "../kv-CIvR3Non.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
6
6
  import { t as assertInstanceOf } from "../assert_instance_of-CxoC8bVq.mjs";
7
7
  import { t as assert } from "../assert-DvVHoIZ0.mjs";
8
- import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-CjHqy-1i.mjs";
8
+ import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-eIA8GL1A.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.1570+f1b6aaa3";
6
+ var version = "2.4.0-dev.1573+246bd0b2";
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-o0_ipvUR.mjs";
5
- import { n as doubleKnock } from "./http-JdRPUYku.mjs";
4
+ import { o as validateCryptoKey } from "./key-DRzXlJqV.mjs";
5
+ import { n as doubleKnock } from "./http-Bz2dzdDd.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { curry } from "es-toolkit";
8
8
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
@@ -5,7 +5,7 @@ import { t as MemoryKvStore } from "../kv-CIvR3Non.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
6
6
  import { r as assertExists } from "../std__assert-Dh6uLf_q.mjs";
7
7
  import { t as assertThrows } from "../assert_throws-zN79lgIC.mjs";
8
- import { r as createFederationBuilder } from "../builder-CJnWbgbj.mjs";
8
+ import { r as createFederationBuilder } from "../builder-DRvTk1DV.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";
@@ -9,10 +9,10 @@ import { n as assertGreaterOrEqual, t as assertRejects } from "../assert_rejects
9
9
  import { t as assertInstanceOf } from "../assert_instance_of-CxoC8bVq.mjs";
10
10
  import { t as assert } from "../assert-DvVHoIZ0.mjs";
11
11
  import { r as parseAcceptSignature } from "../accept-CgDcxvjV.mjs";
12
- import { s as signRequest } from "../http-JdRPUYku.mjs";
12
+ import { s as signRequest } from "../http-Bz2dzdDd.mjs";
13
13
  import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-CSYsOMFG.mjs";
14
- import { a as compactJsonLd, p as signJsonLd } from "../ld-C__CEgQH.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-CjHqy-1i.mjs";
14
+ import { a as compactJsonLd, p as signJsonLd } from "../ld-Fg4L4ACx.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-eIA8GL1A.mjs";
16
16
  import { t as ActivityListenerSet } from "../activity-listener-BeTGV3wc.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",
@@ -5,8 +5,8 @@ import { t as MemoryKvStore } from "../kv-CIvR3Non.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
6
6
  import "../std__assert-Dh6uLf_q.mjs";
7
7
  import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-CSYsOMFG.mjs";
8
- import { r as signObject } from "../proof-CuQpZ_AT.mjs";
9
- import { o as createFederation } from "../middleware-CjHqy-1i.mjs";
8
+ import { r as signObject } from "../proof-CYRfoVyl.mjs";
9
+ import { o as createFederation } from "../middleware-eIA8GL1A.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-PBVKNMJd.mjs";
5
5
  import "../std__assert-Dh6uLf_q.mjs";
6
6
  import { t as assertRejects } from "../assert_rejects-DAdaaIWM.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-CLSPm4dZ.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-BcukmbIq.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";
@@ -12,14 +12,14 @@ import { t as assertThrows } from "../assert_throws-zN79lgIC.mjs";
12
12
  import { t as assertNotEquals } from "../assert_not_equals-C8vcTTA3.mjs";
13
13
  import { t as assertStrictEquals } from "../assert_strict_equals-BzqyKuYL.mjs";
14
14
  import { t as assert } from "../assert-DvVHoIZ0.mjs";
15
- import { g as recordInboxActivity } from "../metrics-CLSPm4dZ.mjs";
16
- import { l as verifyRequest, s as signRequest } from "../http-JdRPUYku.mjs";
15
+ import { g as recordInboxActivity } from "../metrics-BcukmbIq.mjs";
16
+ import { l as verifyRequest, s as signRequest } from "../http-Bz2dzdDd.mjs";
17
17
  import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CSYsOMFG.mjs";
18
- import { t as getAuthenticatedDocumentLoader } from "../docloader-CuFH35j1.mjs";
19
- import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-C__CEgQH.mjs";
20
- import { t as doesActorOwnKey } from "../owner-gz4TUfKG.mjs";
21
- import { i as verifyObject, r as signObject } from "../proof-CuQpZ_AT.mjs";
22
- import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-CjHqy-1i.mjs";
18
+ import { t as getAuthenticatedDocumentLoader } from "../docloader-B3zJcGV1.mjs";
19
+ import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-Fg4L4ACx.mjs";
20
+ import { t as doesActorOwnKey } from "../owner-BuTQfsLw.mjs";
21
+ import { i as verifyObject, r as signObject } from "../proof-CYRfoVyl.mjs";
22
+ import { g as handleBenchmarkTrigger, i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-eIA8GL1A.mjs";
23
23
  import { t as CircuitBreaker } from "../circuit-breaker-hJBB6jwA.mjs";
24
24
  import { t as TaskCodec } from "../codec-nfBU4Up4.mjs";
25
25
  import { configure, reset } from "@logtape/logtape";
@@ -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-B502nwxx.cjs");
5
+ const require_middleware = require("../middleware-DluTV87a.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 ParallelMessageQueue, c as respondWithObject, d as digest, f as CircuitBreaker, h as createFederationBuilder, i as InProcessMessageQueue, l as respondWithObjectIfAcceptable, m as parseCircuitBreakerKvState, o as createExponentialBackoffPolicy, p as normalizeCircuitBreakerOptions, r as handleWebFinger, s as SendActivityError, t as createFederation, u as buildCollectionSynchronizationHeader } from "../middleware-zuLSkPIk.js";
3
+ import { a as ParallelMessageQueue, c as respondWithObject, d as digest, f as CircuitBreaker, h as createFederationBuilder, i as InProcessMessageQueue, l as respondWithObjectIfAcceptable, m as parseCircuitBreakerKvState, o as createExponentialBackoffPolicy, p as normalizeCircuitBreakerOptions, r as handleWebFinger, s as SendActivityError, t as createFederation, u as buildCollectionSynchronizationHeader } from "../middleware-Bq3xO08m.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-CxoC8bVq.mjs";
9
9
  import { t as assertNotEquals } from "../assert_not_equals-C8vcTTA3.mjs";
10
10
  import { t as assert } from "../assert-DvVHoIZ0.mjs";
11
- import { l as verifyRequest } from "../http-JdRPUYku.mjs";
11
+ import { l as verifyRequest } from "../http-Bz2dzdDd.mjs";
12
12
  import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CSYsOMFG.mjs";
13
- import { t as doesActorOwnKey } from "../owner-gz4TUfKG.mjs";
14
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-B60teucv.mjs";
13
+ import { t as doesActorOwnKey } from "../owner-BuTQfsLw.mjs";
14
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-CUsSH2KQ.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";
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as MemoryKvStore } from "../../kv-CIvR3Non.mjs";
5
5
  import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-Dy-WhqpN.mjs";
6
- import { o as createFederation } from "../../middleware-CjHqy-1i.mjs";
6
+ import { o as createFederation } from "../../middleware-eIA8GL1A.mjs";
7
7
  import { n as ParallelMessageQueue } from "../../mq-03vS-C9P.mjs";
8
8
  import { configure, reset } from "@logtape/logtape";
9
9
  import { delay } from "es-toolkit";
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as MemoryKvStore } from "../../kv-CIvR3Non.mjs";
5
5
  import { a as numberSchema, i as makeSchema, n as baseOptions, o as stringSchema, t as MockQueue } from "../../testing-Dy-WhqpN.mjs";
6
- import { o as createFederation } from "../../middleware-CjHqy-1i.mjs";
7
- import { r as createFederationBuilder } from "../../builder-CJnWbgbj.mjs";
6
+ import { o as createFederation } from "../../middleware-eIA8GL1A.mjs";
7
+ import { r as createFederationBuilder } from "../../builder-DRvTk1DV.mjs";
8
8
  import { t as TaskCodec } from "../../codec-nfBU4Up4.mjs";
9
9
  import { t as InProcessMessageQueue } from "../../mq-03vS-C9P.mjs";
10
10
  import { W3CTraceContextPropagator } from "@opentelemetry/core";
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import "../std__assert-Dh6uLf_q.mjs";
5
5
  import { r as assertFalse } from "../assert_rejects-DAdaaIWM.mjs";
6
6
  import { t as assert } from "../assert-DvVHoIZ0.mjs";
7
- import { t as hasMalformedKnownTemporalLiteral } from "../temporal-CvVMrvJJ.mjs";
7
+ import { t as hasMalformedKnownTemporalLiteral } from "../temporal-uleCkDIj.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 MemoryKvStore } from "../kv-CIvR3Non.mjs";
6
6
  import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
7
7
  import "../std__assert-Dh6uLf_q.mjs";
8
8
  import { t as assertNotEquals } from "../assert_not_equals-C8vcTTA3.mjs";
9
- import { o as createFederation, s as handleWebFinger } from "../middleware-CjHqy-1i.mjs";
9
+ import { o as createFederation, s as handleWebFinger } from "../middleware-eIA8GL1A.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,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.1570+f1b6aaa3";
13
+ var version = "2.4.0-dev.1573+246bd0b2";
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,
@@ -1149,16 +1149,22 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
1149
1149
  async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1150
1150
  if (keyCache == null) return null;
1151
1151
  const cachedKey = await keyCache.get(cacheKey);
1152
- if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1153
- logger.debug("Key {keyId} found in cache.", { keyId });
1152
+ const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
1153
+ if (hit != null) return hit;
1154
+ if (cachedKey === null) {
1155
+ logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1154
1156
  return {
1155
- key: cachedKey,
1157
+ key: null,
1156
1158
  cached: true
1157
1159
  };
1158
- } else if (cachedKey === null) {
1159
- logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1160
+ }
1161
+ return null;
1162
+ }
1163
+ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
1164
+ if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1165
+ logger.debug("Key {keyId} found in cache.", { keyId });
1160
1166
  return {
1161
- key: null,
1167
+ key: cachedKey,
1162
1168
  cached: true
1163
1169
  };
1164
1170
  }
@@ -1167,6 +1173,61 @@ async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1167
1173
  async function clearFetchErrorMetadata(keyId, keyCache) {
1168
1174
  await keyCache?.setFetchError?.(keyId, null);
1169
1175
  }
1176
+ function isDidKeyUrl(keyId) {
1177
+ return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
1178
+ }
1179
+ async function doRawKeysMatch(left, right) {
1180
+ const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
1181
+ if (leftRaw.byteLength !== rightRaw.byteLength) return false;
1182
+ const leftBytes = new Uint8Array(leftRaw);
1183
+ const rightBytes = new Uint8Array(rightRaw);
1184
+ return leftBytes.every((byte, index) => byte === rightBytes[index]);
1185
+ }
1186
+ async function isCachedDidKeyValid(key, verificationMethod) {
1187
+ try {
1188
+ return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
1189
+ } catch {
1190
+ return false;
1191
+ }
1192
+ }
1193
+ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
1194
+ if (!isDidKeyUrl(cacheKey)) return null;
1195
+ const keyId = cacheKey.href;
1196
+ if (!(cls === Multikey)) {
1197
+ logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
1198
+ return {
1199
+ key: null,
1200
+ cached: false
1201
+ };
1202
+ }
1203
+ let verificationMethod;
1204
+ try {
1205
+ verificationMethod = await parseDidKeyVerificationMethod(cacheKey);
1206
+ } catch (error) {
1207
+ logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
1208
+ keyId,
1209
+ error
1210
+ });
1211
+ return {
1212
+ key: null,
1213
+ cached: false
1214
+ };
1215
+ }
1216
+ const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
1217
+ if (hit?.key instanceof Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
1218
+ const key = new Multikey({
1219
+ id: verificationMethod.id,
1220
+ controller: verificationMethod.controller,
1221
+ publicKey: verificationMethod.publicKey
1222
+ });
1223
+ await keyCache?.set(cacheKey, key);
1224
+ await clearFetchErrorMetadata(cacheKey, keyCache);
1225
+ logger.debug("Resolved did:key verification method {keyId}.", { keyId });
1226
+ return {
1227
+ key,
1228
+ cached: false
1229
+ };
1230
+ }
1170
1231
  async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
1171
1232
  let object;
1172
1233
  try {
@@ -1281,6 +1342,11 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
1281
1342
  ]);
1282
1343
  const keyId = cacheKey.href;
1283
1344
  const keyCache = options.keyCache;
1345
+ const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
1346
+ if (didKey != null) {
1347
+ outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
1348
+ return didKey;
1349
+ }
1284
1350
  const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
1285
1351
  if (cached?.key === null && cached.cached) {
1286
1352
  const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
@@ -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-klNxGW7W.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CLSPm4dZ.mjs";
4
+ import { n as version, t as name } from "./deno-NNtxIQMN.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BcukmbIq.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CgDcxvjV.mjs";
7
- import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-o0_ipvUR.mjs";
7
+ import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-DRzXlJqV.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.1570+f1b6aaa3";
14
+ var version = "2.4.0-dev.1573+246bd0b2";
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,
@@ -1150,16 +1150,22 @@ async function fetchKeyDetailed(keyId, cls, options = {}) {
1150
1150
  async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1151
1151
  if (keyCache == null) return null;
1152
1152
  const cachedKey = await keyCache.get(cacheKey);
1153
- if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1154
- logger.debug("Key {keyId} found in cache.", { keyId });
1153
+ const hit = checkCachedKeyHit(cachedKey, keyId, cls, logger);
1154
+ if (hit != null) return hit;
1155
+ if (cachedKey === null) {
1156
+ logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1155
1157
  return {
1156
- key: cachedKey,
1158
+ key: null,
1157
1159
  cached: true
1158
1160
  };
1159
- } else if (cachedKey === null) {
1160
- logger.debug("Entry {keyId} found in cache, but it is unavailable.", { keyId });
1161
+ }
1162
+ return null;
1163
+ }
1164
+ function checkCachedKeyHit(cachedKey, keyId, cls, logger) {
1165
+ if (cachedKey instanceof cls && cachedKey.publicKey != null) {
1166
+ logger.debug("Key {keyId} found in cache.", { keyId });
1161
1167
  return {
1162
- key: null,
1168
+ key: cachedKey,
1163
1169
  cached: true
1164
1170
  };
1165
1171
  }
@@ -1168,6 +1174,61 @@ async function getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger) {
1168
1174
  async function clearFetchErrorMetadata(keyId, keyCache) {
1169
1175
  await keyCache?.setFetchError?.(keyId, null);
1170
1176
  }
1177
+ function isDidKeyUrl(keyId) {
1178
+ return keyId.protocol === "did:" && keyId.pathname.startsWith("key:");
1179
+ }
1180
+ async function doRawKeysMatch(left, right) {
1181
+ const [leftRaw, rightRaw] = await Promise.all([crypto.subtle.exportKey("raw", left), crypto.subtle.exportKey("raw", right)]);
1182
+ if (leftRaw.byteLength !== rightRaw.byteLength) return false;
1183
+ const leftBytes = new Uint8Array(leftRaw);
1184
+ const rightBytes = new Uint8Array(rightRaw);
1185
+ return leftBytes.every((byte, index) => byte === rightBytes[index]);
1186
+ }
1187
+ async function isCachedDidKeyValid(key, verificationMethod) {
1188
+ try {
1189
+ return key.id?.href === verificationMethod.id.href && key.controllerId?.href === verificationMethod.controller.href && await doRawKeysMatch(key.publicKey, verificationMethod.publicKey);
1190
+ } catch {
1191
+ return false;
1192
+ }
1193
+ }
1194
+ async function resolveDidKey(cacheKey, cls, keyCache, logger) {
1195
+ if (!isDidKeyUrl(cacheKey)) return null;
1196
+ const keyId = cacheKey.href;
1197
+ if (!(cls === _fedify_vocab.Multikey)) {
1198
+ logger.debug("Failed to resolve did:key {keyId}; did:key verification methods are only supported as Multikey values.", { keyId });
1199
+ return {
1200
+ key: null,
1201
+ cached: false
1202
+ };
1203
+ }
1204
+ let verificationMethod;
1205
+ try {
1206
+ verificationMethod = await (0, _fedify_vocab_runtime.parseDidKeyVerificationMethod)(cacheKey);
1207
+ } catch (error) {
1208
+ logger.debug("Failed to resolve did:key verification method {keyId}: {error}", {
1209
+ keyId,
1210
+ error
1211
+ });
1212
+ return {
1213
+ key: null,
1214
+ cached: false
1215
+ };
1216
+ }
1217
+ const hit = checkCachedKeyHit(await keyCache?.get(cacheKey), keyId, cls, logger);
1218
+ if (hit?.key instanceof _fedify_vocab.Multikey && await isCachedDidKeyValid(hit.key, verificationMethod)) return hit;
1219
+ const key = new _fedify_vocab.Multikey({
1220
+ id: verificationMethod.id,
1221
+ controller: verificationMethod.controller,
1222
+ publicKey: verificationMethod.publicKey
1223
+ });
1224
+ await keyCache?.set(cacheKey, key);
1225
+ await clearFetchErrorMetadata(cacheKey, keyCache);
1226
+ logger.debug("Resolved did:key verification method {keyId}.", { keyId });
1227
+ return {
1228
+ key,
1229
+ cached: false
1230
+ };
1231
+ }
1171
1232
  async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoader, contextLoader, keyCache, tracerProvider }, logger) {
1172
1233
  let object;
1173
1234
  try {
@@ -1282,6 +1343,11 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
1282
1343
  ]);
1283
1344
  const keyId = cacheKey.href;
1284
1345
  const keyCache = options.keyCache;
1346
+ const didKey = await resolveDidKey(cacheKey, cls, keyCache, logger);
1347
+ if (didKey != null) {
1348
+ outcome = { result: didKey.key == null ? "invalid" : didKey.cached ? "hit" : "fetched" };
1349
+ return didKey;
1350
+ }
1285
1351
  const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
1286
1352
  if (cached?.key === null && cached.cached) {
1287
1353
  const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);