@fedify/fedify 2.4.2 → 2.4.4
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/{builder-9ovCSqLp.mjs → builder-DdY0E0w9.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-G2J_bU0u.mjs → compound-proof-fxkyiXYM.mjs} +2 -2
- package/dist/{deno-BZ4z-lJJ.mjs → deno-CO1X_K_q.mjs} +1 -1
- package/dist/{docloader-DUXXI-7G.mjs → docloader-DFB_TNVp.mjs} +6 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +5 -5
- package/dist/federation/handler.test.mjs +258 -5
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +43 -0
- package/dist/federation/keycache.test.mjs +20 -9
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +173 -11
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +4 -4
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +5 -5
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-DpT8bDM6.cjs → federation-Bf4FEork.cjs} +122 -21
- package/dist/{http-Qq7jR2rC.js → http-D_AGUmSq.js} +17 -3
- package/dist/{http-B5w_qcIg.mjs → http-DkLKT8Vp.mjs} +4 -4
- package/dist/{http-x1satM4y.cjs → http-g5f1D2tm.cjs} +17 -3
- package/dist/inbox-Di1-EKqa.mjs +188 -0
- package/dist/{keycache-D-MNltOk.mjs → keycache-N2opu4-3.mjs} +1 -1
- package/dist/{kv-cache-BgQMAKIg.mjs → kv-cache-BxfOpUP9.mjs} +1 -1
- package/dist/{kv-cache-B0SZfzFb.js → kv-cache-C0AsMZ4U.js} +5 -1
- package/dist/{kv-cache-D4throaQ.cjs → kv-cache-HsXADkl9.cjs} +5 -1
- package/dist/{ld-Dkkyk65e.mjs → ld-Cy86r-Ty.mjs} +18 -4
- package/dist/{metrics-CRv6_IBg.mjs → metrics-BguhdXt-.mjs} +1 -1
- package/dist/{middleware-BqefXH6B.js → middleware-BOBF7req.js} +122 -21
- package/dist/{middleware-DFtNaBcH.mjs → middleware-BYojyPi4.mjs} +1 -1
- package/dist/{middleware-C-swet0z.mjs → middleware-C_gtR3fV.mjs} +104 -180
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-BHUhedVc.mjs → owner-Dc-Lg_Xn.mjs} +3 -3
- package/dist/{portable-collection-DL-1Wy1s.cjs → portable-collection-Bl2UkqcO.cjs} +1 -1
- package/dist/{portable-collection-CfIc190c.js → portable-collection-CjdP7fQ4.js} +1 -1
- package/dist/{portable-collection-DONEPTXV.mjs → portable-collection-DSKqMgvr.mjs} +2 -2
- package/dist/{portable-key-Cdw3vfl-.mjs → portable-key-ClXZ25LT.mjs} +1 -1
- package/dist/{proof-DuSE1ABD.mjs → proof-kJtQ49gr.mjs} +3 -3
- package/dist/{send-D9oTjA6A.mjs → send-D6hcL5qf.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +3 -3
- package/dist/sig/key.test.mjs +196 -1
- package/dist/sig/ld.test.mjs +46 -1
- package/dist/sig/mitra-receive-interop.test.mjs +4 -4
- package/dist/sig/mitra-send-interop.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +46 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.mjs +3 -3
- package/dist/sig/portable-key.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +54 -3
- package/dist/sig/tootik-request-interop.test.mjs +4 -4
- package/dist/sig/tootik-send-interop.test.mjs +3 -3
- package/dist/sig/verification.test.mjs +3 -3
- package/dist/{temporal-iyAxBq0I.mjs → temporal-C8WqyM34.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +176 -37
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { i as getPortableDid, l as isPortableId, n as getCanonicalPortableId } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
+
import { n as version, t as name } from "./deno-CO1X_K_q.mjs";
|
|
6
6
|
import { t as ActivityListenerSet } from "./activity-listener-C-BSbKI7.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
@@ -91,7 +91,7 @@ var FederationBuilderImpl = class {
|
|
|
91
91
|
* specified.
|
|
92
92
|
*/
|
|
93
93
|
async build(options) {
|
|
94
|
-
const { FederationImpl } = await import("./middleware-
|
|
94
|
+
const { FederationImpl } = await import("./middleware-BYojyPi4.mjs");
|
|
95
95
|
const f = new FederationImpl(options);
|
|
96
96
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
97
97
|
f.router = this.router.clone();
|
|
@@ -5,7 +5,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
7
7
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
8
|
-
import { O as actorDehydrator, k as autoIdAssigner, n as FederationImpl } from "../middleware-
|
|
8
|
+
import { O as actorDehydrator, k as autoIdAssigner, n as FederationImpl } from "../middleware-C_gtR3fV.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,9 +3,9 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { a as getRawCanonicalPortableId, l as isPortableId, n as getCanonicalPortableId } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
5
|
import { a as verificationObservation, t as observeAttempt } from "./verification-Dpfcw8ml.mjs";
|
|
6
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
6
|
+
import { c as getNormalizationContextLoader } from "./ld-Cy86r-Ty.mjs";
|
|
7
7
|
import { n as preloadedOnlyDocumentLoader } from "./public-audience--klBIOk1.mjs";
|
|
8
|
-
import { l as verifyPortableObjectProofPolicy, n as classifyFep2277CoreType, o as verifyMapLocalProof } from "./proof-
|
|
8
|
+
import { l as verifyPortableObjectProofPolicy, n as classifyFep2277CoreType, o as verifyMapLocalProof } from "./proof-kJtQ49gr.mjs";
|
|
9
9
|
import { parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
10
10
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
11
11
|
//#region src/sig/compound-proof.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { T as validateCryptoKey } from "./ld-
|
|
5
|
-
import { n as doubleKnock } from "./http-
|
|
4
|
+
import { T as validateCryptoKey } from "./ld-Cy86r-Ty.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-DkLKT8Vp.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, resolveDocumentLoaderTimeout, validatePublicUrl, withDocumentLoaderTimeout } from "@fedify/vocab-runtime";
|
|
8
8
|
import { curry } from "es-toolkit";
|
|
@@ -64,6 +64,10 @@ function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedi
|
|
|
64
64
|
}, options);
|
|
65
65
|
}
|
|
66
66
|
async function validateUrl(url, options) {
|
|
67
|
+
const parsedUrl = new URL(url);
|
|
68
|
+
const protocol = parsedUrl.protocol;
|
|
69
|
+
if (protocol !== "http:" && protocol !== "https:") throw new UrlError(`Unsupported protocol: ${protocol}`);
|
|
70
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
67
71
|
if (!allowPrivateAddress) {
|
|
68
72
|
try {
|
|
69
73
|
await validatePublicUrl(url);
|
|
@@ -7,7 +7,7 @@ import { t as assertExists } from "../assert_exists-cffSpJ7X.mjs";
|
|
|
7
7
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
10
|
-
import { r as createFederationBuilder } from "../builder-
|
|
10
|
+
import { r as createFederationBuilder } from "../builder-DdY0E0w9.mjs";
|
|
11
11
|
import { DisallowedOperatorError, DisallowedVarSpecModifierError, DuplicateRouteVariableError, RouteTemplateOptionsNotMatchedError, RouterError } from "@fedify/uri-template";
|
|
12
12
|
import { Activity, Note, Person } from "@fedify/vocab";
|
|
13
13
|
import { test } from "@fedify/fixture";
|
|
@@ -6,11 +6,11 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
9
|
-
import { y as exportJwk } from "../ld-
|
|
9
|
+
import { y as exportJwk } from "../ld-Cy86r-Ty.mjs";
|
|
10
10
|
import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-4IJqPYos.mjs";
|
|
11
|
-
import { a as signObject, d as verifyProof } from "../proof-
|
|
11
|
+
import { a as signObject, d as verifyProof } from "../proof-kJtQ49gr.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { n as FederationImpl } from "../middleware-
|
|
13
|
+
import { n as FederationImpl } from "../middleware-C_gtR3fV.mjs";
|
|
14
14
|
import { Create, DataIntegrityProof, Note } from "@fedify/vocab";
|
|
15
15
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
16
16
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -5,10 +5,10 @@ import { r as createRequestContext, t as createInboxContext } from "../context-8
|
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
|
-
import { a as compactJsonLd, m as verifyCompactJsonLd, p as signJsonLd } from "../ld-
|
|
9
|
-
import { l as signRequest } from "../http-
|
|
8
|
+
import { a as compactJsonLd, m as verifyCompactJsonLd, p as signJsonLd } from "../ld-Cy86r-Ty.mjs";
|
|
9
|
+
import { l as signRequest } from "../http-DkLKT8Vp.mjs";
|
|
10
10
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
11
|
-
import { f as handleInbox, o as createFederation } from "../middleware-
|
|
11
|
+
import { f as handleInbox, o as createFederation } from "../middleware-C_gtR3fV.mjs";
|
|
12
12
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
13
13
|
import { t as map_local_create_note_default } from "../map-local-create-note-B0SeXJms.mjs";
|
|
14
14
|
import { Create, CryptographicKey, Multikey, Person, Update } from "@fedify/vocab";
|
|
@@ -134,7 +134,7 @@ test("handleInbox() enforces compounds after alternate outer auth", async () =>
|
|
|
134
134
|
test("handleInbox() preserves ordinary top-level proof behavior", async () => {
|
|
135
135
|
assertEquals((await handle(await secureDocument({
|
|
136
136
|
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
137
|
-
id:
|
|
137
|
+
id: `${map_local_create_note_default.keys.outer.controller}/activities/ordinary`,
|
|
138
138
|
type: "Create",
|
|
139
139
|
actor: map_local_create_note_default.keys.outer.controller,
|
|
140
140
|
object: {
|
|
@@ -254,7 +254,7 @@ test("handleInbox() keeps embedded signature properties in proof inputs", async
|
|
|
254
254
|
test("handleInbox() inspects compounds without the Linked Data Signature", async () => {
|
|
255
255
|
const activity = await secureDocument({
|
|
256
256
|
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"],
|
|
257
|
-
id:
|
|
257
|
+
id: `${map_local_create_note_default.keys.outer.controller}/activities/ordinary-ld`,
|
|
258
258
|
type: "Create",
|
|
259
259
|
actor: map_local_create_note_default.keys.outer.controller,
|
|
260
260
|
object: {
|
|
@@ -10,11 +10,11 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
10
10
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
11
11
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
12
|
import { r as parseAcceptSignature } from "../accept-CPVqki78.mjs";
|
|
13
|
-
import { C as generateCryptoKeyPair, a as compactJsonLd, p as signJsonLd } from "../ld-
|
|
14
|
-
import { a as signObject } from "../proof-
|
|
15
|
-
import { l as signRequest } from "../http-
|
|
16
|
-
import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
17
|
-
import { d as handleCustomCollection, f as handleInbox, g as respondWithObjectIfAcceptable, h as respondWithObject, l as handleActor, m as handleOutbox, o as createFederation, p as handleObject, u as handleCollection } from "../middleware-
|
|
13
|
+
import { C as generateCryptoKeyPair, a as compactJsonLd, p as signJsonLd } from "../ld-Cy86r-Ty.mjs";
|
|
14
|
+
import { a as signObject } from "../proof-kJtQ49gr.mjs";
|
|
15
|
+
import { l as signRequest } from "../http-DkLKT8Vp.mjs";
|
|
16
|
+
import { a as rsaPrivateKey3, c as rsaPublicKey3, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
17
|
+
import { d as handleCustomCollection, f as handleInbox, g as respondWithObjectIfAcceptable, h as respondWithObject, l as handleActor, m as handleOutbox, o as createFederation, p as handleObject, u as handleCollection } from "../middleware-C_gtR3fV.mjs";
|
|
18
18
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
19
19
|
import { Activity, Create, CryptographicKey, Multikey, Note, Person, Tombstone } from "@fedify/vocab";
|
|
20
20
|
import { FetchError, parseIri } from "@fedify/vocab-runtime";
|
|
@@ -3341,6 +3341,259 @@ test("handleInbox() - authentication bypass vulnerability", async () => {
|
|
|
3341
3341
|
assertEquals(await response.text(), "The signer and the actor do not match.");
|
|
3342
3342
|
assertEquals(processedActivity, void 0, `SECURITY VULNERABILITY: Malicious activity with mismatched signature was processed! Activity ID: ${processedActivity?.id?.href}, Claimed actor: ${processedActivity?.actorId?.href}`);
|
|
3343
3343
|
});
|
|
3344
|
+
test("handleInbox() rejects cross-origin activity IDs", async () => {
|
|
3345
|
+
const federation = createFederation({ kv: new MemoryKvStore() });
|
|
3346
|
+
const kv = new MemoryKvStore();
|
|
3347
|
+
const inboxListeners = new ActivityListenerSet();
|
|
3348
|
+
let idempotencyCalls = 0;
|
|
3349
|
+
let listenerCalls = 0;
|
|
3350
|
+
inboxListeners.add(Create, () => {
|
|
3351
|
+
listenerCalls++;
|
|
3352
|
+
});
|
|
3353
|
+
const activity = new Create({
|
|
3354
|
+
id: new URL("https://victim.example/activities/1"),
|
|
3355
|
+
actor: rsaPublicKey3.ownerId,
|
|
3356
|
+
object: new Note({ content: "Forged" })
|
|
3357
|
+
});
|
|
3358
|
+
const activityJson = await activity.toJsonLd({
|
|
3359
|
+
format: "compact",
|
|
3360
|
+
contextLoader: mockDocumentLoader
|
|
3361
|
+
});
|
|
3362
|
+
const proofSigned = await signObject(activity, ed25519PrivateKey, ed25519Multikey.id, {
|
|
3363
|
+
contextLoader: mockDocumentLoader,
|
|
3364
|
+
documentLoader: mockDocumentLoader
|
|
3365
|
+
});
|
|
3366
|
+
const requests = [
|
|
3367
|
+
await signRequest(new Request("https://local.example/inbox", {
|
|
3368
|
+
method: "POST",
|
|
3369
|
+
body: JSON.stringify(activityJson)
|
|
3370
|
+
}), rsaPrivateKey3, rsaPublicKey3.id),
|
|
3371
|
+
new Request("https://local.example/inbox", {
|
|
3372
|
+
method: "POST",
|
|
3373
|
+
body: JSON.stringify(await signJsonLd(activityJson, rsaPrivateKey3, rsaPublicKey3.id, { contextLoader: mockDocumentLoader }))
|
|
3374
|
+
}),
|
|
3375
|
+
new Request("https://local.example/inbox", {
|
|
3376
|
+
method: "POST",
|
|
3377
|
+
body: JSON.stringify(await proofSigned.toJsonLd({
|
|
3378
|
+
format: "compact",
|
|
3379
|
+
contextLoader: mockDocumentLoader
|
|
3380
|
+
}))
|
|
3381
|
+
}),
|
|
3382
|
+
await signRequest(new Request("https://local.example/inbox", {
|
|
3383
|
+
method: "POST",
|
|
3384
|
+
body: JSON.stringify(await new Create({
|
|
3385
|
+
id: new URL("https://example.com/activities/multiple-actors"),
|
|
3386
|
+
actors: [rsaPublicKey3.ownerId, new URL("https://attacker.example/actor")]
|
|
3387
|
+
}).toJsonLd())
|
|
3388
|
+
}), rsaPrivateKey3, rsaPublicKey3.id)
|
|
3389
|
+
];
|
|
3390
|
+
for (const request of requests) {
|
|
3391
|
+
const context = createRequestContext({
|
|
3392
|
+
federation,
|
|
3393
|
+
request,
|
|
3394
|
+
url: new URL(request.url),
|
|
3395
|
+
data: void 0,
|
|
3396
|
+
documentLoader: mockDocumentLoader,
|
|
3397
|
+
contextLoader: mockDocumentLoader
|
|
3398
|
+
});
|
|
3399
|
+
const response = await handleInbox(request, {
|
|
3400
|
+
recipient: null,
|
|
3401
|
+
context,
|
|
3402
|
+
inboxContextFactory(_activity) {
|
|
3403
|
+
return createInboxContext({
|
|
3404
|
+
...context,
|
|
3405
|
+
clone: void 0
|
|
3406
|
+
});
|
|
3407
|
+
},
|
|
3408
|
+
kv,
|
|
3409
|
+
kvPrefixes: {
|
|
3410
|
+
activityIdempotence: ["_fedify", "activityIdempotence"],
|
|
3411
|
+
publicKey: ["_fedify", "publicKey"],
|
|
3412
|
+
acceptSignatureNonce: ["_fedify", "acceptSignatureNonce"]
|
|
3413
|
+
},
|
|
3414
|
+
actorDispatcher: () => null,
|
|
3415
|
+
inboxListeners,
|
|
3416
|
+
idempotencyStrategy() {
|
|
3417
|
+
idempotencyCalls++;
|
|
3418
|
+
return "forged";
|
|
3419
|
+
},
|
|
3420
|
+
onNotFound: () => new Response("Not found", { status: 404 }),
|
|
3421
|
+
signatureTimeWindow: { minutes: 5 },
|
|
3422
|
+
skipSignatureVerification: false
|
|
3423
|
+
});
|
|
3424
|
+
assertEquals([response.status, await response.text()], [401, "The activity and its actors do not have the same origin."]);
|
|
3425
|
+
}
|
|
3426
|
+
assertEquals(idempotencyCalls, 0);
|
|
3427
|
+
assertEquals(listenerCalls, 0);
|
|
3428
|
+
});
|
|
3429
|
+
test("handleInbox() preserves the signature-verification opt-out", async () => {
|
|
3430
|
+
const federation = createFederation({ kv: new MemoryKvStore() });
|
|
3431
|
+
const activity = new Create({
|
|
3432
|
+
id: new URL("https://victim.example/activities/1"),
|
|
3433
|
+
actor: new URL("https://attacker.example/actor")
|
|
3434
|
+
});
|
|
3435
|
+
const request = new Request("https://local.example/inbox", {
|
|
3436
|
+
method: "POST",
|
|
3437
|
+
body: JSON.stringify(await activity.toJsonLd())
|
|
3438
|
+
});
|
|
3439
|
+
const context = createRequestContext({
|
|
3440
|
+
federation,
|
|
3441
|
+
request,
|
|
3442
|
+
url: new URL(request.url),
|
|
3443
|
+
data: void 0,
|
|
3444
|
+
documentLoader: mockDocumentLoader
|
|
3445
|
+
});
|
|
3446
|
+
let listenerCalls = 0;
|
|
3447
|
+
const inboxListeners = new ActivityListenerSet();
|
|
3448
|
+
inboxListeners.add(Create, () => {
|
|
3449
|
+
listenerCalls++;
|
|
3450
|
+
});
|
|
3451
|
+
assertEquals((await handleInbox(request, {
|
|
3452
|
+
recipient: null,
|
|
3453
|
+
context,
|
|
3454
|
+
inboxContextFactory(_activity) {
|
|
3455
|
+
return createInboxContext({
|
|
3456
|
+
...context,
|
|
3457
|
+
clone: void 0
|
|
3458
|
+
});
|
|
3459
|
+
},
|
|
3460
|
+
kv: new MemoryKvStore(),
|
|
3461
|
+
kvPrefixes: {
|
|
3462
|
+
activityIdempotence: ["_fedify", "activityIdempotence"],
|
|
3463
|
+
publicKey: ["_fedify", "publicKey"],
|
|
3464
|
+
acceptSignatureNonce: ["_fedify", "acceptSignatureNonce"]
|
|
3465
|
+
},
|
|
3466
|
+
actorDispatcher: () => null,
|
|
3467
|
+
inboxListeners,
|
|
3468
|
+
onNotFound: () => new Response("Not found", { status: 404 }),
|
|
3469
|
+
signatureTimeWindow: { minutes: 5 },
|
|
3470
|
+
skipSignatureVerification: true
|
|
3471
|
+
})).status, 202);
|
|
3472
|
+
assertEquals(listenerCalls, 1);
|
|
3473
|
+
});
|
|
3474
|
+
test("handleInbox() rejects missing actors before idempotency", async () => {
|
|
3475
|
+
const federation = createFederation({ kv: new MemoryKvStore() });
|
|
3476
|
+
const unsignedJson = {
|
|
3477
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
3478
|
+
id: "https://remote.example/activities/actorless",
|
|
3479
|
+
type: "Create"
|
|
3480
|
+
};
|
|
3481
|
+
const requests = [new Request("https://local.example/inbox", {
|
|
3482
|
+
method: "POST",
|
|
3483
|
+
body: JSON.stringify(unsignedJson)
|
|
3484
|
+
}), new Request("https://local.example/inbox", {
|
|
3485
|
+
method: "POST",
|
|
3486
|
+
body: JSON.stringify(await signJsonLd(unsignedJson, rsaPrivateKey3, rsaPublicKey3.id, { contextLoader: mockDocumentLoader }))
|
|
3487
|
+
})];
|
|
3488
|
+
let idempotencyCalls = 0;
|
|
3489
|
+
for (const request of requests) {
|
|
3490
|
+
const context = createRequestContext({
|
|
3491
|
+
federation,
|
|
3492
|
+
request,
|
|
3493
|
+
url: new URL(request.url),
|
|
3494
|
+
data: void 0,
|
|
3495
|
+
documentLoader: mockDocumentLoader,
|
|
3496
|
+
contextLoader: mockDocumentLoader
|
|
3497
|
+
});
|
|
3498
|
+
const response = await handleInbox(request, {
|
|
3499
|
+
recipient: null,
|
|
3500
|
+
context,
|
|
3501
|
+
inboxContextFactory(_activity) {
|
|
3502
|
+
return createInboxContext({
|
|
3503
|
+
...context,
|
|
3504
|
+
clone: void 0
|
|
3505
|
+
});
|
|
3506
|
+
},
|
|
3507
|
+
kv: new MemoryKvStore(),
|
|
3508
|
+
kvPrefixes: {
|
|
3509
|
+
activityIdempotence: ["_fedify", "activityIdempotence"],
|
|
3510
|
+
publicKey: ["_fedify", "publicKey"],
|
|
3511
|
+
acceptSignatureNonce: ["_fedify", "acceptSignatureNonce"]
|
|
3512
|
+
},
|
|
3513
|
+
actorDispatcher: () => null,
|
|
3514
|
+
idempotencyStrategy() {
|
|
3515
|
+
idempotencyCalls++;
|
|
3516
|
+
return "actorless";
|
|
3517
|
+
},
|
|
3518
|
+
onNotFound: () => new Response("Not found", { status: 404 }),
|
|
3519
|
+
signatureTimeWindow: { minutes: 5 },
|
|
3520
|
+
skipSignatureVerification: false
|
|
3521
|
+
});
|
|
3522
|
+
assertEquals([response.status, await response.text()], [400, "Missing actor."]);
|
|
3523
|
+
}
|
|
3524
|
+
assertEquals(idempotencyCalls, 0);
|
|
3525
|
+
});
|
|
3526
|
+
test("handleInbox() leaves a rejected activity ID available", async () => {
|
|
3527
|
+
const activityId = new URL("https://example.com/activities/genuine");
|
|
3528
|
+
const attackerId = new URL("https://attacker.example/actor");
|
|
3529
|
+
const attackerKeyId = new URL(`${attackerId.href}#main-key`);
|
|
3530
|
+
const attackerKeys = await generateCryptoKeyPair("RSASSA-PKCS1-v1_5");
|
|
3531
|
+
const attackerDocument = await new Person({
|
|
3532
|
+
id: attackerId,
|
|
3533
|
+
publicKey: new CryptographicKey({
|
|
3534
|
+
id: attackerKeyId,
|
|
3535
|
+
owner: attackerId,
|
|
3536
|
+
publicKey: attackerKeys.publicKey
|
|
3537
|
+
})
|
|
3538
|
+
}).toJsonLd({ contextLoader: mockDocumentLoader });
|
|
3539
|
+
const documentLoader = (resource) => resource === attackerId.href || resource === attackerKeyId.href ? Promise.resolve({
|
|
3540
|
+
contextUrl: null,
|
|
3541
|
+
documentUrl: resource,
|
|
3542
|
+
document: attackerDocument
|
|
3543
|
+
}) : mockDocumentLoader(resource);
|
|
3544
|
+
for (const strategy of ["per-inbox", "global"]) {
|
|
3545
|
+
const kv = new MemoryKvStore();
|
|
3546
|
+
const federation = createFederation({ kv });
|
|
3547
|
+
const inboxListeners = new ActivityListenerSet();
|
|
3548
|
+
const received = [];
|
|
3549
|
+
inboxListeners.add(Create, (_ctx, activity) => {
|
|
3550
|
+
received.push(activity.actorId.href);
|
|
3551
|
+
});
|
|
3552
|
+
const handle = async (request) => {
|
|
3553
|
+
const context = createRequestContext({
|
|
3554
|
+
federation,
|
|
3555
|
+
request,
|
|
3556
|
+
url: new URL(request.url),
|
|
3557
|
+
data: void 0,
|
|
3558
|
+
documentLoader,
|
|
3559
|
+
contextLoader: mockDocumentLoader
|
|
3560
|
+
});
|
|
3561
|
+
return await handleInbox(request, {
|
|
3562
|
+
recipient: null,
|
|
3563
|
+
context,
|
|
3564
|
+
inboxContextFactory(_activity) {
|
|
3565
|
+
return createInboxContext({
|
|
3566
|
+
...context,
|
|
3567
|
+
clone: void 0
|
|
3568
|
+
});
|
|
3569
|
+
},
|
|
3570
|
+
kv,
|
|
3571
|
+
kvPrefixes: {
|
|
3572
|
+
activityIdempotence: ["_fedify", "activityIdempotence"],
|
|
3573
|
+
publicKey: ["_fedify", "publicKey"],
|
|
3574
|
+
acceptSignatureNonce: ["_fedify", "acceptSignatureNonce"]
|
|
3575
|
+
},
|
|
3576
|
+
actorDispatcher: () => null,
|
|
3577
|
+
inboxListeners,
|
|
3578
|
+
idempotencyStrategy: strategy,
|
|
3579
|
+
onNotFound: () => new Response("Not found", { status: 404 }),
|
|
3580
|
+
signatureTimeWindow: { minutes: 5 },
|
|
3581
|
+
skipSignatureVerification: false
|
|
3582
|
+
});
|
|
3583
|
+
};
|
|
3584
|
+
const createRequest = async (actor, privateKey, keyId) => await signRequest(new Request("https://local.example/inbox", {
|
|
3585
|
+
method: "POST",
|
|
3586
|
+
body: JSON.stringify(await new Create({
|
|
3587
|
+
id: activityId,
|
|
3588
|
+
actor
|
|
3589
|
+
}).toJsonLd())
|
|
3590
|
+
}), privateKey, keyId);
|
|
3591
|
+
const forged = await handle(await createRequest(attackerId, attackerKeys.privateKey, attackerKeyId));
|
|
3592
|
+
const genuine = await handle(await createRequest(rsaPublicKey3.ownerId, rsaPrivateKey3, rsaPublicKey3.id));
|
|
3593
|
+
assertEquals([forged.status, genuine.status], [401, 202]);
|
|
3594
|
+
assertEquals(received, [rsaPublicKey3.ownerId.href]);
|
|
3595
|
+
}
|
|
3596
|
+
});
|
|
3344
3597
|
test("respondWithObjectIfAcceptable", async () => {
|
|
3345
3598
|
let request = new Request("https://example.com/", { headers: { Accept: "application/activity+json" } });
|
|
3346
3599
|
let response = await respondWithObjectIfAcceptable(new Note({
|
|
@@ -10,8 +10,8 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
10
10
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
11
11
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
12
|
import { r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { o as createFederation, x as parseHashlinkGatewayRequest } from "../middleware-
|
|
14
|
-
import { r as createFederationBuilder } from "../builder-
|
|
13
|
+
import { o as createFederation, x as parseHashlinkGatewayRequest } from "../middleware-C_gtR3fV.mjs";
|
|
14
|
+
import { r as createFederationBuilder } from "../builder-DdY0E0w9.mjs";
|
|
15
15
|
import { n as RouterError } from "../router-u5O5KCQr.mjs";
|
|
16
16
|
import { Note } from "@fedify/vocab";
|
|
17
17
|
import { computeDigestMultibase, encodeMultibase, exportDidKey } from "@fedify/vocab-runtime";
|
|
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
|
-
import { a as signObject } from "../proof-
|
|
7
|
+
import { a as signObject } from "../proof-kJtQ49gr.mjs";
|
|
8
8
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-C_gtR3fV.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
|
|
@@ -2,12 +2,12 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
|
-
import { p as signJsonLd } from "../ld-
|
|
6
|
-
import { a as signObject } from "../proof-
|
|
7
|
-
import { l as signRequest } from "../http-
|
|
5
|
+
import { p as signJsonLd } from "../ld-Cy86r-Ty.mjs";
|
|
6
|
+
import { a as signObject } from "../proof-kJtQ49gr.mjs";
|
|
7
|
+
import { l as signRequest } from "../http-DkLKT8Vp.mjs";
|
|
8
8
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
10
|
-
import { r as createFederationBuilder } from "../builder-
|
|
9
|
+
import { o as createFederation } from "../middleware-C_gtR3fV.mjs";
|
|
10
|
+
import { r as createFederationBuilder } from "../builder-DdY0E0w9.mjs";
|
|
11
11
|
import { Create, Person } from "@fedify/vocab";
|
|
12
12
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
13
13
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -2,11 +2,54 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
5
|
+
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
5
6
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
6
7
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
8
|
+
import { t as actorsHaveSameOrigin } from "../inbox-Di1-EKqa.mjs";
|
|
7
9
|
import { Activity, Create, Invite, Offer, Update } from "@fedify/vocab";
|
|
10
|
+
import { parseIri } from "@fedify/vocab-runtime";
|
|
8
11
|
import { test } from "@fedify/fixture";
|
|
9
12
|
//#region src/federation/inbox.test.ts
|
|
13
|
+
test("actorsHaveSameOrigin()", () => {
|
|
14
|
+
assertEquals(actorsHaveSameOrigin(new Create({ actor: new URL("https://remote.example/actor") })), true);
|
|
15
|
+
assertEquals(actorsHaveSameOrigin(new Create({
|
|
16
|
+
id: new URL("https://remote.example/activity"),
|
|
17
|
+
actors: [new URL("https://remote.example/actor/1"), new URL("https://remote.example:443/actor/2")]
|
|
18
|
+
})), true);
|
|
19
|
+
for (const actor of [
|
|
20
|
+
"http://remote.example/actor",
|
|
21
|
+
"https://sub.remote.example/actor",
|
|
22
|
+
"https://remote.example:8443/actor"
|
|
23
|
+
]) assertFalse(actorsHaveSameOrigin(new Create({
|
|
24
|
+
id: new URL("https://remote.example/activity"),
|
|
25
|
+
actor: new URL(actor)
|
|
26
|
+
})));
|
|
27
|
+
assertFalse(actorsHaveSameOrigin(new Create({
|
|
28
|
+
id: new URL("urn:example:activity"),
|
|
29
|
+
actor: new URL("urn:example:actor")
|
|
30
|
+
})));
|
|
31
|
+
assertFalse(actorsHaveSameOrigin(new Create({
|
|
32
|
+
id: new URL("https://remote.example/activity"),
|
|
33
|
+
actors: [new URL("https://remote.example/actor/1"), new URL("https://other.example/actor/2")]
|
|
34
|
+
})));
|
|
35
|
+
});
|
|
36
|
+
test("actorsHaveSameOrigin() compares portable IDs by their DIDs", () => {
|
|
37
|
+
const did = "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2";
|
|
38
|
+
const otherDid = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK";
|
|
39
|
+
const activityId = parseIri(`ap+ef61://${did}/activities/1`);
|
|
40
|
+
for (const actor of [`ap+ef61://${did}/actor`, `https://gw.example/.well-known/apgateway/${did}/actor`]) assertEquals(actorsHaveSameOrigin(new Create({
|
|
41
|
+
id: activityId,
|
|
42
|
+
actor: parseIri(actor)
|
|
43
|
+
})), true);
|
|
44
|
+
for (const actor of [
|
|
45
|
+
`ap+ef61://${otherDid}/actor`,
|
|
46
|
+
`https://gw.example/.well-known/apgateway/${otherDid}/actor`,
|
|
47
|
+
"https://gw.example/actor"
|
|
48
|
+
]) assertFalse(actorsHaveSameOrigin(new Create({
|
|
49
|
+
id: activityId,
|
|
50
|
+
actor: parseIri(actor)
|
|
51
|
+
})));
|
|
52
|
+
});
|
|
10
53
|
test("ActivityListenerSet", () => {
|
|
11
54
|
const listeners = new ActivityListenerSet();
|
|
12
55
|
const activity = new Activity({});
|
|
@@ -6,7 +6,7 @@ import { t as ManualClockKvStore } from "../kv-DBRWVx3Q.mjs";
|
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
8
8
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
9
|
-
import { t as KvKeyCache } from "../keycache-
|
|
9
|
+
import { t as KvKeyCache } from "../keycache-N2opu4-3.mjs";
|
|
10
10
|
import { CryptographicKey, Multikey } from "@fedify/vocab";
|
|
11
11
|
import { test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/keycache.test.ts
|
|
@@ -16,7 +16,7 @@ test("KvKeyCache.set()", async () => {
|
|
|
16
16
|
await cache.set(new URL("https://example.com/key"), new CryptographicKey({ id: new URL("https://example.com/key") }));
|
|
17
17
|
assertEquals(await kv.get([
|
|
18
18
|
"pk",
|
|
19
|
-
"
|
|
19
|
+
"3",
|
|
20
20
|
"https://example.com/key"
|
|
21
21
|
]), {
|
|
22
22
|
"@context": "https://w3id.org/security/v1",
|
|
@@ -26,7 +26,7 @@ test("KvKeyCache.set()", async () => {
|
|
|
26
26
|
await cache.set(new URL("https://example.com/key2"), new Multikey({ id: new URL("https://example.com/key2") }));
|
|
27
27
|
assertEquals(await kv.get([
|
|
28
28
|
"pk",
|
|
29
|
-
"
|
|
29
|
+
"3",
|
|
30
30
|
"https://example.com/key2"
|
|
31
31
|
]), {
|
|
32
32
|
"@context": "https://w3id.org/security/multikey/v1",
|
|
@@ -37,7 +37,7 @@ test("KvKeyCache.set()", async () => {
|
|
|
37
37
|
assert(cache.nullKeys.has("https://example.com/null"));
|
|
38
38
|
assertEquals(await kv.get([
|
|
39
39
|
"pk",
|
|
40
|
-
"
|
|
40
|
+
"3",
|
|
41
41
|
"https://example.com/null"
|
|
42
42
|
]), null);
|
|
43
43
|
});
|
|
@@ -46,7 +46,7 @@ test("KvKeyCache.get()", async () => {
|
|
|
46
46
|
const cache = new KvKeyCache(kv, ["pk"]);
|
|
47
47
|
await kv.set([
|
|
48
48
|
"pk",
|
|
49
|
-
"
|
|
49
|
+
"3",
|
|
50
50
|
"https://example.com/key"
|
|
51
51
|
], {
|
|
52
52
|
"@context": "https://w3id.org/security/v1",
|
|
@@ -58,7 +58,7 @@ test("KvKeyCache.get()", async () => {
|
|
|
58
58
|
assertEquals(cryptoKey?.id?.href, "https://example.com/key");
|
|
59
59
|
await kv.set([
|
|
60
60
|
"pk",
|
|
61
|
-
"
|
|
61
|
+
"3",
|
|
62
62
|
"https://example.com/key2"
|
|
63
63
|
], {
|
|
64
64
|
"@context": "https://w3id.org/security/multikey/v1",
|
|
@@ -72,7 +72,7 @@ test("KvKeyCache.get()", async () => {
|
|
|
72
72
|
assertEquals(await cache.get(new URL("https://example.com/null")), null);
|
|
73
73
|
await kv.set([
|
|
74
74
|
"pk",
|
|
75
|
-
"
|
|
75
|
+
"3",
|
|
76
76
|
"https://example.com/null2"
|
|
77
77
|
], null);
|
|
78
78
|
assertEquals(await new KvKeyCache(kv, ["pk"]).get(new URL("https://example.com/null2")), null);
|
|
@@ -162,14 +162,14 @@ test("KvKeyCache cached keys expire after keyTtl", async () => {
|
|
|
162
162
|
await cache.set(keyId, new CryptographicKey({ id: keyId }));
|
|
163
163
|
assert(await kv.get([
|
|
164
164
|
"pk",
|
|
165
|
-
"
|
|
165
|
+
"3",
|
|
166
166
|
keyId.href
|
|
167
167
|
]) != null);
|
|
168
168
|
assertInstanceOf(await cache.get(keyId), CryptographicKey);
|
|
169
169
|
kv.advance({ days: 31 });
|
|
170
170
|
assertEquals(await kv.get([
|
|
171
171
|
"pk",
|
|
172
|
-
"
|
|
172
|
+
"3",
|
|
173
173
|
keyId.href
|
|
174
174
|
]), void 0);
|
|
175
175
|
assertEquals(await cache.get(keyId), void 0);
|
|
@@ -189,6 +189,17 @@ test("KvKeyCache.get() ignores entries from an earlier generation", async () =>
|
|
|
189
189
|
type: "CryptographicKey"
|
|
190
190
|
});
|
|
191
191
|
assertEquals(await cache.get(new URL("https://example.com/key")), void 0);
|
|
192
|
+
await kv.set([
|
|
193
|
+
"pk",
|
|
194
|
+
"2",
|
|
195
|
+
"https://example.com/key2"
|
|
196
|
+
], {
|
|
197
|
+
"@context": "https://w3id.org/security/v1",
|
|
198
|
+
id: "https://example.com/key2",
|
|
199
|
+
owner: "https://example.com/impersonated",
|
|
200
|
+
type: "CryptographicKey"
|
|
201
|
+
});
|
|
202
|
+
assertEquals(await cache.get(new URL("https://example.com/key2")), void 0);
|
|
192
203
|
});
|
|
193
204
|
test("KvKeyCache.compatibleKeyScope() keeps each purpose apart", async () => {
|
|
194
205
|
const cache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
5
5
|
import "../std__assert-DvMDRPes.mjs";
|
|
6
6
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.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-
|
|
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-BguhdXt-.mjs";
|
|
8
8
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
9
9
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
10
10
|
import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
|