@fedify/fedify 2.0.28-dev.1979 → 2.0.28-dev.1982
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{assert_instance_of-C4Ri6VuN.mjs → assert-BhQd8QHP.mjs} +19 -1
- package/dist/{builder-CAAXTNeK.mjs → builder-DG5rS_Zv.mjs} +3 -3
- package/dist/{client-HLLGHiTU.mjs → client-glFHmpn4.mjs} +78 -4
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +3 -4
- package/dist/{context-DJ5oMnte.d.ts → context-B21klrfz.d.ts} +2 -2
- package/dist/{context-zLLwVY_G.d.cts → context-M_MxoQgC.d.cts} +2 -2
- package/dist/{deno-D3gZ1DsB.mjs → deno-eqaJj6JL.mjs} +1 -1
- package/dist/{docloader-DIk3fEXZ.mjs → docloader-BXUqhXNd.mjs} +2 -2
- package/dist/federation/builder.test.mjs +2 -2
- package/dist/federation/collection.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +125 -8
- package/dist/federation/idempotency.test.mjs +4 -4
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +44 -10
- package/dist/federation/kv.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +66 -10
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +1 -1
- package/dist/federation/negotiation.test.mjs +2 -2
- package/dist/federation/retry.test.mjs +1 -1
- package/dist/federation/router.test.mjs +1 -1
- package/dist/federation/send.test.mjs +5 -6
- package/dist/federation/temporal.test.mjs +2 -2
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{http-BLqv_3ue.cjs → http-BgOlx4n1.cjs} +163 -3
- package/dist/{http-C4D0ajx0.d.ts → http-Bs6thuCC.d.cts} +2 -2
- package/dist/{http-Bn3-am6C.mjs → http-Bu3NxfGb.mjs} +2 -2
- package/dist/{http-RYvZHWMc.d.cts → http-CDupyfOc.d.ts} +2 -2
- package/dist/{http-Cx5dD1D_.js → http-CwcG2wDs.js} +152 -4
- package/dist/{inbox-DC8NbYIj.mjs → inbox-Hou2ZAjv.mjs} +1 -1
- package/dist/{key-BQUnVMwc.mjs → key-bSphUqhB.mjs} +152 -4
- package/dist/{keycache-DaQ3ndaJ.mjs → keycache-D239uGT9.mjs} +12 -4
- package/dist/{kv-cache-CCEitzFw.cjs → kv-cache-B8GaLaNy.cjs} +1 -1
- package/dist/{kv-cache-DI4m-4xy.js → kv-cache-lbswb9pg.js} +1 -1
- package/dist/{ld-CVbwQ8Fz.mjs → ld-D0uFMLmq.mjs} +2 -2
- package/dist/{middleware-C7Afa66S.cjs → middleware-BKpP3cnZ.cjs} +1 -1
- package/dist/{middleware-D3a1JsO1.mjs → middleware-BuVM1K-J.mjs} +27 -19
- package/dist/{middleware-BqkNe0c6.mjs → middleware-DXPBIbm6.mjs} +1 -1
- package/dist/{middleware-Fcpx7tz6.cjs → middleware-D_7wZH27.cjs} +26 -10
- package/dist/{middleware-2Qp34eTb.js → middleware-DomxFoLd.js} +25 -9
- package/dist/{mod-B2zB0rDg.d.cts → mod-Bt0eg_Lv.d.cts} +1 -1
- package/dist/{mod-Du-UVCX_.d.ts → mod-D24V_w-K.d.ts} +1 -1
- package/dist/{mod-BtvLkCgb.d.cts → mod-Dp5dfH-i.d.cts} +1 -1
- package/dist/{mod-CiQNNAQL.d.ts → mod-E7YM72JZ.d.ts} +1 -1
- package/dist/{mod-CB6pc2pw.d.cts → mod-IOWUF5Yr.d.cts} +1 -1
- package/dist/{mod-CD1youdZ.d.ts → mod-XucBiDNd.d.ts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +28 -1
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/types.test.mjs +1 -1
- package/dist/otel/exporter.test.mjs +1 -1
- package/dist/{owner-CnngXDNJ.d.ts → owner-B3hNQCG8.d.cts} +12 -1
- package/dist/owner-Bzg6w7eA.mjs +175 -0
- package/dist/{owner-DEvZuyOE.d.cts → owner-CiBPcC6F.d.ts} +12 -1
- package/dist/{proof-DZWmoF6Z.mjs → proof-CgLA51pO.mjs} +2 -2
- package/dist/{proof-EY-uItWr.js → proof-DsJHFTkx.js} +112 -58
- package/dist/{proof-liMyPvsb.cjs → proof-xCEe8t7U.cjs} +112 -58
- package/dist/{send-IMhmEkun.mjs → send-D89-FDX-.mjs} +2 -2
- package/dist/sig/http.test.mjs +4 -4
- package/dist/sig/key.test.mjs +169 -2
- package/dist/sig/ld.test.mjs +56 -4
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +105 -6
- package/dist/sig/proof.test.mjs +72 -3
- package/dist/{temporal-BovRWwqL.mjs → temporal-DPJlkHh3.mjs} +1 -1
- package/dist/{types-m8u9L86X.cjs → types-DWs-qZaY.cjs} +94 -2
- package/dist/{types-DTONwNqL.js → types-sXITXcWa.js} +78 -4
- package/dist/utils/docloader.test.mjs +28 -4
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +5 -5
- package/dist/assert-ddO5KLpe.mjs +0 -23
- package/dist/owner-D9CjMxWb.mjs +0 -120
- /package/dist/{collection-ChgDTHLz.mjs → collection-DI6YzYpd.mjs} +0 -0
- /package/dist/{keys-CtZLJq76.mjs → keys-CCxRJhWa.mjs} +0 -0
- /package/dist/{kv-cache-DqEKe5E0.mjs → kv-cache-BrjuJue8.mjs} +0 -0
- /package/dist/{kv-BrZHNugx.mjs → kv-mI4Ix2EU.mjs} +0 -0
- /package/dist/{negotiation-BehA2uul.mjs → negotiation-TWEs6Cl8.mjs} +0 -0
- /package/dist/{retry-B_E3V_Dx.mjs → retry-Ddbq3AcK.mjs} +0 -0
- /package/dist/{types-C37hquWI.mjs → types-MNlFfxjv.mjs} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "../context-
|
|
2
|
+
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "../context-M_MxoQgC.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-gJ8LYbxX.cjs";
|
|
4
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-
|
|
4
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-Dp5dfH-i.cjs";
|
|
5
5
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "../context-
|
|
2
|
+
import { $ as AuthorizePredicate, A as CreateExponentialBackoffPolicyOptions, B as RespondWithObjectOptions, C as InboxListenerSetters, D as FederationOrigin, E as FederationKvPrefixes, F as createFederationBuilder, G as MessageQueue, H as respondWithObjectIfAcceptable, I as Router, J as ParallelMessageQueue, K as MessageQueueEnqueueOptions, L as RouterError, M as RetryPolicy, N as createExponentialBackoffPolicy, O as FederationQueueOptions, P as Message, Q as ActorKeyPairsDispatcher, R as RouterOptions, S as IdempotencyStrategy, T as Rfc6570Expression, U as InProcessMessageQueue, V as respondWithObject, W as InProcessMessageQueueOptions, X as ActorDispatcher, Y as ActorAliasMapper, Z as ActorHandleMapper, _ as FederationBuilder, _t as PageItems, a as InboxContext, at as CustomCollectionDispatcher, b as FederationStartQueueOptions, c as RouteActivityOptions, ct as NodeInfoDispatcher, d as ActorCallbackSetters, dt as OutboxErrorHandler, et as CollectionCounter, f as CollectionCallbackSetters, ft as OutboxPermanentFailureHandler, g as Federation, gt as SenderKeyPair, h as Federatable, ht as SendActivityError, i as GetSignedKeyOptions, it as CustomCollectionCursor, j as RetryContext, k as createFederation, l as SendActivityOptions, lt as ObjectAuthorizePredicate, m as CustomCollectionCallbackSetters, mt as WebFingerLinksDispatcher, n as Context, nt as CollectionDispatcher, o as ParseUriResult, ot as InboxErrorHandler, p as ConstructorWithTypeId, pt as SharedInboxKeyDispatcher, q as MessageQueueListenOptions, r as ForwardActivityOptions, rt as CustomCollectionCounter, s as RequestContext, st as InboxListener, t as ActorKeyPair, tt as CollectionCursor, u as SendActivityOptionsForCollection, ut as ObjectDispatcher, v as FederationFetchOptions, vt as buildCollectionSynchronizationHeader, w as ObjectCallbackSetters, x as IdempotencyKeyCallback, y as FederationOptions, yt as digest, z as RouterRouteResult } from "../context-B21klrfz.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-D6hNiMTK.js";
|
|
4
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-
|
|
4
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-D24V_w-K.js";
|
|
5
5
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-
|
|
3
|
+
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-DomxFoLd.js";
|
|
4
4
|
import { isEqual } from "es-toolkit";
|
|
5
5
|
//#region src/federation/kv.ts
|
|
6
6
|
/**
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import { i as assertGreaterOrEqual, r as assertGreater } from "../std__assert-Duiq_YC9.mjs";
|
|
6
6
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
7
|
-
import { t as assert } from "../assert-
|
|
7
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
import { delay } from "es-toolkit";
|
|
10
10
|
//#region src/federation/mq.ts
|
|
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import "../std__assert-Duiq_YC9.mjs";
|
|
5
5
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
6
|
-
import { t as assert } from "../assert-
|
|
7
|
-
import { t as acceptsJsonLd } from "../negotiation-
|
|
6
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
7
|
+
import { t as acceptsJsonLd } from "../negotiation-TWEs6Cl8.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/negotiation.test.ts
|
|
10
10
|
test("acceptsJsonLd()", () => {
|
|
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { l as AssertionError, t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
6
|
-
import { t as createExponentialBackoffPolicy } from "../retry-
|
|
6
|
+
import { t as createExponentialBackoffPolicy } from "../retry-Ddbq3AcK.mjs";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
//#region src/federation/retry.test.ts
|
|
9
9
|
test("createExponentialBackoffPolicy()", () => {
|
|
@@ -5,8 +5,8 @@ import { n as RouterError, t as Router } from "../router-CrMLXoOr.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
7
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
8
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
8
9
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
9
|
-
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/federation/router.test.ts
|
|
12
12
|
function setUp(options = {}) {
|
|
@@ -5,13 +5,12 @@ import { t as esm_default } from "../esm-DVILvP5e.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
7
|
import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import { n as assertInstanceOf, t as assert } from "../assert-BhQd8QHP.mjs";
|
|
9
9
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { t as
|
|
14
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-IMhmEkun.mjs";
|
|
10
|
+
import { l as verifyRequest } from "../http-Bu3NxfGb.mjs";
|
|
11
|
+
import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CCxRJhWa.mjs";
|
|
12
|
+
import { t as doesActorOwnKey } from "../owner-Bzg6w7eA.mjs";
|
|
13
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-D89-FDX-.mjs";
|
|
15
14
|
import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
16
15
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
17
16
|
import { UrlError } from "@fedify/vocab-runtime";
|
|
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import "../std__assert-Duiq_YC9.mjs";
|
|
5
5
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
6
|
-
import { t as assert } from "../assert-
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
6
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-DPJlkHh3.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 () => {
|
|
@@ -4,8 +4,8 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { n as createRequestContext } from "../context-Juj6bdHC.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
|
-
import { t as MemoryKvStore } from "../kv-
|
|
8
|
-
import { a as createFederation, o as handleWebFinger } from "../middleware-
|
|
7
|
+
import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
|
|
8
|
+
import { a as createFederation, o as handleWebFinger } from "../middleware-BuVM1K-J.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Image, Link, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/federation/webfinger.test.ts
|
|
@@ -11,7 +11,7 @@ let byte_encodings_base64 = require("byte-encodings/base64");
|
|
|
11
11
|
let structured_field_values = require("structured-field-values");
|
|
12
12
|
//#region deno.json
|
|
13
13
|
var name = "@fedify/fedify";
|
|
14
|
-
var version = "2.0.28-dev.
|
|
14
|
+
var version = "2.0.28-dev.1982+a57dec3f";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/key.ts
|
|
17
17
|
/**
|
|
@@ -93,6 +93,118 @@ async function importJwk(jwk, type) {
|
|
|
93
93
|
return key;
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
|
+
* Fetches the document that the given actor URI dereferences to, and returns
|
|
97
|
+
* the actor only if the host that served the document is authoritative for
|
|
98
|
+
* the id the document claims.
|
|
99
|
+
*
|
|
100
|
+
* Only the origin that serves an actor id can speak for it. Without that
|
|
101
|
+
* rule any host could serve a document describing somebody else's actor—and
|
|
102
|
+
* listing its own keys as that actor's.
|
|
103
|
+
*
|
|
104
|
+
* @param actorId The URI of the actor to fetch.
|
|
105
|
+
* @param options Options for fetching the document.
|
|
106
|
+
* @returns The actor, or `null` if the document cannot be fetched, is not an
|
|
107
|
+
* actor, or belongs to another origin.
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
async function fetchActorDocument(actorId, options = {}) {
|
|
111
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
112
|
+
"fedify",
|
|
113
|
+
"sig",
|
|
114
|
+
"key"
|
|
115
|
+
]);
|
|
116
|
+
const documentLoader = options.documentLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)();
|
|
117
|
+
const contextLoader = options.contextLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)();
|
|
118
|
+
const { tracerProvider } = options;
|
|
119
|
+
let document;
|
|
120
|
+
let documentUrl = actorId;
|
|
121
|
+
try {
|
|
122
|
+
const remoteDocument = await documentLoader(actorId.href);
|
|
123
|
+
document = remoteDocument.document;
|
|
124
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", actorId);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
logger.debug("Failed to fetch the actor {actorId}: {error}", {
|
|
127
|
+
actorId: actorId.href,
|
|
128
|
+
error
|
|
129
|
+
});
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
let object;
|
|
133
|
+
try {
|
|
134
|
+
object = await _fedify_vocab.Object.fromJsonLd(document, {
|
|
135
|
+
documentLoader,
|
|
136
|
+
contextLoader,
|
|
137
|
+
tracerProvider,
|
|
138
|
+
baseUrl: documentUrl
|
|
139
|
+
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (!(error instanceof TypeError)) throw error;
|
|
142
|
+
logger.debug("The document served at {documentUrl} is not a valid object: {error}", {
|
|
143
|
+
documentUrl: documentUrl.href,
|
|
144
|
+
error
|
|
145
|
+
});
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
if (!(0, _fedify_vocab.isActor)(object)) return null;
|
|
149
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
150
|
+
logger.debug("The document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin; refusing to treat it as that actor's document.", {
|
|
151
|
+
documentUrl: documentUrl.href,
|
|
152
|
+
actorId: object.id?.href
|
|
153
|
+
});
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return object;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Resolves the owner that the given key claims, and returns it only if the
|
|
160
|
+
* claim holds.
|
|
161
|
+
*
|
|
162
|
+
* The `owner` of a {@link CryptographicKey}, like the `controller` of
|
|
163
|
+
* a {@link Multikey}, proves nothing on its own: the key document and the
|
|
164
|
+
* claim inside it are served by the same host, so anyone able to serve a key
|
|
165
|
+
* document can name any actor in the world as its owner. The claim becomes
|
|
166
|
+
* meaningful only once the named actor's own document is fetched and turns
|
|
167
|
+
* out to link back to the key. This function performs that mutual-link
|
|
168
|
+
* check, which is the only sound way to learn a fetched key's owner.
|
|
169
|
+
*
|
|
170
|
+
* The claimed owner is always dereferenced, never read out of the key
|
|
171
|
+
* document: an owner embedded there is written by whoever wrote the key.
|
|
172
|
+
*
|
|
173
|
+
* @param key The key whose ownership claim is to be verified. It must carry
|
|
174
|
+
* an `id`, as that is what the owner has to link back to.
|
|
175
|
+
* @param options Options for fetching the claimed owner.
|
|
176
|
+
* @returns The verified owner, or `null` if the key claims no owner, the
|
|
177
|
+
* owner cannot be fetched, or the owner does not link back to
|
|
178
|
+
* the key.
|
|
179
|
+
* @internal
|
|
180
|
+
*/
|
|
181
|
+
async function verifyKeyOwnership(key, options = {}) {
|
|
182
|
+
const logger = (0, _logtape_logtape.getLogger)([
|
|
183
|
+
"fedify",
|
|
184
|
+
"sig",
|
|
185
|
+
"key"
|
|
186
|
+
]);
|
|
187
|
+
const keyId = key.id;
|
|
188
|
+
if (keyId == null) return null;
|
|
189
|
+
const claimedOwnerId = key instanceof _fedify_vocab.CryptographicKey ? key.ownerId : key.controllerId;
|
|
190
|
+
if (claimedOwnerId == null) return null;
|
|
191
|
+
const owner = await fetchActorDocument(claimedOwnerId, options);
|
|
192
|
+
if (owner == null) {
|
|
193
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims could not be resolved.", {
|
|
194
|
+
keyId: keyId.href,
|
|
195
|
+
claimedOwnerId: claimedOwnerId.href
|
|
196
|
+
});
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
const linkedKeyIds = key instanceof _fedify_vocab.CryptographicKey ? owner.publicKeyIds : owner.assertionMethodIds;
|
|
200
|
+
for (const linkedKeyId of linkedKeyIds) if (linkedKeyId.href === keyId.href) return owner;
|
|
201
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims does not list the key as its own.", {
|
|
202
|
+
keyId: keyId.href,
|
|
203
|
+
claimedOwnerId: claimedOwnerId.href
|
|
204
|
+
});
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
96
208
|
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL.
|
|
97
209
|
* If the given URL contains an {@link Actor} object, it tries to find
|
|
98
210
|
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
@@ -161,8 +273,11 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
161
273
|
}
|
|
162
274
|
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
163
275
|
let document;
|
|
276
|
+
let documentUrl = cacheKey;
|
|
164
277
|
try {
|
|
165
|
-
|
|
278
|
+
const remoteDocument = await (documentLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)())(keyId);
|
|
279
|
+
document = remoteDocument.document;
|
|
280
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", cacheKey);
|
|
166
281
|
} catch (_) {
|
|
167
282
|
logger.debug("Failed to fetch key {keyId}.", { keyId });
|
|
168
283
|
await keyCache?.set(cacheKey, null);
|
|
@@ -199,8 +314,22 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
199
314
|
}
|
|
200
315
|
}
|
|
201
316
|
let key = null;
|
|
202
|
-
|
|
317
|
+
let ownerDocument = null;
|
|
318
|
+
if (object instanceof cls && (object.id == null || object.id.href === keyId)) key = object.id == null ? object.clone({ id: cacheKey }) : object;
|
|
203
319
|
else if ((0, _fedify_vocab.isActor)(object)) {
|
|
320
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
321
|
+
logger.debug("Failed to verify; the document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin.", {
|
|
322
|
+
keyId,
|
|
323
|
+
documentUrl: documentUrl.href,
|
|
324
|
+
actorId: object.id?.href
|
|
325
|
+
});
|
|
326
|
+
await keyCache?.set(cacheKey, null);
|
|
327
|
+
return {
|
|
328
|
+
key: null,
|
|
329
|
+
cached: false
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
ownerDocument = object;
|
|
204
333
|
const keys = cls === _fedify_vocab.CryptographicKey ? object.getPublicKeys({
|
|
205
334
|
documentLoader,
|
|
206
335
|
contextLoader,
|
|
@@ -259,6 +388,25 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
259
388
|
cached: false
|
|
260
389
|
};
|
|
261
390
|
}
|
|
391
|
+
const claimedOwnerId = key instanceof _fedify_vocab.CryptographicKey ? key.ownerId : key.controllerId;
|
|
392
|
+
if (ownerDocument != null && claimedOwnerId == null) key = key instanceof _fedify_vocab.CryptographicKey ? key.clone({ owner: ownerDocument.id }) : key.clone({ controller: ownerDocument.id });
|
|
393
|
+
else if (claimedOwnerId != null && claimedOwnerId.href !== ownerDocument?.id?.href) {
|
|
394
|
+
if (await verifyKeyOwnership(key, {
|
|
395
|
+
documentLoader,
|
|
396
|
+
contextLoader,
|
|
397
|
+
tracerProvider
|
|
398
|
+
}) == null) {
|
|
399
|
+
logger.debug("Failed to verify; the owner {claimedOwnerId} that key {keyId} claims does not list the key as its own.", {
|
|
400
|
+
keyId,
|
|
401
|
+
claimedOwnerId: claimedOwnerId.href
|
|
402
|
+
});
|
|
403
|
+
await keyCache?.set(cacheKey, null);
|
|
404
|
+
return {
|
|
405
|
+
key: null,
|
|
406
|
+
cached: false
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
262
410
|
if (keyCache != null) {
|
|
263
411
|
await keyCache.set(cacheKey, key);
|
|
264
412
|
logger.debug("Key {keyId} cached.", { keyId });
|
|
@@ -1122,6 +1270,12 @@ Object.defineProperty(exports, "exportJwk", {
|
|
|
1122
1270
|
return exportJwk;
|
|
1123
1271
|
}
|
|
1124
1272
|
});
|
|
1273
|
+
Object.defineProperty(exports, "fetchActorDocument", {
|
|
1274
|
+
enumerable: true,
|
|
1275
|
+
get: function() {
|
|
1276
|
+
return fetchActorDocument;
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1125
1279
|
Object.defineProperty(exports, "fetchKey", {
|
|
1126
1280
|
enumerable: true,
|
|
1127
1281
|
get: function() {
|
|
@@ -1158,6 +1312,12 @@ Object.defineProperty(exports, "validateCryptoKey", {
|
|
|
1158
1312
|
return validateCryptoKey;
|
|
1159
1313
|
}
|
|
1160
1314
|
});
|
|
1315
|
+
Object.defineProperty(exports, "verifyKeyOwnership", {
|
|
1316
|
+
enumerable: true,
|
|
1317
|
+
get: function() {
|
|
1318
|
+
return verifyKeyOwnership;
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1161
1321
|
Object.defineProperty(exports, "verifyRequest", {
|
|
1162
1322
|
enumerable: true,
|
|
1163
1323
|
get: function() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
3
|
-
import { TracerProvider } from "@opentelemetry/api";
|
|
2
|
+
import { Actor, CryptographicKey, Multikey } from "@fedify/vocab";
|
|
4
3
|
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
4
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
5
5
|
|
|
6
6
|
//#region src/sig/key.d.ts
|
|
7
7
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
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-
|
|
5
|
-
import {
|
|
4
|
+
import { n as version, t as name } from "./deno-eqaJj6JL.mjs";
|
|
5
|
+
import { o as validateCryptoKey, r as fetchKey } from "./key-bSphUqhB.mjs";
|
|
6
6
|
import { CryptographicKey } from "@fedify/vocab";
|
|
7
7
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
8
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
3
|
-
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
2
|
+
import { Actor, CryptographicKey, Multikey } from "@fedify/vocab";
|
|
4
3
|
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
5
5
|
|
|
6
6
|
//#region src/sig/key.d.ts
|
|
7
7
|
/**
|
|
@@ -10,7 +10,7 @@ import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
|
10
10
|
import { Item, decodeDict, encodeItem } from "structured-field-values";
|
|
11
11
|
//#region deno.json
|
|
12
12
|
var name = "@fedify/fedify";
|
|
13
|
-
var version = "2.0.28-dev.
|
|
13
|
+
var version = "2.0.28-dev.1982+a57dec3f";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/key.ts
|
|
16
16
|
/**
|
|
@@ -92,6 +92,118 @@ async function importJwk(jwk, type) {
|
|
|
92
92
|
return key;
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
|
+
* Fetches the document that the given actor URI dereferences to, and returns
|
|
96
|
+
* the actor only if the host that served the document is authoritative for
|
|
97
|
+
* the id the document claims.
|
|
98
|
+
*
|
|
99
|
+
* Only the origin that serves an actor id can speak for it. Without that
|
|
100
|
+
* rule any host could serve a document describing somebody else's actor—and
|
|
101
|
+
* listing its own keys as that actor's.
|
|
102
|
+
*
|
|
103
|
+
* @param actorId The URI of the actor to fetch.
|
|
104
|
+
* @param options Options for fetching the document.
|
|
105
|
+
* @returns The actor, or `null` if the document cannot be fetched, is not an
|
|
106
|
+
* actor, or belongs to another origin.
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
109
|
+
async function fetchActorDocument(actorId, options = {}) {
|
|
110
|
+
const logger = getLogger([
|
|
111
|
+
"fedify",
|
|
112
|
+
"sig",
|
|
113
|
+
"key"
|
|
114
|
+
]);
|
|
115
|
+
const documentLoader = options.documentLoader ?? getDocumentLoader();
|
|
116
|
+
const contextLoader = options.contextLoader ?? getDocumentLoader();
|
|
117
|
+
const { tracerProvider } = options;
|
|
118
|
+
let document;
|
|
119
|
+
let documentUrl = actorId;
|
|
120
|
+
try {
|
|
121
|
+
const remoteDocument = await documentLoader(actorId.href);
|
|
122
|
+
document = remoteDocument.document;
|
|
123
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", actorId);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
logger.debug("Failed to fetch the actor {actorId}: {error}", {
|
|
126
|
+
actorId: actorId.href,
|
|
127
|
+
error
|
|
128
|
+
});
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
let object;
|
|
132
|
+
try {
|
|
133
|
+
object = await Object$1.fromJsonLd(document, {
|
|
134
|
+
documentLoader,
|
|
135
|
+
contextLoader,
|
|
136
|
+
tracerProvider,
|
|
137
|
+
baseUrl: documentUrl
|
|
138
|
+
});
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (!(error instanceof TypeError)) throw error;
|
|
141
|
+
logger.debug("The document served at {documentUrl} is not a valid object: {error}", {
|
|
142
|
+
documentUrl: documentUrl.href,
|
|
143
|
+
error
|
|
144
|
+
});
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
if (!isActor(object)) return null;
|
|
148
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
149
|
+
logger.debug("The document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin; refusing to treat it as that actor's document.", {
|
|
150
|
+
documentUrl: documentUrl.href,
|
|
151
|
+
actorId: object.id?.href
|
|
152
|
+
});
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return object;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Resolves the owner that the given key claims, and returns it only if the
|
|
159
|
+
* claim holds.
|
|
160
|
+
*
|
|
161
|
+
* The `owner` of a {@link CryptographicKey}, like the `controller` of
|
|
162
|
+
* a {@link Multikey}, proves nothing on its own: the key document and the
|
|
163
|
+
* claim inside it are served by the same host, so anyone able to serve a key
|
|
164
|
+
* document can name any actor in the world as its owner. The claim becomes
|
|
165
|
+
* meaningful only once the named actor's own document is fetched and turns
|
|
166
|
+
* out to link back to the key. This function performs that mutual-link
|
|
167
|
+
* check, which is the only sound way to learn a fetched key's owner.
|
|
168
|
+
*
|
|
169
|
+
* The claimed owner is always dereferenced, never read out of the key
|
|
170
|
+
* document: an owner embedded there is written by whoever wrote the key.
|
|
171
|
+
*
|
|
172
|
+
* @param key The key whose ownership claim is to be verified. It must carry
|
|
173
|
+
* an `id`, as that is what the owner has to link back to.
|
|
174
|
+
* @param options Options for fetching the claimed owner.
|
|
175
|
+
* @returns The verified owner, or `null` if the key claims no owner, the
|
|
176
|
+
* owner cannot be fetched, or the owner does not link back to
|
|
177
|
+
* the key.
|
|
178
|
+
* @internal
|
|
179
|
+
*/
|
|
180
|
+
async function verifyKeyOwnership(key, options = {}) {
|
|
181
|
+
const logger = getLogger([
|
|
182
|
+
"fedify",
|
|
183
|
+
"sig",
|
|
184
|
+
"key"
|
|
185
|
+
]);
|
|
186
|
+
const keyId = key.id;
|
|
187
|
+
if (keyId == null) return null;
|
|
188
|
+
const claimedOwnerId = key instanceof CryptographicKey ? key.ownerId : key.controllerId;
|
|
189
|
+
if (claimedOwnerId == null) return null;
|
|
190
|
+
const owner = await fetchActorDocument(claimedOwnerId, options);
|
|
191
|
+
if (owner == null) {
|
|
192
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims could not be resolved.", {
|
|
193
|
+
keyId: keyId.href,
|
|
194
|
+
claimedOwnerId: claimedOwnerId.href
|
|
195
|
+
});
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
const linkedKeyIds = key instanceof CryptographicKey ? owner.publicKeyIds : owner.assertionMethodIds;
|
|
199
|
+
for (const linkedKeyId of linkedKeyIds) if (linkedKeyId.href === keyId.href) return owner;
|
|
200
|
+
logger.debug("The owner ({claimedOwnerId}) that key {keyId} claims does not list the key as its own.", {
|
|
201
|
+
keyId: keyId.href,
|
|
202
|
+
claimedOwnerId: claimedOwnerId.href
|
|
203
|
+
});
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
95
207
|
* Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL.
|
|
96
208
|
* If the given URL contains an {@link Actor} object, it tries to find
|
|
97
209
|
* the corresponding key in the `publicKey` or `assertionMethod` property.
|
|
@@ -160,8 +272,11 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
160
272
|
}
|
|
161
273
|
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
162
274
|
let document;
|
|
275
|
+
let documentUrl = cacheKey;
|
|
163
276
|
try {
|
|
164
|
-
|
|
277
|
+
const remoteDocument = await (documentLoader ?? getDocumentLoader())(keyId);
|
|
278
|
+
document = remoteDocument.document;
|
|
279
|
+
documentUrl = new URL(remoteDocument.documentUrl ?? "", cacheKey);
|
|
165
280
|
} catch (_) {
|
|
166
281
|
logger.debug("Failed to fetch key {keyId}.", { keyId });
|
|
167
282
|
await keyCache?.set(cacheKey, null);
|
|
@@ -198,8 +313,22 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
198
313
|
}
|
|
199
314
|
}
|
|
200
315
|
let key = null;
|
|
201
|
-
|
|
316
|
+
let ownerDocument = null;
|
|
317
|
+
if (object instanceof cls && (object.id == null || object.id.href === keyId)) key = object.id == null ? object.clone({ id: cacheKey }) : object;
|
|
202
318
|
else if (isActor(object)) {
|
|
319
|
+
if (object.id == null || object.id.origin !== documentUrl.origin) {
|
|
320
|
+
logger.debug("Failed to verify; the document served at {documentUrl} claims to be the actor {actorId}, which belongs to another origin.", {
|
|
321
|
+
keyId,
|
|
322
|
+
documentUrl: documentUrl.href,
|
|
323
|
+
actorId: object.id?.href
|
|
324
|
+
});
|
|
325
|
+
await keyCache?.set(cacheKey, null);
|
|
326
|
+
return {
|
|
327
|
+
key: null,
|
|
328
|
+
cached: false
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
ownerDocument = object;
|
|
203
332
|
const keys = cls === CryptographicKey ? object.getPublicKeys({
|
|
204
333
|
documentLoader,
|
|
205
334
|
contextLoader,
|
|
@@ -258,6 +387,25 @@ async function fetchKeyInternal(keyId, cls, { documentLoader, contextLoader, key
|
|
|
258
387
|
cached: false
|
|
259
388
|
};
|
|
260
389
|
}
|
|
390
|
+
const claimedOwnerId = key instanceof CryptographicKey ? key.ownerId : key.controllerId;
|
|
391
|
+
if (ownerDocument != null && claimedOwnerId == null) key = key instanceof CryptographicKey ? key.clone({ owner: ownerDocument.id }) : key.clone({ controller: ownerDocument.id });
|
|
392
|
+
else if (claimedOwnerId != null && claimedOwnerId.href !== ownerDocument?.id?.href) {
|
|
393
|
+
if (await verifyKeyOwnership(key, {
|
|
394
|
+
documentLoader,
|
|
395
|
+
contextLoader,
|
|
396
|
+
tracerProvider
|
|
397
|
+
}) == null) {
|
|
398
|
+
logger.debug("Failed to verify; the owner {claimedOwnerId} that key {keyId} claims does not list the key as its own.", {
|
|
399
|
+
keyId,
|
|
400
|
+
claimedOwnerId: claimedOwnerId.href
|
|
401
|
+
});
|
|
402
|
+
await keyCache?.set(cacheKey, null);
|
|
403
|
+
return {
|
|
404
|
+
key: null,
|
|
405
|
+
cached: false
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
}
|
|
261
409
|
if (keyCache != null) {
|
|
262
410
|
await keyCache.set(cacheKey, key);
|
|
263
411
|
logger.debug("Key {keyId} cached.", { keyId });
|
|
@@ -1109,4 +1257,4 @@ function timingSafeEqual(a, b) {
|
|
|
1109
1257
|
return result === 0;
|
|
1110
1258
|
}
|
|
1111
1259
|
//#endregion
|
|
1112
|
-
export {
|
|
1260
|
+
export { fetchActorDocument as a, importJwk as c, name as d, version as f, exportJwk as i, validateCryptoKey as l, signRequest as n, fetchKey as o, verifyRequest as r, generateCryptoKeyPair as s, doubleKnock as t, verifyKeyOwnership as u };
|
|
@@ -1,7 +1,7 @@
|
|
|
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-
|
|
4
|
+
import { n as version, t as name } from "./deno-eqaJj6JL.mjs";
|
|
5
5
|
import { Activity, getTypeId } from "@fedify/vocab";
|
|
6
6
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|