@fedify/fedify 2.4.5-dev.2453 → 2.4.5
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 +3 -0
- package/dist/{builder-CS2LjGi-.mjs → builder-CUAVOHg6.mjs} +2 -2
- package/dist/{client-D-XP_Ccb.d.cts → client-3InDZbba.d.cts} +0 -1
- package/dist/{client-D-XP_Ccb.d.ts → client-3InDZbba.d.ts} +0 -1
- package/dist/{client-CEnNz8O7.mjs → client-5SIFzW3q.mjs} +113 -64
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-C6_4hMjm.mjs → compound-proof-BNjXclzO.mjs} +2 -2
- package/dist/{context-7NyiqIcg.d.ts → context-CVOOd9pD.d.ts} +28 -2
- package/dist/{context-tsYPJ2Ew.d.cts → context-D0gFIgev.d.cts} +28 -2
- package/dist/{deno-CTWhU1oT.mjs → deno-DcJISdwu.mjs} +1 -1
- package/dist/docloader-CP1UxMLL.mjs +136 -0
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +6 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +4 -4
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-report.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +465 -32
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +9 -6
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +2 -2
- package/dist/federation/portable-gateway-keys.test.mjs +11 -5
- package/dist/federation/portable-inbox.test.mjs +4 -4
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +498 -88
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-DWVfQYX_.cjs → federation-Bkfq2YpS.cjs} +240 -102
- package/dist/{http-Dx5s5-pP.cjs → http-DHVH0DqC.cjs} +179 -110
- package/dist/{http-rgt1uxns.mjs → http-DuGmr8J8.mjs} +204 -106
- package/dist/{http-y9FnJFIe.js → http-R0ty0Udi.js} +178 -109
- package/dist/{inbox-4AZHfaO8.mjs → inbox-Bl1Y0s_A.mjs} +2 -2
- package/dist/{key-DYxuyd-s.d.cts → key-CyCcut3h.d.ts} +1 -2
- package/dist/{key-C1nv7_jD.d.ts → key-VEL1QqHF.d.cts} +1 -2
- package/dist/{kv-cache-DmxFPJaR.cjs → kv-cache-BtBSBZi9.cjs} +72 -27
- package/dist/{kv-cache-C3QkJF-x.mjs → kv-cache-DAV2_U44.mjs} +1 -1
- package/dist/{kv-cache-w4yWxqS1.js → kv-cache-FnLtmATH.js} +73 -28
- package/dist/{ld-CT-bAqSC.mjs → ld-Cy5GqbvS.mjs} +2 -2
- package/dist/{metrics-DsFjgE5X.mjs → metrics-CW8LoN7n.mjs} +1 -1
- package/dist/{middleware-DC8Omn-e.mjs → middleware-CdP-lz8Q.mjs} +1 -1
- package/dist/{middleware-Ch9WIaoZ.mjs → middleware-D2fk45uN.mjs} +82 -42
- package/dist/{middleware-BCHbutlW.js → middleware-D4rQARvq.js} +241 -103
- package/dist/{mod-DEZXwV6J.d.ts → mod-B1Qt5cQQ.d.ts} +2 -9
- package/dist/{mod-Xj5P4s4d.d.ts → mod-B5COx5Wd.d.ts} +1 -1
- package/dist/{mod-CavhAgLw.d.cts → mod-BTxJG7ZH.d.cts} +1 -1
- package/dist/{mod-CtpF2BU5.d.ts → mod-CpyjFA9s.d.ts} +1 -1
- package/dist/{mod-BojP2Bw3.d.cts → mod-makPMVMg.d.cts} +1 -1
- package/dist/{mod-Dw-nPxQh.d.cts → mod-ss0wBUH1.d.cts} +2 -9
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +337 -19
- package/dist/nodeinfo/handler.test.mjs +1 -1
- 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/otel/exporter.test.mjs +292 -30
- package/dist/otel/mod.cjs +36 -30
- package/dist/otel/mod.d.cts +13 -0
- package/dist/otel/mod.d.ts +13 -0
- package/dist/otel/mod.js +36 -30
- package/dist/{owner-BGYYk-xi.mjs → owner-CbQZqFim.mjs} +3 -3
- package/dist/{portable-collection-DzEc4cB2.js → portable-collection-B5Aryi8I.js} +1 -1
- package/dist/{portable-collection-Cwn7DM0G.cjs → portable-collection-C_Kmvl3q.cjs} +1 -1
- package/dist/{portable-collection-DJSwe8QM.mjs → portable-collection-D2JYDadi.mjs} +2 -2
- package/dist/{portable-key-Dc6N1SEB.mjs → portable-key-Cc-ctNU2.mjs} +1 -1
- package/dist/{proof-DP93iZiH.mjs → proof-UN4CW55z.mjs} +3 -3
- package/dist/{send-c6buRbhI.mjs → send-BzbX2e6v.mjs} +174 -76
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +553 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +1 -1
- package/dist/sig/mitra-receive-interop.test.mjs +4 -4
- package/dist/sig/mitra-send-interop.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.mjs +3 -3
- package/dist/sig/portable-key.test.mjs +5 -5
- package/dist/sig/proof.test.mjs +4 -4
- package/dist/sig/tootik-request-interop.test.mjs +4 -4
- package/dist/sig/tootik-send-interop.test.mjs +3 -3
- package/dist/sig/verification.test.mjs +3 -3
- package/dist/{temporal-DfC1NkLg.mjs → temporal-B7Wvxrjs.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +26 -0
- package/dist/{types-_S2_MeLF.js → types-DUjZb4i6.js} +112 -63
- package/dist/{types-poIao40f.cjs → types-hKCCjii0.cjs} +111 -62
- package/dist/utils/docloader.test.mjs +344 -36
- 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/dist/docloader-CXFE-n2O.mjs +0 -91
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ It aims to eliminate the complexity and boilerplate code when
|
|
|
15
15
|
building a federated server app, so that you can focus on your business logic
|
|
16
16
|
and user experience.
|
|
17
17
|
|
|
18
|
+
Fedify supports Node.js, Bun, and Deno. We recommend using the latest
|
|
19
|
+
version of Node.js for the best experience.
|
|
20
|
+
|
|
18
21
|
Currently, Fedify provides the following features out of the box:
|
|
19
22
|
|
|
20
23
|
- Type-safe objects for [Activity Vocabulary] (including some vendor-specific
|
|
@@ -2,7 +2,7 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { i as getPortableDid, l as isPortableId, n as getCanonicalPortableId } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
+
import { n as version, t as name } from "./deno-DcJISdwu.mjs";
|
|
6
6
|
import { t as ActivityListenerSet } from "./activity-listener-C-BSbKI7.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
@@ -91,7 +91,7 @@ var FederationBuilderImpl = class {
|
|
|
91
91
|
* specified.
|
|
92
92
|
*/
|
|
93
93
|
async build(options) {
|
|
94
|
-
const { FederationImpl } = await import("./middleware-
|
|
94
|
+
const { FederationImpl } = await import("./middleware-CdP-lz8Q.mjs");
|
|
95
95
|
const f = new FederationImpl(options);
|
|
96
96
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
97
97
|
f.router = this.router.clone();
|
|
@@ -2,7 +2,8 @@ import "temporal-polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
|
-
import { FetchError, UrlError, getUserAgent
|
|
5
|
+
import { FetchError, UrlError, getUserAgent } from "@fedify/vocab-runtime";
|
|
6
|
+
import { openPublicFetch } from "@fedify/vocab-runtime/internal";
|
|
6
7
|
//#region src/utils/body.ts
|
|
7
8
|
/** Decoded JSON body limit: 16 MiB. @internal */
|
|
8
9
|
const MAX_BODY_SIZE = 16 * 1024 * 1024;
|
|
@@ -85,23 +86,34 @@ const logger = getLogger([
|
|
|
85
86
|
]);
|
|
86
87
|
const DEFAULT_MAX_REDIRECTION = 5;
|
|
87
88
|
/**
|
|
88
|
-
* Fetches a URL while guarding against SSRF.
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* bounce the request to an internal
|
|
89
|
+
* Fetches a URL while guarding against SSRF. Every request—including each
|
|
90
|
+
* redirect hop—is made in its own session opened with `openPublicFetch()`,
|
|
91
|
+
* which rejects loopback, link-local, and private addresses, as well as
|
|
92
|
+
* non-HTTP(S) schemes such as `data:`, and connects only to the validated
|
|
93
|
+
* addresses where the runtime supports it. Redirects are followed manually
|
|
94
|
+
* with a cap, so that a public URL cannot bounce the request to an internal
|
|
95
|
+
* address.
|
|
96
|
+
*
|
|
97
|
+
* The final response is passed to `consume`, which must consume or cancel its
|
|
98
|
+
* body; the session is closed after `consume` settles. The cancellation of
|
|
99
|
+
* redirect response bodies is started before their sessions are closed.
|
|
94
100
|
* @param url The URL to fetch.
|
|
95
101
|
* @param headers The request headers.
|
|
96
|
-
* @
|
|
97
|
-
*
|
|
102
|
+
* @param consume The function to consume the final response with.
|
|
103
|
+
* @param deps The dependencies.
|
|
104
|
+
* @returns The value returned by `consume`, or `null` if the URL is
|
|
105
|
+
* disallowed, its hostname cannot be resolved, or there are too many
|
|
106
|
+
* redirects.
|
|
107
|
+
* @internal
|
|
98
108
|
*/
|
|
99
|
-
async function fetchPublicUrl(url, headers) {
|
|
109
|
+
async function fetchPublicUrl(url, headers, consume, deps = {}) {
|
|
110
|
+
const openHop = deps.openHop ?? ((hopUrl) => openPublicFetch(hopUrl));
|
|
100
111
|
let current = url instanceof URL ? url : new URL(url);
|
|
101
112
|
let redirected = 0;
|
|
102
113
|
while (true) {
|
|
114
|
+
let session;
|
|
103
115
|
try {
|
|
104
|
-
await
|
|
116
|
+
session = await openHop(current.href);
|
|
105
117
|
} catch (e) {
|
|
106
118
|
if (e instanceof UrlError) {
|
|
107
119
|
if (e.reason === "dns") logger.error("DNS lookup failed for {url}: {error}", {
|
|
@@ -116,52 +128,89 @@ async function fetchPublicUrl(url, headers) {
|
|
|
116
128
|
}
|
|
117
129
|
throw e;
|
|
118
130
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
let location;
|
|
132
|
+
try {
|
|
133
|
+
const response = await session.fetch(current, {
|
|
134
|
+
headers,
|
|
135
|
+
redirect: "manual"
|
|
136
|
+
});
|
|
137
|
+
if (response.status < 300 || response.status >= 400 || !response.headers.has("Location")) return await consume(response);
|
|
138
|
+
location = response.headers.get("Location");
|
|
139
|
+
cancelBody(response, current);
|
|
140
|
+
} finally {
|
|
141
|
+
await session.close();
|
|
142
|
+
}
|
|
143
|
+
redirected++;
|
|
144
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) {
|
|
145
|
+
logger.error("Too many redirections ({redirections}) while fetching {url}.", {
|
|
146
|
+
redirections: redirected,
|
|
147
|
+
url: current.href
|
|
148
|
+
});
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const next = new URL(location, current);
|
|
152
|
+
if (next.protocol !== current.protocol) {
|
|
153
|
+
logger.error("Refused a redirect to a different protocol ({protocol} to {redirectedProtocol}) while fetching NodeInfo.", {
|
|
154
|
+
protocol: current.protocol,
|
|
155
|
+
redirectedProtocol: next.protocol
|
|
156
|
+
});
|
|
157
|
+
return null;
|
|
142
158
|
}
|
|
143
|
-
|
|
159
|
+
current = next;
|
|
144
160
|
}
|
|
145
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Starts cancelling a response body that is not read, without waiting for it
|
|
164
|
+
* to settle. The cancellation of a branch of a tee (e.g., a body cloned by
|
|
165
|
+
* a fetch mock) settles only after the other branch is cancelled too, per
|
|
166
|
+
* the Streams standard, so awaiting it could block forever. A failure is
|
|
167
|
+
* only logged.
|
|
168
|
+
*/
|
|
169
|
+
function cancelBody(response, url) {
|
|
170
|
+
response.body?.cancel().catch((error) => {
|
|
171
|
+
logger.debug("Failed to cancel the response body from {url}: {error}", {
|
|
172
|
+
url: url.toString(),
|
|
173
|
+
error
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
146
177
|
async function getNodeInfo(url, options = {}) {
|
|
178
|
+
return await getNodeInfoInternal(url, options);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The implementation of {@link getNodeInfo}, which is not exported from any
|
|
182
|
+
* entry point.
|
|
183
|
+
* @param url The base URL of the server, or the URL of the NodeInfo document
|
|
184
|
+
* if `options.direct` is turned on.
|
|
185
|
+
* @param options Options for fetching the NodeInfo document.
|
|
186
|
+
* @param deps The dependencies.
|
|
187
|
+
* @returns The NodeInfo document if it could be fetched successfully.
|
|
188
|
+
* Otherwise, `undefined` is returned.
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
async function getNodeInfoInternal(url, options = {}, deps = {}) {
|
|
147
192
|
try {
|
|
193
|
+
const headers = {
|
|
194
|
+
Accept: "application/json",
|
|
195
|
+
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
196
|
+
};
|
|
148
197
|
let nodeInfoUrl = url;
|
|
149
198
|
if (!options.direct) {
|
|
150
199
|
const wellKnownUrl = new URL("/.well-known/nodeinfo", url);
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
const wellKnownRd =
|
|
200
|
+
const wellKnown = await fetchPublicUrl(wellKnownUrl, headers, async (response) => {
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
logger.error("Failed to fetch {url}: {status} {statusText}", {
|
|
203
|
+
url: wellKnownUrl.href,
|
|
204
|
+
status: response.status,
|
|
205
|
+
statusText: response.statusText
|
|
206
|
+
});
|
|
207
|
+
cancelBody(response, wellKnownUrl);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
return { rd: JSON.parse(await readBoundedText(response, MAX_BODY_SIZE, wellKnownUrl)) };
|
|
211
|
+
}, deps);
|
|
212
|
+
if (wellKnown == null) return void 0;
|
|
213
|
+
const wellKnownRd = wellKnown.rd;
|
|
165
214
|
const link = wellKnownRd?.links?.find((link) => link != null && "rel" in link && (link.rel === "http://nodeinfo.diaspora.software/ns/schema/2.0" || link.rel === "http://nodeinfo.diaspora.software/ns/schema/2.1") && "href" in link && link.href != null);
|
|
166
215
|
if (link == null || link.href == null) {
|
|
167
216
|
logger.error("Failed to find a NodeInfo document link from {url}: {resourceDescriptor}", {
|
|
@@ -172,20 +221,20 @@ async function getNodeInfo(url, options = {}) {
|
|
|
172
221
|
}
|
|
173
222
|
nodeInfoUrl = link.href;
|
|
174
223
|
}
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const data =
|
|
224
|
+
const document = await fetchPublicUrl(nodeInfoUrl, headers, async (response) => {
|
|
225
|
+
if (!response.ok) {
|
|
226
|
+
logger.error("Failed to fetch NodeInfo document from {url}: {status} {statusText}", {
|
|
227
|
+
url: nodeInfoUrl.toString(),
|
|
228
|
+
status: response.status,
|
|
229
|
+
statusText: response.statusText
|
|
230
|
+
});
|
|
231
|
+
cancelBody(response, nodeInfoUrl);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
return { data: JSON.parse(await readBoundedText(response, MAX_BODY_SIZE, nodeInfoUrl)) };
|
|
235
|
+
}, deps);
|
|
236
|
+
if (document == null) return void 0;
|
|
237
|
+
const { data } = document;
|
|
189
238
|
if (options.parse === "none") return data;
|
|
190
239
|
return parseNodeInfo(data, { tryBestEffort: options.parse === "best-effort" }) ?? void 0;
|
|
191
240
|
} catch (error) {
|
|
@@ -389,4 +438,4 @@ function parseUsage(data, options = {}) {
|
|
|
389
438
|
};
|
|
390
439
|
}
|
|
391
440
|
//#endregion
|
|
392
|
-
export {
|
|
441
|
+
export { parseOutboundService as a, parseSoftware as c, MAX_BODY_SIZE as d, readBoundedText as f, parseNodeInfo as i, parseUsage as l, getNodeInfoInternal as n, parseProtocol as o, parseInboundService as r, parseServices as s, getNodeInfo as t, BodyTooLargeError as u };
|
package/dist/compat/mod.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { en as ActivityTransformer, n as Context } from "../context-
|
|
2
|
+
import { en as ActivityTransformer, n as Context } from "../context-D0gFIgev.cjs";
|
|
3
3
|
import { Activity } from "@fedify/vocab";
|
|
4
4
|
|
|
5
5
|
//#region src/compat/transformers.d.ts
|
package/dist/compat/mod.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { en as ActivityTransformer, n as Context } from "../context-
|
|
2
|
+
import { en as ActivityTransformer, n as Context } from "../context-CVOOd9pD.js";
|
|
3
3
|
import { Activity } from "@fedify/vocab";
|
|
4
4
|
|
|
5
5
|
//#region src/compat/transformers.d.ts
|
|
@@ -5,7 +5,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
7
7
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
8
|
-
import { O as actorDehydrator, k as autoIdAssigner, n as FederationImpl } from "../middleware-
|
|
8
|
+
import { O as actorDehydrator, k as autoIdAssigner, n as FederationImpl } from "../middleware-D2fk45uN.mjs";
|
|
9
9
|
import { Follow, Person } from "@fedify/vocab";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/compat/transformers.test.ts
|
|
@@ -3,9 +3,9 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { a as getRawCanonicalPortableId, l as isPortableId, n as getCanonicalPortableId } from "./portable-key-id-Ca30-hOa.mjs";
|
|
5
5
|
import { a as verificationObservation, t as observeAttempt } from "./verification-Dpfcw8ml.mjs";
|
|
6
|
-
import { c as getNormalizationContextLoader } from "./ld-
|
|
6
|
+
import { c as getNormalizationContextLoader } from "./ld-Cy5GqbvS.mjs";
|
|
7
7
|
import { n as preloadedOnlyDocumentLoader } from "./public-audience--klBIOk1.mjs";
|
|
8
|
-
import { l as verifyPortableObjectProofPolicy, n as classifyFep2277CoreType, o as verifyMapLocalProof } from "./proof-
|
|
8
|
+
import { l as verifyPortableObjectProofPolicy, n as classifyFep2277CoreType, o as verifyMapLocalProof } from "./proof-UN4CW55z.mjs";
|
|
9
9
|
import { parseIri, preloadedContexts } from "@fedify/vocab-runtime";
|
|
10
10
|
import jsonld from "@fedify/vocab-runtime/jsonld";
|
|
11
11
|
//#region src/sig/compound-proof.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { o as JsonValue, s as NodeInfo, t as GetNodeInfoOptions } from "./client-
|
|
3
|
-
import { _ as InboxVerificationKey, d as InboxProofPolicyFailureReason, h as InboxVerificationAttempt, w as VerifyRequestFailureReason, y as HttpMessageSignaturesSpec } from "./key-
|
|
2
|
+
import { o as JsonValue, s as NodeInfo, t as GetNodeInfoOptions } from "./client-3InDZbba.js";
|
|
3
|
+
import { _ as InboxVerificationKey, d as InboxProofPolicyFailureReason, h as InboxVerificationAttempt, w as VerifyRequestFailureReason, y as HttpMessageSignaturesSpec } from "./key-CyCcut3h.js";
|
|
4
4
|
import { n as GetKeyOwnerOptions } from "./owner-BSzr5-I8.js";
|
|
5
5
|
import { n as KvStore, t as KvKey } from "./kv-B2mzK5tl.js";
|
|
6
6
|
import { Router } from "@fedify/uri-template";
|
|
@@ -4285,6 +4285,11 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4285
4285
|
* Gets the public key of the sender, if any exists and it is verified.
|
|
4286
4286
|
* Otherwise, `null` is returned.
|
|
4287
4287
|
*
|
|
4288
|
+
* Successful results are reused for this request regardless of the options.
|
|
4289
|
+
* Pending checks and `null` results are reused for the same effective
|
|
4290
|
+
* document and context loaders, including failed lookups. Rejected checks
|
|
4291
|
+
* can be retried. Shared work uses the first caller's tracer provider.
|
|
4292
|
+
*
|
|
4288
4293
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4289
4294
|
* secure mode) in ActivityPub.
|
|
4290
4295
|
*
|
|
@@ -4298,6 +4303,11 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4298
4303
|
* Gets the public key of the sender, if any exists and it is verified.
|
|
4299
4304
|
* Otherwise, `null` is returned.
|
|
4300
4305
|
*
|
|
4306
|
+
* Successful results are reused for this request regardless of the options.
|
|
4307
|
+
* Pending checks and `null` results are reused for the same effective
|
|
4308
|
+
* document and context loaders, including failed lookups. Rejected checks
|
|
4309
|
+
* can be retried. Shared work uses the first caller's tracer provider.
|
|
4310
|
+
*
|
|
4301
4311
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4302
4312
|
* secure mode) in ActivityPub.
|
|
4303
4313
|
*
|
|
@@ -4317,6 +4327,14 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4317
4327
|
* Gets the owner of the signed key, if any exists and it is verified.
|
|
4318
4328
|
* Otherwise, `null` is returned.
|
|
4319
4329
|
*
|
|
4330
|
+
* Verified keys and owners are reused for this request regardless of the
|
|
4331
|
+
* options. Pending checks are shared for the same effective document and
|
|
4332
|
+
* context loaders. A `null` result from an owner lookup after key
|
|
4333
|
+
* verification is retained for those loaders. A `null` result caused by
|
|
4334
|
+
* an unverified key is not retained, allowing an owner lookup after another
|
|
4335
|
+
* loader verifies the key. Rejected checks can be retried. Shared work
|
|
4336
|
+
* uses the first caller's tracer provider.
|
|
4337
|
+
*
|
|
4320
4338
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4321
4339
|
* secure mode) in ActivityPub.
|
|
4322
4340
|
*
|
|
@@ -4331,6 +4349,14 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4331
4349
|
* Gets the owner of the signed key, if any exists and it is verified.
|
|
4332
4350
|
* Otherwise, `null` is returned.
|
|
4333
4351
|
*
|
|
4352
|
+
* Verified keys and owners are reused for this request regardless of the
|
|
4353
|
+
* options. Pending checks are shared for the same effective document and
|
|
4354
|
+
* context loaders. A `null` result from an owner lookup after key
|
|
4355
|
+
* verification is retained for those loaders. A `null` result caused by
|
|
4356
|
+
* an unverified key is not retained, allowing an owner lookup after another
|
|
4357
|
+
* loader verifies the key. Rejected checks can be retried. Shared work
|
|
4358
|
+
* uses the first caller's tracer provider.
|
|
4359
|
+
*
|
|
4334
4360
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4335
4361
|
* secure mode) in ActivityPub.
|
|
4336
4362
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { o as JsonValue, s as NodeInfo, t as GetNodeInfoOptions } from "./client-
|
|
3
|
-
import { _ as InboxVerificationKey, d as InboxProofPolicyFailureReason, h as InboxVerificationAttempt, w as VerifyRequestFailureReason, y as HttpMessageSignaturesSpec } from "./key-
|
|
2
|
+
import { o as JsonValue, s as NodeInfo, t as GetNodeInfoOptions } from "./client-3InDZbba.cjs";
|
|
3
|
+
import { _ as InboxVerificationKey, d as InboxProofPolicyFailureReason, h as InboxVerificationAttempt, w as VerifyRequestFailureReason, y as HttpMessageSignaturesSpec } from "./key-VEL1QqHF.cjs";
|
|
4
4
|
import { n as GetKeyOwnerOptions } from "./owner-BF0L9cMt.cjs";
|
|
5
5
|
import { n as KvStore, t as KvKey } from "./kv-B2mzK5tl.cjs";
|
|
6
6
|
import { Activity, Actor, Collection, CryptographicKey, Hashtag, Link, LookupObjectOptions, Multikey, Object as Object$1, Recipient, Tombstone, TraverseCollectionOptions } from "@fedify/vocab";
|
|
@@ -4283,6 +4283,11 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4283
4283
|
* Gets the public key of the sender, if any exists and it is verified.
|
|
4284
4284
|
* Otherwise, `null` is returned.
|
|
4285
4285
|
*
|
|
4286
|
+
* Successful results are reused for this request regardless of the options.
|
|
4287
|
+
* Pending checks and `null` results are reused for the same effective
|
|
4288
|
+
* document and context loaders, including failed lookups. Rejected checks
|
|
4289
|
+
* can be retried. Shared work uses the first caller's tracer provider.
|
|
4290
|
+
*
|
|
4286
4291
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4287
4292
|
* secure mode) in ActivityPub.
|
|
4288
4293
|
*
|
|
@@ -4296,6 +4301,11 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4296
4301
|
* Gets the public key of the sender, if any exists and it is verified.
|
|
4297
4302
|
* Otherwise, `null` is returned.
|
|
4298
4303
|
*
|
|
4304
|
+
* Successful results are reused for this request regardless of the options.
|
|
4305
|
+
* Pending checks and `null` results are reused for the same effective
|
|
4306
|
+
* document and context loaders, including failed lookups. Rejected checks
|
|
4307
|
+
* can be retried. Shared work uses the first caller's tracer provider.
|
|
4308
|
+
*
|
|
4299
4309
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4300
4310
|
* secure mode) in ActivityPub.
|
|
4301
4311
|
*
|
|
@@ -4315,6 +4325,14 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4315
4325
|
* Gets the owner of the signed key, if any exists and it is verified.
|
|
4316
4326
|
* Otherwise, `null` is returned.
|
|
4317
4327
|
*
|
|
4328
|
+
* Verified keys and owners are reused for this request regardless of the
|
|
4329
|
+
* options. Pending checks are shared for the same effective document and
|
|
4330
|
+
* context loaders. A `null` result from an owner lookup after key
|
|
4331
|
+
* verification is retained for those loaders. A `null` result caused by
|
|
4332
|
+
* an unverified key is not retained, allowing an owner lookup after another
|
|
4333
|
+
* loader verifies the key. Rejected checks can be retried. Shared work
|
|
4334
|
+
* uses the first caller's tracer provider.
|
|
4335
|
+
*
|
|
4318
4336
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4319
4337
|
* secure mode) in ActivityPub.
|
|
4320
4338
|
*
|
|
@@ -4329,6 +4347,14 @@ interface RequestContext<TContextData> extends Context<TContextData> {
|
|
|
4329
4347
|
* Gets the owner of the signed key, if any exists and it is verified.
|
|
4330
4348
|
* Otherwise, `null` is returned.
|
|
4331
4349
|
*
|
|
4350
|
+
* Verified keys and owners are reused for this request regardless of the
|
|
4351
|
+
* options. Pending checks are shared for the same effective document and
|
|
4352
|
+
* context loaders. A `null` result from an owner lookup after key
|
|
4353
|
+
* verification is retained for those loaders. A `null` result caused by
|
|
4354
|
+
* an unverified key is not retained, allowing an owner lookup after another
|
|
4355
|
+
* loader verifies the key. Rejected checks can be retried. Shared work
|
|
4356
|
+
* uses the first caller's tracer provider.
|
|
4357
|
+
*
|
|
4332
4358
|
* This can be used for implementing [authorized fetch] (also known as
|
|
4333
4359
|
* secure mode) in ActivityPub.
|
|
4334
4360
|
*
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { T as validateCryptoKey } from "./ld-Cy5GqbvS.mjs";
|
|
5
|
+
import { r as doubleKnockScoped } from "./http-DuGmr8J8.mjs";
|
|
6
|
+
import { getLogger } from "@logtape/logtape";
|
|
7
|
+
import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, resolveDocumentLoaderTimeout, withDocumentLoaderTimeout } from "@fedify/vocab-runtime";
|
|
8
|
+
import { curry } from "es-toolkit";
|
|
9
|
+
import { openDirectFetch, openPublicFetch } from "@fedify/vocab-runtime/internal";
|
|
10
|
+
//#region src/utils/docloader.ts
|
|
11
|
+
const logger = getLogger([
|
|
12
|
+
"fedify",
|
|
13
|
+
"utils",
|
|
14
|
+
"docloader"
|
|
15
|
+
]);
|
|
16
|
+
const DEFAULT_MAX_REDIRECTION = 20;
|
|
17
|
+
/**
|
|
18
|
+
* Gets an authenticated {@link DocumentLoader} for the given identity.
|
|
19
|
+
* Note that an authenticated document loader intentionally does not cache
|
|
20
|
+
* the fetched documents.
|
|
21
|
+
* At most 20 HTTP redirects and alternate document links are followed in total
|
|
22
|
+
* per call. Revisiting a URL within that chain throws a {@link FetchError}.
|
|
23
|
+
* Each call, including its double-knocking retries, times out after
|
|
24
|
+
* 10 seconds by default; see {@link DocumentLoaderFactoryOptions.timeout}.
|
|
25
|
+
* @param identity The identity to get the document loader for.
|
|
26
|
+
* The actor's key pair.
|
|
27
|
+
* @param options The options for the document loader.
|
|
28
|
+
* @returns The authenticated document loader.
|
|
29
|
+
* @throws {TypeError} If the key is invalid or unsupported.
|
|
30
|
+
* @throws {RangeError} If the `timeout` option is invalid.
|
|
31
|
+
* @since 0.4.0
|
|
32
|
+
*/
|
|
33
|
+
function getAuthenticatedDocumentLoader(identity, options = {}) {
|
|
34
|
+
return createAuthenticatedDocumentLoader(identity, options);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The placeholder that the alternate document callback of
|
|
38
|
+
* `getRemoteDocument()` returns, so that the alternate document is loaded
|
|
39
|
+
* after the current hop is closed.
|
|
40
|
+
*/
|
|
41
|
+
const ALTERNATE_PLACEHOLDER = Object.freeze({
|
|
42
|
+
contextUrl: null,
|
|
43
|
+
document: null,
|
|
44
|
+
documentUrl: "about:blank"
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* The implementation of {@link getAuthenticatedDocumentLoader}. This is not
|
|
48
|
+
* exported from any entry point.
|
|
49
|
+
* @param identity The identity to get the document loader for.
|
|
50
|
+
* @param options The options for the document loader.
|
|
51
|
+
* @param deps The dependencies, for tests.
|
|
52
|
+
* @returns The authenticated document loader.
|
|
53
|
+
* @throws {TypeError} If the key is invalid or unsupported.
|
|
54
|
+
*/
|
|
55
|
+
function createAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedirection, userAgent, specDeterminer, timeout, tracerProvider } = {}, deps = {}) {
|
|
56
|
+
validateCryptoKey(identity.privateKey);
|
|
57
|
+
const resolvedTimeout = resolveDocumentLoaderTimeout(timeout);
|
|
58
|
+
async function load(url, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
|
|
59
|
+
options?.signal?.throwIfAborted();
|
|
60
|
+
let currentUrl = new URL(url).href;
|
|
61
|
+
validateUrl(currentUrl);
|
|
62
|
+
visited.add(currentUrl);
|
|
63
|
+
const originalRequest = createActivityPubRequest(currentUrl, { userAgent });
|
|
64
|
+
function follow(nextUrl) {
|
|
65
|
+
options?.signal?.throwIfAborted();
|
|
66
|
+
if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(currentUrl, `Too many redirections (${redirected + 1})`);
|
|
67
|
+
if (visited.has(nextUrl)) throw new FetchError(currentUrl, `Redirect loop detected: ${nextUrl}`);
|
|
68
|
+
redirected++;
|
|
69
|
+
}
|
|
70
|
+
const result = await doubleKnockScoped(originalRequest, identity, {
|
|
71
|
+
maxRedirection,
|
|
72
|
+
specDeterminer,
|
|
73
|
+
log: curry(logRequest)(logger),
|
|
74
|
+
tracerProvider,
|
|
75
|
+
signal: options?.signal,
|
|
76
|
+
validateRedirect: (nextUrl) => {
|
|
77
|
+
follow(nextUrl);
|
|
78
|
+
validateUrl(nextUrl);
|
|
79
|
+
visited.add(nextUrl);
|
|
80
|
+
currentUrl = nextUrl;
|
|
81
|
+
}
|
|
82
|
+
}, (hopUrl) => openHop(hopUrl, options), async (response) => {
|
|
83
|
+
options?.signal?.throwIfAborted();
|
|
84
|
+
let alternateUrl;
|
|
85
|
+
const document = await getRemoteDocument(currentUrl, response, (url) => {
|
|
86
|
+
alternateUrl = url;
|
|
87
|
+
return Promise.resolve(ALTERNATE_PLACEHOLDER);
|
|
88
|
+
}, options);
|
|
89
|
+
if (alternateUrl == null) return { document };
|
|
90
|
+
if (!response.bodyUsed && response.body?.locked !== true) response.body?.cancel().catch((error) => {
|
|
91
|
+
logger.debug("Failed to cancel the response body from {url}: {error}", {
|
|
92
|
+
url: currentUrl,
|
|
93
|
+
error
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
return { alternateUrl };
|
|
97
|
+
});
|
|
98
|
+
options?.signal?.throwIfAborted();
|
|
99
|
+
if ("document" in result) return result.document;
|
|
100
|
+
follow(result.alternateUrl);
|
|
101
|
+
return load(result.alternateUrl, options, redirected, visited);
|
|
102
|
+
}
|
|
103
|
+
function openUnvalidatedHop(url, signal) {
|
|
104
|
+
if (deps.openHop != null) return deps.openHop(url);
|
|
105
|
+
return allowPrivateAddress ? openDirectFetch(url) : openPublicFetch(url, { signal });
|
|
106
|
+
}
|
|
107
|
+
async function openHop(url, options) {
|
|
108
|
+
try {
|
|
109
|
+
const session = await openUnvalidatedHop(url, options?.signal);
|
|
110
|
+
if (options?.signal?.aborted) {
|
|
111
|
+
await session.close();
|
|
112
|
+
options.signal.throwIfAborted();
|
|
113
|
+
}
|
|
114
|
+
return session;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error instanceof UrlError) if (error.reason === "dns") logger.debug("DNS lookup failed for {url}", {
|
|
117
|
+
url,
|
|
118
|
+
error
|
|
119
|
+
});
|
|
120
|
+
else logger[options?.suppressError ? "warn" : "error"]("Disallowed private URL: {url}", {
|
|
121
|
+
url,
|
|
122
|
+
error
|
|
123
|
+
});
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function validateUrl(url) {
|
|
128
|
+
const parsedUrl = new URL(url);
|
|
129
|
+
const protocol = parsedUrl.protocol;
|
|
130
|
+
if (protocol !== "http:" && protocol !== "https:") throw new UrlError(`Unsupported protocol: ${protocol}`);
|
|
131
|
+
if (parsedUrl.username !== "" || parsedUrl.password !== "") throw new UrlError("URLs with credentials are not allowed");
|
|
132
|
+
}
|
|
133
|
+
return withDocumentLoaderTimeout((url, options) => load(url, options), resolvedTimeout);
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { getAuthenticatedDocumentLoader as n, createAuthenticatedDocumentLoader as t };
|
|
@@ -7,7 +7,7 @@ import { t as assertExists } from "../assert_exists-cffSpJ7X.mjs";
|
|
|
7
7
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
10
|
-
import { r as createFederationBuilder } from "../builder-
|
|
10
|
+
import { r as createFederationBuilder } from "../builder-CUAVOHg6.mjs";
|
|
11
11
|
import { DisallowedOperatorError, DisallowedVarSpecModifierError, DuplicateRouteVariableError, RouteTemplateOptionsNotMatchedError, RouterError } from "@fedify/uri-template";
|
|
12
12
|
import { Activity, Note, Person } from "@fedify/vocab";
|
|
13
13
|
import { test } from "@fedify/fixture";
|
|
@@ -6,11 +6,11 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
9
|
-
import { y as exportJwk } from "../ld-
|
|
9
|
+
import { y as exportJwk } from "../ld-Cy5GqbvS.mjs";
|
|
10
10
|
import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-4IJqPYos.mjs";
|
|
11
|
-
import { a as signObject, d as verifyProof } from "../proof-
|
|
11
|
+
import { a as signObject, d as verifyProof } from "../proof-UN4CW55z.mjs";
|
|
12
12
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
-
import { n as FederationImpl } from "../middleware-
|
|
13
|
+
import { n as FederationImpl } from "../middleware-D2fk45uN.mjs";
|
|
14
14
|
import { Create, DataIntegrityProof, Note } from "@fedify/vocab";
|
|
15
15
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
16
16
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -68,6 +68,7 @@ test("fanout delivery keeps an embedded signed child intact", async () => {
|
|
|
68
68
|
kv: new MemoryKvStore(),
|
|
69
69
|
contextLoaderFactory: () => mockDocumentLoader
|
|
70
70
|
});
|
|
71
|
+
federation.allowPrivateAddress = true;
|
|
71
72
|
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
72
73
|
const message = {
|
|
73
74
|
type: "fanout",
|
|
@@ -139,6 +140,7 @@ test("forced fanout signs before serializing so the child survives", async () =>
|
|
|
139
140
|
manuallyStartQueue: true,
|
|
140
141
|
contextLoaderFactory: () => mockDocumentLoader
|
|
141
142
|
});
|
|
143
|
+
federation.allowPrivateAddress = true;
|
|
142
144
|
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
143
145
|
await federation.createContext(new URL("https://example.com/")).sendActivity({
|
|
144
146
|
keyId: childKeyId,
|
|
@@ -203,6 +205,7 @@ test("an already signed activity keeps its single proof through fanout", async (
|
|
|
203
205
|
manuallyStartQueue: true,
|
|
204
206
|
contextLoaderFactory: () => mockDocumentLoader
|
|
205
207
|
});
|
|
208
|
+
federation.allowPrivateAddress = true;
|
|
206
209
|
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
207
210
|
await federation.createContext(new URL("https://example.com/")).sendActivity({
|
|
208
211
|
keyId: childKeyId,
|
|
@@ -5,10 +5,10 @@ import { r as createRequestContext, t as createInboxContext } from "../context-8
|
|
|
5
5
|
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
|
-
import { a as compactJsonLd, m as verifyCompactJsonLd, p as signJsonLd } from "../ld-
|
|
9
|
-
import {
|
|
8
|
+
import { a as compactJsonLd, m as verifyCompactJsonLd, p as signJsonLd } from "../ld-Cy5GqbvS.mjs";
|
|
9
|
+
import { u as signRequest } from "../http-DuGmr8J8.mjs";
|
|
10
10
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
11
|
-
import { f as handleInbox, o as createFederation } from "../middleware-
|
|
11
|
+
import { f as handleInbox, o as createFederation } from "../middleware-D2fk45uN.mjs";
|
|
12
12
|
import { t as ActivityListenerSet } from "../activity-listener-C-BSbKI7.mjs";
|
|
13
13
|
import { t as map_local_create_note_default } from "../map-local-create-note-B0SeXJms.mjs";
|
|
14
14
|
import { Create, CryptographicKey, Multikey, Person, Update } from "@fedify/vocab";
|