@fedify/fedify 2.4.0-dev.1668 → 2.4.0-dev.1740
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/README.md +1 -1
- package/dist/{assert-CJ1KXcvv.mjs → assert-CebeUf0C.mjs} +1 -1
- package/dist/assert_exists-DtzkXC47.mjs +28 -0
- package/dist/assert_false-3pLLLsO4.mjs +23 -0
- package/dist/assert_greater_or_equal-BApOTh1h.mjs +30 -0
- package/dist/{assert_instance_of-Q9KTBnrf.mjs → assert_instance_of-g3WcyYNR.mjs} +1 -1
- package/dist/{assert_not_equals-EPJPoxuf.mjs → assert_not_equals-BN7yDMWe.mjs} +1 -1
- package/dist/assert_rejects-wFbSPn1O.mjs +39 -0
- package/dist/{assert_strict_equals-Ec20AUwa.mjs → assert_strict_equals-Bpjl4Psw.mjs} +1 -1
- package/dist/{assert_throws-NiFfqbnH.mjs → assert_throws-BJ5wuvR2.mjs} +1 -1
- package/dist/{builder-iXZ5jNVg.mjs → builder-Bw6LVKGw.mjs} +5 -3
- package/dist/{circuit-breaker-CBGyz5F7.mjs → circuit-breaker-BT7CiPbz.mjs} +191 -9
- package/dist/circuit-breaker-test-utils-BYIHoliq.mjs +14 -0
- package/dist/{client-CjF5IYQS.mjs → client-CtxvmazV.mjs} +63 -5
- package/dist/{collection-BIhlldqK.mjs → collection-CnnP1UAv.mjs} +1 -1
- package/dist/compat/mod.cjs +1 -1
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/mod.js +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +3 -3
- package/dist/compat/public-audience.test.mjs +3 -3
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/{context-C05Rgxmu.d.cts → context-B-dsBjZ9.d.cts} +281 -7
- package/dist/{context-Cjnr0ig1.d.ts → context-DrLXudbA.d.ts} +281 -7
- package/dist/{deno-DtHcfB0f.mjs → deno-tRdp8MCl.mjs} +1 -1
- package/dist/{docloader-0vAfF6XW.mjs → docloader-Dg_7gMC7.mjs} +2 -2
- package/dist/{esm-yYQfPhIY.mjs → esm-BHXXx4Wx.mjs} +13 -6
- package/dist/federation/builder.test.mjs +18 -5
- package/dist/federation/circuit-breaker.test.mjs +626 -7
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +14 -13
- package/dist/federation/idempotency.test.mjs +6 -6
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +5 -5
- package/dist/federation/kv.test.mjs +3 -3
- package/dist/federation/metrics.test.mjs +4 -4
- package/dist/federation/middleware.test.mjs +37 -28
- package/dist/federation/mod.cjs +18 -540
- package/dist/federation/mod.d.cts +3 -4
- package/dist/federation/mod.d.ts +3 -4
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +32 -5
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +3 -3
- package/dist/federation/router.test.mjs +7 -7
- package/dist/federation/send.test.mjs +28 -26
- package/dist/federation/tasks/codec.test.mjs +4 -4
- package/dist/federation/tasks/enqueue.test.mjs +4 -4
- package/dist/federation/tasks/tasks.test.mjs +6 -6
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +74 -12
- package/dist/{middleware-DzIUFRO2.cjs → federation-BJBpt_Am.cjs} +855 -114
- package/dist/{http-BbnOMQoy.js → http-BIxGa6AG.js} +3 -3
- package/dist/{http-DUmWq5Pw.mjs → http-Day1kcpT.mjs} +5 -5
- package/dist/{temporal-polyfill-BCdTHexd.cjs → http-DggG1scN.cjs} +2801 -104
- package/dist/{key-CM7wDnZG.mjs → key-igh0AMsL.mjs} +2 -2
- package/dist/{kv-cache-ZQ22hm44.js → kv-cache-BIAB0HKx.js} +1 -1
- package/dist/{kv-cache-DEXKemJ9.mjs → kv-cache-Bz6aQOOX.mjs} +1 -1
- package/dist/{kv-cache-zmgG1HUp.cjs → kv-cache-C4U_uBqD.cjs} +2 -4
- package/dist/{ld-BttH_-8K.mjs → ld-DnT9sCWa.mjs} +5 -5
- package/dist/metrics-DVKYY6K1.d.cts +36 -0
- package/dist/{metrics-DT-CnD1g.mjs → metrics-DbdNnWIt.mjs} +2 -2
- package/dist/metrics-DoRtI0qU.d.ts +36 -0
- package/dist/{middleware-ChlYS0Af.mjs → middleware-B6GweVcg.mjs} +1 -1
- package/dist/{middleware-D3IAVMcT.js → middleware-CnsPXG0O.js} +241 -40
- package/dist/{middleware-DrroX3aD.mjs → middleware-DPIS4fsB.mjs} +60 -43
- package/dist/{mod-BrpVsSfY.d.cts → mod-CLHkCwLm.d.cts} +3 -3
- package/dist/{mod-B0hW12_O.d.cts → mod-CnGLNoVw.d.cts} +86 -4
- package/dist/{mod-DdONo-ep.d.cts → mod-D-abvu2C.d.cts} +1 -1
- package/dist/{mod-BsCE5Ihq.d.ts → mod-D6O8C7eN.d.ts} +1 -1
- package/dist/{mod-CNef4in0.d.ts → mod-DypxPS9H.d.ts} +3 -3
- package/dist/{mod-COIAjwRS.d.ts → mod-DzRXACM5.d.ts} +86 -4
- package/dist/mod.cjs +25 -25
- package/dist/mod.d.cts +10 -11
- package/dist/mod.d.ts +10 -11
- package/dist/mod.js +8 -8
- package/dist/nodeinfo/client.test.mjs +64 -4
- package/dist/nodeinfo/handler.test.mjs +5 -5
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.d.cts +1 -1
- package/dist/nodeinfo/mod.d.ts +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/types.test.mjs +4 -4
- package/dist/otel/exporter.test.mjs +3 -3
- package/dist/otel/mod.cjs +0 -1
- package/dist/otel/mod.d.cts +1 -1
- package/dist/otel/mod.d.ts +1 -1
- package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-BQSHRLhg.mjs} +2 -2
- package/dist/{owner-DZALmhdl.mjs → owner-B3ef8GfJ.mjs} +2 -2
- package/dist/{proof-CqA-2nfW.js → proof-BBLQXRWw.js} +608 -36
- package/dist/{proof-a60oVJ_4.cjs → proof-Cqk2TcLX.cjs} +616 -39
- package/dist/proof-DVoDZ8d7.mjs +890 -0
- package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--9hx7IGx.mjs} +1 -1
- package/dist/runtime/mod.cjs +1 -1
- package/dist/runtime/mod.js +1 -1
- package/dist/{send-DcwZnQWG.mjs → send-PbBSZ7Qk.mjs} +3 -3
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +37 -11
- package/dist/sig/key.test.mjs +6 -6
- package/dist/sig/ld.test.mjs +9 -7
- package/dist/sig/mod.cjs +3 -2
- package/dist/sig/mod.d.cts +4 -4
- package/dist/sig/mod.d.ts +4 -4
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +965 -15
- package/dist/std__assert-CxFT0MNt.mjs +8 -0
- package/dist/{temporal-Bpxpsl2k.mjs → temporal-DLQIjuTn.mjs} +3 -3
- package/dist/testing/mod.d.mts +10 -0
- package/dist/testing/mod.mjs +2 -2
- package/dist/{testing-CO7ftO8A.mjs → testing-BX0Nicyq.mjs} +2 -2
- package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
- package/dist/{types-DC1pNgJA.js → types-Dtyf8lVj.js} +63 -5
- package/dist/{types-CPym83zc.cjs → types-RXm5YxpC.cjs} +62 -5
- package/dist/utils/docloader.test.mjs +7 -7
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
- package/skills/fedify/SKILL.md +462 -0
- package/dist/assert_rejects-EgstcQy5.mjs +0 -82
- package/dist/http-BpT5cE6r.cjs +0 -2694
- package/dist/metrics-DN13mCAw.d.cts +0 -294
- package/dist/metrics-v_e0n5GQ.d.ts +0 -294
- package/dist/proof-DiQ0uBal.mjs +0 -316
- package/dist/std__assert-B2NnY9bq.mjs +0 -79
- /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
- /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
- /package/dist/{assert_equals-BV7oLMxm.mjs → assert_equals-CBlRfA-_.mjs} +0 -0
- /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
- /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
- /package/dist/{codec-BBga-FWI.mjs → codec-peqOdBaE.mjs} +0 -0
- /package/dist/{context-BJXxPElm.mjs → context-Dt36KFEJ.mjs} +0 -0
- /package/dist/{http-VyDTd4G3.d.cts → http-6TI0tI03.d.cts} +0 -0
- /package/dist/{http-lf8Hsd91.d.ts → http-CdrSn2ip.d.ts} +0 -0
- /package/dist/{keycache-_DHqz5z_.mjs → keycache-0Jk78XmB.mjs} +0 -0
- /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
- /package/dist/{kv-D6hNiMTK.d.ts → kv-BhNbN8Ed.d.cts} +0 -0
- /package/dist/{kv-gJ8LYbxX.d.cts → kv-BhNbN8Ed.d.ts} +0 -0
- /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
- /package/dist/{mq-Bo7Etgh6.mjs → mq-Dm1Wmtm-.mjs} +0 -0
- /package/dist/{negotiation-RuwrPFqi.mjs → negotiation-CCocWT_N.mjs} +0 -0
- /package/dist/{owner-CnngXDNJ.d.ts → owner-DGSfntI-.d.ts} +0 -0
- /package/dist/{owner-DEvZuyOE.d.cts → owner-r_waTiQj.d.cts} +0 -0
- /package/dist/{retry-DgFqeS5k.mjs → retry-zX5xw5e0.mjs} +0 -0
- /package/dist/{chunk-D5IdezsZ.js → rolldown-runtime-BC-Eo5Mj.js} +0 -0
- /package/dist/{chunk-Czpeue4M.cjs → rolldown-runtime-Dmm3t92W.cjs} +0 -0
- /package/dist/{transformers-DXze6FUB.js → transformers-DAtXl_Kc.js} +0 -0
- /package/dist/{types-CrtdVuDP.mjs → types-DE_LV1JB.mjs} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-tRdp8MCl.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-DbdNnWIt.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-BIxGa6AG.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { curry } from "es-toolkit";
|
|
6
6
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { p as recordDocumentCache } from "./metrics-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-DbdNnWIt.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
import { preloadedContexts } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/utils/kv-cache.ts
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
|
-
require("./
|
|
3
|
-
const require_http = require("./http-BpT5cE6r.cjs");
|
|
4
|
-
const require_temporal_polyfill = require("./temporal-polyfill-BCdTHexd.cjs");
|
|
2
|
+
const require_http = require("./http-DggG1scN.cjs");
|
|
5
3
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
4
|
let es_toolkit = require("es-toolkit");
|
|
7
5
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
@@ -46,7 +44,7 @@ function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedi
|
|
|
46
44
|
}
|
|
47
45
|
//#endregion
|
|
48
46
|
//#region src/utils/kv-cache.ts
|
|
49
|
-
const Temporal =
|
|
47
|
+
const Temporal = require_http.Temporal;
|
|
50
48
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
51
49
|
"fedify",
|
|
52
50
|
"utils",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { n as fetchKey, o as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-tRdp8MCl.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DbdNnWIt.mjs";
|
|
6
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-igh0AMsL.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
9
9
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -25,7 +25,7 @@ const localContext = [
|
|
|
25
25
|
];
|
|
26
26
|
const localContextUrls = new Set(localContext);
|
|
27
27
|
const builtInContextLoader = getDocumentLoader();
|
|
28
|
-
const disallowedJsonLdKeywords = new Set([
|
|
28
|
+
const disallowedJsonLdKeywords = /* @__PURE__ */ new Set([
|
|
29
29
|
"@graph",
|
|
30
30
|
"@included",
|
|
31
31
|
"@reverse"
|
|
@@ -525,7 +525,7 @@ async function verifySignature(jsonLd, options = {}) {
|
|
|
525
525
|
* only from external documents and are dropped from the metric attribute to
|
|
526
526
|
* avoid attacker-controlled cardinality.
|
|
527
527
|
*/
|
|
528
|
-
const LD_KNOWN_SIGNATURE_TYPES = new Set(["RsaSignature2017"]);
|
|
528
|
+
const LD_KNOWN_SIGNATURE_TYPES = /* @__PURE__ */ new Set(["RsaSignature2017"]);
|
|
529
529
|
/**
|
|
530
530
|
* Reports only whether a `signature` key is present on the document, with
|
|
531
531
|
* no shape check on its value. This is intentionally looser than
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
3
|
+
import { MeterProvider } from "@opentelemetry/api";
|
|
4
|
+
|
|
5
|
+
//#region src/federation/metrics.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The kind of remote ActivityPub lookup, recorded as
|
|
8
|
+
* `activitypub.lookup.kind` on the public-key lookup and remote document
|
|
9
|
+
* fetch metric families.
|
|
10
|
+
*
|
|
11
|
+
* - `public_key`: a public key lookup performed by `fetchKey` /
|
|
12
|
+
* `fetchKeyDetailed` (always recorded on `activitypub.key.lookup*`).
|
|
13
|
+
* - `actor`: a document fetch whose resolved value is an Actor. The
|
|
14
|
+
* bucket exists in the taxonomy for future actor-aware call sites;
|
|
15
|
+
* today, actor documents fetched through Fedify's generic document
|
|
16
|
+
* loader are still classified as `object` because the kind is decided
|
|
17
|
+
* at the loader boundary, before the response is parsed.
|
|
18
|
+
* - `object`: a generic ActivityPub object fetch through Fedify's
|
|
19
|
+
* document loader. This is the default classification for
|
|
20
|
+
* `documentLoader` invocations that do not match a more specific
|
|
21
|
+
* bucket.
|
|
22
|
+
* - `context`: a JSON-LD `@context` document fetch through Fedify's
|
|
23
|
+
* context loader.
|
|
24
|
+
* - `other`: a fetch that does not fit any of the above classifications.
|
|
25
|
+
* @since 2.3.0
|
|
26
|
+
*/
|
|
27
|
+
type LookupKind = "public_key" | "actor" | "object" | "context" | "other";
|
|
28
|
+
/**
|
|
29
|
+
* The {@link LookupKind} values that can appear on remote document fetch
|
|
30
|
+
* metrics. `public_key` lookups are reported on the
|
|
31
|
+
* `activitypub.key.lookup` metric family instead, so it is excluded here.
|
|
32
|
+
* @since 2.3.0
|
|
33
|
+
*/
|
|
34
|
+
type DocumentFetchKind = Exclude<LookupKind, "public_key">;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { DocumentFetchKind as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "temporal-polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-tRdp8MCl.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/federation/metrics.ts
|
|
@@ -770,7 +770,7 @@ function isAbortError(error) {
|
|
|
770
770
|
const name = error.name;
|
|
771
771
|
return typeof name === "string" && name === "AbortError";
|
|
772
772
|
}
|
|
773
|
-
const KNOWN_HTTP_METHODS = new Set([
|
|
773
|
+
const KNOWN_HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
774
774
|
"CONNECT",
|
|
775
775
|
"DELETE",
|
|
776
776
|
"GET",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { MeterProvider } from "@opentelemetry/api";
|
|
3
|
+
import { DocumentLoader } from "@fedify/vocab-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/federation/metrics.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The kind of remote ActivityPub lookup, recorded as
|
|
8
|
+
* `activitypub.lookup.kind` on the public-key lookup and remote document
|
|
9
|
+
* fetch metric families.
|
|
10
|
+
*
|
|
11
|
+
* - `public_key`: a public key lookup performed by `fetchKey` /
|
|
12
|
+
* `fetchKeyDetailed` (always recorded on `activitypub.key.lookup*`).
|
|
13
|
+
* - `actor`: a document fetch whose resolved value is an Actor. The
|
|
14
|
+
* bucket exists in the taxonomy for future actor-aware call sites;
|
|
15
|
+
* today, actor documents fetched through Fedify's generic document
|
|
16
|
+
* loader are still classified as `object` because the kind is decided
|
|
17
|
+
* at the loader boundary, before the response is parsed.
|
|
18
|
+
* - `object`: a generic ActivityPub object fetch through Fedify's
|
|
19
|
+
* document loader. This is the default classification for
|
|
20
|
+
* `documentLoader` invocations that do not match a more specific
|
|
21
|
+
* bucket.
|
|
22
|
+
* - `context`: a JSON-LD `@context` document fetch through Fedify's
|
|
23
|
+
* context loader.
|
|
24
|
+
* - `other`: a fetch that does not fit any of the above classifications.
|
|
25
|
+
* @since 2.3.0
|
|
26
|
+
*/
|
|
27
|
+
type LookupKind = "public_key" | "actor" | "object" | "context" | "other";
|
|
28
|
+
/**
|
|
29
|
+
* The {@link LookupKind} values that can appear on remote document fetch
|
|
30
|
+
* metrics. `public_key` lookups are reported on the
|
|
31
|
+
* `activitypub.key.lookup` metric family instead, so it is excluded here.
|
|
32
|
+
* @since 2.3.0
|
|
33
|
+
*/
|
|
34
|
+
type DocumentFetchKind = Exclude<LookupKind, "public_key">;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { DocumentFetchKind as t };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { t as __exportAll } from "./
|
|
4
|
-
import { r as getDefaultActivityTransformers } from "./transformers-
|
|
5
|
-
import { A as formatAcceptSignature, D as recordOutboxEnqueue, E as recordOutboxActivity, F as version, O as recordWebFingerHandle, P as name, S as recordCollectionTotalItems, T as recordInboxActivity, a as verifyRequestDetailed, b as recordCollectionPageItems, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, k as registerQueueDepthGauge, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, v as recordCircuitBreakerStateChange, w as recordFanoutRecipients, x as recordCollectionRequest, y as recordCollectionDispatchDuration } from "./http-
|
|
6
|
-
import { _ as
|
|
7
|
-
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
3
|
+
import { t as __exportAll } from "./rolldown-runtime-BC-Eo5Mj.js";
|
|
4
|
+
import { r as getDefaultActivityTransformers } from "./transformers-DAtXl_Kc.js";
|
|
5
|
+
import { A as formatAcceptSignature, D as recordOutboxEnqueue, E as recordOutboxActivity, F as version, O as recordWebFingerHandle, P as name, S as recordCollectionTotalItems, T as recordInboxActivity, a as verifyRequestDetailed, b as recordCollectionPageItems, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, k as registerQueueDepthGauge, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, v as recordCircuitBreakerStateChange, w as recordFanoutRecipients, x as recordCollectionRequest, y as recordCollectionDispatchDuration } from "./http-BIxGa6AG.js";
|
|
6
|
+
import { S as verifyCompactJsonLd, T as wrapContextLoaderForJsonLd, _ as hasSignature, b as isInvalidUrlTypeError, c as doesActorOwnKey, d as assertSafeJsonLd, g as getNormalizationContextLoader, h as detachSignature, i as verifyObject, l as getKeyOwner, n as hasProofLike, p as compactJsonLd, r as signObject, s as normalizeOutgoingActivityJsonLd, u as InvalidContextReferenceError, v as hasSignatureLike, x as signJsonLd, y as isClearlyMalformedContextReference } from "./proof-BBLQXRWw.js";
|
|
7
|
+
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-Dtyf8lVj.js";
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-BIAB0HKx.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
11
11
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -143,6 +143,8 @@ var FederationBuilderImpl = class {
|
|
|
143
143
|
f.webFingerLinksDispatcher = this.webFingerLinksDispatcher;
|
|
144
144
|
f.objectCallbacks = { ...this.objectCallbacks };
|
|
145
145
|
f.objectTypeIds = { ...this.objectTypeIds };
|
|
146
|
+
f.collectionCallbacks = { ...this.collectionCallbacks };
|
|
147
|
+
f.collectionTypeIds = { ...this.collectionTypeIds };
|
|
146
148
|
f.inboxPath = this.inboxPath;
|
|
147
149
|
f.outboxPath = this.outboxPath;
|
|
148
150
|
f.inboxCallbacks = this.inboxCallbacks == null ? void 0 : { ...this.inboxCallbacks };
|
|
@@ -722,7 +724,13 @@ function createFederationBuilder() {
|
|
|
722
724
|
}
|
|
723
725
|
//#endregion
|
|
724
726
|
//#region src/federation/circuit-breaker.ts
|
|
725
|
-
const
|
|
727
|
+
const LEGACY_SWEEP_MARKER = ["__fedify_meta", "circuit_breaker_state_ttl_sweep_v1"];
|
|
728
|
+
const LEGACY_SWEEP_DELETING_MARKER = { __fedifyDeletingCircuitBreakerLegacyState: true };
|
|
729
|
+
const CIRCUIT_BREAKER_STATE_VERSION = 1;
|
|
730
|
+
const LEGACY_SWEEP_LOCK_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
731
|
+
const LEGACY_SWEEP_RETRY_WINDOW = Temporal.Duration.from({ hours: 168 });
|
|
732
|
+
const LEGACY_SWEEP_WAIT_INTERVAL = 10;
|
|
733
|
+
const LEGACY_SWEEP_CAS_ATTEMPTS = 3;
|
|
726
734
|
/**
|
|
727
735
|
* Tracks reachability state for remote outbox delivery hosts.
|
|
728
736
|
* @since 2.3.0
|
|
@@ -732,6 +740,8 @@ var CircuitBreaker = class {
|
|
|
732
740
|
#prefix;
|
|
733
741
|
#options;
|
|
734
742
|
#now;
|
|
743
|
+
#legacySweep;
|
|
744
|
+
#legacySweepDone;
|
|
735
745
|
#stateChangeObserver;
|
|
736
746
|
constructor(options) {
|
|
737
747
|
this.#kv = options.kv;
|
|
@@ -748,6 +758,7 @@ var CircuitBreaker = class {
|
|
|
748
758
|
return now.until(this.#capHeldRetryAt(now, heldSince, now.add(delay)));
|
|
749
759
|
}
|
|
750
760
|
async beforeSend(remoteHost, message) {
|
|
761
|
+
this.#sweepLegacyStates();
|
|
751
762
|
const heldSince = parseHeldSince(message.circuitHeldSince);
|
|
752
763
|
const now = this.#now();
|
|
753
764
|
if (heldSince != null && Temporal.Instant.compare(heldSince.add(this.#options.heldActivityTtl), now) <= 0) return {
|
|
@@ -829,6 +840,7 @@ var CircuitBreaker = class {
|
|
|
829
840
|
throw new Error(`Failed to update circuit breaker state for ${remoteHost}`);
|
|
830
841
|
}
|
|
831
842
|
async recordSuccess(remoteHost) {
|
|
843
|
+
this.#sweepLegacyStates();
|
|
832
844
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
833
845
|
const oldState = await this.#get(remoteHost);
|
|
834
846
|
if (oldState == null) return void 0;
|
|
@@ -849,6 +861,7 @@ var CircuitBreaker = class {
|
|
|
849
861
|
return await this.recordSuccess(remoteHost);
|
|
850
862
|
}
|
|
851
863
|
async recordFailure(remoteHost) {
|
|
864
|
+
this.#sweepLegacyStates();
|
|
852
865
|
const now = this.#now();
|
|
853
866
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
854
867
|
const oldState = await this.#get(remoteHost);
|
|
@@ -896,26 +909,122 @@ var CircuitBreaker = class {
|
|
|
896
909
|
}
|
|
897
910
|
}
|
|
898
911
|
async getState(remoteHost) {
|
|
899
|
-
|
|
912
|
+
this.#sweepLegacyStates();
|
|
913
|
+
return stripStoredCircuitBreakerState(await this.#get(remoteHost));
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* The currently running background legacy sweep, if any.
|
|
917
|
+
* @internal
|
|
918
|
+
*/
|
|
919
|
+
get pendingSweep() {
|
|
920
|
+
return this.#legacySweep;
|
|
900
921
|
}
|
|
901
922
|
#key(remoteHost) {
|
|
902
923
|
return [...this.#prefix, remoteHost];
|
|
903
924
|
}
|
|
925
|
+
#legacySweepMarkerKey() {
|
|
926
|
+
return [...this.#prefix, ...LEGACY_SWEEP_MARKER];
|
|
927
|
+
}
|
|
928
|
+
#sweepLegacyStates() {
|
|
929
|
+
if (this.#kv.cas == null) return;
|
|
930
|
+
if (this.#options.stateTtl == null) return;
|
|
931
|
+
if (this.#legacySweep != null) return;
|
|
932
|
+
if (this.#isLegacySweepDone()) return;
|
|
933
|
+
this.#legacySweep = this.#sweepLegacyStatesImpl().catch((error) => {
|
|
934
|
+
getLogger([
|
|
935
|
+
"fedify",
|
|
936
|
+
"federation",
|
|
937
|
+
"circuit"
|
|
938
|
+
]).warn("Failed to sweep legacy circuit breaker state:\n{error}", { error });
|
|
939
|
+
}).finally(() => {
|
|
940
|
+
this.#legacySweep = void 0;
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
async #sweepLegacyStatesImpl() {
|
|
944
|
+
const markerKey = this.#legacySweepMarkerKey();
|
|
945
|
+
const marker = await this.#acquireLegacySweep(markerKey);
|
|
946
|
+
if (marker === "done") return;
|
|
947
|
+
try {
|
|
948
|
+
for await (const { key, value } of this.#kv.list(this.#prefix)) {
|
|
949
|
+
if (key.length !== this.#prefix.length + 1) continue;
|
|
950
|
+
await this.#migrateLegacyState(key, value);
|
|
951
|
+
}
|
|
952
|
+
} catch (error) {
|
|
953
|
+
await this.#deleteIfUnchanged(markerKey, marker);
|
|
954
|
+
throw error;
|
|
955
|
+
}
|
|
956
|
+
const finishedMarker = this.#finishLegacySweepMarker(marker);
|
|
957
|
+
if (await this.#kv.cas(markerKey, marker, finishedMarker)) this.#rememberLegacySweepMarker(finishedMarker);
|
|
958
|
+
}
|
|
959
|
+
#finishLegacySweepMarker(marker) {
|
|
960
|
+
const retryUntil = getLegacySweepRetryUntil(marker);
|
|
961
|
+
if (retryUntil != null && Temporal.Instant.compare(this.#now(), Temporal.Instant.from(retryUntil)) < 0) return {
|
|
962
|
+
state: "done",
|
|
963
|
+
retryUntil
|
|
964
|
+
};
|
|
965
|
+
return { state: "final" };
|
|
966
|
+
}
|
|
967
|
+
async #migrateLegacyState(key, value) {
|
|
968
|
+
if (isCurrentCircuitBreakerState(value)) return;
|
|
969
|
+
const state = parseCircuitBreakerKvState(value);
|
|
970
|
+
if (state != null) {
|
|
971
|
+
await this.#kv.cas(key, value, markCircuitBreakerState(state), this.#setOptions());
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
await this.#deleteIfUnchanged(key, value);
|
|
975
|
+
}
|
|
976
|
+
async #deleteIfUnchanged(key, value) {
|
|
977
|
+
if (await this.#kv.cas(key, value, LEGACY_SWEEP_DELETING_MARKER, { ttl: LEGACY_SWEEP_LOCK_TTL })) await this.#kv.delete(key);
|
|
978
|
+
}
|
|
979
|
+
async #acquireLegacySweep(markerKey) {
|
|
980
|
+
for (let attempt = 0; attempt < LEGACY_SWEEP_CAS_ATTEMPTS; attempt++) {
|
|
981
|
+
const marker = await this.#kv.get(markerKey);
|
|
982
|
+
const now = this.#now();
|
|
983
|
+
if (isLegacySweepActive(marker, now)) {
|
|
984
|
+
this.#rememberLegacySweepMarker(marker);
|
|
985
|
+
return "done";
|
|
986
|
+
}
|
|
987
|
+
const retryUntil = isLegacySweepRetryDue(marker, now) ? marker.retryUntil : getLegacySweepRetryUntil(marker) ?? now.add(LEGACY_SWEEP_RETRY_WINDOW).toString();
|
|
988
|
+
const sweeping = {
|
|
989
|
+
state: "sweeping",
|
|
990
|
+
started: now.toString(),
|
|
991
|
+
retryUntil
|
|
992
|
+
};
|
|
993
|
+
if (await this.#kv.cas(markerKey, marker ?? void 0, sweeping, { ttl: LEGACY_SWEEP_LOCK_TTL })) return sweeping;
|
|
994
|
+
await delay(LEGACY_SWEEP_WAIT_INTERVAL);
|
|
995
|
+
}
|
|
996
|
+
return "done";
|
|
997
|
+
}
|
|
998
|
+
#isLegacySweepDone() {
|
|
999
|
+
if (this.#legacySweepDone === "final") return true;
|
|
1000
|
+
if (this.#legacySweepDone == null) return false;
|
|
1001
|
+
if (Temporal.Instant.compare(this.#now(), this.#legacySweepDone) < 0) return true;
|
|
1002
|
+
this.#legacySweepDone = void 0;
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
#rememberLegacySweepMarker(marker) {
|
|
1006
|
+
const doneUntil = getLegacySweepDoneUntil(marker, this.#now());
|
|
1007
|
+
if (doneUntil != null) this.#legacySweepDone = doneUntil;
|
|
1008
|
+
}
|
|
904
1009
|
#capHeldRetryAt(now, heldSince, retryAt) {
|
|
905
1010
|
const expiresAt = (heldSince ?? now).add(this.#options.heldActivityTtl);
|
|
906
1011
|
return Temporal.Instant.compare(expiresAt, retryAt) < 0 ? expiresAt : retryAt;
|
|
907
1012
|
}
|
|
908
1013
|
async #get(remoteHost) {
|
|
909
|
-
return
|
|
1014
|
+
return parseStoredCircuitBreakerKvState(await this.#kv.get(this.#key(remoteHost)));
|
|
910
1015
|
}
|
|
911
1016
|
async #replace(remoteHost, oldState, newState) {
|
|
912
1017
|
const key = this.#key(remoteHost);
|
|
1018
|
+
const storedState = newState == null ? void 0 : markCircuitBreakerState(newState);
|
|
913
1019
|
if (this.#kv.cas == null) {
|
|
914
|
-
if (
|
|
915
|
-
else await this.#kv.set(key,
|
|
1020
|
+
if (storedState == null) await this.#kv.delete(key);
|
|
1021
|
+
else await this.#kv.set(key, storedState, this.#setOptions());
|
|
916
1022
|
return true;
|
|
917
1023
|
}
|
|
918
|
-
return await this.#kv.cas(key, oldState,
|
|
1024
|
+
return await this.#kv.cas(key, oldState, storedState, storedState == null ? void 0 : this.#setOptions());
|
|
1025
|
+
}
|
|
1026
|
+
#setOptions() {
|
|
1027
|
+
return this.#options.stateTtl == null ? void 0 : { ttl: this.#options.stateTtl };
|
|
919
1028
|
}
|
|
920
1029
|
async #notifyStateChange(remoteHost, previousState, newState) {
|
|
921
1030
|
try {
|
|
@@ -955,18 +1064,25 @@ var CircuitBreaker = class {
|
|
|
955
1064
|
* @param options The public circuit breaker options supplied to Fedify.
|
|
956
1065
|
* @returns The normalized failure predicate, failure pruning function,
|
|
957
1066
|
* duration values, and optional callbacks with defaults applied.
|
|
958
|
-
* @throws {RangeError} If any configured duration is not positive
|
|
1067
|
+
* @throws {RangeError} If any configured duration is not positive, or if
|
|
1068
|
+
* `stateTtl` is shorter than `recoveryDelay`.
|
|
959
1069
|
* @throws {TypeError} If `failureThreshold` is not a positive integer.
|
|
960
1070
|
*/
|
|
961
1071
|
function normalizeCircuitBreakerOptions(options) {
|
|
962
1072
|
const recoveryDelay = toInstantDuration(options.recoveryDelay ?? { minutes: 30 });
|
|
963
1073
|
const heldActivityTtl = toInstantDuration(options.heldActivityTtl ?? { hours: 168 });
|
|
964
1074
|
const releaseInterval = toInstantDuration(options.releaseInterval ?? { seconds: 1 });
|
|
1075
|
+
const configuredStateTtl = options.stateTtl == null ? void 0 : toInstantDuration(options.stateTtl);
|
|
965
1076
|
assertPositiveDuration(recoveryDelay, "recoveryDelay");
|
|
966
1077
|
assertPositiveDuration(heldActivityTtl, "heldActivityTtl");
|
|
967
1078
|
assertPositiveDuration(releaseInterval, "releaseInterval");
|
|
1079
|
+
if (configuredStateTtl != null) {
|
|
1080
|
+
assertPositiveDuration(configuredStateTtl, "stateTtl");
|
|
1081
|
+
if (Temporal.Duration.compare(configuredStateTtl, recoveryDelay) < 0) throw new RangeError("stateTtl must be at least recoveryDelay.");
|
|
1082
|
+
}
|
|
968
1083
|
let failure;
|
|
969
1084
|
let pruneFailures;
|
|
1085
|
+
let stateTtl;
|
|
970
1086
|
if (options.failure == null) {
|
|
971
1087
|
const failureThreshold = options.failureThreshold ?? 5;
|
|
972
1088
|
if (!Number.isInteger(failureThreshold) || failureThreshold <= 0) throw new TypeError("failureThreshold must be a positive integer.");
|
|
@@ -982,9 +1098,11 @@ function normalizeCircuitBreakerOptions(options) {
|
|
|
982
1098
|
const last = timestamps[timestamps.length - 1];
|
|
983
1099
|
return Temporal.Duration.compare(first.until(last), failureWindow) <= 0;
|
|
984
1100
|
};
|
|
1101
|
+
stateTtl = configuredStateTtl ?? maxDuration(recoveryDelay.add(failureWindow), recoveryDelay.add(heldActivityTtl));
|
|
985
1102
|
} else {
|
|
986
1103
|
failure = options.failure;
|
|
987
|
-
pruneFailures = (timestamps) => timestamps.slice(-
|
|
1104
|
+
pruneFailures = (timestamps) => timestamps.slice(-100);
|
|
1105
|
+
stateTtl = configuredStateTtl;
|
|
988
1106
|
}
|
|
989
1107
|
return {
|
|
990
1108
|
failure,
|
|
@@ -992,10 +1110,72 @@ function normalizeCircuitBreakerOptions(options) {
|
|
|
992
1110
|
recoveryDelay,
|
|
993
1111
|
heldActivityTtl,
|
|
994
1112
|
releaseInterval,
|
|
1113
|
+
stateTtl,
|
|
995
1114
|
onStateChange: options.onStateChange,
|
|
996
1115
|
onActivityDrop: options.onActivityDrop
|
|
997
1116
|
};
|
|
998
1117
|
}
|
|
1118
|
+
function maxDuration(duration, ...durations) {
|
|
1119
|
+
return durations.reduce((max, candidate) => Temporal.Duration.compare(candidate, max) > 0 ? candidate : max, duration);
|
|
1120
|
+
}
|
|
1121
|
+
function isLegacySweepDone(value, now) {
|
|
1122
|
+
return getLegacySweepDoneUntil(value, now) != null;
|
|
1123
|
+
}
|
|
1124
|
+
function getLegacySweepDoneUntil(value, now) {
|
|
1125
|
+
if (typeof value !== "object" || value == null || !("state" in value)) return;
|
|
1126
|
+
if (value.state === "final") return "final";
|
|
1127
|
+
if (value.state === "done" && "retryUntil" in value && typeof value.retryUntil === "string") try {
|
|
1128
|
+
const retryUntil = Temporal.Instant.from(value.retryUntil);
|
|
1129
|
+
return Temporal.Instant.compare(now, retryUntil) < 0 ? retryUntil : void 0;
|
|
1130
|
+
} catch {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
function isLegacySweepRetryDue(value, now) {
|
|
1135
|
+
if (typeof value !== "object" || value == null || !("state" in value) || value.state !== "done" || !("retryUntil" in value) || typeof value.retryUntil !== "string") return false;
|
|
1136
|
+
try {
|
|
1137
|
+
return Temporal.Instant.compare(now, Temporal.Instant.from(value.retryUntil)) >= 0;
|
|
1138
|
+
} catch {
|
|
1139
|
+
return false;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
function isLegacySweepActive(value, now) {
|
|
1143
|
+
return isLegacySweepDone(value, now) || isLegacySweepInProgress(value, now);
|
|
1144
|
+
}
|
|
1145
|
+
function isLegacySweepInProgress(value, now) {
|
|
1146
|
+
if (typeof value !== "object" || value == null || !("state" in value) || value.state !== "sweeping" || !("started" in value) || typeof value.started !== "string") return false;
|
|
1147
|
+
try {
|
|
1148
|
+
return Temporal.Instant.compare(now, Temporal.Instant.from(value.started).add(LEGACY_SWEEP_LOCK_TTL)) < 0;
|
|
1149
|
+
} catch {
|
|
1150
|
+
return false;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
function getLegacySweepRetryUntil(value) {
|
|
1154
|
+
if (typeof value !== "object" || value == null || !("retryUntil" in value) || typeof value.retryUntil !== "string") return;
|
|
1155
|
+
try {
|
|
1156
|
+
Temporal.Instant.from(value.retryUntil);
|
|
1157
|
+
return value.retryUntil;
|
|
1158
|
+
} catch {
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
function isCurrentCircuitBreakerState(value) {
|
|
1163
|
+
return typeof value === "object" && value != null && "__fedifyCircuitBreakerStateVersion" in value && value.__fedifyCircuitBreakerStateVersion === CIRCUIT_BREAKER_STATE_VERSION;
|
|
1164
|
+
}
|
|
1165
|
+
function markCircuitBreakerState(state) {
|
|
1166
|
+
return {
|
|
1167
|
+
...state,
|
|
1168
|
+
__fedifyCircuitBreakerStateVersion: CIRCUIT_BREAKER_STATE_VERSION
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
function stripStoredCircuitBreakerState(state) {
|
|
1172
|
+
if (state == null) return void 0;
|
|
1173
|
+
const { __fedifyCircuitBreakerStateVersion: _, ...publicState } = state;
|
|
1174
|
+
return publicState;
|
|
1175
|
+
}
|
|
1176
|
+
function delay(milliseconds) {
|
|
1177
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
1178
|
+
}
|
|
999
1179
|
function toInstantDuration(duration) {
|
|
1000
1180
|
const parsed = Temporal.Duration.from(duration);
|
|
1001
1181
|
return Temporal.Duration.from({ milliseconds: Math.trunc(parsed.total({
|
|
@@ -1030,6 +1210,9 @@ function parseHeldSince(value) {
|
|
|
1030
1210
|
* valid instant strings, or `undefined` when the stored value is malformed.
|
|
1031
1211
|
*/
|
|
1032
1212
|
function parseCircuitBreakerKvState(value) {
|
|
1213
|
+
return stripStoredCircuitBreakerState(parseStoredCircuitBreakerKvState(value));
|
|
1214
|
+
}
|
|
1215
|
+
function parseStoredCircuitBreakerKvState(value) {
|
|
1033
1216
|
const isInstantString = (v) => {
|
|
1034
1217
|
if (typeof v !== "string") return false;
|
|
1035
1218
|
try {
|
|
@@ -1049,7 +1232,8 @@ function parseCircuitBreakerKvState(value) {
|
|
|
1049
1232
|
state: record.state,
|
|
1050
1233
|
failures: record.failures,
|
|
1051
1234
|
...record.opened == null ? {} : { opened: record.opened },
|
|
1052
|
-
...record.halfOpened == null ? {} : { halfOpened: record.halfOpened }
|
|
1235
|
+
...record.halfOpened == null ? {} : { halfOpened: record.halfOpened },
|
|
1236
|
+
...record.__fedifyCircuitBreakerStateVersion === CIRCUIT_BREAKER_STATE_VERSION ? { __fedifyCircuitBreakerStateVersion: CIRCUIT_BREAKER_STATE_VERSION } : {}
|
|
1053
1237
|
};
|
|
1054
1238
|
}
|
|
1055
1239
|
//#endregion
|
|
@@ -1064,7 +1248,7 @@ function parseCircuitBreakerKvState(value) {
|
|
|
1064
1248
|
async function digest(uris) {
|
|
1065
1249
|
const processed = /* @__PURE__ */ new Set();
|
|
1066
1250
|
const encoder = new TextEncoder();
|
|
1067
|
-
const result = new Uint8Array(32);
|
|
1251
|
+
const result = /* @__PURE__ */ new Uint8Array(32);
|
|
1068
1252
|
for (const uri of uris) {
|
|
1069
1253
|
const u = uri instanceof URL ? uri.href : uri;
|
|
1070
1254
|
if (processed.has(u)) continue;
|
|
@@ -1459,7 +1643,7 @@ function isMalformedDurationLiteral(value) {
|
|
|
1459
1643
|
return true;
|
|
1460
1644
|
}
|
|
1461
1645
|
}
|
|
1462
|
-
const TEMPORAL_DATE_TIME_IRIS = new Set([
|
|
1646
|
+
const TEMPORAL_DATE_TIME_IRIS = /* @__PURE__ */ new Set([
|
|
1463
1647
|
"https://www.w3.org/ns/activitystreams#deleted",
|
|
1464
1648
|
"https://www.w3.org/ns/activitystreams#endTime",
|
|
1465
1649
|
"https://www.w3.org/ns/activitystreams#published",
|
|
@@ -1468,7 +1652,7 @@ const TEMPORAL_DATE_TIME_IRIS = new Set([
|
|
|
1468
1652
|
"http://purl.org/dc/terms/created",
|
|
1469
1653
|
"https://w3id.org/security#created"
|
|
1470
1654
|
]);
|
|
1471
|
-
const TEMPORAL_DURATION_IRIS = new Set(["https://www.w3.org/ns/activitystreams#duration"]);
|
|
1655
|
+
const TEMPORAL_DURATION_IRIS = /* @__PURE__ */ new Set(["https://www.w3.org/ns/activitystreams#duration"]);
|
|
1472
1656
|
const QUESTION_CLOSED_IRI = "https://www.w3.org/ns/activitystreams#closed";
|
|
1473
1657
|
const XSD_DATE_TIME_IRI = "http://www.w3.org/2001/XMLSchema#dateTime";
|
|
1474
1658
|
function hasMalformedExpandedDateTimeLiteral(value) {
|
|
@@ -1612,7 +1796,7 @@ async function handleObject(request, { values, context, objectDispatcher, author
|
|
|
1612
1796
|
Vary: "Accept"
|
|
1613
1797
|
} });
|
|
1614
1798
|
}
|
|
1615
|
-
const BUILT_IN_COLLECTION_METRIC_KINDS = new Set([
|
|
1799
|
+
const BUILT_IN_COLLECTION_METRIC_KINDS = /* @__PURE__ */ new Set([
|
|
1616
1800
|
"inbox",
|
|
1617
1801
|
"outbox",
|
|
1618
1802
|
"following",
|
|
@@ -3223,7 +3407,7 @@ async function respondWithObjectIfAcceptable(object, request, options) {
|
|
|
3223
3407
|
return response;
|
|
3224
3408
|
}
|
|
3225
3409
|
function generateNonce() {
|
|
3226
|
-
const bytes = new Uint8Array(16);
|
|
3410
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
3227
3411
|
crypto.getRandomValues(bytes);
|
|
3228
3412
|
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3229
3413
|
}
|
|
@@ -4099,6 +4283,24 @@ const logger = getLogger([
|
|
|
4099
4283
|
"webfinger",
|
|
4100
4284
|
"server"
|
|
4101
4285
|
]);
|
|
4286
|
+
function getWebFingerSubjectAndAliases({ resourceUrl, actorUri, preferredUsername, acctUsername, host, contextHost }) {
|
|
4287
|
+
const aliases = [];
|
|
4288
|
+
let subject = resourceUrl.href;
|
|
4289
|
+
if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
|
|
4290
|
+
aliases.push(`acct:${preferredUsername}@${host ?? contextHost}`);
|
|
4291
|
+
if (host != null && host !== contextHost) aliases.push(`acct:${preferredUsername}@${contextHost}`);
|
|
4292
|
+
}
|
|
4293
|
+
if (resourceUrl.href !== actorUri.href) aliases.push(actorUri.href);
|
|
4294
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== contextHost && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
4295
|
+
subject = `acct:${preferredUsername ?? acctUsername}@${host}`;
|
|
4296
|
+
aliases.push(resourceUrl.href);
|
|
4297
|
+
if (preferredUsername != null && preferredUsername !== "" && preferredUsername !== acctUsername) aliases.push(`acct:${preferredUsername}@${contextHost}`);
|
|
4298
|
+
}
|
|
4299
|
+
return {
|
|
4300
|
+
subject,
|
|
4301
|
+
aliases
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4102
4304
|
/**
|
|
4103
4305
|
* Handles a WebFinger request. You would not typically call this function
|
|
4104
4306
|
* directly, but instead use {@link Federation.fetch} method.
|
|
@@ -4147,7 +4349,7 @@ async function handleWebFinger(request, options) {
|
|
|
4147
4349
|
});
|
|
4148
4350
|
}
|
|
4149
4351
|
}
|
|
4150
|
-
const WEBFINGER_HANDLE_SCHEME_WHITELIST = new Set([
|
|
4352
|
+
const WEBFINGER_HANDLE_SCHEME_WHITELIST = /* @__PURE__ */ new Set([
|
|
4151
4353
|
"acct",
|
|
4152
4354
|
"http",
|
|
4153
4355
|
"https",
|
|
@@ -4203,6 +4405,7 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
4203
4405
|
return identifier;
|
|
4204
4406
|
}
|
|
4205
4407
|
let identifier = null;
|
|
4408
|
+
let acctUsername = null;
|
|
4206
4409
|
const uriParsed = context.parseUri(resourceUrl);
|
|
4207
4410
|
if (uriParsed?.type != "actor") {
|
|
4208
4411
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
@@ -4216,8 +4419,9 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
4216
4419
|
const normalizedHost = portMatch == null ? domainToASCII(match[2].toLowerCase()) : domainToASCII(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
4217
4420
|
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
4218
4421
|
else {
|
|
4219
|
-
|
|
4220
|
-
|
|
4422
|
+
acctUsername = match[1];
|
|
4423
|
+
identifier = await mapUsernameToIdentifier(acctUsername);
|
|
4424
|
+
resourceUrl = new URL(`acct:${acctUsername}@${normalizedHost}`);
|
|
4221
4425
|
}
|
|
4222
4426
|
}
|
|
4223
4427
|
} else identifier = uriParsed.identifier;
|
|
@@ -4231,9 +4435,10 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
4231
4435
|
status: 410,
|
|
4232
4436
|
headers: { "Access-Control-Allow-Origin": "*" }
|
|
4233
4437
|
});
|
|
4438
|
+
const actorUri = context.getActorUri(identifier);
|
|
4234
4439
|
const links = [{
|
|
4235
4440
|
rel: "self",
|
|
4236
|
-
href:
|
|
4441
|
+
href: actorUri.href,
|
|
4237
4442
|
type: "application/activity+json"
|
|
4238
4443
|
}];
|
|
4239
4444
|
for (const url of actor.urls) if (url instanceof Link && url.href != null) links.push({
|
|
@@ -4257,23 +4462,19 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
4257
4462
|
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
4258
4463
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
4259
4464
|
}
|
|
4260
|
-
const aliases =
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
}
|
|
4271
|
-
const jrd = {
|
|
4272
|
-
subject: resourceUrl.href,
|
|
4465
|
+
const { subject, aliases } = getWebFingerSubjectAndAliases({
|
|
4466
|
+
resourceUrl,
|
|
4467
|
+
actorUri,
|
|
4468
|
+
preferredUsername: actor.preferredUsername,
|
|
4469
|
+
acctUsername,
|
|
4470
|
+
host,
|
|
4471
|
+
contextHost: context.url.host
|
|
4472
|
+
});
|
|
4473
|
+
return new Response(JSON.stringify({
|
|
4474
|
+
subject,
|
|
4273
4475
|
aliases,
|
|
4274
4476
|
links
|
|
4275
|
-
}
|
|
4276
|
-
return new Response(JSON.stringify(jrd), { headers: {
|
|
4477
|
+
}), { headers: {
|
|
4277
4478
|
"Content-Type": "application/jrd+json",
|
|
4278
4479
|
"Access-Control-Allow-Origin": "*"
|
|
4279
4480
|
} });
|
|
@@ -7132,4 +7333,4 @@ function getRequestId(request) {
|
|
|
7132
7333
|
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
7133
7334
|
}
|
|
7134
7335
|
//#endregion
|
|
7135
|
-
export {
|
|
7336
|
+
export { respondWithObject as a, digest as c, parseCircuitBreakerKvState as d, createFederationBuilder as f, SendActivityError as i, CircuitBreaker as l, handleWebFinger as n, respondWithObjectIfAcceptable as o, createExponentialBackoffPolicy as r, buildCollectionSynchronizationHeader as s, createFederation as t, normalizeCircuitBreakerOptions as u };
|