@fedify/fedify 1.0.0-dev.402 → 1.0.0-dev.404
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/CHANGES.md +66 -0
- package/esm/federation/handler.js +27 -27
- package/esm/federation/middleware.js +347 -134
- package/esm/webfinger/handler.js +12 -12
- package/package.json +1 -1
- package/types/federation/callback.d.ts +32 -15
- package/types/federation/callback.d.ts.map +1 -1
- package/types/federation/context.d.ts +96 -57
- package/types/federation/context.d.ts.map +1 -1
- package/types/federation/federation.d.ts +33 -34
- package/types/federation/federation.d.ts.map +1 -1
- package/types/federation/handler.d.ts +6 -6
- package/types/federation/handler.d.ts.map +1 -1
- package/types/federation/middleware.d.ts +39 -23
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/federation/queue.d.ts +1 -1
- package/types/federation/queue.d.ts.map +1 -1
- package/types/webfinger/handler.d.ts +1 -1
package/CHANGES.md
CHANGED
@@ -8,6 +8,72 @@ Version 1.0.0
|
|
8
8
|
|
9
9
|
To be released.
|
10
10
|
|
11
|
+
- The term `handle` for dispatching actors is deprecated in favor of
|
12
|
+
`identifier`.
|
13
|
+
|
14
|
+
- The URI template for the following methods now accepts variable
|
15
|
+
`{identifier}` instead of `{handle}`:
|
16
|
+
|
17
|
+
- `Federation.setActorDispatcher()`
|
18
|
+
- `Federation.setInboxDispatcher()`
|
19
|
+
- `Federation.setOutboxDispatcher()`
|
20
|
+
- `Federation.setFollowingDispatcher()`
|
21
|
+
- `Federation.setFollowersDispatcher()`
|
22
|
+
- `Federation.setLikedDispatcher()`
|
23
|
+
- `Federation.setFeaturedDispatcher()`
|
24
|
+
- `Federation.setFeaturedTagsDispatcher()`
|
25
|
+
- `Federation.setInboxListeners()`
|
26
|
+
|
27
|
+
The `{handle}` variable is deprecated, and it will be removed in
|
28
|
+
the future.
|
29
|
+
- The type of `Federation.setActorDispatcher()` method's first parameter
|
30
|
+
became ```${string}{identifier}${string}` |
|
31
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
32
|
+
- The type of `Federation.setInboxDispatcher()` method's first parameter
|
33
|
+
became ```${string}{identifier}${string}` |
|
34
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
35
|
+
- The type of `Federation.setOutboxDispatcher()` method's first parameter
|
36
|
+
became ```${string}{identifier}${string}` |
|
37
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
38
|
+
- The type of `Federation.setFollowingDispatcher()` method's first
|
39
|
+
parameter became ```${string}{identifier}${string}` |
|
40
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
41
|
+
- The type of `Federation.setFollowersDispatcher()` method's first
|
42
|
+
parameter became ```${string}{identifier}${string}` |
|
43
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
44
|
+
- The type of `Federation.setLikedDispatcher()` method's first parameter
|
45
|
+
became ```${string}{identifier}${string}` |
|
46
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
47
|
+
- The type of `Federation.setFeaturedDispatcher()` method's first
|
48
|
+
parameter became ```${string}{identifier}${string}` |
|
49
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
50
|
+
- The type of `Federation.setFeaturedTagsDispatcher()` method's first
|
51
|
+
parameter became ```${string}{identifier}${string}` |
|
52
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
53
|
+
- The type of `Federation.setInboxListeners()` method's first parameter
|
54
|
+
became ```${string}{identifier}${string}` |
|
55
|
+
`${string}{handle}${string}``` (was ```${string}{handle}${string}```).
|
56
|
+
- The type of `Context.getDocumentLoader()` method's first parameter
|
57
|
+
became `{ identifier: string } | { username: string } | { handle:
|
58
|
+
string } | { keyId: URL; privateKey: CryptoKey }` (was `{ handle:
|
59
|
+
string } | { keyId: URL; privateKey: CryptoKey }`).
|
60
|
+
- Passing `{ handle: string }` to `Context.getDocumentLoader()` method is
|
61
|
+
deprecated in favor of `{ username: string }`.
|
62
|
+
- The type of `Context.sendActivity()` method's first parameter became
|
63
|
+
`SenderKeyPair | SenderKeyPair[] | { identifier: string } | { handle:
|
64
|
+
string }` (was `SenderKeyPair | SenderKeyPair[] | { handle: string }`).
|
65
|
+
- All properties of `ParseUriResult` type became readonly.
|
66
|
+
- Added `identifier` properties next to `handle` properties in
|
67
|
+
`ParseUriResult` type.
|
68
|
+
- The `handle` properties of `ParseUriResult` type are deprecated in favor
|
69
|
+
of `identifier` properties.
|
70
|
+
- The return type of `SharedInboxKeyDispatcher` callback type became
|
71
|
+
`SenderKeyPair | { identifier: string } | { username: string } |
|
72
|
+
{ handle: string } | null | Promise<SenderKeyPair | { identifier:
|
73
|
+
string } | { username: string } | { handle: string } | null>`
|
74
|
+
(was `SenderKeyPair | { handle: string } | null |
|
75
|
+
Promise<SenderKeyPair | { handle: string } | null>`).
|
76
|
+
|
11
77
|
- Fedify now supports [Linked Data Signatures], which is outdated but still
|
12
78
|
widely used in the fediverse.
|
13
79
|
|
@@ -17,15 +17,15 @@ export function acceptsJsonLd(request) {
|
|
17
17
|
types.includes("application/ld+json") ||
|
18
18
|
types.includes("application/json");
|
19
19
|
}
|
20
|
-
export async function handleActor(request, {
|
20
|
+
export async function handleActor(request, { identifier, context, actorDispatcher, authorizePredicate, onNotFound, onNotAcceptable, onUnauthorized, }) {
|
21
21
|
const logger = getLogger(["fedify", "federation", "actor"]);
|
22
22
|
if (actorDispatcher == null) {
|
23
|
-
logger.debug("Actor dispatcher is not set.", {
|
23
|
+
logger.debug("Actor dispatcher is not set.", { identifier });
|
24
24
|
return await onNotFound(request);
|
25
25
|
}
|
26
|
-
const actor = await actorDispatcher(context,
|
26
|
+
const actor = await actorDispatcher(context, identifier);
|
27
27
|
if (actor == null) {
|
28
|
-
logger.debug("Actor {
|
28
|
+
logger.debug("Actor {identifier} not found.", { identifier });
|
29
29
|
return await onNotFound(request);
|
30
30
|
}
|
31
31
|
if (!acceptsJsonLd(request))
|
@@ -33,7 +33,7 @@ export async function handleActor(request, { handle, context, actorDispatcher, a
|
|
33
33
|
if (authorizePredicate != null) {
|
34
34
|
const key = await context.getSignedKey();
|
35
35
|
const keyOwner = await context.getSignedKeyOwner();
|
36
|
-
if (!await authorizePredicate(context,
|
36
|
+
if (!await authorizePredicate(context, identifier, key, keyOwner)) {
|
37
37
|
return await onUnauthorized(request);
|
38
38
|
}
|
39
39
|
}
|
@@ -68,18 +68,18 @@ export async function handleObject(request, { values, context, objectDispatcher,
|
|
68
68
|
},
|
69
69
|
});
|
70
70
|
}
|
71
|
-
export async function handleCollection(request, { name,
|
71
|
+
export async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, onUnauthorized, onNotFound, onNotAcceptable, }) {
|
72
72
|
if (collectionCallbacks == null)
|
73
73
|
return await onNotFound(request);
|
74
74
|
const url = new URL(request.url);
|
75
75
|
const cursor = url.searchParams.get("cursor");
|
76
76
|
let collection;
|
77
|
-
const baseUri = uriGetter(
|
77
|
+
const baseUri = uriGetter(identifier);
|
78
78
|
if (cursor == null) {
|
79
|
-
const firstCursor = await collectionCallbacks.firstCursor?.(context,
|
80
|
-
const totalItems = await collectionCallbacks.counter?.(context,
|
79
|
+
const firstCursor = await collectionCallbacks.firstCursor?.(context, identifier);
|
80
|
+
const totalItems = await collectionCallbacks.counter?.(context, identifier);
|
81
81
|
if (firstCursor == null) {
|
82
|
-
const page = await collectionCallbacks.dispatcher(context,
|
82
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, null, filter);
|
83
83
|
if (page == null)
|
84
84
|
return await onNotFound(request);
|
85
85
|
const { items } = page;
|
@@ -90,7 +90,7 @@ export async function handleCollection(request, { name, handle, uriGetter, filte
|
|
90
90
|
});
|
91
91
|
}
|
92
92
|
else {
|
93
|
-
const lastCursor = await collectionCallbacks.lastCursor?.(context,
|
93
|
+
const lastCursor = await collectionCallbacks.lastCursor?.(context, identifier);
|
94
94
|
const first = new URL(context.url);
|
95
95
|
first.searchParams.set("cursor", firstCursor);
|
96
96
|
let last = null;
|
@@ -109,7 +109,7 @@ export async function handleCollection(request, { name, handle, uriGetter, filte
|
|
109
109
|
else {
|
110
110
|
const uri = new URL(baseUri);
|
111
111
|
uri.searchParams.set("cursor", cursor);
|
112
|
-
const page = await collectionCallbacks.dispatcher(context,
|
112
|
+
const page = await collectionCallbacks.dispatcher(context, identifier, cursor, filter);
|
113
113
|
if (page == null)
|
114
114
|
return await onNotFound(request);
|
115
115
|
const { items, prevCursor, nextCursor } = page;
|
@@ -138,7 +138,7 @@ export async function handleCollection(request, { name, handle, uriGetter, filte
|
|
138
138
|
if (collectionCallbacks.authorizePredicate != null) {
|
139
139
|
const key = await context.getSignedKey();
|
140
140
|
const keyOwner = await context.getSignedKeyOwner();
|
141
|
-
if (!await collectionCallbacks.authorizePredicate(context,
|
141
|
+
if (!await collectionCallbacks.authorizePredicate(context, identifier, key, keyOwner)) {
|
142
142
|
return await onUnauthorized(request);
|
143
143
|
}
|
144
144
|
}
|
@@ -175,16 +175,16 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
|
|
175
175
|
}
|
176
176
|
return result;
|
177
177
|
}
|
178
|
-
export async function handleInbox(request, {
|
178
|
+
export async function handleInbox(request, { identifier, context, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, }) {
|
179
179
|
const logger = getLogger(["fedify", "federation", "inbox"]);
|
180
180
|
if (actorDispatcher == null) {
|
181
|
-
logger.error("Actor dispatcher is not set.", {
|
181
|
+
logger.error("Actor dispatcher is not set.", { identifier });
|
182
182
|
return await onNotFound(request);
|
183
183
|
}
|
184
|
-
else if (
|
185
|
-
const actor = await actorDispatcher(context,
|
184
|
+
else if (identifier != null) {
|
185
|
+
const actor = await actorDispatcher(context, identifier);
|
186
186
|
if (actor == null) {
|
187
|
-
logger.error("Actor {
|
187
|
+
logger.error("Actor {identifier} not found.", { identifier });
|
188
188
|
return await onNotFound(request);
|
189
189
|
}
|
190
190
|
}
|
@@ -193,7 +193,7 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
193
193
|
json = await request.clone().json();
|
194
194
|
}
|
195
195
|
catch (error) {
|
196
|
-
logger.error("Failed to parse JSON:\n{error}", {
|
196
|
+
logger.error("Failed to parse JSON:\n{error}", { identifier, error });
|
197
197
|
try {
|
198
198
|
await inboxErrorHandler?.(context, error);
|
199
199
|
}
|
@@ -238,11 +238,11 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
238
238
|
const jsonWithoutSig = detachSignature(json);
|
239
239
|
let activity = null;
|
240
240
|
if (ldSigVerified) {
|
241
|
-
logger.debug("Linked Data Signatures are verified.", {
|
241
|
+
logger.debug("Linked Data Signatures are verified.", { identifier, json });
|
242
242
|
activity = await Activity.fromJsonLd(jsonWithoutSig, context);
|
243
243
|
}
|
244
244
|
else {
|
245
|
-
logger.debug("Linked Data Signatures are not verified.", {
|
245
|
+
logger.debug("Linked Data Signatures are not verified.", { identifier, json });
|
246
246
|
try {
|
247
247
|
activity = await verifyObject(Activity, jsonWithoutSig, {
|
248
248
|
contextLoader: context.contextLoader,
|
@@ -252,7 +252,7 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
252
252
|
}
|
253
253
|
catch (error) {
|
254
254
|
logger.error("Failed to parse activity:\n{error}", {
|
255
|
-
|
255
|
+
identifier,
|
256
256
|
json,
|
257
257
|
error,
|
258
258
|
});
|
@@ -268,10 +268,10 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
268
268
|
});
|
269
269
|
}
|
270
270
|
if (activity == null) {
|
271
|
-
logger.debug("Object Integrity Proofs are not verified.", {
|
271
|
+
logger.debug("Object Integrity Proofs are not verified.", { identifier, json });
|
272
272
|
}
|
273
273
|
else {
|
274
|
-
logger.debug("Object Integrity Proofs are verified.", {
|
274
|
+
logger.debug("Object Integrity Proofs are verified.", { identifier, json });
|
275
275
|
}
|
276
276
|
}
|
277
277
|
let httpSigKey = null;
|
@@ -284,7 +284,7 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
284
284
|
keyCache,
|
285
285
|
});
|
286
286
|
if (key == null) {
|
287
|
-
logger.error("Failed to verify the request's HTTP Signatures.", {
|
287
|
+
logger.error("Failed to verify the request's HTTP Signatures.", { identifier });
|
288
288
|
const response = new Response("Failed to verify the request signature.", {
|
289
289
|
status: 401,
|
290
290
|
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
@@ -292,7 +292,7 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
292
292
|
return response;
|
293
293
|
}
|
294
294
|
else {
|
295
|
-
logger.debug("HTTP Signatures are verified.", {
|
295
|
+
logger.debug("HTTP Signatures are verified.", { identifier });
|
296
296
|
}
|
297
297
|
httpSigKey = key;
|
298
298
|
}
|
@@ -339,7 +339,7 @@ export async function handleInbox(request, { handle, context, inboxContextFactor
|
|
339
339
|
type: "inbox",
|
340
340
|
baseUrl: request.url,
|
341
341
|
activity: json,
|
342
|
-
|
342
|
+
identifier,
|
343
343
|
attempt: 0,
|
344
344
|
started: new Date().toISOString(),
|
345
345
|
});
|