@fedify/fedify 1.0.0-dev.402 → 1.0.0-dev.404
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
});
|