@fedify/fedify 1.4.0-dev.630 → 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 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/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "@fedify/fedify",
3
- "version": "1.4.0-dev.630+203d67a0",
3
+ "version": "1.4.0-dev.632+c8474d94",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./mod.ts",
@@ -56,8 +56,8 @@ export class FederationImpl {
56
56
  inboxListeners;
57
57
  inboxErrorHandler;
58
58
  sharedInboxKeyDispatcher;
59
- documentLoader;
60
- contextLoader;
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
- this.documentLoader = options.documentLoader ?? kvCache({
119
- loader: getDocumentLoader({ allowPrivateAddress, userAgent }),
120
- kv: options.kv,
121
- prefix: this.kvPrefixes.remoteDocument,
122
- });
123
- this.contextLoader = options.contextLoader ?? this.documentLoader;
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.contextLoader,
288
+ contextLoader: this.contextLoaderFactory(loaderOptions),
257
289
  documentLoader: rsaKeyPair == null
258
- ? this.documentLoader
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 ?? this.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: this.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: this.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: this.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,