@fedify/fedify 1.4.0-dev.629 → 1.4.0-dev.632
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 +14 -0
- package/README.md +1 -1
- package/esm/deno.js +1 -1
- package/esm/federation/middleware.js +71 -20
- package/esm/vocab/vocab.js +176 -176
- package/package.json +1 -1
- package/types/federation/middleware.d.ts +20 -5
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/federation/queue.d.ts +1 -0
- package/types/federation/queue.d.ts.map +1 -1
- package/types/runtime/docloader.d.ts +32 -25
- package/types/runtime/docloader.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -8,6 +8,20 @@ Version 1.4.0
|
|
8
8
|
|
9
9
|
To be released.
|
10
10
|
|
11
|
+
- Document loader and context loader are now configurable with a factory
|
12
|
+
function for more flexibility.
|
13
|
+
|
14
|
+
- Deprecated `CreateFederationOptions.documentLoader` option.
|
15
|
+
Use `CreateFederationOptions.documentLoaderFactory` option instead.
|
16
|
+
- Deprecated `CreateFederationOptions.contextLoader` option.
|
17
|
+
Use `CreateFederationOptions.contextLoaderFactory` option instead.
|
18
|
+
- Added `DocumentLoaderFactory` type.
|
19
|
+
- Added `DocumentLoaderFactoryOptions` interface.
|
20
|
+
- Added the second parameter with `DocumentLoaderFactoryOptions` type
|
21
|
+
to `AuthenticatedDocumentLoaderFactory` type.
|
22
|
+
- `GetAuthenticatedDocumentLoaderOptions` interface became to extend
|
23
|
+
`DocumentLoaderFactoryOptions` interface.
|
24
|
+
|
11
25
|
- The `suppressError` option of Activity Vocabulary APIs,
|
12
26
|
`traverseCollection()` function, and `Context.traverseCollection()` method
|
13
27
|
now suppresses errors occurred JSON-LD processing.
|
package/README.md
CHANGED
package/esm/deno.js
CHANGED
@@ -56,8 +56,8 @@ export class FederationImpl {
|
|
56
56
|
inboxListeners;
|
57
57
|
inboxErrorHandler;
|
58
58
|
sharedInboxKeyDispatcher;
|
59
|
-
|
60
|
-
|
59
|
+
documentLoaderFactory;
|
60
|
+
contextLoaderFactory;
|
61
61
|
authenticatedDocumentLoaderFactory;
|
62
62
|
allowPrivateAddress;
|
63
63
|
userAgent;
|
@@ -68,6 +68,7 @@ export class FederationImpl {
|
|
68
68
|
inboxRetryPolicy;
|
69
69
|
tracerProvider;
|
70
70
|
constructor(options) {
|
71
|
+
const logger = getLogger(["fedify", "federation"]);
|
71
72
|
this.kv = options.kv;
|
72
73
|
this.kvPrefixes = {
|
73
74
|
...({
|
@@ -115,12 +116,42 @@ export class FederationImpl {
|
|
115
116
|
}
|
116
117
|
const { allowPrivateAddress, userAgent } = options;
|
117
118
|
this.allowPrivateAddress = allowPrivateAddress ?? false;
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
if (options.documentLoader != null) {
|
120
|
+
if (options.documentLoaderFactory != null) {
|
121
|
+
throw new TypeError("Cannot set both documentLoader and documentLoaderFactory options " +
|
122
|
+
"at a time; use documentLoaderFactory only.");
|
123
|
+
}
|
124
|
+
this.documentLoaderFactory = () => options.documentLoader;
|
125
|
+
logger.warn("The documentLoader option is deprecated; use documentLoaderFactory " +
|
126
|
+
"option instead.");
|
127
|
+
}
|
128
|
+
else {
|
129
|
+
this.documentLoaderFactory = options.documentLoaderFactory ??
|
130
|
+
((opts) => {
|
131
|
+
return kvCache({
|
132
|
+
loader: getDocumentLoader({
|
133
|
+
allowPrivateAddress: opts?.allowPrivateAddress ??
|
134
|
+
allowPrivateAddress,
|
135
|
+
userAgent: opts?.userAgent ?? userAgent,
|
136
|
+
}),
|
137
|
+
kv: options.kv,
|
138
|
+
prefix: this.kvPrefixes.remoteDocument,
|
139
|
+
});
|
140
|
+
});
|
141
|
+
}
|
142
|
+
if (options.contextLoader != null) {
|
143
|
+
if (options.contextLoaderFactory != null) {
|
144
|
+
throw new TypeError("Cannot set both contextLoader and contextLoaderFactory options " +
|
145
|
+
"at a time; use contextLoaderFactory only.");
|
146
|
+
}
|
147
|
+
this.contextLoaderFactory = () => options.contextLoader;
|
148
|
+
logger.warn("The contextLoader option is deprecated; use contextLoaderFactory " +
|
149
|
+
"option instead.");
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
this.contextLoaderFactory = options.contextLoaderFactory ??
|
153
|
+
this.documentLoaderFactory;
|
154
|
+
}
|
124
155
|
this.authenticatedDocumentLoaderFactory =
|
125
156
|
options.authenticatedDocumentLoaderFactory ??
|
126
157
|
((identity) => getAuthenticatedDocumentLoader(identity, {
|
@@ -252,11 +283,12 @@ export class FederationImpl {
|
|
252
283
|
}
|
253
284
|
catch (error) {
|
254
285
|
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
286
|
+
const loaderOptions = this.#getLoaderOptions(message.baseUrl);
|
255
287
|
const activity = await Activity.fromJsonLd(message.activity, {
|
256
|
-
contextLoader: this.
|
288
|
+
contextLoader: this.contextLoaderFactory(loaderOptions),
|
257
289
|
documentLoader: rsaKeyPair == null
|
258
|
-
? this.
|
259
|
-
: this.authenticatedDocumentLoaderFactory(rsaKeyPair),
|
290
|
+
? this.documentLoaderFactory(loaderOptions)
|
291
|
+
: this.authenticatedDocumentLoaderFactory(rsaKeyPair, loaderOptions),
|
260
292
|
tracerProvider: this.tracerProvider,
|
261
293
|
});
|
262
294
|
try {
|
@@ -435,11 +467,14 @@ export class FederationImpl {
|
|
435
467
|
url.hash = "";
|
436
468
|
url.search = "";
|
437
469
|
}
|
470
|
+
const loaderOptions = this.#getLoaderOptions(url.origin);
|
438
471
|
const ctxOptions = {
|
439
472
|
url,
|
440
473
|
federation: this,
|
441
474
|
data: contextData,
|
442
|
-
documentLoader: opts.documentLoader ??
|
475
|
+
documentLoader: opts.documentLoader ??
|
476
|
+
this.documentLoaderFactory(loaderOptions),
|
477
|
+
contextLoader: this.contextLoaderFactory(loaderOptions),
|
443
478
|
};
|
444
479
|
if (request == null)
|
445
480
|
return new ContextImpl(ctxOptions);
|
@@ -450,6 +485,18 @@ export class FederationImpl {
|
|
450
485
|
invokedFromObjectDispatcher: opts.invokedFromObjectDispatcher,
|
451
486
|
});
|
452
487
|
}
|
488
|
+
#getLoaderOptions(origin) {
|
489
|
+
origin = typeof origin === "string"
|
490
|
+
? new URL(origin).origin
|
491
|
+
: origin.origin;
|
492
|
+
return {
|
493
|
+
allowPrivateAddress: this.allowPrivateAddress,
|
494
|
+
userAgent: typeof this.userAgent === "string" ? this.userAgent : {
|
495
|
+
url: origin,
|
496
|
+
...this.userAgent,
|
497
|
+
},
|
498
|
+
};
|
499
|
+
}
|
453
500
|
setNodeInfoDispatcher(path, dispatcher) {
|
454
501
|
if (this.router.has("nodeInfo")) {
|
455
502
|
throw new RouterError("NodeInfo dispatcher already set.");
|
@@ -1038,7 +1085,7 @@ export class FederationImpl {
|
|
1038
1085
|
}
|
1039
1086
|
async sendActivity(keys, recipients, activity, options, span) {
|
1040
1087
|
const logger = getLogger(["fedify", "federation", "outbox"]);
|
1041
|
-
const { preferSharedInbox, immediate, excludeBaseUris, collectionSync, contextData, } = options;
|
1088
|
+
const { preferSharedInbox, immediate, excludeBaseUris, collectionSync, contextData, origin, } = options;
|
1042
1089
|
if (keys.length < 1) {
|
1043
1090
|
throw new TypeError("The sender's keys must not be empty.");
|
1044
1091
|
}
|
@@ -1076,6 +1123,7 @@ export class FederationImpl {
|
|
1076
1123
|
else if (keys.length < 1) {
|
1077
1124
|
throw new TypeError("The keys must not be empty.");
|
1078
1125
|
}
|
1126
|
+
const contextLoader = this.contextLoaderFactory(this.#getLoaderOptions(origin));
|
1079
1127
|
const activityId = activity.id.href;
|
1080
1128
|
let proofCreated = false;
|
1081
1129
|
let rsaKey = null;
|
@@ -1087,7 +1135,7 @@ export class FederationImpl {
|
|
1087
1135
|
}
|
1088
1136
|
if (privateKey.algorithm.name === "Ed25519") {
|
1089
1137
|
activity = await signObject(activity, privateKey, keyId, {
|
1090
|
-
contextLoader
|
1138
|
+
contextLoader,
|
1091
1139
|
tracerProvider: this.tracerProvider,
|
1092
1140
|
});
|
1093
1141
|
proofCreated = true;
|
@@ -1095,7 +1143,7 @@ export class FederationImpl {
|
|
1095
1143
|
}
|
1096
1144
|
let jsonLd = await activity.toJsonLd({
|
1097
1145
|
format: "compact",
|
1098
|
-
contextLoader
|
1146
|
+
contextLoader,
|
1099
1147
|
});
|
1100
1148
|
if (rsaKey == null) {
|
1101
1149
|
logger.warn("No supported key found to create a Linked Data signature for " +
|
@@ -1111,7 +1159,7 @@ export class FederationImpl {
|
|
1111
1159
|
}
|
1112
1160
|
else {
|
1113
1161
|
jsonLd = await signJsonLd(jsonLd, rsaKey.privateKey, rsaKey.keyId, {
|
1114
|
-
contextLoader
|
1162
|
+
contextLoader,
|
1115
1163
|
tracerProvider: this.tracerProvider,
|
1116
1164
|
});
|
1117
1165
|
}
|
@@ -1167,6 +1215,7 @@ export class FederationImpl {
|
|
1167
1215
|
const message = {
|
1168
1216
|
type: "outbox",
|
1169
1217
|
id: dntShim.crypto.randomUUID(),
|
1218
|
+
baseUrl: origin,
|
1170
1219
|
keys: keyJwkPairs,
|
1171
1220
|
activity: jsonLd,
|
1172
1221
|
activityId: activity.id?.href,
|
@@ -1458,12 +1507,14 @@ export class ContextImpl {
|
|
1458
1507
|
federation;
|
1459
1508
|
data;
|
1460
1509
|
documentLoader;
|
1510
|
+
contextLoader;
|
1461
1511
|
invokedFromActorKeyPairsDispatcher;
|
1462
|
-
constructor({ url, federation, data, documentLoader, invokedFromActorKeyPairsDispatcher, }) {
|
1512
|
+
constructor({ url, federation, data, documentLoader, contextLoader, invokedFromActorKeyPairsDispatcher, }) {
|
1463
1513
|
this.url = url;
|
1464
1514
|
this.federation = federation;
|
1465
1515
|
this.data = data;
|
1466
1516
|
this.documentLoader = documentLoader;
|
1517
|
+
this.contextLoader = contextLoader;
|
1467
1518
|
this.invokedFromActorKeyPairsDispatcher =
|
1468
1519
|
invokedFromActorKeyPairsDispatcher;
|
1469
1520
|
}
|
@@ -1473,6 +1524,7 @@ export class ContextImpl {
|
|
1473
1524
|
federation: this.federation,
|
1474
1525
|
data: this.data,
|
1475
1526
|
documentLoader: this.documentLoader,
|
1527
|
+
contextLoader: this.contextLoader,
|
1476
1528
|
invokedFromActorKeyPairsDispatcher: this.invokedFromActorKeyPairsDispatcher,
|
1477
1529
|
});
|
1478
1530
|
}
|
@@ -1485,9 +1537,6 @@ export class ContextImpl {
|
|
1485
1537
|
get origin() {
|
1486
1538
|
return this.url.origin;
|
1487
1539
|
}
|
1488
|
-
get contextLoader() {
|
1489
|
-
return this.federation.contextLoader;
|
1490
|
-
}
|
1491
1540
|
get tracerProvider() {
|
1492
1541
|
return this.federation.tracerProvider;
|
1493
1542
|
}
|
@@ -1928,6 +1977,7 @@ export class ContextImpl {
|
|
1928
1977
|
}
|
1929
1978
|
const opts = {
|
1930
1979
|
contextData: this.data,
|
1980
|
+
origin: this.origin,
|
1931
1981
|
...options,
|
1932
1982
|
};
|
1933
1983
|
let expandedRecipients;
|
@@ -2322,6 +2372,7 @@ export class InboxContextImpl extends ContextImpl {
|
|
2322
2372
|
const message = {
|
2323
2373
|
type: "outbox",
|
2324
2374
|
id: dntShim.crypto.randomUUID(),
|
2375
|
+
baseUrl: this.origin,
|
2325
2376
|
keys: keyJwkPairs,
|
2326
2377
|
activity: this.activity,
|
2327
2378
|
activityId: this.activityId,
|