@fedify/fedify 1.4.0-dev.633 → 1.4.0-dev.634
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 +6 -0
- package/esm/compat/transformers.js +20 -10
- package/esm/deno.js +1 -1
- package/esm/federation/middleware.js +8 -9
- package/esm/vocab/vocab.js +176 -176
- package/package.json +1 -1
- package/types/compat/transformers.d.ts +15 -6
- package/types/compat/transformers.d.ts.map +1 -1
- package/types/compat/types.d.ts +2 -1
- package/types/compat/types.d.ts.map +1 -1
- package/types/federation/middleware.d.ts +7 -7
- package/types/federation/middleware.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -21,6 +21,12 @@ To be released.
|
|
21
21
|
to `AuthenticatedDocumentLoaderFactory` type.
|
22
22
|
- `GetAuthenticatedDocumentLoaderOptions` interface became to extend
|
23
23
|
`DocumentLoaderFactoryOptions` interface.
|
24
|
+
- Added a type parameter `TContextData` to `CreateFederationOptions`
|
25
|
+
interface.
|
26
|
+
- Fedify now assigns a random-generated *http:*/*https:* URI to
|
27
|
+
activities if these do not have explicit `id` properties. This behavior
|
28
|
+
can be disabled by excluding `autoIdAssigner()` from
|
29
|
+
the `CreateFederationOptions.activityTransformers` option.
|
24
30
|
|
25
31
|
- Introduced `ActivityTransformer`s for adjusting outgoing activities
|
26
32
|
before sending them so that some ActivityPub implementations with quirks
|
@@ -6,19 +6,23 @@ const logger = getLogger(["fedify", "compat", "transformers"]);
|
|
6
6
|
* does not already have one. This is useful for ensuring that activities
|
7
7
|
* have an ID before they are sent to other servers.
|
8
8
|
*
|
9
|
-
* The generated ID is a
|
9
|
+
* The generated ID is an origin URI with a fragment which contains an activity
|
10
|
+
* type name with a random UUID:
|
10
11
|
*
|
11
12
|
* ```
|
12
|
-
*
|
13
|
+
* https://example.com/#Follow/12345678-1234-5678-1234-567812345678
|
13
14
|
* ```
|
15
|
+
*
|
16
|
+
* @typeParam TContextData The type of the context data.
|
14
17
|
* @param activity The activity to assign an ID to.
|
18
|
+
* @param context The context of the activity.
|
15
19
|
* @return The activity with an ID assigned.
|
16
20
|
* @since 1.4.0
|
17
21
|
*/
|
18
|
-
export function autoIdAssigner(activity) {
|
22
|
+
export function autoIdAssigner(activity, context) {
|
19
23
|
if (activity.id != null)
|
20
24
|
return activity;
|
21
|
-
const id = new URL(
|
25
|
+
const id = new URL(`/#${activity.constructor.name}/${dntShim.crypto.randomUUID()}`, context.origin);
|
22
26
|
logger.warn("As the activity to send does not have an id, a new id {id} has " +
|
23
27
|
"been generated for it. However, it is recommended to explicitly " +
|
24
28
|
"set the id for the activity.", { id: id.href });
|
@@ -63,11 +67,13 @@ export function autoIdAssigner(activity) {
|
|
63
67
|
*
|
64
68
|
* As some ActivityPub implementations like Threads fail to deal with inlined
|
65
69
|
* actor objects, this transformer can be used to work around this issue.
|
70
|
+
* @typeParam TContextData The type of the context data.
|
66
71
|
* @param activity The activity to dehydrate the actor property of.
|
72
|
+
* @param context The context of the activity.
|
67
73
|
* @returns The dehydrated activity.
|
68
74
|
* @since 1.4.0
|
69
75
|
*/
|
70
|
-
export function actorDehydrator(activity) {
|
76
|
+
export function actorDehydrator(activity, _context) {
|
71
77
|
if (activity.actorIds.length < 1)
|
72
78
|
return activity;
|
73
79
|
return activity.clone({
|
@@ -75,11 +81,15 @@ export function actorDehydrator(activity) {
|
|
75
81
|
});
|
76
82
|
}
|
77
83
|
/**
|
78
|
-
*
|
84
|
+
* Gets the default activity transformers that are applied to all outgoing
|
79
85
|
* activities.
|
86
|
+
* @typeParam TContextData The type of the context data.
|
87
|
+
* @returns The default activity transformers.
|
80
88
|
* @since 1.4.0
|
81
89
|
*/
|
82
|
-
export
|
83
|
-
|
84
|
-
|
85
|
-
|
90
|
+
export function getDefaultActivityTransformers() {
|
91
|
+
return [
|
92
|
+
autoIdAssigner,
|
93
|
+
actorDehydrator,
|
94
|
+
];
|
95
|
+
}
|
package/esm/deno.js
CHANGED
@@ -3,7 +3,7 @@ import { verifyObject } from "../mod.js";
|
|
3
3
|
import { getLogger, withContext } from "@logtape/logtape";
|
4
4
|
import { context, propagation, SpanKind, SpanStatusCode, trace, } from "@opentelemetry/api";
|
5
5
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL, } from "@opentelemetry/semantic-conventions";
|
6
|
-
import {
|
6
|
+
import { getDefaultActivityTransformers } from "../compat/transformers.js";
|
7
7
|
import metadata from "../deno.js";
|
8
8
|
import { getNodeInfo } from "../nodeinfo/client.js";
|
9
9
|
import { handleNodeInfo, handleNodeInfoJrd } from "../nodeinfo/handler.js";
|
@@ -169,7 +169,7 @@ export class FederationImpl {
|
|
169
169
|
this.inboxRetryPolicy = options.inboxRetryPolicy ??
|
170
170
|
createExponentialBackoffPolicy();
|
171
171
|
this.activityTransformers = options.activityTransformers ??
|
172
|
-
|
172
|
+
getDefaultActivityTransformers();
|
173
173
|
this.tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
174
174
|
}
|
175
175
|
#getTracer() {
|
@@ -1089,7 +1089,7 @@ export class FederationImpl {
|
|
1089
1089
|
}
|
1090
1090
|
async sendActivity(keys, recipients, activity, options, span) {
|
1091
1091
|
const logger = getLogger(["fedify", "federation", "outbox"]);
|
1092
|
-
const { preferSharedInbox, immediate, excludeBaseUris, collectionSync,
|
1092
|
+
const { preferSharedInbox, immediate, excludeBaseUris, collectionSync, context: ctx, } = options;
|
1093
1093
|
if (keys.length < 1) {
|
1094
1094
|
throw new TypeError("The sender's keys must not be empty.");
|
1095
1095
|
}
|
@@ -1097,7 +1097,7 @@ export class FederationImpl {
|
|
1097
1097
|
validateCryptoKey(privateKey, "private");
|
1098
1098
|
}
|
1099
1099
|
for (const activityTransformer of this.activityTransformers) {
|
1100
|
-
activity = activityTransformer(activity);
|
1100
|
+
activity = activityTransformer(activity, ctx);
|
1101
1101
|
}
|
1102
1102
|
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
1103
1103
|
if (activity.actorId == null) {
|
@@ -1123,7 +1123,7 @@ export class FederationImpl {
|
|
1123
1123
|
else if (keys.length < 1) {
|
1124
1124
|
throw new TypeError("The keys must not be empty.");
|
1125
1125
|
}
|
1126
|
-
const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(origin));
|
1126
|
+
const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(ctx.origin));
|
1127
1127
|
const activityId = activity.id.href;
|
1128
1128
|
let proofCreated = false;
|
1129
1129
|
let rsaKey = null;
|
@@ -1207,7 +1207,7 @@ export class FederationImpl {
|
|
1207
1207
|
keyJwkPairs.push({ keyId: keyId.href, privateKey: privateKeyJwk });
|
1208
1208
|
}
|
1209
1209
|
if (!this.manuallyStartQueue)
|
1210
|
-
this.#startQueue(
|
1210
|
+
this.#startQueue(ctx.data);
|
1211
1211
|
const carrier = {};
|
1212
1212
|
propagation.inject(context.active(), carrier);
|
1213
1213
|
const promises = [];
|
@@ -1215,7 +1215,7 @@ export class FederationImpl {
|
|
1215
1215
|
const message = {
|
1216
1216
|
type: "outbox",
|
1217
1217
|
id: dntShim.crypto.randomUUID(),
|
1218
|
-
baseUrl: origin,
|
1218
|
+
baseUrl: ctx.origin,
|
1219
1219
|
keys: keyJwkPairs,
|
1220
1220
|
activity: jsonLd,
|
1221
1221
|
activityId: activity.id?.href,
|
@@ -1976,8 +1976,7 @@ export class ContextImpl {
|
|
1976
1976
|
keys = [sender];
|
1977
1977
|
}
|
1978
1978
|
const opts = {
|
1979
|
-
|
1980
|
-
origin: this.origin,
|
1979
|
+
context: this,
|
1981
1980
|
...options,
|
1982
1981
|
};
|
1983
1982
|
let expandedRecipients;
|