@fedify/fedify 2.2.0-pr.695.16 → 2.2.0-pr.697.18
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/activity-listener-Ck3JZ_hR.mjs +40 -0
- package/dist/{builder-7PVCiLiR.mjs → builder-CssIxEgK.mjs} +57 -7
- 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/{context-78ecvxf5.d.ts → context-BGrYMSTk.d.ts} +143 -1
- package/dist/{context-DYDPdoCb.d.cts → context-CMUd4wy0.d.cts} +143 -1
- package/dist/{context-Juj6bdHC.mjs → context-Dk_tacqz.mjs} +17 -2
- package/dist/{deno-vxcWcxQS.mjs → deno-DFC3hdDk.mjs} +1 -1
- package/dist/{docloader-D7q0-Xef.mjs → docloader-DJSGzW4N.mjs} +2 -2
- package/dist/federation/builder.test.mjs +25 -1
- package/dist/federation/handler.test.mjs +369 -8
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/middleware.test.mjs +510 -8
- 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/send.test.mjs +3 -3
- package/dist/federation/webfinger.test.mjs +2 -2
- package/dist/{http-RZPxDWq5.mjs → http-BrF-JQov.mjs} +2 -2
- package/dist/{http-JxF7bG0o.cjs → http-DDRsBRY5.cjs} +1 -1
- package/dist/{http-D-MhhYUF.js → http-nVAbZPuI.js} +1 -1
- package/dist/{key-CGx_dDkX.mjs → key-2MxqHz-F.mjs} +1 -1
- package/dist/{kv-cache-D84Mk0fZ.js → kv-cache-5w7DZnmJ.js} +1 -1
- package/dist/{kv-cache-C2gdVgvb.cjs → kv-cache-CPeV5q6I.cjs} +1 -1
- package/dist/{ld-wup-liFO.mjs → ld-bY6topKr.mjs} +26 -3
- package/dist/{middleware-BjVx-_bv.mjs → middleware-BCJUFXYb.mjs} +612 -180
- package/dist/{middleware-Bn75dPug.cjs → middleware-BPHO6DE3.cjs} +676 -323
- package/dist/{middleware-RF-sUfTr.js → middleware-C10kVjEo.js} +670 -322
- package/dist/{middleware-wdfeWjRJ.mjs → middleware-DI82-dr3.mjs} +1 -1
- package/dist/{middleware-CXOVT4Ph.cjs → middleware-JAlnEFGy.cjs} +1 -1
- package/dist/{mod-CEohtXhV.d.cts → mod-BcJHeuv1.d.cts} +1 -1
- package/dist/{mod-CokIUYDr.d.ts → mod-CJXfyw7v.d.ts} +1 -1
- package/dist/{mod-DvxszxXC.d.ts → mod-CR8soWa9.d.ts} +18 -1
- package/dist/{mod-DoJBjjnO.d.cts → mod-Cr3f-ACa.d.cts} +18 -1
- package/dist/mod.cjs +6 -4
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/{owner-q2mUMM9a.mjs → owner-D4-A8f_n.mjs} +2 -2
- package/dist/{proof--CpZsF_p.mjs → proof-45_MjnD1.mjs} +32 -3
- package/dist/{proof-_Zyfqyce.cjs → proof-COdach6j.cjs} +61 -3
- package/dist/{proof-CirP9OSd.js → proof-CnfkRjXL.js} +54 -2
- package/dist/{send-CVJfx7bF.mjs → send-BeNvLSaC.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 +44 -2
- package/dist/sig/mod.cjs +4 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +3 -3
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +46 -2
- package/dist/testing/mod.d.mts +149 -1
- package/dist/testing/mod.mjs +2 -2
- 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
- package/dist/inbox-CmYvcSMM.mjs +0 -179
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import "@js-temporal/polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { Activity } from "@fedify/vocab";
|
|
5
|
+
//#region src/federation/activity-listener.ts
|
|
6
|
+
var ActivityListenerSet = class {
|
|
7
|
+
#listeners;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.#listeners = /* @__PURE__ */ new Map();
|
|
10
|
+
}
|
|
11
|
+
clone() {
|
|
12
|
+
const Clone = this.constructor;
|
|
13
|
+
const clone = new Clone();
|
|
14
|
+
clone.#listeners = new Map(this.#listeners);
|
|
15
|
+
return clone;
|
|
16
|
+
}
|
|
17
|
+
add(type, listener) {
|
|
18
|
+
if (this.#listeners.has(type)) throw new TypeError("Listener already set for this type.");
|
|
19
|
+
this.#listeners.set(type, listener);
|
|
20
|
+
}
|
|
21
|
+
dispatchWithClass(activity) {
|
|
22
|
+
let cls = activity.constructor;
|
|
23
|
+
while (cls != null) {
|
|
24
|
+
if (this.#listeners.has(cls)) break;
|
|
25
|
+
if (cls === Activity) return null;
|
|
26
|
+
cls = globalThis.Object.getPrototypeOf(cls);
|
|
27
|
+
}
|
|
28
|
+
if (cls == null) return null;
|
|
29
|
+
const listener = this.#listeners.get(cls);
|
|
30
|
+
return {
|
|
31
|
+
class: cls,
|
|
32
|
+
listener
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
dispatch(activity) {
|
|
36
|
+
return this.dispatchWithClass(activity)?.listener ?? null;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { ActivityListenerSet as t };
|
|
@@ -2,12 +2,23 @@ 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
|
|
5
|
+
import { n as version, t as name } from "./deno-DFC3hdDk.mjs";
|
|
6
|
+
import { t as ActivityListenerSet } from "./activity-listener-Ck3JZ_hR.mjs";
|
|
7
7
|
import { Tombstone, getTypeId } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
9
|
import { getLogger } from "@logtape/logtape";
|
|
10
10
|
//#region src/federation/builder.ts
|
|
11
|
+
function validateSingleIdentifierVariablePath(path, errorMessage) {
|
|
12
|
+
const operatorMatches = globalThis.Array.from(path.matchAll(/{([+#./;?&]?)([A-Za-z_][A-Za-z0-9_]*)}/g));
|
|
13
|
+
if (operatorMatches.length !== 1 || operatorMatches[0]?.[2] !== "identifier") throw new RouterError(errorMessage);
|
|
14
|
+
if (operatorMatches.some((match) => [
|
|
15
|
+
"?",
|
|
16
|
+
"&",
|
|
17
|
+
"#"
|
|
18
|
+
].includes(match[1]) && match[2] === "identifier")) throw new RouterError(errorMessage);
|
|
19
|
+
const variables = new Router().add(path, "outbox");
|
|
20
|
+
if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError(errorMessage);
|
|
21
|
+
}
|
|
11
22
|
var FederationBuilderImpl = class {
|
|
12
23
|
router;
|
|
13
24
|
actorCallbacks;
|
|
@@ -16,6 +27,7 @@ var FederationBuilderImpl = class {
|
|
|
16
27
|
objectCallbacks;
|
|
17
28
|
objectTypeIds;
|
|
18
29
|
inboxPath;
|
|
30
|
+
outboxPath;
|
|
19
31
|
inboxCallbacks;
|
|
20
32
|
outboxCallbacks;
|
|
21
33
|
followingCallbacks;
|
|
@@ -24,7 +36,10 @@ var FederationBuilderImpl = class {
|
|
|
24
36
|
featuredCallbacks;
|
|
25
37
|
featuredTagsCallbacks;
|
|
26
38
|
inboxListeners;
|
|
39
|
+
outboxListeners;
|
|
27
40
|
inboxErrorHandler;
|
|
41
|
+
outboxListenerErrorHandler;
|
|
42
|
+
outboxAuthorizePredicate;
|
|
28
43
|
sharedInboxKeyDispatcher;
|
|
29
44
|
unverifiedActivityHandler;
|
|
30
45
|
outboxPermanentFailureHandler;
|
|
@@ -43,7 +58,7 @@ var FederationBuilderImpl = class {
|
|
|
43
58
|
this.collectionTypeIds = {};
|
|
44
59
|
}
|
|
45
60
|
async build(options) {
|
|
46
|
-
const { FederationImpl } = await import("./middleware-
|
|
61
|
+
const { FederationImpl } = await import("./middleware-DI82-dr3.mjs");
|
|
47
62
|
const f = new FederationImpl(options);
|
|
48
63
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
49
64
|
f.router = this.router.clone();
|
|
@@ -55,6 +70,7 @@ var FederationBuilderImpl = class {
|
|
|
55
70
|
f.objectCallbacks = { ...this.objectCallbacks };
|
|
56
71
|
f.objectTypeIds = { ...this.objectTypeIds };
|
|
57
72
|
f.inboxPath = this.inboxPath;
|
|
73
|
+
f.outboxPath = this.outboxPath;
|
|
58
74
|
f.inboxCallbacks = this.inboxCallbacks == null ? void 0 : { ...this.inboxCallbacks };
|
|
59
75
|
f.outboxCallbacks = this.outboxCallbacks == null ? void 0 : { ...this.outboxCallbacks };
|
|
60
76
|
f.followingCallbacks = this.followingCallbacks == null ? void 0 : { ...this.followingCallbacks };
|
|
@@ -63,7 +79,10 @@ var FederationBuilderImpl = class {
|
|
|
63
79
|
f.featuredCallbacks = this.featuredCallbacks == null ? void 0 : { ...this.featuredCallbacks };
|
|
64
80
|
f.featuredTagsCallbacks = this.featuredTagsCallbacks == null ? void 0 : { ...this.featuredTagsCallbacks };
|
|
65
81
|
f.inboxListeners = this.inboxListeners?.clone();
|
|
82
|
+
f.outboxListeners = this.outboxListeners?.clone();
|
|
66
83
|
f.inboxErrorHandler = this.inboxErrorHandler;
|
|
84
|
+
f.outboxListenerErrorHandler = this.outboxListenerErrorHandler;
|
|
85
|
+
f.outboxAuthorizePredicate = this.outboxAuthorizePredicate;
|
|
67
86
|
f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
|
|
68
87
|
f.unverifiedActivityHandler = this.unverifiedActivityHandler;
|
|
69
88
|
f.outboxPermanentFailureHandler = this.outboxPermanentFailureHandler;
|
|
@@ -263,9 +282,14 @@ var FederationBuilderImpl = class {
|
|
|
263
282
|
return setters;
|
|
264
283
|
}
|
|
265
284
|
setOutboxDispatcher(path, dispatcher) {
|
|
266
|
-
if (this.
|
|
267
|
-
|
|
268
|
-
|
|
285
|
+
if (this.outboxCallbacks != null) throw new RouterError("Outbox dispatcher already set.");
|
|
286
|
+
if (this.router.has("outbox")) {
|
|
287
|
+
if (this.outboxPath !== path) throw new RouterError("Outbox dispatcher path must match outbox listener path.");
|
|
288
|
+
} else {
|
|
289
|
+
validateSingleIdentifierVariablePath(path, "Path for outbox dispatcher must have one variable: {identifier}");
|
|
290
|
+
this.router.add(path, "outbox");
|
|
291
|
+
this.outboxPath = path;
|
|
292
|
+
}
|
|
269
293
|
const callbacks = { dispatcher };
|
|
270
294
|
this.outboxCallbacks = callbacks;
|
|
271
295
|
const setters = {
|
|
@@ -288,6 +312,32 @@ var FederationBuilderImpl = class {
|
|
|
288
312
|
};
|
|
289
313
|
return setters;
|
|
290
314
|
}
|
|
315
|
+
setOutboxListeners(outboxPath) {
|
|
316
|
+
if (this.outboxListeners != null) throw new RouterError("Outbox listeners already set.");
|
|
317
|
+
if (this.router.has("outbox")) {
|
|
318
|
+
if (this.outboxPath !== outboxPath) throw new RouterError("Outbox listener path must match outbox dispatcher path.");
|
|
319
|
+
} else {
|
|
320
|
+
validateSingleIdentifierVariablePath(outboxPath, "Path for outbox must have one variable: {identifier}");
|
|
321
|
+
this.router.add(outboxPath, "outbox");
|
|
322
|
+
this.outboxPath = outboxPath;
|
|
323
|
+
}
|
|
324
|
+
const listeners = this.outboxListeners = new ActivityListenerSet();
|
|
325
|
+
const setters = {
|
|
326
|
+
on(type, listener) {
|
|
327
|
+
listeners.add(type, listener);
|
|
328
|
+
return setters;
|
|
329
|
+
},
|
|
330
|
+
onError: (handler) => {
|
|
331
|
+
this.outboxListenerErrorHandler = handler;
|
|
332
|
+
return setters;
|
|
333
|
+
},
|
|
334
|
+
authorize: (predicate) => {
|
|
335
|
+
this.outboxAuthorizePredicate = predicate;
|
|
336
|
+
return setters;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
return setters;
|
|
340
|
+
}
|
|
291
341
|
setFollowingDispatcher(path, dispatcher) {
|
|
292
342
|
if (this.router.has("following")) throw new RouterError("Following collection dispatcher already set.");
|
|
293
343
|
const variables = this.router.add(path, "following");
|
|
@@ -430,7 +480,7 @@ var FederationBuilderImpl = class {
|
|
|
430
480
|
if (sharedInboxPath != null) {
|
|
431
481
|
if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
|
|
432
482
|
}
|
|
433
|
-
const listeners = this.inboxListeners = new
|
|
483
|
+
const listeners = this.inboxListeners = new ActivityListenerSet();
|
|
434
484
|
const setters = {
|
|
435
485
|
on(type, listener) {
|
|
436
486
|
listeners.add(type, listener);
|
package/dist/compat/mod.d.cts
CHANGED
package/dist/compat/mod.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import {
|
|
3
|
+
import { Ot as ActivityTransformer, n as Context } from "../context-BGrYMSTk.js";
|
|
4
4
|
import { Activity } from "@fedify/vocab";
|
|
5
5
|
|
|
6
6
|
//#region src/compat/transformers.d.ts
|
|
@@ -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-tL2TOE9X.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import { n as FederationImpl, v as actorDehydrator, y as autoIdAssigner } from "../middleware-BCJUFXYb.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Follow, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/compat/transformers.test.ts
|
|
@@ -212,6 +212,16 @@ type CollectionCursor<TContext extends Context<TContextData>, TContextData, TFil
|
|
|
212
212
|
*/
|
|
213
213
|
type InboxListener<TContextData, TActivity extends Activity> = (context: InboxContext<TContextData>, activity: TActivity) => void | Promise<void>;
|
|
214
214
|
/**
|
|
215
|
+
* A callback that listens for activities in an outbox.
|
|
216
|
+
*
|
|
217
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
218
|
+
* @template TActivity The type of activity to listen for.
|
|
219
|
+
* @param context The outbox context.
|
|
220
|
+
* @param activity The activity that was received.
|
|
221
|
+
* @since 2.2.0
|
|
222
|
+
*/
|
|
223
|
+
type OutboxListener<TContextData, TActivity extends Activity> = (context: OutboxContext<TContextData>, activity: TActivity) => void | Promise<void>;
|
|
224
|
+
/**
|
|
215
225
|
* The reason why an incoming activity could not be verified.
|
|
216
226
|
*
|
|
217
227
|
* Unlike inbox listeners registered through {@link InboxListenerSetters.on},
|
|
@@ -242,6 +252,15 @@ type UnverifiedActivityHandler<TContextData> = (context: RequestContext<TContext
|
|
|
242
252
|
*/
|
|
243
253
|
type InboxErrorHandler<TContextData> = (context: Context<TContextData>, error: Error) => void | Promise<void>;
|
|
244
254
|
/**
|
|
255
|
+
* A callback that handles errors in an outbox listener.
|
|
256
|
+
*
|
|
257
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
258
|
+
* @param context The outbox context.
|
|
259
|
+
* @param error The error that occurred.
|
|
260
|
+
* @since 2.2.0
|
|
261
|
+
*/
|
|
262
|
+
type OutboxListenerErrorHandler<TContextData> = (context: OutboxContext<TContextData>, error: Error) => void | Promise<void>;
|
|
263
|
+
/**
|
|
245
264
|
* A callback that dispatches the key pair for the authenticated document loader
|
|
246
265
|
* of the {@link Context} passed to the shared inbox listener.
|
|
247
266
|
*
|
|
@@ -1051,6 +1070,32 @@ interface Federatable<TContextData> {
|
|
|
1051
1070
|
*/
|
|
1052
1071
|
setOutboxDispatcher(path: `${string}${Rfc6570Expression<"identifier">}${string}`, dispatcher: CollectionDispatcher<Activity, RequestContext<TContextData>, TContextData, void>): CollectionCallbackSetters<RequestContext<TContextData>, TContextData, void>;
|
|
1053
1072
|
/**
|
|
1073
|
+
* Assigns the URL path for the outbox and starts setting outbox listeners.
|
|
1074
|
+
*
|
|
1075
|
+
* @example
|
|
1076
|
+
* ``` typescript
|
|
1077
|
+
* federation
|
|
1078
|
+
* .setOutboxListeners("/users/{identifier}/outbox")
|
|
1079
|
+
* .on(Activity, async (ctx, activity) => {
|
|
1080
|
+
* await ctx.sendActivity({ identifier: ctx.identifier }, "followers", activity);
|
|
1081
|
+
* })
|
|
1082
|
+
* .authorize(async (ctx, identifier) => {
|
|
1083
|
+
* return ctx.request.headers.get("authorization") === `Bearer ${identifier}`;
|
|
1084
|
+
* });
|
|
1085
|
+
* ```
|
|
1086
|
+
*
|
|
1087
|
+
* @param outboxPath The URI path pattern for the outbox. The syntax is based
|
|
1088
|
+
* on URI Template
|
|
1089
|
+
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The
|
|
1090
|
+
* path must have one variable: `{identifier}`. If an
|
|
1091
|
+
* outbox dispatcher is configured, this path must match
|
|
1092
|
+
* the outbox dispatcher path.
|
|
1093
|
+
* @returns An object to register outbox listeners.
|
|
1094
|
+
* @throws {RouterError} Thrown if the path pattern is invalid.
|
|
1095
|
+
* @since 2.2.0
|
|
1096
|
+
*/
|
|
1097
|
+
setOutboxListeners(outboxPath: `${string}${Rfc6570Expression<"identifier">}${string}`): OutboxListenerSetters<TContextData>;
|
|
1098
|
+
/**
|
|
1054
1099
|
* Registers a following collection dispatcher.
|
|
1055
1100
|
* @param path The URI path pattern for the following collection. The syntax
|
|
1056
1101
|
* is based on URI Template
|
|
@@ -1674,6 +1719,38 @@ type IdempotencyStrategy = "global" | "per-origin" | "per-inbox";
|
|
|
1674
1719
|
*/
|
|
1675
1720
|
type IdempotencyKeyCallback<TContextData> = (ctx: InboxContext<TContextData>, activity: Activity) => string | null | Promise<string | null>;
|
|
1676
1721
|
/**
|
|
1722
|
+
* Registry for outbox listeners for different activity types.
|
|
1723
|
+
* @since 2.2.0
|
|
1724
|
+
*/
|
|
1725
|
+
interface OutboxListenerSetters<TContextData> {
|
|
1726
|
+
/**
|
|
1727
|
+
* Registers a listener for a specific incoming activity type.
|
|
1728
|
+
*
|
|
1729
|
+
* @param type A subclass of {@link Activity} to listen to.
|
|
1730
|
+
* @param listener A callback to handle an incoming activity.
|
|
1731
|
+
* @returns The setters object so that settings can be chained.
|
|
1732
|
+
* @since 2.2.0
|
|
1733
|
+
*/
|
|
1734
|
+
on<TActivity extends Activity>(type: new (...args: any[]) => TActivity, listener: OutboxListener<TContextData, TActivity>): OutboxListenerSetters<TContextData>;
|
|
1735
|
+
/**
|
|
1736
|
+
* Registers an error handler for outbox listeners. Any exceptions thrown
|
|
1737
|
+
* from the listeners are caught and passed to this handler.
|
|
1738
|
+
*
|
|
1739
|
+
* @param handler A callback to handle an error.
|
|
1740
|
+
* @returns The setters object so that settings can be chained.
|
|
1741
|
+
* @since 2.2.0
|
|
1742
|
+
*/
|
|
1743
|
+
onError(handler: OutboxListenerErrorHandler<TContextData>): OutboxListenerSetters<TContextData>;
|
|
1744
|
+
/**
|
|
1745
|
+
* Registers a callback to authorize POST requests to the outbox.
|
|
1746
|
+
*
|
|
1747
|
+
* @param predicate A callback to authorize the request.
|
|
1748
|
+
* @returns The setters object so that settings can be chained.
|
|
1749
|
+
* @since 2.2.0
|
|
1750
|
+
*/
|
|
1751
|
+
authorize(predicate: AuthorizePredicate<TContextData>): OutboxListenerSetters<TContextData>;
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1677
1754
|
* Registry for inbox listeners for different activity types.
|
|
1678
1755
|
*/
|
|
1679
1756
|
interface InboxListenerSetters<TContextData> {
|
|
@@ -2445,6 +2522,71 @@ interface InboxContext<TContextData> extends Context<TContextData> {
|
|
|
2445
2522
|
}, recipients: "followers", options?: ForwardActivityOptions): Promise<void>;
|
|
2446
2523
|
}
|
|
2447
2524
|
/**
|
|
2525
|
+
* A context for outbox listeners.
|
|
2526
|
+
* @since 2.2.0
|
|
2527
|
+
*/
|
|
2528
|
+
interface OutboxContext<TContextData> extends Context<TContextData> {
|
|
2529
|
+
/**
|
|
2530
|
+
* The identifier of the actor whose outbox received the POST.
|
|
2531
|
+
* @since 2.2.0
|
|
2532
|
+
*/
|
|
2533
|
+
readonly identifier: string;
|
|
2534
|
+
/**
|
|
2535
|
+
* Indicates whether the posted activity has been delivered during the
|
|
2536
|
+
* current outbox listener invocation.
|
|
2537
|
+
* @returns `true` if the posted activity has been delivered; `false`
|
|
2538
|
+
* otherwise.
|
|
2539
|
+
* @since 2.2.0
|
|
2540
|
+
*/
|
|
2541
|
+
hasDeliveredActivity(): boolean;
|
|
2542
|
+
/**
|
|
2543
|
+
* Forwards a posted activity to the recipients' inboxes without
|
|
2544
|
+
* re-serializing the original payload. The forwarded activity will be
|
|
2545
|
+
* signed in HTTP Signatures by the forwarder, but its payload will not be
|
|
2546
|
+
* modified, i.e., Linked Data Signatures and Object Integrity Proofs will
|
|
2547
|
+
* not be added. Therefore, if the posted activity is not signed (i.e., it
|
|
2548
|
+
* has neither Linked Data Signatures nor Object Integrity Proofs), the
|
|
2549
|
+
* recipients probably will not trust the activity.
|
|
2550
|
+
* @param forwarder The forwarder's identifier or the forwarder's username
|
|
2551
|
+
* or the forwarder's key pair(s).
|
|
2552
|
+
* @param recipients The recipients of the activity.
|
|
2553
|
+
* @param options Options for forwarding the activity.
|
|
2554
|
+
* @since 2.2.0
|
|
2555
|
+
*/
|
|
2556
|
+
forwardActivity(forwarder: SenderKeyPair | SenderKeyPair[] | {
|
|
2557
|
+
identifier: string;
|
|
2558
|
+
} | {
|
|
2559
|
+
username: string;
|
|
2560
|
+
}, recipients: Recipient | Recipient[], options?: ForwardActivityOptions): Promise<void>;
|
|
2561
|
+
/**
|
|
2562
|
+
* Forwards a posted activity to the recipients' inboxes without
|
|
2563
|
+
* re-serializing the original payload. The forwarded activity will be
|
|
2564
|
+
* signed in HTTP Signatures by the forwarder, but its payload will not be
|
|
2565
|
+
* modified, i.e., Linked Data Signatures and Object Integrity Proofs will
|
|
2566
|
+
* not be added. Therefore, if the posted activity is not signed (i.e., it
|
|
2567
|
+
* has neither Linked Data Signatures nor Object Integrity Proofs), the
|
|
2568
|
+
* recipients probably will not trust the activity.
|
|
2569
|
+
* @param forwarder The forwarder's identifier or the forwarder's username.
|
|
2570
|
+
* @param recipients In this case, it must be `"followers"`.
|
|
2571
|
+
* @param options Options for forwarding the activity.
|
|
2572
|
+
* @since 2.2.0
|
|
2573
|
+
*/
|
|
2574
|
+
forwardActivity(forwarder: {
|
|
2575
|
+
identifier: string;
|
|
2576
|
+
} | {
|
|
2577
|
+
username: string;
|
|
2578
|
+
}, recipients: "followers", options?: ForwardActivityOptions): Promise<void>;
|
|
2579
|
+
/**
|
|
2580
|
+
* Creates a new context with the same properties as this one,
|
|
2581
|
+
* but with the given data.
|
|
2582
|
+
* @param data The new data to associate with the context.
|
|
2583
|
+
* @returns A new context with the same properties as this one,
|
|
2584
|
+
* but with the given data.
|
|
2585
|
+
* @since 2.2.0
|
|
2586
|
+
*/
|
|
2587
|
+
clone(data: TContextData): OutboxContext<TContextData>;
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2448
2590
|
* A result of parsing an URI.
|
|
2449
2591
|
*/
|
|
2450
2592
|
type ParseUriResult = {
|
|
@@ -2644,4 +2786,4 @@ interface ActorKeyPair extends CryptoKeyPair {
|
|
|
2644
2786
|
readonly multikey: Multikey;
|
|
2645
2787
|
}
|
|
2646
2788
|
//#endregion
|
|
2647
|
-
export {
|
|
2789
|
+
export { ActorAliasMapper as $, FederationKvPrefixes as A, Router as B, IdempotencyKeyCallback as C, SendActivityError as Ct, ObjectCallbackSetters as D, digest as Dt, InboxListenerSetters as E, buildCollectionSynchronizationHeader as Et, RetryContext as F, respondWithObject as G, RouterOptions as H, RetryPolicy as I, InProcessMessageQueueOptions as J, respondWithObjectIfAcceptable as K, createExponentialBackoffPolicy as L, FederationQueueOptions as M, createFederation as N, OutboxListenerSetters as O, ActivityTransformer as Ot, CreateExponentialBackoffPolicyOptions as P, ParallelMessageQueue as Q, Message as R, FederationStartQueueOptions as S, WebFingerLinksDispatcher as St, InboxChallengePolicy as T, PageItems as Tt, RouterRouteResult as U, RouterError as V, RespondWithObjectOptions as W, MessageQueueEnqueueOptions as X, MessageQueue as Y, MessageQueueListenOptions as Z, Federatable as _, OutboxListenerErrorHandler as _t, GetSignedKeyOptions as a, CollectionCursor as at, FederationFetchOptions as b, UnverifiedActivityHandler as bt, ParseUriResult as c, CustomCollectionCursor as ct, SendActivityOptions as d, InboxListener as dt, ActorDispatcher as et, SendActivityOptionsForCollection as f, NodeInfoDispatcher as ft, CustomCollectionCallbackSetters as g, OutboxListener as gt, ConstructorWithTypeId as h, OutboxErrorHandler as ht, GetActorOptions as i, CollectionCounter as it, FederationOrigin as j, Rfc6570Expression as k, RequestContext as l, CustomCollectionDispatcher as lt, CollectionCallbackSetters as m, ObjectDispatcher as mt, Context as n, ActorKeyPairsDispatcher as nt, InboxContext as o, CollectionDispatcher as ot, ActorCallbackSetters as p, ObjectAuthorizePredicate as pt, InProcessMessageQueue as q, ForwardActivityOptions as r, AuthorizePredicate as rt, OutboxContext as s, CustomCollectionCounter as st, ActorKeyPair as t, ActorHandleMapper as tt, RouteActivityOptions as u, InboxErrorHandler as ut, Federation as v, OutboxPermanentFailureHandler as vt, IdempotencyStrategy as w, SenderKeyPair as wt, FederationOptions as x, UnverifiedActivityReason as xt, FederationBuilder as y, SharedInboxKeyDispatcher as yt, createFederationBuilder as z };
|
|
@@ -210,6 +210,16 @@ type CollectionCursor<TContext extends Context<TContextData>, TContextData, TFil
|
|
|
210
210
|
*/
|
|
211
211
|
type InboxListener<TContextData, TActivity extends Activity> = (context: InboxContext<TContextData>, activity: TActivity) => void | Promise<void>;
|
|
212
212
|
/**
|
|
213
|
+
* A callback that listens for activities in an outbox.
|
|
214
|
+
*
|
|
215
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
216
|
+
* @template TActivity The type of activity to listen for.
|
|
217
|
+
* @param context The outbox context.
|
|
218
|
+
* @param activity The activity that was received.
|
|
219
|
+
* @since 2.2.0
|
|
220
|
+
*/
|
|
221
|
+
type OutboxListener<TContextData, TActivity extends Activity> = (context: OutboxContext<TContextData>, activity: TActivity) => void | Promise<void>;
|
|
222
|
+
/**
|
|
213
223
|
* The reason why an incoming activity could not be verified.
|
|
214
224
|
*
|
|
215
225
|
* Unlike inbox listeners registered through {@link InboxListenerSetters.on},
|
|
@@ -240,6 +250,15 @@ type UnverifiedActivityHandler<TContextData> = (context: RequestContext<TContext
|
|
|
240
250
|
*/
|
|
241
251
|
type InboxErrorHandler<TContextData> = (context: Context<TContextData>, error: Error) => void | Promise<void>;
|
|
242
252
|
/**
|
|
253
|
+
* A callback that handles errors in an outbox listener.
|
|
254
|
+
*
|
|
255
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
256
|
+
* @param context The outbox context.
|
|
257
|
+
* @param error The error that occurred.
|
|
258
|
+
* @since 2.2.0
|
|
259
|
+
*/
|
|
260
|
+
type OutboxListenerErrorHandler<TContextData> = (context: OutboxContext<TContextData>, error: Error) => void | Promise<void>;
|
|
261
|
+
/**
|
|
243
262
|
* A callback that dispatches the key pair for the authenticated document loader
|
|
244
263
|
* of the {@link Context} passed to the shared inbox listener.
|
|
245
264
|
*
|
|
@@ -1049,6 +1068,32 @@ interface Federatable<TContextData> {
|
|
|
1049
1068
|
*/
|
|
1050
1069
|
setOutboxDispatcher(path: `${string}${Rfc6570Expression<"identifier">}${string}`, dispatcher: CollectionDispatcher<Activity, RequestContext<TContextData>, TContextData, void>): CollectionCallbackSetters<RequestContext<TContextData>, TContextData, void>;
|
|
1051
1070
|
/**
|
|
1071
|
+
* Assigns the URL path for the outbox and starts setting outbox listeners.
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* ``` typescript
|
|
1075
|
+
* federation
|
|
1076
|
+
* .setOutboxListeners("/users/{identifier}/outbox")
|
|
1077
|
+
* .on(Activity, async (ctx, activity) => {
|
|
1078
|
+
* await ctx.sendActivity({ identifier: ctx.identifier }, "followers", activity);
|
|
1079
|
+
* })
|
|
1080
|
+
* .authorize(async (ctx, identifier) => {
|
|
1081
|
+
* return ctx.request.headers.get("authorization") === `Bearer ${identifier}`;
|
|
1082
|
+
* });
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* @param outboxPath The URI path pattern for the outbox. The syntax is based
|
|
1086
|
+
* on URI Template
|
|
1087
|
+
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The
|
|
1088
|
+
* path must have one variable: `{identifier}`. If an
|
|
1089
|
+
* outbox dispatcher is configured, this path must match
|
|
1090
|
+
* the outbox dispatcher path.
|
|
1091
|
+
* @returns An object to register outbox listeners.
|
|
1092
|
+
* @throws {RouterError} Thrown if the path pattern is invalid.
|
|
1093
|
+
* @since 2.2.0
|
|
1094
|
+
*/
|
|
1095
|
+
setOutboxListeners(outboxPath: `${string}${Rfc6570Expression<"identifier">}${string}`): OutboxListenerSetters<TContextData>;
|
|
1096
|
+
/**
|
|
1052
1097
|
* Registers a following collection dispatcher.
|
|
1053
1098
|
* @param path The URI path pattern for the following collection. The syntax
|
|
1054
1099
|
* is based on URI Template
|
|
@@ -1672,6 +1717,38 @@ type IdempotencyStrategy = "global" | "per-origin" | "per-inbox";
|
|
|
1672
1717
|
*/
|
|
1673
1718
|
type IdempotencyKeyCallback<TContextData> = (ctx: InboxContext<TContextData>, activity: Activity) => string | null | Promise<string | null>;
|
|
1674
1719
|
/**
|
|
1720
|
+
* Registry for outbox listeners for different activity types.
|
|
1721
|
+
* @since 2.2.0
|
|
1722
|
+
*/
|
|
1723
|
+
interface OutboxListenerSetters<TContextData> {
|
|
1724
|
+
/**
|
|
1725
|
+
* Registers a listener for a specific incoming activity type.
|
|
1726
|
+
*
|
|
1727
|
+
* @param type A subclass of {@link Activity} to listen to.
|
|
1728
|
+
* @param listener A callback to handle an incoming activity.
|
|
1729
|
+
* @returns The setters object so that settings can be chained.
|
|
1730
|
+
* @since 2.2.0
|
|
1731
|
+
*/
|
|
1732
|
+
on<TActivity extends Activity>(type: new (...args: any[]) => TActivity, listener: OutboxListener<TContextData, TActivity>): OutboxListenerSetters<TContextData>;
|
|
1733
|
+
/**
|
|
1734
|
+
* Registers an error handler for outbox listeners. Any exceptions thrown
|
|
1735
|
+
* from the listeners are caught and passed to this handler.
|
|
1736
|
+
*
|
|
1737
|
+
* @param handler A callback to handle an error.
|
|
1738
|
+
* @returns The setters object so that settings can be chained.
|
|
1739
|
+
* @since 2.2.0
|
|
1740
|
+
*/
|
|
1741
|
+
onError(handler: OutboxListenerErrorHandler<TContextData>): OutboxListenerSetters<TContextData>;
|
|
1742
|
+
/**
|
|
1743
|
+
* Registers a callback to authorize POST requests to the outbox.
|
|
1744
|
+
*
|
|
1745
|
+
* @param predicate A callback to authorize the request.
|
|
1746
|
+
* @returns The setters object so that settings can be chained.
|
|
1747
|
+
* @since 2.2.0
|
|
1748
|
+
*/
|
|
1749
|
+
authorize(predicate: AuthorizePredicate<TContextData>): OutboxListenerSetters<TContextData>;
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1675
1752
|
* Registry for inbox listeners for different activity types.
|
|
1676
1753
|
*/
|
|
1677
1754
|
interface InboxListenerSetters<TContextData> {
|
|
@@ -2443,6 +2520,71 @@ interface InboxContext<TContextData> extends Context<TContextData> {
|
|
|
2443
2520
|
}, recipients: "followers", options?: ForwardActivityOptions): Promise<void>;
|
|
2444
2521
|
}
|
|
2445
2522
|
/**
|
|
2523
|
+
* A context for outbox listeners.
|
|
2524
|
+
* @since 2.2.0
|
|
2525
|
+
*/
|
|
2526
|
+
interface OutboxContext<TContextData> extends Context<TContextData> {
|
|
2527
|
+
/**
|
|
2528
|
+
* The identifier of the actor whose outbox received the POST.
|
|
2529
|
+
* @since 2.2.0
|
|
2530
|
+
*/
|
|
2531
|
+
readonly identifier: string;
|
|
2532
|
+
/**
|
|
2533
|
+
* Indicates whether the posted activity has been delivered during the
|
|
2534
|
+
* current outbox listener invocation.
|
|
2535
|
+
* @returns `true` if the posted activity has been delivered; `false`
|
|
2536
|
+
* otherwise.
|
|
2537
|
+
* @since 2.2.0
|
|
2538
|
+
*/
|
|
2539
|
+
hasDeliveredActivity(): boolean;
|
|
2540
|
+
/**
|
|
2541
|
+
* Forwards a posted activity to the recipients' inboxes without
|
|
2542
|
+
* re-serializing the original payload. The forwarded activity will be
|
|
2543
|
+
* signed in HTTP Signatures by the forwarder, but its payload will not be
|
|
2544
|
+
* modified, i.e., Linked Data Signatures and Object Integrity Proofs will
|
|
2545
|
+
* not be added. Therefore, if the posted activity is not signed (i.e., it
|
|
2546
|
+
* has neither Linked Data Signatures nor Object Integrity Proofs), the
|
|
2547
|
+
* recipients probably will not trust the activity.
|
|
2548
|
+
* @param forwarder The forwarder's identifier or the forwarder's username
|
|
2549
|
+
* or the forwarder's key pair(s).
|
|
2550
|
+
* @param recipients The recipients of the activity.
|
|
2551
|
+
* @param options Options for forwarding the activity.
|
|
2552
|
+
* @since 2.2.0
|
|
2553
|
+
*/
|
|
2554
|
+
forwardActivity(forwarder: SenderKeyPair | SenderKeyPair[] | {
|
|
2555
|
+
identifier: string;
|
|
2556
|
+
} | {
|
|
2557
|
+
username: string;
|
|
2558
|
+
}, recipients: Recipient | Recipient[], options?: ForwardActivityOptions): Promise<void>;
|
|
2559
|
+
/**
|
|
2560
|
+
* Forwards a posted activity to the recipients' inboxes without
|
|
2561
|
+
* re-serializing the original payload. The forwarded activity will be
|
|
2562
|
+
* signed in HTTP Signatures by the forwarder, but its payload will not be
|
|
2563
|
+
* modified, i.e., Linked Data Signatures and Object Integrity Proofs will
|
|
2564
|
+
* not be added. Therefore, if the posted activity is not signed (i.e., it
|
|
2565
|
+
* has neither Linked Data Signatures nor Object Integrity Proofs), the
|
|
2566
|
+
* recipients probably will not trust the activity.
|
|
2567
|
+
* @param forwarder The forwarder's identifier or the forwarder's username.
|
|
2568
|
+
* @param recipients In this case, it must be `"followers"`.
|
|
2569
|
+
* @param options Options for forwarding the activity.
|
|
2570
|
+
* @since 2.2.0
|
|
2571
|
+
*/
|
|
2572
|
+
forwardActivity(forwarder: {
|
|
2573
|
+
identifier: string;
|
|
2574
|
+
} | {
|
|
2575
|
+
username: string;
|
|
2576
|
+
}, recipients: "followers", options?: ForwardActivityOptions): Promise<void>;
|
|
2577
|
+
/**
|
|
2578
|
+
* Creates a new context with the same properties as this one,
|
|
2579
|
+
* but with the given data.
|
|
2580
|
+
* @param data The new data to associate with the context.
|
|
2581
|
+
* @returns A new context with the same properties as this one,
|
|
2582
|
+
* but with the given data.
|
|
2583
|
+
* @since 2.2.0
|
|
2584
|
+
*/
|
|
2585
|
+
clone(data: TContextData): OutboxContext<TContextData>;
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2446
2588
|
* A result of parsing an URI.
|
|
2447
2589
|
*/
|
|
2448
2590
|
type ParseUriResult = {
|
|
@@ -2642,4 +2784,4 @@ interface ActorKeyPair extends CryptoKeyPair {
|
|
|
2642
2784
|
readonly multikey: Multikey;
|
|
2643
2785
|
}
|
|
2644
2786
|
//#endregion
|
|
2645
|
-
export {
|
|
2787
|
+
export { ActorAliasMapper as $, FederationKvPrefixes as A, Router as B, IdempotencyKeyCallback as C, SendActivityError as Ct, ObjectCallbackSetters as D, digest as Dt, InboxListenerSetters as E, buildCollectionSynchronizationHeader as Et, RetryContext as F, respondWithObject as G, RouterOptions as H, RetryPolicy as I, InProcessMessageQueueOptions as J, respondWithObjectIfAcceptable as K, createExponentialBackoffPolicy as L, FederationQueueOptions as M, createFederation as N, OutboxListenerSetters as O, ActivityTransformer as Ot, CreateExponentialBackoffPolicyOptions as P, ParallelMessageQueue as Q, Message as R, FederationStartQueueOptions as S, WebFingerLinksDispatcher as St, InboxChallengePolicy as T, PageItems as Tt, RouterRouteResult as U, RouterError as V, RespondWithObjectOptions as W, MessageQueueEnqueueOptions as X, MessageQueue as Y, MessageQueueListenOptions as Z, Federatable as _, OutboxListenerErrorHandler as _t, GetSignedKeyOptions as a, CollectionCursor as at, FederationFetchOptions as b, UnverifiedActivityHandler as bt, ParseUriResult as c, CustomCollectionCursor as ct, SendActivityOptions as d, InboxListener as dt, ActorDispatcher as et, SendActivityOptionsForCollection as f, NodeInfoDispatcher as ft, CustomCollectionCallbackSetters as g, OutboxListener as gt, ConstructorWithTypeId as h, OutboxErrorHandler as ht, GetActorOptions as i, CollectionCounter as it, FederationOrigin as j, Rfc6570Expression as k, RequestContext as l, CustomCollectionDispatcher as lt, CollectionCallbackSetters as m, ObjectDispatcher as mt, Context as n, ActorKeyPairsDispatcher as nt, InboxContext as o, CollectionDispatcher as ot, ActorCallbackSetters as p, ObjectAuthorizePredicate as pt, InProcessMessageQueue as q, ForwardActivityOptions as r, AuthorizePredicate as rt, OutboxContext as s, CustomCollectionCounter as st, ActorKeyPair as t, ActorHandleMapper as tt, RouteActivityOptions as u, InboxErrorHandler as ut, Federation as v, OutboxPermanentFailureHandler as vt, IdempotencyStrategy as w, SenderKeyPair as wt, FederationOptions as x, UnverifiedActivityReason as xt, FederationBuilder as y, SharedInboxKeyDispatcher as yt, createFederationBuilder as z };
|
|
@@ -96,10 +96,25 @@ function createInboxContext(args) {
|
|
|
96
96
|
data
|
|
97
97
|
})),
|
|
98
98
|
recipient: args.recipient ?? null,
|
|
99
|
-
forwardActivity: args.forwardActivity ?? ((
|
|
99
|
+
forwardActivity: args.forwardActivity ?? ((_forwarder, _recipients, _options) => {
|
|
100
100
|
throw new Error("Not implemented");
|
|
101
101
|
})
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
|
+
function createOutboxContext(args) {
|
|
105
|
+
const forwardActivity = args.forwardActivity ?? ((_forwarder, _recipients, _options) => {
|
|
106
|
+
throw new Error("Not implemented");
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
...createContext(args),
|
|
110
|
+
clone: args.clone ?? ((data) => createOutboxContext({
|
|
111
|
+
...args,
|
|
112
|
+
data
|
|
113
|
+
})),
|
|
114
|
+
identifier: args.identifier,
|
|
115
|
+
hasDeliveredActivity: args.hasDeliveredActivity ?? (() => false),
|
|
116
|
+
forwardActivity
|
|
117
|
+
};
|
|
118
|
+
}
|
|
104
119
|
//#endregion
|
|
105
|
-
export {
|
|
120
|
+
export { createOutboxContext as n, createRequestContext as r, createInboxContext as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { o as validateCryptoKey } from "./key-
|
|
5
|
-
import { n as doubleKnock } from "./http-
|
|
4
|
+
import { o as validateCryptoKey } from "./key-2MxqHz-F.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-BrF-JQov.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";
|