@fedify/fedify 2.1.0 → 2.1.2
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/{accept-D7sAxyNa.js → accept-Dd__NiUL.mjs} +10 -8
- package/dist/{assert-MZs1qjMx.js → assert-ddO5KLpe.mjs} +5 -9
- package/dist/{assert_equals-DSbWqCm3.js → assert_equals-Ew3jOFa3.mjs} +55 -69
- package/dist/{assert_instance_of-DHz7EHNU.js → assert_instance_of-C4Ri6VuN.mjs} +5 -9
- package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals--wG9hV7u.mjs} +6 -13
- package/dist/{assert_rejects-0h7I2Esa.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
- package/dist/{assert_throws-rjdMBf31.js → assert_throws-4NwKEy2q.mjs} +5 -10
- package/dist/{builder-WiHhZvjW.js → builder-DkJDAzes.mjs} +32 -41
- package/dist/{chunk-CGaQZ11T.cjs → chunk-DDcVe30Y.cjs} +23 -24
- package/dist/{chunk-DJNbSFdH.js → chunk-nlSIicah.js} +8 -8
- package/dist/{client-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
- package/dist/{client-CoCIaTNO.js → client-DEpOVgY1.mjs} +9 -13
- package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
- package/dist/{collection-CSzG2j1P.js → collection-BD6-SZ6O.mjs} +7 -12
- package/dist/compat/mod.cjs +5 -8
- package/dist/compat/mod.d.cts +78 -6
- package/dist/compat/mod.d.ts +78 -6
- package/dist/compat/mod.js +4 -8
- package/dist/compat/transformers.test.mjs +62 -0
- package/dist/{context-DyJjQQ_H.d.ts → context-BOiMZBu5.d.ts} +9 -18
- package/dist/{context-BcqA-0BL.d.cts → context-BhZVy7RB.d.cts} +9 -18
- package/dist/{context-Aqenou7c.js → context-Juj6bdHC.mjs} +7 -11
- package/dist/deno-C5VMwnFV.mjs +8 -0
- package/dist/{docloader-bVO2EvL9.js → docloader-X9mcJ9Tz.mjs} +8 -14
- package/dist/{esm-nLm00z9V.js → esm-DVILvP5e.mjs} +50 -89
- package/dist/federation/builder.test.d.mts +2 -0
- package/dist/federation/{builder.test.js → builder.test.mjs} +21 -44
- package/dist/federation/collection.test.d.mts +2 -0
- package/dist/federation/collection.test.mjs +21 -0
- package/dist/federation/handler.test.d.mts +2 -0
- package/dist/federation/{handler.test.js → handler.test.mjs} +69 -131
- package/dist/federation/idempotency.test.d.mts +2 -0
- package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -63
- package/dist/federation/inbox.test.d.mts +2 -0
- package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
- package/dist/federation/keycache.test.d.mts +2 -0
- package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -19
- package/dist/federation/kv.test.d.mts +2 -0
- package/dist/federation/{kv.test.js → kv.test.mjs} +11 -22
- package/dist/federation/middleware.test.d.mts +2 -0
- package/dist/federation/{middleware.test.js → middleware.test.mjs} +173 -262
- package/dist/federation/mod.cjs +327 -16
- package/dist/federation/mod.d.cts +3 -6
- package/dist/federation/mod.d.ts +3 -6
- package/dist/federation/mod.js +322 -13
- package/dist/federation/mq.test.d.mts +2 -0
- package/dist/federation/{mq.test.js → mq.test.mjs} +21 -35
- package/dist/federation/negotiation.test.d.mts +2 -0
- package/dist/federation/{negotiation.test.js → negotiation.test.mjs} +9 -16
- package/dist/federation/retry.test.d.mts +2 -0
- package/dist/federation/{retry.test.js → retry.test.mjs} +8 -11
- package/dist/federation/router.test.d.mts +2 -0
- package/dist/federation/{router.test.js → router.test.mjs} +11 -16
- package/dist/federation/send.test.d.mts +2 -0
- package/dist/federation/{send.test.js → send.test.mjs} +22 -30
- package/dist/federation/webfinger.test.d.mts +2 -0
- package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -56
- package/dist/{http-DhH623ma.js → http-BLZWcpzg.js} +67 -187
- package/dist/{http-CKDim8Tw.js → http-BTLPIzFa.mjs} +37 -45
- package/dist/{http-BudnHZE2.d.cts → http-CrGuipxe.d.cts} +1 -6
- package/dist/{http-gvnJbMS1.cjs → http-CxodXLwi.cjs} +186 -300
- package/dist/{http-Dax_FIBo.d.ts → http-aQzN9Ayi.d.ts} +1 -6
- package/dist/{inbox-CA9AUEGa.js → inbox-mcbmhjTW.mjs} +18 -26
- package/dist/{key-BsSCz8Z_.js → key-1MaItIGc.mjs} +29 -37
- package/dist/{keycache-CpGWAUbj.js → keycache-CCSwkQcY.mjs} +5 -10
- package/dist/{keys-BFve7QQv.js → keys-BAK-tUlf.mjs} +5 -9
- package/dist/{kv-BL4nlICN.d.cts → kv-CbLNp3zQ.d.cts} +1 -1
- package/dist/{kv-DXEUEP6z.d.ts → kv-GFYnFoOl.d.ts} +1 -1
- package/dist/{kv-cache-Bw2F2ABq.js → kv-cache-B01V7s3h.mjs} +4 -8
- package/dist/{kv-cache-DK4GFVWx.cjs → kv-cache-DjC82_4n.cjs} +27 -34
- package/dist/{kv-cache-CxoHCR44.js → kv-cache-GIDK1oLs.js} +6 -13
- package/dist/{kv-QzKcOQgP.js → kv-tL2TOE9X.mjs} +6 -10
- package/dist/{ld-Bo_Rx0Fc.js → ld-94uHZ1eO.mjs} +17 -31
- package/dist/{middleware-BkrUA3da.js → middleware-B5Er10wE.js} +336 -383
- package/dist/middleware-CDuHbSVE.mjs +5 -0
- package/dist/middleware-CTyq5KB0.cjs +4 -0
- package/dist/{middleware-CpAnWzjC.cjs → middleware-CqDJSLoG.cjs} +532 -587
- package/dist/{middleware-CZ8jOOa3.js → middleware-DMZGXHm3.mjs} +282 -317
- package/dist/{mod-Bx9jcLB8.d.cts → mod-B505FZBC.d.cts} +3 -3
- package/dist/{mod-em2Il1eD.d.cts → mod-Bp_CzKd4.d.cts} +2 -2
- package/dist/{mod-Cs2dYEwI.d.ts → mod-D7PAuO6k.d.ts} +3 -3
- package/dist/{mod-D6MdymW7.d.ts → mod-DKOAow7a.d.ts} +2 -2
- package/dist/{mod-Coe7KEgX.d.cts → mod-DoJBjjnO.d.cts} +2 -2
- package/dist/{mod-D6dOd--H.d.ts → mod-DvxszxXC.d.ts} +2 -2
- package/dist/mod.cjs +29 -74
- package/dist/mod.d.cts +11 -14
- package/dist/mod.d.ts +11 -15
- package/dist/mod.js +17 -71
- package/dist/{negotiation-BlAuS_nr.js → negotiation-DnsfFF8I.mjs} +7 -11
- package/dist/nodeinfo/client.test.d.mts +2 -0
- package/dist/nodeinfo/{client.test.js → client.test.mjs} +22 -40
- package/dist/nodeinfo/handler.test.d.mts +2 -0
- package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +13 -43
- package/dist/nodeinfo/mod.cjs +5 -8
- package/dist/nodeinfo/mod.d.cts +2 -3
- package/dist/nodeinfo/mod.d.ts +2 -3
- package/dist/nodeinfo/mod.js +4 -8
- package/dist/nodeinfo/types.test.d.mts +2 -0
- package/dist/nodeinfo/{types.test.js → types.test.mjs} +9 -16
- package/dist/otel/exporter.test.d.mts +2 -0
- package/dist/otel/{exporter.test.js → exporter.test.mjs} +124 -178
- package/dist/otel/mod.cjs +15 -20
- package/dist/otel/mod.d.cts +2 -2
- package/dist/otel/mod.d.ts +2 -2
- package/dist/otel/mod.js +8 -14
- package/dist/{owner-gd0Q9FuU.d.ts → owner-74ARJ5TL.d.ts} +1 -1
- package/dist/{owner-Bj_IbwIT.js → owner-B4aIDhg_.mjs} +11 -16
- package/dist/{owner-1AbPBOOZ.d.cts → owner-CptqhsOy.d.cts} +1 -1
- package/dist/{proof-u6Y358J-.js → proof-DYZWMWOC.mjs} +21 -33
- package/dist/{proof-BhFF_JVj.cjs → proof-DqCjiFwb.cjs} +133 -157
- package/dist/{proof-D5BQTIcU.js → proof-j-of9m5W.js} +33 -59
- package/dist/{retry-mqLf4b-R.js → retry-B_E3V_Dx.mjs} +4 -7
- package/dist/{router-D9eI0s4b.js → router-CrMLXoOr.mjs} +4 -8
- package/dist/runtime/mod.cjs +11 -13
- package/dist/runtime/mod.d.cts +6 -2
- package/dist/runtime/mod.d.ts +0 -1
- package/dist/runtime/mod.js +4 -7
- package/dist/{send-CE8h59oe.js → send-uLjD0uAe.mjs} +8 -13
- package/dist/sig/accept.test.d.mts +2 -0
- package/dist/sig/{accept.test.js → accept.test.mjs} +35 -70
- package/dist/sig/http.test.d.mts +2 -0
- package/dist/sig/{http.test.js → http.test.mjs} +209 -280
- package/dist/sig/key.test.d.mts +2 -0
- package/dist/sig/{key.test.js → key.test.mjs} +11 -18
- package/dist/sig/ld.test.d.mts +2 -0
- package/dist/sig/{ld.test.js → ld.test.mjs} +22 -35
- package/dist/sig/mod.cjs +6 -9
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +5 -9
- package/dist/sig/owner.test.d.mts +2 -0
- package/dist/sig/{owner.test.js → owner.test.mjs} +19 -34
- package/dist/sig/proof.test.d.mts +2 -0
- package/dist/sig/{proof.test.js → proof.test.mjs} +16 -27
- package/dist/{std__assert-X-_kMxKM.js → std__assert-Duiq_YC9.mjs} +12 -24
- package/dist/testing/{mod.d.ts → mod.d.mts} +26 -90
- package/dist/testing/mod.mjs +6 -0
- package/dist/{transformers-3g8GZwkZ.cjs → transformers-NeAONrAq.cjs} +20 -25
- package/dist/{transformers-C3FLHUd6.js → transformers-ve6e2xcg.js} +3 -7
- package/dist/{types-CPz01LGH.js → types-DCP0WLdt.mjs} +4 -7
- package/dist/{types-Cd_hszr_.cjs → types-KC4QAoxe.cjs} +29 -34
- package/dist/{types-C93Ob9cU.js → types-hvL8ElAs.js} +8 -13
- package/dist/utils/docloader.test.d.mts +2 -0
- package/dist/utils/{docloader.test.js → docloader.test.mjs} +14 -25
- package/dist/utils/kv-cache.test.d.mts +2 -0
- package/dist/utils/{kv-cache.test.js → kv-cache.test.mjs} +25 -40
- package/dist/utils/mod.cjs +5 -9
- package/dist/utils/mod.d.cts +1 -3
- package/dist/utils/mod.d.ts +1 -3
- package/dist/utils/mod.js +4 -9
- package/dist/vocab/cjs.test.d.mts +2 -0
- package/dist/vocab/cjs.test.mjs +14 -0
- package/dist/vocab/mod.cjs +10 -12
- package/dist/vocab/mod.js +3 -5
- package/package.json +7 -7
- package/dist/compat/transformers.test.d.ts +0 -3
- package/dist/compat/transformers.test.js +0 -88
- package/dist/compat-Bb4NuTUO.js +0 -4
- package/dist/compat-DmDDELst.cjs +0 -4
- package/dist/deno-BRMCYThi.js +0 -121
- package/dist/federation/builder.test.d.ts +0 -3
- package/dist/federation/collection.test.d.ts +0 -3
- package/dist/federation/collection.test.js +0 -32
- package/dist/federation/handler.test.d.ts +0 -3
- package/dist/federation/idempotency.test.d.ts +0 -3
- package/dist/federation/inbox.test.d.ts +0 -3
- package/dist/federation/keycache.test.d.ts +0 -3
- package/dist/federation/kv.test.d.ts +0 -3
- package/dist/federation/middleware.test.d.ts +0 -3
- package/dist/federation/mq.test.d.ts +0 -3
- package/dist/federation/negotiation.test.d.ts +0 -3
- package/dist/federation/retry.test.d.ts +0 -3
- package/dist/federation/router.test.d.ts +0 -3
- package/dist/federation/send.test.d.ts +0 -3
- package/dist/federation/webfinger.test.d.ts +0 -3
- package/dist/federation-Bp3HI26G.cjs +0 -350
- package/dist/federation-DaMfqRm4.js +0 -332
- package/dist/middleware-BtT_mKsB.cjs +0 -12
- package/dist/middleware-CUMoHNCA.js +0 -12
- package/dist/middleware-CzeVJTA1.js +0 -27
- package/dist/mod-B7QkWzrL.d.cts +0 -80
- package/dist/mod-Bh8mqlYw.d.cts +0 -9
- package/dist/mod-D6HodEq7.d.ts +0 -7
- package/dist/mod-SMHOMNpZ.d.ts +0 -82
- package/dist/mod-gq_Xfdz8.d.cts +0 -1
- package/dist/nodeinfo/client.test.d.ts +0 -3
- package/dist/nodeinfo/handler.test.d.ts +0 -3
- package/dist/nodeinfo/types.test.d.ts +0 -3
- package/dist/nodeinfo-DoESQxq5.js +0 -4
- package/dist/nodeinfo-DuMYTpbZ.cjs +0 -4
- package/dist/otel/exporter.test.d.ts +0 -3
- package/dist/runtime-c2Njxsry.cjs +0 -17
- package/dist/runtime-poamPCMb.js +0 -13
- package/dist/sig/accept.test.d.ts +0 -3
- package/dist/sig/http.test.d.ts +0 -3
- package/dist/sig/key.test.d.ts +0 -3
- package/dist/sig/ld.test.d.ts +0 -3
- package/dist/sig/owner.test.d.ts +0 -3
- package/dist/sig/proof.test.d.ts +0 -3
- package/dist/sig-BNhspNOf.js +0 -4
- package/dist/sig-vX39WyWI.cjs +0 -4
- package/dist/testing/mod.js +0 -10
- package/dist/utils/docloader.test.d.ts +0 -3
- package/dist/utils/kv-cache.test.d.ts +0 -3
- package/dist/utils-BQ9KqEK9.cjs +0 -4
- package/dist/utils-Dn5OPdSW.js +0 -4
- /package/dist/{mod-AGjRfPjT.d.ts → compat/transformers.test.d.mts} +0 -0
|
@@ -1,51 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import "../
|
|
8
|
-
import "../
|
|
9
|
-
import { MemoryKvStore } from "../kv-QzKcOQgP.js";
|
|
10
|
-
import "../deno-BRMCYThi.js";
|
|
11
|
-
import { createFederation, handleWebFinger } from "../middleware-CZ8jOOa3.js";
|
|
12
|
-
import "../client-CoCIaTNO.js";
|
|
13
|
-
import "../router-D9eI0s4b.js";
|
|
14
|
-
import "../types-CPz01LGH.js";
|
|
15
|
-
import "../accept-D7sAxyNa.js";
|
|
16
|
-
import "../key-BsSCz8Z_.js";
|
|
17
|
-
import "../http-CKDim8Tw.js";
|
|
18
|
-
import "../ld-Bo_Rx0Fc.js";
|
|
19
|
-
import "../owner-Bj_IbwIT.js";
|
|
20
|
-
import "../proof-u6Y358J-.js";
|
|
21
|
-
import "../docloader-bVO2EvL9.js";
|
|
22
|
-
import "../kv-cache-Bw2F2ABq.js";
|
|
23
|
-
import "../inbox-CA9AUEGa.js";
|
|
24
|
-
import "../builder-WiHhZvjW.js";
|
|
25
|
-
import "../collection-CSzG2j1P.js";
|
|
26
|
-
import "../keycache-CpGWAUbj.js";
|
|
27
|
-
import "../negotiation-BlAuS_nr.js";
|
|
28
|
-
import "../retry-mqLf4b-R.js";
|
|
29
|
-
import "../send-CE8h59oe.js";
|
|
30
|
-
import "../std__assert-X-_kMxKM.js";
|
|
31
|
-
import "../assert_rejects-0h7I2Esa.js";
|
|
32
|
-
import "../assert_throws-rjdMBf31.js";
|
|
33
|
-
import "../assert_not_equals-f3m3epl3.js";
|
|
34
|
-
import { createRequestContext } from "../context-Aqenou7c.js";
|
|
1
|
+
import "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { n as createRequestContext } from "../context-Juj6bdHC.mjs";
|
|
5
|
+
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
|
+
import "../std__assert-Duiq_YC9.mjs";
|
|
7
|
+
import { t as MemoryKvStore } from "../kv-tL2TOE9X.mjs";
|
|
8
|
+
import { a as createFederation, o as handleWebFinger } from "../middleware-DMZGXHm3.mjs";
|
|
35
9
|
import { test } from "@fedify/fixture";
|
|
36
10
|
import { Image, Link, Person } from "@fedify/vocab";
|
|
37
|
-
|
|
38
11
|
//#region src/federation/webfinger.test.ts
|
|
39
12
|
test("handleWebFinger()", async (t) => {
|
|
40
13
|
const url = new URL("https://example.com/.well-known/webfinger");
|
|
41
|
-
function createContext(url
|
|
42
|
-
const federation = createFederation({ kv: new MemoryKvStore() });
|
|
14
|
+
function createContext(url) {
|
|
43
15
|
const context = createRequestContext({
|
|
44
|
-
federation,
|
|
45
|
-
url
|
|
16
|
+
federation: createFederation({ kv: new MemoryKvStore() }),
|
|
17
|
+
url,
|
|
46
18
|
data: void 0,
|
|
47
19
|
getActorUri(identifier) {
|
|
48
|
-
return new URL(`${url
|
|
20
|
+
return new URL(`${url.origin}/users/${identifier}`);
|
|
49
21
|
},
|
|
50
22
|
async getActor(handle) {
|
|
51
23
|
return await actorDispatcher(context, handle);
|
|
@@ -55,10 +27,9 @@ test("handleWebFinger()", async (t) => {
|
|
|
55
27
|
if (uri.protocol === "acct:") return null;
|
|
56
28
|
if (!uri.pathname.startsWith("/users/")) return null;
|
|
57
29
|
const paths = uri.pathname.split("/");
|
|
58
|
-
const identifier = paths[paths.length - 1];
|
|
59
30
|
return {
|
|
60
31
|
type: "actor",
|
|
61
|
-
identifier
|
|
32
|
+
identifier: paths[paths.length - 1]
|
|
62
33
|
};
|
|
63
34
|
}
|
|
64
35
|
});
|
|
@@ -90,11 +61,10 @@ test("handleWebFinger()", async (t) => {
|
|
|
90
61
|
await t.step("no actor dispatcher", async () => {
|
|
91
62
|
const context = createContext(url);
|
|
92
63
|
const request = context.request;
|
|
93
|
-
|
|
64
|
+
assertEquals((await handleWebFinger(request, {
|
|
94
65
|
context,
|
|
95
66
|
onNotFound
|
|
96
|
-
});
|
|
97
|
-
assertEquals(response.status, 404);
|
|
67
|
+
})).status, 404);
|
|
98
68
|
assertEquals(onNotFoundCalled, request);
|
|
99
69
|
});
|
|
100
70
|
onNotFoundCalled = null;
|
|
@@ -114,8 +84,7 @@ test("handleWebFinger()", async (t) => {
|
|
|
114
84
|
const u = new URL(url);
|
|
115
85
|
u.searchParams.set("resource", " invalid ");
|
|
116
86
|
const context = createContext(u);
|
|
117
|
-
const
|
|
118
|
-
const response = await handleWebFinger(request, {
|
|
87
|
+
const response = await handleWebFinger(new Request(u), {
|
|
119
88
|
context,
|
|
120
89
|
actorDispatcher,
|
|
121
90
|
onNotFound
|
|
@@ -221,12 +190,11 @@ test("handleWebFinger()", async (t) => {
|
|
|
221
190
|
u.searchParams.set("resource", "acct:no-one@example.com");
|
|
222
191
|
const context = createContext(u);
|
|
223
192
|
const request = context.request;
|
|
224
|
-
|
|
193
|
+
assertEquals((await handleWebFinger(request, {
|
|
225
194
|
context,
|
|
226
195
|
actorDispatcher,
|
|
227
196
|
onNotFound
|
|
228
|
-
});
|
|
229
|
-
assertEquals(response.status, 404);
|
|
197
|
+
})).status, 404);
|
|
230
198
|
assertEquals(onNotFoundCalled, request);
|
|
231
199
|
});
|
|
232
200
|
onNotFoundCalled = null;
|
|
@@ -522,16 +490,14 @@ test("handleWebFinger()", async (t) => {
|
|
|
522
490
|
onNotFound
|
|
523
491
|
});
|
|
524
492
|
assertEquals(response.status, 200);
|
|
525
|
-
|
|
526
|
-
const expectedWithCustomLinks = {
|
|
493
|
+
assertEquals(await response.json(), {
|
|
527
494
|
...expected,
|
|
528
495
|
links: [...expected.links, {
|
|
529
496
|
rel: "http://ostatus.org/schema/1.0/subscribe",
|
|
530
497
|
template: "https://example.com/follow?acct={uri}"
|
|
531
498
|
}]
|
|
532
|
-
};
|
|
533
|
-
assertEquals(result, expectedWithCustomLinks);
|
|
499
|
+
});
|
|
534
500
|
});
|
|
535
501
|
});
|
|
536
|
-
|
|
537
|
-
|
|
502
|
+
//#endregion
|
|
503
|
+
export {};
|
|
@@ -1,133 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { URLPattern } from "urlpattern-polyfill";
|
|
4
|
-
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
5
3
|
import { getLogger } from "@logtape/logtape";
|
|
6
4
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
7
5
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
6
|
import { encodeHex } from "byte-encodings/hex";
|
|
9
7
|
import { Item, decodeDict, encodeDict, encodeItem } from "structured-field-values";
|
|
8
|
+
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
10
9
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
|
|
11
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
12
|
-
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
13
|
-
|
|
14
11
|
//#region deno.json
|
|
15
12
|
var name = "@fedify/fedify";
|
|
16
|
-
var version = "2.1.
|
|
17
|
-
var license = "MIT";
|
|
18
|
-
var exports = {
|
|
19
|
-
".": "./src/mod.ts",
|
|
20
|
-
"./compat": "./src/compat/mod.ts",
|
|
21
|
-
"./federation": "./src/federation/mod.ts",
|
|
22
|
-
"./nodeinfo": "./src/nodeinfo/mod.ts",
|
|
23
|
-
"./otel": "./src/otel/mod.ts",
|
|
24
|
-
"./runtime": "./src/runtime/mod.ts",
|
|
25
|
-
"./sig": "./src/sig/mod.ts",
|
|
26
|
-
"./utils": "./src/utils/mod.ts",
|
|
27
|
-
"./vocab": "./src/vocab/mod.ts"
|
|
28
|
-
};
|
|
29
|
-
var imports = {
|
|
30
|
-
"@multiformats/base-x": "npm:@multiformats/base-x@^4.0.1",
|
|
31
|
-
"@std/assert": "jsr:@std/assert@^0.226.0",
|
|
32
|
-
"@std/url": "jsr:@std/url@^0.225.1",
|
|
33
|
-
"asn1js": "npm:asn1js@^3.0.7",
|
|
34
|
-
"fast-check": "npm:fast-check@^3.22.0",
|
|
35
|
-
"fetch-mock": "npm:fetch-mock@^12.5.2",
|
|
36
|
-
"json-canon": "npm:json-canon@^1.0.1",
|
|
37
|
-
"jsonld": "npm:jsonld@^9.0.0",
|
|
38
|
-
"pkijs": "npm:pkijs@^3.3.3",
|
|
39
|
-
"structured-field-values": "npm:structured-field-values@^2.0.4",
|
|
40
|
-
"uri-template-router": "npm:uri-template-router@^1.0.0",
|
|
41
|
-
"url-template": "npm:url-template@^3.1.1"
|
|
42
|
-
};
|
|
43
|
-
var exclude = [
|
|
44
|
-
".test-report.xml",
|
|
45
|
-
"apidoc/",
|
|
46
|
-
"dist/",
|
|
47
|
-
"node_modules/",
|
|
48
|
-
"npm/",
|
|
49
|
-
"pnpm-lock.yaml",
|
|
50
|
-
"src/cfworkers/dist/",
|
|
51
|
-
"src/cfworkers/fixtures/",
|
|
52
|
-
"src/cfworkers/imports.ts",
|
|
53
|
-
"src/cfworkers/README.md",
|
|
54
|
-
"src/cfworkers/server.ts",
|
|
55
|
-
"src/cfworkers/server.js",
|
|
56
|
-
"src/cfworkers/server.js.map"
|
|
57
|
-
];
|
|
58
|
-
var publish = { "exclude": [
|
|
59
|
-
"**/*.test.ts",
|
|
60
|
-
"src/testing/",
|
|
61
|
-
"tsdown.config.ts",
|
|
62
|
-
"scripts/",
|
|
63
|
-
"wrangler.toml"
|
|
64
|
-
] };
|
|
65
|
-
var tasks = {
|
|
66
|
-
"codegen": "deno task -f @fedify/vocab compile",
|
|
67
|
-
"cache": {
|
|
68
|
-
"command": "deno cache src/mod.ts",
|
|
69
|
-
"dependencies": ["codegen"]
|
|
70
|
-
},
|
|
71
|
-
"check": {
|
|
72
|
-
"command": "deno fmt --check && deno lint && deno check src/**/*.ts",
|
|
73
|
-
"dependencies": ["codegen"]
|
|
74
|
-
},
|
|
75
|
-
"test": {
|
|
76
|
-
"command": "deno test --check --doc --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel",
|
|
77
|
-
"dependencies": ["codegen"]
|
|
78
|
-
},
|
|
79
|
-
"coverage": "deno task test --clean --coverage && deno coverage --html coverage",
|
|
80
|
-
"bench": {
|
|
81
|
-
"command": "deno bench --allow-read --allow-write --allow-net --allow-env --allow-run --unstable-kv",
|
|
82
|
-
"dependencies": ["codegen"]
|
|
83
|
-
},
|
|
84
|
-
"apidoc": {
|
|
85
|
-
"command": "deno doc --html --name=Fedify --output=apidoc/ src/mod.ts",
|
|
86
|
-
"dependencies": ["codegen"]
|
|
87
|
-
},
|
|
88
|
-
"publish": {
|
|
89
|
-
"command": "deno publish",
|
|
90
|
-
"dependencies": ["codegen"]
|
|
91
|
-
},
|
|
92
|
-
"pnpm:install": "pnpm install --silent",
|
|
93
|
-
"pnpm:build": {
|
|
94
|
-
"command": "pnpm exec tsdown",
|
|
95
|
-
"dependencies": ["pnpm:build-vocab"]
|
|
96
|
-
},
|
|
97
|
-
"test:node": {
|
|
98
|
-
"command": "cd dist/ && node --test",
|
|
99
|
-
"dependencies": ["pnpm:build"]
|
|
100
|
-
},
|
|
101
|
-
"test:bun": {
|
|
102
|
-
"command": "cd dist/ && bun test --timeout 60000",
|
|
103
|
-
"dependencies": ["pnpm:build"]
|
|
104
|
-
},
|
|
105
|
-
"test:cfworkers": {
|
|
106
|
-
"command": "pnpm exec wrangler deploy --dry-run --outdir src/cfworkers && node --import=tsx src/cfworkers/client.ts",
|
|
107
|
-
"dependencies": ["pnpm:build"]
|
|
108
|
-
},
|
|
109
|
-
"test-all": { "dependencies": [
|
|
110
|
-
"check",
|
|
111
|
-
"test",
|
|
112
|
-
"test:node",
|
|
113
|
-
"test:bun",
|
|
114
|
-
"test:cfworkers"
|
|
115
|
-
] }
|
|
116
|
-
};
|
|
117
|
-
var deno_default = {
|
|
118
|
-
name,
|
|
119
|
-
version,
|
|
120
|
-
license,
|
|
121
|
-
exports,
|
|
122
|
-
imports,
|
|
123
|
-
exclude,
|
|
124
|
-
publish,
|
|
125
|
-
tasks
|
|
126
|
-
};
|
|
127
|
-
|
|
13
|
+
var version = "2.1.2";
|
|
128
14
|
//#endregion
|
|
129
15
|
//#region src/sig/accept.ts
|
|
130
16
|
/**
|
|
17
|
+
* `Accept-Signature` header parsing, serialization, and validation utilities
|
|
18
|
+
* for RFC 9421 §5 challenge-response negotiation.
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
131
23
|
* Parses an `Accept-Signature` header value (RFC 9421 §5.1) into an
|
|
132
24
|
* array of {@link AcceptSignatureMember} objects.
|
|
133
25
|
*
|
|
@@ -258,7 +150,6 @@ function fulfillAcceptSignature(entry, localKeyId, localAlg) {
|
|
|
258
150
|
expires: entry.parameters.expires
|
|
259
151
|
};
|
|
260
152
|
}
|
|
261
|
-
|
|
262
153
|
//#endregion
|
|
263
154
|
//#region src/sig/key.ts
|
|
264
155
|
/**
|
|
@@ -274,8 +165,7 @@ function validateCryptoKey(key, type) {
|
|
|
274
165
|
if (!key.extractable) throw new TypeError("The key is not extractable.");
|
|
275
166
|
if (key.algorithm.name !== "RSASSA-PKCS1-v1_5" && key.algorithm.name !== "Ed25519") throw new TypeError("Currently only RSASSA-PKCS1-v1_5 and Ed25519 keys are supported. More algorithms will be added in the future!");
|
|
276
167
|
if (key.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
|
277
|
-
|
|
278
|
-
if (algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
|
|
168
|
+
if (key.algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
|
|
279
169
|
}
|
|
280
170
|
}
|
|
281
171
|
/**
|
|
@@ -342,8 +232,7 @@ async function importJwk(jwk, type) {
|
|
|
342
232
|
}
|
|
343
233
|
async function withFetchKeySpan(keyId, tracerProvider, fetcher) {
|
|
344
234
|
tracerProvider ??= trace.getTracerProvider();
|
|
345
|
-
|
|
346
|
-
return await tracer.startActiveSpan("activitypub.fetch_key", {
|
|
235
|
+
return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.fetch_key", {
|
|
347
236
|
kind: SpanKind.CLIENT,
|
|
348
237
|
attributes: {
|
|
349
238
|
"http.method": "GET",
|
|
@@ -404,41 +293,41 @@ function fetchKey(keyId, cls, options = {}) {
|
|
|
404
293
|
async function fetchKeyDetailed(keyId, cls, options = {}) {
|
|
405
294
|
const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
|
|
406
295
|
return await withFetchKeySpan(cacheKey, options.tracerProvider, async () => {
|
|
407
|
-
return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey
|
|
408
|
-
const fetchError = await keyCache?.getFetchError?.(cacheKey
|
|
296
|
+
return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey, keyId, keyCache, logger) => {
|
|
297
|
+
const fetchError = await keyCache?.getFetchError?.(cacheKey);
|
|
409
298
|
if (fetchError != null) {
|
|
410
|
-
logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId
|
|
299
|
+
logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId });
|
|
411
300
|
return {
|
|
412
301
|
key: null,
|
|
413
302
|
cached: true,
|
|
414
303
|
fetchError
|
|
415
304
|
};
|
|
416
305
|
}
|
|
417
|
-
logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId
|
|
306
|
+
logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId });
|
|
418
307
|
return {
|
|
419
308
|
key: null,
|
|
420
309
|
cached: true
|
|
421
310
|
};
|
|
422
|
-
}, async (error, cacheKey
|
|
311
|
+
}, async (error, cacheKey, keyId, keyCache, logger) => {
|
|
423
312
|
logger.debug("Failed to fetch key {keyId}.", {
|
|
424
|
-
keyId
|
|
313
|
+
keyId,
|
|
425
314
|
error
|
|
426
315
|
});
|
|
427
|
-
await keyCache?.set(cacheKey
|
|
316
|
+
await keyCache?.set(cacheKey, null);
|
|
428
317
|
if (error instanceof FetchError && error.response != null) {
|
|
429
|
-
const fetchError
|
|
318
|
+
const fetchError = {
|
|
430
319
|
status: error.response.status,
|
|
431
320
|
response: error.response.clone()
|
|
432
321
|
};
|
|
433
|
-
await keyCache?.setFetchError?.(cacheKey
|
|
322
|
+
await keyCache?.setFetchError?.(cacheKey, fetchError);
|
|
434
323
|
return {
|
|
435
324
|
key: null,
|
|
436
325
|
cached: false,
|
|
437
|
-
fetchError
|
|
326
|
+
fetchError
|
|
438
327
|
};
|
|
439
328
|
}
|
|
440
329
|
const fetchError = { error: error instanceof Error ? error : new Error(String(error)) };
|
|
441
|
-
await keyCache?.setFetchError?.(cacheKey
|
|
330
|
+
await keyCache?.setFetchError?.(cacheKey, fetchError);
|
|
442
331
|
return {
|
|
443
332
|
key: null,
|
|
444
333
|
cached: false,
|
|
@@ -484,8 +373,8 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
|
|
|
484
373
|
contextLoader,
|
|
485
374
|
tracerProvider
|
|
486
375
|
});
|
|
487
|
-
} catch (e
|
|
488
|
-
if (e
|
|
376
|
+
} catch (e) {
|
|
377
|
+
if (e instanceof TypeError) {
|
|
489
378
|
logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
|
|
490
379
|
await keyCache?.set(cacheKey, null);
|
|
491
380
|
await clearFetchErrorMetadata(cacheKey, keyCache);
|
|
@@ -494,7 +383,7 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
|
|
|
494
383
|
cached: false
|
|
495
384
|
};
|
|
496
385
|
}
|
|
497
|
-
throw e
|
|
386
|
+
throw e;
|
|
498
387
|
}
|
|
499
388
|
}
|
|
500
389
|
let key = null;
|
|
@@ -575,40 +464,38 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
|
|
|
575
464
|
logger.debug("Fetching key {keyId} to verify signature...", { keyId });
|
|
576
465
|
let document;
|
|
577
466
|
try {
|
|
578
|
-
|
|
579
|
-
document = remoteDocument.document;
|
|
467
|
+
document = (await (options.documentLoader ?? getDocumentLoader())(keyId)).document;
|
|
580
468
|
} catch (error) {
|
|
581
469
|
return await onFetchError(error, cacheKey, keyId, keyCache, logger);
|
|
582
470
|
}
|
|
583
471
|
return await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
|
|
584
472
|
}
|
|
585
473
|
async function fetchKeyInternal(keyId, cls, options = {}) {
|
|
586
|
-
|
|
587
|
-
return await fetchKeyWithResult(cacheKey, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
|
|
474
|
+
return await fetchKeyWithResult(typeof keyId === "string" ? new URL(keyId) : keyId, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
|
|
588
475
|
return {
|
|
589
476
|
key: null,
|
|
590
477
|
cached: true
|
|
591
478
|
};
|
|
592
|
-
}, async (error, cacheKey
|
|
479
|
+
}, async (error, cacheKey, keyId, keyCache, logger) => {
|
|
593
480
|
logger.debug("Failed to fetch key {keyId}.", {
|
|
594
|
-
keyId
|
|
481
|
+
keyId,
|
|
595
482
|
error
|
|
596
483
|
});
|
|
597
|
-
await keyCache?.set(cacheKey
|
|
598
|
-
if (error instanceof FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey
|
|
484
|
+
await keyCache?.set(cacheKey, null);
|
|
485
|
+
if (error instanceof FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey, {
|
|
599
486
|
status: error.response.status,
|
|
600
487
|
response: error.response.clone()
|
|
601
488
|
});
|
|
602
|
-
else await keyCache?.setFetchError?.(cacheKey
|
|
489
|
+
else await keyCache?.setFetchError?.(cacheKey, { error: error instanceof Error ? error : new Error(String(error)) });
|
|
603
490
|
return {
|
|
604
491
|
key: null,
|
|
605
492
|
cached: false
|
|
606
493
|
};
|
|
607
494
|
});
|
|
608
495
|
}
|
|
609
|
-
|
|
610
496
|
//#endregion
|
|
611
497
|
//#region src/sig/http.ts
|
|
498
|
+
const DEFAULT_MAX_REDIRECTION = 20;
|
|
612
499
|
/**
|
|
613
500
|
* Signs a request using the given private key.
|
|
614
501
|
* @param request The request to sign.
|
|
@@ -620,9 +507,7 @@ async function fetchKeyInternal(keyId, cls, options = {}) {
|
|
|
620
507
|
*/
|
|
621
508
|
async function signRequest(request, privateKey, keyId, options = {}) {
|
|
622
509
|
validateCryptoKey(privateKey, "private");
|
|
623
|
-
|
|
624
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
625
|
-
return await tracer.startActiveSpan("http_signatures.sign", async (span) => {
|
|
510
|
+
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("http_signatures.sign", async (span) => {
|
|
626
511
|
try {
|
|
627
512
|
const spec = options.spec ?? "draft-cavage-http-signatures-12";
|
|
628
513
|
let signed;
|
|
@@ -631,7 +516,7 @@ async function signRequest(request, privateKey, keyId, options = {}) {
|
|
|
631
516
|
if (span.isRecording()) {
|
|
632
517
|
span.setAttribute(ATTR_HTTP_REQUEST_METHOD, signed.method);
|
|
633
518
|
span.setAttribute(ATTR_URL_FULL, signed.url);
|
|
634
|
-
for (const [name
|
|
519
|
+
for (const [name, value] of signed.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name), value);
|
|
635
520
|
span.setAttribute("http_signatures.key_id", keyId.href);
|
|
636
521
|
}
|
|
637
522
|
return signed;
|
|
@@ -659,8 +544,8 @@ async function signRequestDraft(request, privateKey, keyId, span, currentTime, b
|
|
|
659
544
|
}
|
|
660
545
|
if (!headers.has("Date")) headers.set("Date", currentTime == null ? (/* @__PURE__ */ new Date()).toUTCString() : new Date(currentTime.toString()).toUTCString());
|
|
661
546
|
const serialized = [["(request-target)", `${request.method.toLowerCase()} ${url.pathname}`], ...headers];
|
|
662
|
-
const headerNames = serialized.map(([name
|
|
663
|
-
const message = serialized.map(([name
|
|
547
|
+
const headerNames = serialized.map(([name]) => name);
|
|
548
|
+
const message = serialized.map(([name, value]) => `${name}: ${value.trim()}`).join("\n");
|
|
664
549
|
const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", privateKey, new TextEncoder().encode(message));
|
|
665
550
|
const sigHeader = `keyId="${keyId.href}",algorithm="rsa-sha256",headers="${headerNames.join(" ")}",signature="${encodeBase64(signature)}"`;
|
|
666
551
|
headers.set("Signature", sigHeader);
|
|
@@ -730,9 +615,7 @@ const derivedComponents = {
|
|
|
730
615
|
* @returns The formatted signature string.
|
|
731
616
|
*/
|
|
732
617
|
function formatRfc9421Signature(signature, components, parameters, label = "sig1") {
|
|
733
|
-
|
|
734
|
-
const signatureValue = `${label}=:${encodeBase64(signature)}:`;
|
|
735
|
-
return [signatureInputValue, signatureValue];
|
|
618
|
+
return [`${label}=(${components.map((c) => formatComponentId(c)).join(" ")});${parameters}`, `${label}=:${encodeBase64(signature)}:`];
|
|
736
619
|
}
|
|
737
620
|
/**
|
|
738
621
|
* Parse RFC 9421 Signature-Input header.
|
|
@@ -838,12 +721,11 @@ async function signRequestRfc9421(request, privateKey, keyId, span, currentTime,
|
|
|
838
721
|
value: "content-digest",
|
|
839
722
|
params: {}
|
|
840
723
|
}] : []];
|
|
841
|
-
const expires = rfc9421Options?.expires === true ? (currentTime.epochMilliseconds / 1e3 | 0) + 3600 : void 0;
|
|
842
724
|
const signatureParams = formatRfc9421SignatureParameters({
|
|
843
725
|
algorithm: "rsa-v1_5-sha256",
|
|
844
726
|
keyId,
|
|
845
727
|
created,
|
|
846
|
-
expires,
|
|
728
|
+
expires: rfc9421Options?.expires === true ? (currentTime.epochMilliseconds / 1e3 | 0) + 3600 : void 0,
|
|
847
729
|
nonce: rfc9421Options?.nonce,
|
|
848
730
|
tag: rfc9421Options?.tag
|
|
849
731
|
});
|
|
@@ -953,13 +835,11 @@ async function verifyRequest(request, options = {}) {
|
|
|
953
835
|
* @since 2.1.0
|
|
954
836
|
*/
|
|
955
837
|
async function verifyRequestDetailed(request, options = {}) {
|
|
956
|
-
|
|
957
|
-
const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
|
|
958
|
-
return await tracer.startActiveSpan("http_signatures.verify", async (span) => {
|
|
838
|
+
return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("http_signatures.verify", async (span) => {
|
|
959
839
|
if (span.isRecording()) {
|
|
960
840
|
span.setAttribute(ATTR_HTTP_REQUEST_METHOD, request.method);
|
|
961
841
|
span.setAttribute(ATTR_URL_FULL, request.url);
|
|
962
|
-
for (const [name
|
|
842
|
+
for (const [name, value] of request.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name), value);
|
|
963
843
|
}
|
|
964
844
|
try {
|
|
965
845
|
let spec = options.spec;
|
|
@@ -1147,11 +1027,10 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
1147
1027
|
logger.debug("Failed to verify; required headers missing in the Signature header: {headers}.", { headers });
|
|
1148
1028
|
return invalidSignatureResult(keyIdUrl);
|
|
1149
1029
|
}
|
|
1150
|
-
const message = headerNames.map((name
|
|
1030
|
+
const message = headerNames.map((name) => `${name}: ` + (name === "(request-target)" ? `${request.method.toLowerCase()} ${new URL(request.url).pathname}` : name === "(created)" ? sigValues.created ?? "" : name === "(expires)" ? sigValues.expires ?? "" : name === "host" ? request.headers.get("host") ?? new URL(request.url).host : request.headers.get(name))).join("\n");
|
|
1151
1031
|
const sig = decodeBase64(signature);
|
|
1152
1032
|
span?.setAttribute("http_signatures.signature", encodeHex(sig));
|
|
1153
|
-
|
|
1154
|
-
if (!verified) {
|
|
1033
|
+
if (!await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, sig, new TextEncoder().encode(message))) {
|
|
1155
1034
|
if (cached) {
|
|
1156
1035
|
logger.debug("Failed to verify with the cached key {keyId}; signature {signature} is invalid. Retrying with the freshly fetched key...", {
|
|
1157
1036
|
keyId,
|
|
@@ -1165,7 +1044,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
|
|
|
1165
1044
|
currentTime,
|
|
1166
1045
|
keyCache: {
|
|
1167
1046
|
get: () => Promise.resolve(void 0),
|
|
1168
|
-
set: async (keyId
|
|
1047
|
+
set: async (keyId, key) => await keyCache?.set(keyId, key)
|
|
1169
1048
|
}
|
|
1170
1049
|
});
|
|
1171
1050
|
}
|
|
@@ -1327,9 +1206,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1327
1206
|
failure = invalidSignatureResult(keyId);
|
|
1328
1207
|
continue;
|
|
1329
1208
|
}
|
|
1330
|
-
|
|
1331
|
-
const digestValid = await verifyRfc9421ContentDigest(contentDigestHeader, body);
|
|
1332
|
-
if (!digestValid) {
|
|
1209
|
+
if (!await verifyRfc9421ContentDigest(contentDigestHeader, await request.arrayBuffer())) {
|
|
1333
1210
|
logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
|
|
1334
1211
|
failure = invalidSignatureResult(keyId);
|
|
1335
1212
|
continue;
|
|
@@ -1387,8 +1264,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1387
1264
|
const signatureBaseBytes = new TextEncoder().encode(signatureBase);
|
|
1388
1265
|
span?.setAttribute("http_signatures.signature", encodeHex(sigBytes));
|
|
1389
1266
|
try {
|
|
1390
|
-
|
|
1391
|
-
if (verified) return {
|
|
1267
|
+
if (await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes)) return {
|
|
1392
1268
|
verified: true,
|
|
1393
1269
|
key,
|
|
1394
1270
|
signatureLabel: sigName
|
|
@@ -1402,7 +1278,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
|
|
|
1402
1278
|
currentTime,
|
|
1403
1279
|
keyCache: {
|
|
1404
1280
|
get: () => Promise.resolve(void 0),
|
|
1405
|
-
set: async (keyId
|
|
1281
|
+
set: async (keyId, key) => await keyCache?.set(keyId, key)
|
|
1406
1282
|
},
|
|
1407
1283
|
spec: "rfc9421"
|
|
1408
1284
|
});
|
|
@@ -1459,7 +1335,11 @@ function createRedirectRequest(request, location, body) {
|
|
|
1459
1335
|
* @since 1.6.0
|
|
1460
1336
|
*/
|
|
1461
1337
|
async function doubleKnock(request, identity, options = {}) {
|
|
1338
|
+
return await doubleKnockInternal(request, identity, options);
|
|
1339
|
+
}
|
|
1340
|
+
async function doubleKnockInternal(request, identity, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
|
|
1462
1341
|
const { specDeterminer, log, tracerProvider, signal } = options;
|
|
1342
|
+
visited.add(request.url);
|
|
1463
1343
|
const origin = new URL(request.url).origin;
|
|
1464
1344
|
const firstTrySpec = specDeterminer == null ? "rfc9421" : await specDeterminer.determineSpec(origin);
|
|
1465
1345
|
const body = options.body !== void 0 ? options.body : request.method !== "GET" && request.method !== "HEAD" ? await request.clone().arrayBuffer() : null;
|
|
@@ -1474,11 +1354,13 @@ async function doubleKnock(request, identity, options = {}) {
|
|
|
1474
1354
|
signal
|
|
1475
1355
|
});
|
|
1476
1356
|
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1357
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
|
|
1358
|
+
const redirectRequest = createRedirectRequest(request, response.headers.get("Location"), body);
|
|
1359
|
+
if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
|
|
1360
|
+
return doubleKnockInternal(redirectRequest, identity, {
|
|
1479
1361
|
...options,
|
|
1480
1362
|
body
|
|
1481
|
-
});
|
|
1363
|
+
}, redirected + 1, visited);
|
|
1482
1364
|
} else if (response.status === 400 || response.status === 401 || response.status > 401) {
|
|
1483
1365
|
const logger = getLogger([
|
|
1484
1366
|
"fedify",
|
|
@@ -1521,13 +1403,10 @@ async function doubleKnock(request, identity, options = {}) {
|
|
|
1521
1403
|
redirect: "manual",
|
|
1522
1404
|
signal
|
|
1523
1405
|
});
|
|
1524
|
-
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
body
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1406
|
+
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) return doubleKnock(createRedirectRequest(request, response.headers.get("Location"), body), identity, {
|
|
1407
|
+
...options,
|
|
1408
|
+
body
|
|
1409
|
+
});
|
|
1531
1410
|
}
|
|
1532
1411
|
if (fulfilled && response.status < 300) {
|
|
1533
1412
|
await specDeterminer?.rememberSpec(origin, "rfc9421");
|
|
@@ -1553,11 +1432,13 @@ async function doubleKnock(request, identity, options = {}) {
|
|
|
1553
1432
|
signal
|
|
1554
1433
|
});
|
|
1555
1434
|
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
|
|
1556
|
-
|
|
1557
|
-
|
|
1435
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
|
|
1436
|
+
const redirectRequest = createRedirectRequest(request, response.headers.get("Location"), body);
|
|
1437
|
+
if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
|
|
1438
|
+
return doubleKnockInternal(redirectRequest, identity, {
|
|
1558
1439
|
...options,
|
|
1559
1440
|
body
|
|
1560
|
-
});
|
|
1441
|
+
}, redirected + 1, visited);
|
|
1561
1442
|
} else if (response.status !== 400 && response.status !== 401) await specDeterminer?.rememberSpec(origin, spec);
|
|
1562
1443
|
} else await specDeterminer?.rememberSpec(origin, firstTrySpec);
|
|
1563
1444
|
return response;
|
|
@@ -1589,6 +1470,5 @@ function timingSafeEqual(a, b) {
|
|
|
1589
1470
|
result |= lenA ^ lenB;
|
|
1590
1471
|
return result === 0;
|
|
1591
1472
|
}
|
|
1592
|
-
|
|
1593
1473
|
//#endregion
|
|
1594
|
-
export {
|
|
1474
|
+
export { version as _, verifyRequestDetailed as a, fetchKeyDetailed as c, validateCryptoKey as d, formatAcceptSignature as f, name as g, validateAcceptSignature as h, verifyRequest as i, generateCryptoKeyPair as l, parseAcceptSignature as m, parseRfc9421SignatureInput as n, exportJwk as o, fulfillAcceptSignature as p, signRequest as r, fetchKey as s, doubleKnock as t, importJwk as u };
|