@fedify/fedify 2.0.22-dev.1552 → 2.0.22
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-BGn4fR4T.mjs → builder-BO_JMtJs.mjs} +3 -3
- package/dist/{client-A1UrnX6I.mjs → client-HLLGHiTU.mjs} +63 -5
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-CzWRdvbm.mjs → deno-661NE5Kk.mjs} +1 -1
- package/dist/{docloader-DL03Z6Do.mjs → docloader-Doj2y_GK.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +4 -4
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +6 -6
- 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 +69 -7
- package/dist/{http-vxO9IEIy.mjs → http-BQL35dN0.mjs} +2 -2
- package/dist/{http-DSQs81GP.js → http-CC2-WkSX.js} +1 -1
- package/dist/{http-CN2DyRdw.cjs → http-DWhQe-I5.cjs} +1 -1
- package/dist/{inbox-hJL9klR1.mjs → inbox-Bqoa4PJZ.mjs} +1 -1
- package/dist/{key-4XtzJ1-9.mjs → key-C0qmhoN-.mjs} +1 -1
- package/dist/{kv-cache-dYvBso-A.js → kv-cache-C7XaTsof.js} +1 -1
- package/dist/{kv-cache-BFV5hAXm.cjs → kv-cache-DY8Q_hte.cjs} +1 -1
- package/dist/{ld-B9yNvtQU.mjs → ld-B2MKYZcj.mjs} +2 -2
- package/dist/{middleware-CNRI-93D.cjs → middleware-BxR2EmWw.cjs} +1 -1
- package/dist/{middleware-BqIso1Ys.cjs → middleware-DJcsKDyA.cjs} +40 -22
- package/dist/{middleware-DDZEjS18.js → middleware-DMsZ7PRo.js} +39 -21
- package/dist/{middleware-CfGAgFCR.mjs → middleware-DPmN82D7.mjs} +1 -1
- package/dist/{middleware-DvBRn8oT.mjs → middleware-DVqurycM.mjs} +47 -29
- package/dist/mod.cjs +5 -5
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +61 -1
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/{owner-u-sxpb4s.mjs → owner-BUbV-zsu.mjs} +2 -2
- package/dist/{proof-qW3joN5t.cjs → proof-B8z-9_xo.cjs} +1 -1
- package/dist/{proof-AuTxaSx2.js → proof-CGOJ4Mq3.js} +1 -1
- package/dist/{proof-CU4dSRI6.mjs → proof-pGWMVV0R.mjs} +2 -2
- package/dist/{send-DliU7LA6.mjs → send-DrKWpXWF.mjs} +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +1 -1
- package/dist/{temporal-BdqleueJ.mjs → temporal-BUr1JyFa.mjs} +1 -1
- package/dist/{types-CAY3OdLq.js → types-DTONwNqL.js} +63 -5
- package/dist/{types-KC4QAoxe.cjs → types-m8u9L86X.cjs} +62 -4
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +5 -5
|
@@ -2,8 +2,8 @@ import "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as RouterError, t as Router } from "./router-CrMLXoOr.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno-
|
|
6
|
-
import { t as InboxListenerSet } from "./inbox-
|
|
5
|
+
import { n as version, t as name } from "./deno-661NE5Kk.mjs";
|
|
6
|
+
import { t as InboxListenerSet } from "./inbox-Bqoa4PJZ.mjs";
|
|
7
7
|
import { getTypeId } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
9
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -42,7 +42,7 @@ var FederationBuilderImpl = class {
|
|
|
42
42
|
this.collectionTypeIds = {};
|
|
43
43
|
}
|
|
44
44
|
async build(options) {
|
|
45
|
-
const { FederationImpl } = await import("./middleware-
|
|
45
|
+
const { FederationImpl } = await import("./middleware-DPmN82D7.mjs");
|
|
46
46
|
const f = new FederationImpl(options);
|
|
47
47
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
48
48
|
f.router = this.router.clone();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { getUserAgent } from "@fedify/vocab-runtime";
|
|
4
|
+
import { UrlError, getUserAgent, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|
|
6
6
|
//#region src/nodeinfo/client.ts
|
|
7
7
|
const logger = getLogger([
|
|
@@ -9,15 +9,72 @@ const logger = getLogger([
|
|
|
9
9
|
"nodeinfo",
|
|
10
10
|
"client"
|
|
11
11
|
]);
|
|
12
|
+
const DEFAULT_MAX_REDIRECTION = 5;
|
|
13
|
+
/**
|
|
14
|
+
* Fetches a URL while guarding against SSRF. Before every request—including
|
|
15
|
+
* each redirect hop—the destination is validated with
|
|
16
|
+
* {@link validatePublicUrl}, so that loopback, link-local, and private
|
|
17
|
+
* addresses, as well as non-HTTP(S) schemes such as `data:`, are rejected.
|
|
18
|
+
* Redirects are followed manually with a cap, so that a public URL cannot
|
|
19
|
+
* bounce the request to an internal address.
|
|
20
|
+
* @param url The URL to fetch.
|
|
21
|
+
* @param headers The request headers.
|
|
22
|
+
* @returns The final response, or `null` if the URL is disallowed or there
|
|
23
|
+
* are too many redirects.
|
|
24
|
+
*/
|
|
25
|
+
async function fetchPublicUrl(url, headers) {
|
|
26
|
+
let current = url instanceof URL ? url : new URL(url);
|
|
27
|
+
let redirected = 0;
|
|
28
|
+
while (true) {
|
|
29
|
+
try {
|
|
30
|
+
await validatePublicUrl(current.href);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
if (e instanceof UrlError) {
|
|
33
|
+
logger.error("Refused to fetch a private or invalid URL {url}: {error}", {
|
|
34
|
+
url: current.href,
|
|
35
|
+
error: e
|
|
36
|
+
});
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
const response = await fetch(current, {
|
|
42
|
+
headers,
|
|
43
|
+
redirect: "manual"
|
|
44
|
+
});
|
|
45
|
+
if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
|
|
46
|
+
redirected++;
|
|
47
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) {
|
|
48
|
+
logger.error("Too many redirections ({redirections}) while fetching {url}.", {
|
|
49
|
+
redirections: redirected,
|
|
50
|
+
url: current.href
|
|
51
|
+
});
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const next = new URL(response.headers.get("Location"), response.url == null || response.url === "" ? current : response.url);
|
|
55
|
+
if (next.protocol !== current.protocol) {
|
|
56
|
+
logger.error("Refused a redirect to a different protocol ({protocol} to {redirectedProtocol}) while fetching NodeInfo.", {
|
|
57
|
+
protocol: current.protocol,
|
|
58
|
+
redirectedProtocol: next.protocol
|
|
59
|
+
});
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
current = next;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
return response;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
12
68
|
async function getNodeInfo(url, options = {}) {
|
|
13
69
|
try {
|
|
14
70
|
let nodeInfoUrl = url;
|
|
15
71
|
if (!options.direct) {
|
|
16
72
|
const wellKnownUrl = new URL("/.well-known/nodeinfo", url);
|
|
17
|
-
const wellKnownResponse = await
|
|
73
|
+
const wellKnownResponse = await fetchPublicUrl(wellKnownUrl, {
|
|
18
74
|
Accept: "application/json",
|
|
19
75
|
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
20
|
-
}
|
|
76
|
+
});
|
|
77
|
+
if (wellKnownResponse == null) return void 0;
|
|
21
78
|
if (!wellKnownResponse.ok) {
|
|
22
79
|
logger.error("Failed to fetch {url}: {status} {statusText}", {
|
|
23
80
|
url: wellKnownUrl.href,
|
|
@@ -37,10 +94,11 @@ async function getNodeInfo(url, options = {}) {
|
|
|
37
94
|
}
|
|
38
95
|
nodeInfoUrl = link.href;
|
|
39
96
|
}
|
|
40
|
-
const response = await
|
|
97
|
+
const response = await fetchPublicUrl(nodeInfoUrl, {
|
|
41
98
|
Accept: "application/json",
|
|
42
99
|
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
43
|
-
}
|
|
100
|
+
});
|
|
101
|
+
if (response == null) return void 0;
|
|
44
102
|
if (!response.ok) {
|
|
45
103
|
logger.error("Failed to fetch NodeInfo document from {url}: {status} {statusText}", {
|
|
46
104
|
url: nodeInfoUrl.toString(),
|
|
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
|
5
5
|
import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
6
6
|
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
8
|
-
import { _ as autoIdAssigner, g as actorDehydrator, n as FederationImpl } from "../middleware-
|
|
8
|
+
import { _ as autoIdAssigner, g as actorDehydrator, n as FederationImpl } from "../middleware-DVqurycM.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Follow, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/compat/transformers.test.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { a as validateCryptoKey } from "./key-
|
|
5
|
-
import { n as doubleKnock } from "./http-
|
|
4
|
+
import { a as validateCryptoKey } from "./key-C0qmhoN-.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-BQL35dN0.mjs";
|
|
6
6
|
import { curry } from "es-toolkit";
|
|
7
7
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
|
5
5
|
import { a as assertExists } from "../std__assert-Duiq_YC9.mjs";
|
|
6
6
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
8
|
-
import { n as createFederationBuilder } from "../builder-
|
|
8
|
+
import { n as createFederationBuilder } from "../builder-BO_JMtJs.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Activity, Note, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/federation/builder.test.ts
|
|
@@ -6,12 +6,12 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
7
|
import { t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
8
8
|
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
9
|
-
import { s as signRequest } from "../http-
|
|
9
|
+
import { s as signRequest } from "../http-BQL35dN0.mjs";
|
|
10
10
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-CtZLJq76.mjs";
|
|
11
|
-
import { a as compactJsonLd, f as signJsonLd } from "../ld-
|
|
11
|
+
import { a as compactJsonLd, f as signJsonLd } from "../ld-B2MKYZcj.mjs";
|
|
12
12
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
13
|
-
import { a as createFederation, c as handleCollection, d as handleObject, f as respondWithObject, l as handleCustomCollection, p as respondWithObjectIfAcceptable, s as handleActor, u as handleInbox } from "../middleware-
|
|
14
|
-
import { t as InboxListenerSet } from "../inbox-
|
|
13
|
+
import { a as createFederation, c as handleCollection, d as handleObject, f as respondWithObject, l as handleCustomCollection, p as respondWithObjectIfAcceptable, s as handleActor, u as handleInbox } from "../middleware-DVqurycM.mjs";
|
|
14
|
+
import { t as InboxListenerSet } from "../inbox-Bqoa4PJZ.mjs";
|
|
15
15
|
import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
16
16
|
import { Create, Note, Person } from "@fedify/vocab";
|
|
17
17
|
//#region src/federation/handler.test.ts
|
|
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import "../std__assert-Duiq_YC9.mjs";
|
|
6
6
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-CtZLJq76.mjs";
|
|
7
|
-
import { n as signObject } from "../proof-
|
|
7
|
+
import { n as signObject } from "../proof-pGWMVV0R.mjs";
|
|
8
8
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
9
|
-
import { a as createFederation } from "../middleware-
|
|
9
|
+
import { a as createFederation } from "../middleware-DVqurycM.mjs";
|
|
10
10
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
11
11
|
import { Create, Follow, Person } from "@fedify/vocab";
|
|
12
12
|
//#region src/federation/idempotency.test.ts
|
|
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
6
|
-
import { t as InboxListenerSet } from "../inbox-
|
|
6
|
+
import { t as InboxListenerSet } from "../inbox-Bqoa4PJZ.mjs";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
import { Activity, Create, Invite, Offer, Update } from "@fedify/vocab";
|
|
9
9
|
//#region src/federation/inbox.test.ts
|
|
@@ -10,14 +10,14 @@ import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
|
10
10
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
11
11
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
12
12
|
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
13
|
-
import { l as verifyRequest, s as signRequest } from "../http-
|
|
13
|
+
import { l as verifyRequest, s as signRequest } from "../http-BQL35dN0.mjs";
|
|
14
14
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CtZLJq76.mjs";
|
|
15
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
16
|
-
import { a as compactJsonLd, f as signJsonLd, m as verifyJsonLd, s as detachSignature } from "../ld-
|
|
17
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
18
|
-
import { n as signObject, r as verifyObject } from "../proof-
|
|
15
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-Doj2y_GK.mjs";
|
|
16
|
+
import { a as compactJsonLd, f as signJsonLd, m as verifyJsonLd, s as detachSignature } from "../ld-B2MKYZcj.mjs";
|
|
17
|
+
import { t as doesActorOwnKey } from "../owner-BUbV-zsu.mjs";
|
|
18
|
+
import { n as signObject, r as verifyObject } from "../proof-pGWMVV0R.mjs";
|
|
19
19
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
20
|
-
import { a as createFederation, i as KvSpecDeterminer, n as FederationImpl, r as InboxContextImpl, t as ContextImpl } from "../middleware-
|
|
20
|
+
import { a as createFederation, i as KvSpecDeterminer, n as FederationImpl, r as InboxContextImpl, t as ContextImpl } from "../middleware-DVqurycM.mjs";
|
|
21
21
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
22
22
|
import * as vocab from "@fedify/vocab";
|
|
23
23
|
import { Create, Offer, Person, getTypeId, lookupObject } from "@fedify/vocab";
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -2,7 +2,7 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
require("../chunk-DDcVe30Y.cjs");
|
|
5
|
-
const require_middleware = require("../middleware-
|
|
5
|
+
const require_middleware = require("../middleware-DJcsKDyA.cjs");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
//#region src/federation/kv.ts
|
|
8
8
|
/**
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-
|
|
3
|
+
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-DMsZ7PRo.js";
|
|
4
4
|
import { isEqual } from "es-toolkit";
|
|
5
5
|
//#region src/federation/kv.ts
|
|
6
6
|
/**
|
|
@@ -8,10 +8,10 @@ import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z
|
|
|
8
8
|
import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
9
9
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
10
10
|
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
11
|
-
import { l as verifyRequest } from "../http-
|
|
11
|
+
import { l as verifyRequest } from "../http-BQL35dN0.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CtZLJq76.mjs";
|
|
13
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
14
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-
|
|
13
|
+
import { t as doesActorOwnKey } from "../owner-BUbV-zsu.mjs";
|
|
14
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-DrKWpXWF.mjs";
|
|
15
15
|
import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
16
16
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
17
17
|
//#region src/federation/send.test.ts
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import "../std__assert-Duiq_YC9.mjs";
|
|
5
5
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
6
6
|
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
7
|
-
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-
|
|
7
|
+
import { t as hasMalformedKnownTemporalLiteral } from "../temporal-BUr1JyFa.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/temporal.test.ts
|
|
10
10
|
test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
|
|
@@ -5,7 +5,7 @@ import { n as createRequestContext } from "../context-Juj6bdHC.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-Duiq_YC9.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
8
|
-
import { a as createFederation, o as handleWebFinger } from "../middleware-
|
|
8
|
+
import { a as createFederation, o as handleWebFinger } from "../middleware-DVqurycM.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Image, Link, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/federation/webfinger.test.ts
|
|
@@ -224,7 +224,7 @@ test("handleWebFinger()", async (t) => {
|
|
|
224
224
|
});
|
|
225
225
|
onNotFoundCalled = null;
|
|
226
226
|
const actorHandleMapper = (_ctx, username) => {
|
|
227
|
-
return username === "foo" ? "someone" : username === "bar" ? "someone2" : null;
|
|
227
|
+
return username === "foo" ? "someone" : username === "bar" ? "someone2" : username === "qux" ? "someone2" : null;
|
|
228
228
|
};
|
|
229
229
|
await t.step("handle mapper", async () => {
|
|
230
230
|
const u = new URL(url);
|
|
@@ -347,21 +347,83 @@ test("handleWebFinger()", async (t) => {
|
|
|
347
347
|
assertEquals(response.status, 404);
|
|
348
348
|
});
|
|
349
349
|
await t.step("handleHost", async () => {
|
|
350
|
-
|
|
351
|
-
u.searchParams.set("resource", "acct:someone@example.com");
|
|
350
|
+
let u = new URL("https://ap.example.com/.well-known/webfinger");
|
|
351
|
+
u.searchParams.set("resource", "acct:someone@ap.example.com");
|
|
352
352
|
let context = createContext(u);
|
|
353
353
|
let request = context.request;
|
|
354
354
|
let response = await handleWebFinger(request, {
|
|
355
355
|
context,
|
|
356
|
-
host: "
|
|
356
|
+
host: "example.com",
|
|
357
357
|
actorDispatcher,
|
|
358
358
|
onNotFound
|
|
359
359
|
});
|
|
360
360
|
assertEquals(response.status, 200);
|
|
361
361
|
assertEquals(await response.json(), {
|
|
362
|
-
|
|
363
|
-
aliases: [
|
|
362
|
+
subject: "acct:someone@example.com",
|
|
363
|
+
aliases: ["https://ap.example.com/users/someone", "acct:someone@ap.example.com"],
|
|
364
|
+
links: [
|
|
365
|
+
{
|
|
366
|
+
href: "https://ap.example.com/users/someone",
|
|
367
|
+
rel: "self",
|
|
368
|
+
type: "application/activity+json"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
href: "https://ap.example.com/@someone",
|
|
372
|
+
rel: "http://webfinger.net/rel/profile-page"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
href: "https://ap.example.com/@someone",
|
|
376
|
+
rel: "alternate",
|
|
377
|
+
type: "text/html"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
href: "https://ap.example.com/icon.jpg",
|
|
381
|
+
rel: "http://webfinger.net/rel/avatar",
|
|
382
|
+
type: "image/jpeg"
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
});
|
|
386
|
+
u.searchParams.set("resource", "acct:qux@ap.example.com");
|
|
387
|
+
context = createContext(u);
|
|
388
|
+
request = context.request;
|
|
389
|
+
response = await handleWebFinger(request, {
|
|
390
|
+
context,
|
|
391
|
+
host: "example.com",
|
|
392
|
+
actorDispatcher,
|
|
393
|
+
actorHandleMapper,
|
|
394
|
+
onNotFound
|
|
364
395
|
});
|
|
396
|
+
assertEquals(response.status, 200);
|
|
397
|
+
assertEquals(await response.json(), {
|
|
398
|
+
subject: "acct:bar@example.com",
|
|
399
|
+
aliases: [
|
|
400
|
+
"https://ap.example.com/users/someone2",
|
|
401
|
+
"acct:qux@ap.example.com",
|
|
402
|
+
"acct:bar@ap.example.com"
|
|
403
|
+
],
|
|
404
|
+
links: [
|
|
405
|
+
{
|
|
406
|
+
href: "https://ap.example.com/users/someone2",
|
|
407
|
+
rel: "self",
|
|
408
|
+
type: "application/activity+json"
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
href: "https://ap.example.com/@someone2",
|
|
412
|
+
rel: "http://webfinger.net/rel/profile-page"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
href: "https://ap.example.com/@someone2",
|
|
416
|
+
rel: "alternate",
|
|
417
|
+
type: "text/html"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
href: "https://ap.example.com/icon.jpg",
|
|
421
|
+
rel: "http://webfinger.net/rel/avatar",
|
|
422
|
+
type: "image/jpeg"
|
|
423
|
+
}
|
|
424
|
+
]
|
|
425
|
+
});
|
|
426
|
+
u = new URL(url);
|
|
365
427
|
u.searchParams.set("resource", "acct:someone@handle.example.com");
|
|
366
428
|
context = createContext(u);
|
|
367
429
|
request = context.request;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { a as validateCryptoKey, n as fetchKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-661NE5Kk.mjs";
|
|
5
|
+
import { a as validateCryptoKey, n as fetchKey } from "./key-C0qmhoN-.mjs";
|
|
6
6
|
import { CryptographicKey } from "@fedify/vocab";
|
|
7
7
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
8
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
@@ -10,7 +10,7 @@ import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
|
10
10
|
import { Item, decodeDict, encodeItem } from "structured-field-values";
|
|
11
11
|
//#region deno.json
|
|
12
12
|
var name = "@fedify/fedify";
|
|
13
|
-
var version = "2.0.22
|
|
13
|
+
var version = "2.0.22";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/key.ts
|
|
16
16
|
/**
|
|
@@ -11,7 +11,7 @@ let byte_encodings_base64 = require("byte-encodings/base64");
|
|
|
11
11
|
let structured_field_values = require("structured-field-values");
|
|
12
12
|
//#region deno.json
|
|
13
13
|
var name = "@fedify/fedify";
|
|
14
|
-
var version = "2.0.22
|
|
14
|
+
var version = "2.0.22";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/key.ts
|
|
17
17
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-661NE5Kk.mjs";
|
|
5
5
|
import { Activity, getTypeId } from "@fedify/vocab";
|
|
6
6
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-661NE5Kk.mjs";
|
|
5
5
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
6
6
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
7
7
|
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { c as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { c as validateCryptoKey, t as doubleKnock } from "./http-CC2-WkSX.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
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-DWhQe-I5.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { a as validateCryptoKey, n as fetchKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-661NE5Kk.mjs";
|
|
5
|
+
import { a as validateCryptoKey, n as fetchKey } from "./key-C0qmhoN-.mjs";
|
|
6
6
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
7
7
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
8
|
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
|
-
const require_middleware = require("./middleware-
|
|
3
|
+
const require_middleware = require("./middleware-DJcsKDyA.cjs");
|
|
4
4
|
exports.FederationImpl = require_middleware.FederationImpl;
|
|
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
const require_chunk = require("./chunk-DDcVe30Y.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
-
const require_http = require("./http-
|
|
6
|
-
const require_proof = require("./proof-
|
|
7
|
-
const require_types = require("./types-
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
5
|
+
const require_http = require("./http-DWhQe-I5.cjs");
|
|
6
|
+
const require_proof = require("./proof-B8z-9_xo.cjs");
|
|
7
|
+
const require_types = require("./types-m8u9L86X.cjs");
|
|
8
|
+
const require_kv_cache = require("./kv-cache-DY8Q_hte.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
11
11
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -335,7 +335,7 @@ var FederationBuilderImpl = class {
|
|
|
335
335
|
this.collectionTypeIds = {};
|
|
336
336
|
}
|
|
337
337
|
async build(options) {
|
|
338
|
-
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-
|
|
338
|
+
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-BxR2EmWw.cjs"));
|
|
339
339
|
const f = new FederationImpl(options);
|
|
340
340
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
341
341
|
f.router = this.router.clone();
|
|
@@ -2355,6 +2355,24 @@ const logger = (0, _logtape_logtape.getLogger)([
|
|
|
2355
2355
|
"webfinger",
|
|
2356
2356
|
"server"
|
|
2357
2357
|
]);
|
|
2358
|
+
function getWebFingerSubjectAndAliases({ resourceUrl, actorUri, preferredUsername, acctUsername, host, contextHost }) {
|
|
2359
|
+
const aliases = [];
|
|
2360
|
+
let subject = resourceUrl.href;
|
|
2361
|
+
if (resourceUrl.protocol != "acct:" && preferredUsername != null) {
|
|
2362
|
+
aliases.push(`acct:${preferredUsername}@${host ?? contextHost}`);
|
|
2363
|
+
if (host != null && host !== contextHost) aliases.push(`acct:${preferredUsername}@${contextHost}`);
|
|
2364
|
+
}
|
|
2365
|
+
if (resourceUrl.href !== actorUri.href) aliases.push(actorUri.href);
|
|
2366
|
+
if (resourceUrl.protocol === "acct:" && host != null && host !== contextHost && !resourceUrl.href.endsWith(`@${host}`)) {
|
|
2367
|
+
subject = `acct:${preferredUsername ?? acctUsername}@${host}`;
|
|
2368
|
+
aliases.push(resourceUrl.href);
|
|
2369
|
+
if (preferredUsername != null && preferredUsername !== "" && preferredUsername !== acctUsername) aliases.push(`acct:${preferredUsername}@${contextHost}`);
|
|
2370
|
+
}
|
|
2371
|
+
return {
|
|
2372
|
+
subject,
|
|
2373
|
+
aliases
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2358
2376
|
/**
|
|
2359
2377
|
* Handles a WebFinger request. You would not typically call this function
|
|
2360
2378
|
* directly, but instead use {@link Federation.fetch} method.
|
|
@@ -2409,6 +2427,7 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
2409
2427
|
return identifier;
|
|
2410
2428
|
}
|
|
2411
2429
|
let identifier = null;
|
|
2430
|
+
let acctUsername = null;
|
|
2412
2431
|
const uriParsed = context.parseUri(resourceUrl);
|
|
2413
2432
|
if (uriParsed?.type != "actor") {
|
|
2414
2433
|
const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
|
|
@@ -2422,8 +2441,9 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
2422
2441
|
const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
|
|
2423
2442
|
if (normalizedHost != context.url.host && normalizedHost != host) return await onNotFound(request);
|
|
2424
2443
|
else {
|
|
2425
|
-
|
|
2426
|
-
|
|
2444
|
+
acctUsername = match[1];
|
|
2445
|
+
identifier = await mapUsernameToIdentifier(acctUsername);
|
|
2446
|
+
resourceUrl = new URL(`acct:${acctUsername}@${normalizedHost}`);
|
|
2427
2447
|
}
|
|
2428
2448
|
}
|
|
2429
2449
|
} else identifier = uriParsed.identifier;
|
|
@@ -2433,9 +2453,10 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
2433
2453
|
logger.error("Actor {identifier} not found.", { identifier });
|
|
2434
2454
|
return await onNotFound(request);
|
|
2435
2455
|
}
|
|
2456
|
+
const actorUri = context.getActorUri(identifier);
|
|
2436
2457
|
const links = [{
|
|
2437
2458
|
rel: "self",
|
|
2438
|
-
href:
|
|
2459
|
+
href: actorUri.href,
|
|
2439
2460
|
type: "application/activity+json"
|
|
2440
2461
|
}];
|
|
2441
2462
|
for (const url of actor.urls) if (url instanceof _fedify_vocab.Link && url.href != null) links.push({
|
|
@@ -2459,22 +2480,19 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
2459
2480
|
const customLinks = await webFingerLinksDispatcher(context, resourceUrl);
|
|
2460
2481
|
if (customLinks != null) for (const link of customLinks) links.push(link);
|
|
2461
2482
|
}
|
|
2462
|
-
const aliases =
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
const jrd = {
|
|
2473
|
-
subject: resourceUrl.href,
|
|
2483
|
+
const { subject, aliases } = getWebFingerSubjectAndAliases({
|
|
2484
|
+
resourceUrl,
|
|
2485
|
+
actorUri,
|
|
2486
|
+
preferredUsername: actor.preferredUsername,
|
|
2487
|
+
acctUsername,
|
|
2488
|
+
host,
|
|
2489
|
+
contextHost: context.url.host
|
|
2490
|
+
});
|
|
2491
|
+
return new Response(JSON.stringify({
|
|
2492
|
+
subject,
|
|
2474
2493
|
aliases,
|
|
2475
2494
|
links
|
|
2476
|
-
}
|
|
2477
|
-
return new Response(JSON.stringify(jrd), { headers: {
|
|
2495
|
+
}), { headers: {
|
|
2478
2496
|
"Content-Type": "application/jrd+json",
|
|
2479
2497
|
"Access-Control-Allow-Origin": "*"
|
|
2480
2498
|
} });
|