@fedify/fedify 2.3.13 → 2.3.15-dev.2482
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-BagNDcQw.mjs → builder-CocMrVkL.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-XpcjbHwj.mjs → deno-po8iekMB.mjs} +1 -1
- package/dist/{docloader-QDpF5t9M.mjs → docloader-BVj35vgR.mjs} +5 -3
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +5 -5
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +18 -7
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +72 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-BRrpIDS1.mjs → http-BNCLeQJ-.mjs} +3 -3
- package/dist/{http-GHVGCeb5.js → http-Cdu8BGtv.js} +17 -3
- package/dist/{http-DwPnG87d.cjs → http-WcSdFbt1.cjs} +17 -3
- package/dist/{inbox-BzOuCPLY.mjs → inbox-g1sd_Vjn.mjs} +2 -2
- package/dist/{key-PdEu1lDF.mjs → key-BR2TRTXR.mjs} +18 -4
- package/dist/{keycache-Dkc_sflV.mjs → keycache-BimEQucx.mjs} +1 -1
- package/dist/{kv-cache-Clx3SwMp.mjs → kv-cache-8SigUtvX.mjs} +1 -1
- package/dist/{kv-cache-poF6Tqnz.cjs → kv-cache-Bw_gduSm.cjs} +4 -2
- package/dist/{kv-cache-BmqdF048.js → kv-cache-C0AqpjoS.js} +4 -2
- package/dist/{ld-D6UlzNnG.mjs → ld-CSNsWdYE.mjs} +3 -3
- package/dist/{metrics-62qolVUY.mjs → metrics-BS7YzLVA.mjs} +1 -1
- package/dist/{middleware-CfbFdEO-.mjs → middleware-B1RRLN7m.mjs} +15 -15
- package/dist/{middleware-DkrXqZO_.cjs → middleware-D-SL8Bkj.cjs} +5 -5
- package/dist/{middleware-C3Q3CoR8.mjs → middleware-Dlo7NnZl.mjs} +1 -1
- package/dist/{middleware-xw9fBZoB.js → middleware-WL-JfDiK.js} +5 -5
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-DWnLg-vk.mjs → owner-DeggvxcG.mjs} +2 -2
- package/dist/{proof-mf6h7n4_.mjs → proof-DMcUrrp8.mjs} +3 -3
- package/dist/{proof-DF6CU-SU.cjs → proof-teNNYmFh.cjs} +1 -1
- package/dist/{proof-CUSzBztF.js → proof-v-IzWx7x.js} +1 -1
- package/dist/{send-LJUzNpVF.mjs → send-BsthcvPG.mjs} +3 -3
- package/dist/sig/http.test.mjs +3 -3
- package/dist/sig/key.test.mjs +197 -3
- package/dist/sig/ld.test.mjs +47 -2
- 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/proof.test.mjs +52 -1
- package/dist/{temporal-_3yIqdvy.mjs → temporal-Cji8Y8eQ.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +66 -2
- 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
package/dist/sig/proof.test.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { n as assertGreaterOrEqual, t as assertRejects } from "../assert_rejects
|
|
|
8
8
|
import { n as assertInstanceOf, t as assert } from "../assert-CEO06XCw.mjs";
|
|
9
9
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
|
|
10
10
|
import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-D4iTv7uM.mjs";
|
|
11
|
-
import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-
|
|
11
|
+
import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-DMcUrrp8.mjs";
|
|
12
12
|
import { Create, DataIntegrityProof, Document, Multikey, Note, PUBLIC_COLLECTION, Place } from "@fedify/vocab";
|
|
13
13
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
14
14
|
import { decodeMultibase, importMultibaseKey } from "@fedify/vocab-runtime";
|
|
@@ -599,5 +599,56 @@ test("verifyObject() rejects a key that claims a forged controller", async () =>
|
|
|
599
599
|
contextLoader: mockDocumentLoader
|
|
600
600
|
}), null);
|
|
601
601
|
});
|
|
602
|
+
test("verifyObject() rejects a key whose controller redirects to another actor", async () => {
|
|
603
|
+
const keyId = new URL("https://evil.example/keys/ed25519");
|
|
604
|
+
const victim = "https://victim.example/users/alice";
|
|
605
|
+
const mallory = "https://evil.example/users/mallory";
|
|
606
|
+
const multikeyDocument = await ed25519Multikey.toJsonLd({ contextLoader: mockDocumentLoader });
|
|
607
|
+
const signOptions = {
|
|
608
|
+
format: "compact",
|
|
609
|
+
contextLoader: mockDocumentLoader,
|
|
610
|
+
documentLoader: mockDocumentLoader,
|
|
611
|
+
context: ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1"]
|
|
612
|
+
};
|
|
613
|
+
assertEquals(await verifyObject(Create, await (await signObject(new Create({
|
|
614
|
+
id: new URL("https://victim.example/activities/forged"),
|
|
615
|
+
actor: new URL(victim),
|
|
616
|
+
object: new Note({
|
|
617
|
+
id: new URL("https://victim.example/notes/forged"),
|
|
618
|
+
attribution: new URL(victim),
|
|
619
|
+
content: "forged"
|
|
620
|
+
})
|
|
621
|
+
}), ed25519PrivateKey, keyId, signOptions)).toJsonLd(signOptions), {
|
|
622
|
+
documentLoader(resource) {
|
|
623
|
+
if (resource === keyId.href) return Promise.resolve({
|
|
624
|
+
contextUrl: null,
|
|
625
|
+
documentUrl: resource,
|
|
626
|
+
document: {
|
|
627
|
+
...multikeyDocument,
|
|
628
|
+
id: keyId.href,
|
|
629
|
+
controller: victim
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
if (resource === victim || resource === mallory) return Promise.resolve({
|
|
633
|
+
contextUrl: null,
|
|
634
|
+
documentUrl: mallory,
|
|
635
|
+
document: {
|
|
636
|
+
"@context": [
|
|
637
|
+
"https://www.w3.org/ns/activitystreams",
|
|
638
|
+
"https://w3id.org/security/v1",
|
|
639
|
+
"https://w3id.org/security/multikey/v1",
|
|
640
|
+
"https://w3id.org/security/data-integrity/v1",
|
|
641
|
+
"https://www.w3.org/ns/did/v1"
|
|
642
|
+
],
|
|
643
|
+
id: mallory,
|
|
644
|
+
type: "Person",
|
|
645
|
+
assertionMethod: [keyId.href]
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
return mockDocumentLoader(resource);
|
|
649
|
+
},
|
|
650
|
+
contextLoader: mockDocumentLoader
|
|
651
|
+
}), null);
|
|
652
|
+
});
|
|
602
653
|
//#endregion
|
|
603
654
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
4
|
+
import { c as getNormalizationContextLoader } from "./ld-CSNsWdYE.mjs";
|
|
5
5
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
6
6
|
//#region src/federation/temporal.ts
|
|
7
7
|
function isPlainObject(value) {
|
|
@@ -5,9 +5,9 @@ import { t as esm_default } from "../esm-vrlUxr60.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
6
6
|
import "../std__assert-BjJn2daJ.mjs";
|
|
7
7
|
import { t as assertRejects } from "../assert_rejects-D1HYAik3.mjs";
|
|
8
|
-
import { l as verifyRequest } from "../http-
|
|
8
|
+
import { l as verifyRequest } from "../http-BNCLeQJ-.mjs";
|
|
9
9
|
import { i as rsaPrivateKey2 } from "../keys-BAK-tUlf.mjs";
|
|
10
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
10
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-BVj35vgR.mjs";
|
|
11
11
|
import { configure, reset } from "@logtape/logtape";
|
|
12
12
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
13
13
|
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
@@ -466,6 +466,70 @@ const unsupportedUrls = [
|
|
|
466
466
|
"file:///collection",
|
|
467
467
|
`data:application/ld+json,${encodeURIComponent(JSON.stringify({ id: "https://example.com/data" }))}`
|
|
468
468
|
];
|
|
469
|
+
function isCredentialUrlError(error) {
|
|
470
|
+
return error instanceof UrlError && error.reason === "disallowed" && error.message === "URLs with credentials are not allowed";
|
|
471
|
+
}
|
|
472
|
+
test("getAuthenticatedDocumentLoader() rejects URLs with credentials", async (t) => {
|
|
473
|
+
const identity = {
|
|
474
|
+
keyId: new URL("https://example.com/key2"),
|
|
475
|
+
privateKey: rsaPrivateKey2
|
|
476
|
+
};
|
|
477
|
+
const start = "https://8.8.8.8/start";
|
|
478
|
+
const target = "https://user:pass@8.8.8.8/document";
|
|
479
|
+
for (const allowPrivateAddress of [false, true]) {
|
|
480
|
+
const loader = getAuthenticatedDocumentLoader(identity, { allowPrivateAddress });
|
|
481
|
+
for (const path of [
|
|
482
|
+
"direct",
|
|
483
|
+
"redirect",
|
|
484
|
+
"Link",
|
|
485
|
+
"HTML"
|
|
486
|
+
]) await t.step(`${path}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
487
|
+
await withFetchStub((request) => {
|
|
488
|
+
if (request.url !== start) return Response.json({});
|
|
489
|
+
if (path === "redirect") return Response.redirect(target, 302);
|
|
490
|
+
if (path === "HTML") return new Response(`<link rel="alternate" type="application/activity+json" href="${target}">`, { headers: { "Content-Type": "text/html" } });
|
|
491
|
+
return new Response("", { headers: {
|
|
492
|
+
"Content-Type": "text/plain",
|
|
493
|
+
Link: `<${target}>; rel="alternate"; type="application/activity+json"`
|
|
494
|
+
} });
|
|
495
|
+
}, async (fetched) => {
|
|
496
|
+
await rejects(loader(path === "direct" ? target : start), isCredentialUrlError);
|
|
497
|
+
deepStrictEqual(fetched.map((r) => r.url), path === "direct" ? [] : [start]);
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
for (const url of [
|
|
501
|
+
"https://user@8.8.8.8/document",
|
|
502
|
+
"https://:pass@8.8.8.8/document",
|
|
503
|
+
"https://%75ser:p%40ss@8.8.8.8/document",
|
|
504
|
+
"http://user:pass@8.8.8.8/document"
|
|
505
|
+
]) await t.step(`${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
506
|
+
await withFetchStub(() => Response.json({}), async (fetched) => {
|
|
507
|
+
await rejects(loader(url), isCredentialUrlError);
|
|
508
|
+
deepStrictEqual(fetched, []);
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
for (const url of ["https://:@8.8.8.8/document", "https://8.8.8.8/@user?q=@pass"]) await t.step(`allows ${url}, allowPrivateAddress=${allowPrivateAddress}`, async () => {
|
|
512
|
+
await withFetchStub(() => Response.json({ done: true }), async (fetched) => {
|
|
513
|
+
deepStrictEqual((await loader(url)).document, { done: true });
|
|
514
|
+
deepStrictEqual(fetched.map((r) => r.url), [new URL(url).href]);
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
for (const firstSpec of ["rfc9421", "draft-cavage-http-signatures-12"]) await t.step(`redirect after fallback from ${firstSpec}`, async () => {
|
|
519
|
+
const loader = getAuthenticatedDocumentLoader(identity, {
|
|
520
|
+
allowPrivateAddress: true,
|
|
521
|
+
specDeterminer: {
|
|
522
|
+
determineSpec: () => firstSpec,
|
|
523
|
+
rememberSpec: () => {}
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
await withFetchStub((request) => request.url !== start ? Response.json({}) : request.headers.has("Signature-Input") === (firstSpec === "rfc9421") ? new Response(null, { status: 401 }) : Response.redirect(target, 302), async (fetched) => {
|
|
527
|
+
await rejects(loader(start), isCredentialUrlError);
|
|
528
|
+
deepStrictEqual(fetched.map((r) => r.url), [start, start]);
|
|
529
|
+
deepStrictEqual(fetched.map((r) => r.headers.has("Signature-Input")), [firstSpec === "rfc9421", firstSpec !== "rfc9421"]);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
});
|
|
469
533
|
function isUnsupportedProtocolError(error, url) {
|
|
470
534
|
return error instanceof UrlError && error.message === `Unsupported protocol: ${new URL(url).protocol}` && error.reason === "disallowed";
|
|
471
535
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as kvCache, t as MockKvStore } from "../kv-cache-
|
|
4
|
+
import { n as kvCache, t as MockKvStore } from "../kv-cache-8SigUtvX.mjs";
|
|
5
5
|
import { deepStrictEqual, throws } from "node:assert";
|
|
6
6
|
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
7
7
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
package/dist/utils/mod.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
-
const require_kv_cache = require("../kv-cache-
|
|
4
|
+
const require_kv_cache = require("../kv-cache-Bw_gduSm.cjs");
|
|
5
5
|
exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
|
|
6
6
|
exports.kvCache = require_kv_cache.kvCache;
|
package/dist/utils/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-
|
|
3
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-C0AqpjoS.js";
|
|
4
4
|
export { getAuthenticatedDocumentLoader, kvCache };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/fedify",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.15-dev.2482+41d364a2",
|
|
4
4
|
"description": "An ActivityPub server framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ActivityPub",
|
|
@@ -152,10 +152,10 @@
|
|
|
152
152
|
"jsonld": "^9.0.0",
|
|
153
153
|
"structured-field-values": "^2.0.4",
|
|
154
154
|
"urlpattern-polyfill": "^10.1.0",
|
|
155
|
-
"@fedify/
|
|
156
|
-
"@fedify/vocab": "2.3.
|
|
157
|
-
"@fedify/
|
|
158
|
-
"@fedify/webfinger": "2.3.
|
|
155
|
+
"@fedify/vocab": "2.3.15-dev.2482+41d364a2",
|
|
156
|
+
"@fedify/vocab-runtime": "2.3.15-dev.2482+41d364a2",
|
|
157
|
+
"@fedify/uri-template": "2.3.15-dev.2482+41d364a2",
|
|
158
|
+
"@fedify/webfinger": "2.3.15-dev.2482+41d364a2"
|
|
159
159
|
},
|
|
160
160
|
"devDependencies": {
|
|
161
161
|
"@std/assert": "npm:@jsr/std__assert@^0.226.0",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"typescript": "^6.0.0",
|
|
169
169
|
"wrangler": "^4.17.0",
|
|
170
170
|
"@fedify/fixture": "2.0.0",
|
|
171
|
-
"@fedify/vocab-tools": "^2.3.
|
|
171
|
+
"@fedify/vocab-tools": "^2.3.15-dev.2482+41d364a2"
|
|
172
172
|
},
|
|
173
173
|
"scripts": {
|
|
174
174
|
"build:self": "tsdown",
|