@fedify/fedify 2.3.12 → 2.3.14

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.
Files changed (69) hide show
  1. package/dist/{assert_rejects-DN60FHPX.mjs → assert_rejects-D1HYAik3.mjs} +2 -20
  2. package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-BbSMEFKo.mjs} +19 -1
  3. package/dist/{builder-B6ixdT3y.mjs → builder-C6yXExXl.mjs} +2 -2
  4. package/dist/compat/transformers.test.mjs +2 -2
  5. package/dist/{deno-D4dcoVfF.mjs → deno-y3L4Oa94.mjs} +1 -1
  6. package/dist/{docloader-NOKfswJV.mjs → docloader-yuyzZC9a.mjs} +6 -2
  7. package/dist/federation/builder.test.mjs +3 -3
  8. package/dist/federation/circuit-breaker.test.mjs +3 -3
  9. package/dist/federation/collection.test.mjs +1 -1
  10. package/dist/federation/handler.test.mjs +262 -9
  11. package/dist/federation/idempotency.test.mjs +3 -3
  12. package/dist/federation/inbox.test.mjs +25 -1
  13. package/dist/federation/keycache.test.mjs +19 -8
  14. package/dist/federation/kv.test.mjs +1 -1
  15. package/dist/federation/metrics.test.mjs +3 -3
  16. package/dist/federation/middleware.test.mjs +177 -15
  17. package/dist/federation/mod.cjs +1 -1
  18. package/dist/federation/mod.js +1 -1
  19. package/dist/federation/mq.test.mjs +4 -3
  20. package/dist/federation/negotiation.test.mjs +4 -4
  21. package/dist/federation/retry.test.mjs +1 -1
  22. package/dist/federation/router.test.mjs +3 -4
  23. package/dist/federation/send.test.mjs +7 -6
  24. package/dist/federation/temporal.test.mjs +4 -4
  25. package/dist/federation/webfinger.test.mjs +2 -2
  26. package/dist/{http-HjidyDfF.mjs → http-BCSf1KIY.mjs} +3 -3
  27. package/dist/{http-D_Xrr6kp.cjs → http-D77Wjrcg.cjs} +17 -3
  28. package/dist/{http-DkyUBs_T.js → http-DNM9KyIO.js} +17 -3
  29. package/dist/inbox-NObX26c9.mjs +180 -0
  30. package/dist/{key-Dg-NXm4K.mjs → key-APURZ0ky.mjs} +18 -4
  31. package/dist/{keycache-Dkc_sflV.mjs → keycache-BimEQucx.mjs} +1 -1
  32. package/dist/{kv-cache-BwnC6JGt.cjs → kv-cache-Bg4utAuv.cjs} +5 -1
  33. package/dist/{kv-cache-BpVwvcSI.mjs → kv-cache-C69dzgQi.mjs} +1 -1
  34. package/dist/{kv-cache-BhGeZk_o.js → kv-cache-LBCwHNLu.js} +5 -1
  35. package/dist/{ld-C1wveXXf.mjs → ld-BoLqbDaL.mjs} +3 -3
  36. package/dist/{metrics-cIaMxG0v.mjs → metrics-DBSl8wEr.mjs} +1 -1
  37. package/dist/{middleware-DhOFTXmo.cjs → middleware-BQUQ0pPl.cjs} +107 -35
  38. package/dist/{middleware-CnrzVu9i.js → middleware-CRd1JmuL.js} +107 -35
  39. package/dist/{middleware-I-XlrRVl.mjs → middleware-CZ8tI1qL.mjs} +97 -195
  40. package/dist/{middleware-VxPpU0h_.mjs → middleware-DAqo2eOY.mjs} +1 -1
  41. package/dist/mod.cjs +4 -4
  42. package/dist/mod.js +4 -4
  43. package/dist/nodeinfo/client.test.mjs +2 -2
  44. package/dist/nodeinfo/handler.test.mjs +2 -2
  45. package/dist/nodeinfo/types.test.mjs +2 -2
  46. package/dist/otel/exporter.test.mjs +1 -1
  47. package/dist/{owner-CFKfE85G.mjs → owner-DjKvngeb.mjs} +2 -2
  48. package/dist/{proof-DBxu6g2K.cjs → proof-CWTnYhjS.cjs} +1 -1
  49. package/dist/{proof-DtpGEj0u.mjs → proof-D2oFOdNA.mjs} +3 -3
  50. package/dist/{proof-HU__qtUD.js → proof-s9sy44kx.js} +1 -1
  51. package/dist/{send-CwMea5r6.mjs → send-xDK5UnL-.mjs} +3 -3
  52. package/dist/sig/http.test.mjs +7 -7
  53. package/dist/sig/key.test.mjs +200 -6
  54. package/dist/sig/ld.test.mjs +50 -5
  55. package/dist/sig/mod.cjs +2 -2
  56. package/dist/sig/mod.js +2 -2
  57. package/dist/sig/owner.test.mjs +49 -4
  58. package/dist/sig/proof.test.mjs +56 -4
  59. package/dist/{std__assert-BvGuO4xO.mjs → std__assert-BjJn2daJ.mjs} +2 -2
  60. package/dist/{temporal-ClSXyHyu.mjs → temporal-C6icc5n9.mjs} +1 -1
  61. package/dist/utils/docloader.test.mjs +178 -39
  62. package/dist/utils/kv-cache.test.mjs +1 -1
  63. package/dist/utils/mod.cjs +1 -1
  64. package/dist/utils/mod.js +1 -1
  65. package/package.json +6 -6
  66. /package/dist/{assert-jSdZMYam.mjs → assert-CEO06XCw.mjs} +0 -0
  67. /package/dist/{circuit-breaker-test-utils-Dm5MM6l9.mjs → circuit-breaker-test-utils-CAdwjgMi.mjs} +0 -0
  68. /package/dist/{negotiation-CDW-_gUU.mjs → negotiation-DDstyBvc.mjs} +0 -0
  69. /package/dist/{retry-_VvV0h9f.mjs → retry-CXg_MBI-.mjs} +0 -0
@@ -1,27 +1,28 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-D4dcoVfF.mjs";
5
- import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-cIaMxG0v.mjs";
4
+ import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
5
+ import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-DBSl8wEr.mjs";
6
6
  import { t as formatAcceptSignature } from "./accept-Dd__NiUL.mjs";
7
- import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-Dg-NXm4K.mjs";
8
- import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-HjidyDfF.mjs";
9
- import { t as getAuthenticatedDocumentLoader } from "./docloader-NOKfswJV.mjs";
10
- import { n as kvCache } from "./kv-cache-BpVwvcSI.mjs";
11
- import { t as KvKeyCache } from "./keycache-Dkc_sflV.mjs";
12
- import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-C1wveXXf.mjs";
13
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-CFKfE85G.mjs";
7
+ import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-APURZ0ky.mjs";
8
+ import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-BCSf1KIY.mjs";
9
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-yuyzZC9a.mjs";
10
+ import { n as kvCache } from "./kv-cache-C69dzgQi.mjs";
11
+ import { t as KvKeyCache } from "./keycache-BimEQucx.mjs";
12
+ import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-BoLqbDaL.mjs";
13
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-DjKvngeb.mjs";
14
14
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-D4iTv7uM.mjs";
15
- import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-DtpGEj0u.mjs";
15
+ import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-D2oFOdNA.mjs";
16
16
  import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-1He2YuBF.mjs";
17
17
  import { t as nodeInfoToJson } from "./types-J53Kw7so.mjs";
18
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-CwMea5r6.mjs";
19
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-B6ixdT3y.mjs";
18
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-xDK5UnL-.mjs";
19
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-C6yXExXl.mjs";
20
20
  import { t as CircuitBreaker } from "./circuit-breaker-D1fxthDI.mjs";
21
21
  import { t as buildCollectionSynchronizationHeader } from "./collection-Cc3DVAhE.mjs";
22
- import { t as acceptsJsonLd } from "./negotiation-CDW-_gUU.mjs";
23
- import { t as hasMalformedKnownTemporalLiteral } from "./temporal-ClSXyHyu.mjs";
24
- import { t as createExponentialBackoffPolicy } from "./retry-_VvV0h9f.mjs";
22
+ import { n as routeActivity, t as actorsHaveSameOrigin } from "./inbox-NObX26c9.mjs";
23
+ import { t as acceptsJsonLd } from "./negotiation-DDstyBvc.mjs";
24
+ import { t as hasMalformedKnownTemporalLiteral } from "./temporal-C6icc5n9.mjs";
25
+ import { t as createExponentialBackoffPolicy } from "./retry-CXg_MBI-.mjs";
25
26
  import { getLogger, withContext } from "@logtape/logtape";
26
27
  import { RouterError } from "@fedify/uri-template";
27
28
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
@@ -352,164 +353,6 @@ function serializeDataPointType(dataPointType) {
352
353
  }
353
354
  }
354
355
  //#endregion
355
- //#region src/federation/inbox.ts
356
- async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, meterProvider, tracerProvider, idempotencyStrategy }) {
357
- const logger = getLogger([
358
- "fedify",
359
- "federation",
360
- "inbox"
361
- ]);
362
- let cacheKey = null;
363
- if (activity.id != null) {
364
- const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
365
- const strategy = idempotencyStrategy ?? "per-inbox";
366
- let keyString;
367
- if (typeof strategy === "function") keyString = await strategy(inboxContext, activity);
368
- else switch (strategy) {
369
- case "global":
370
- keyString = activity.id.href;
371
- break;
372
- case "per-origin":
373
- keyString = `${ctx.origin}\n${activity.id.href}`;
374
- break;
375
- case "per-inbox":
376
- keyString = `${ctx.origin}\n${activity.id.href}\n${recipient == null ? "sharedInbox" : `inbox\n${recipient}`}`;
377
- break;
378
- default: keyString = `${ctx.origin}\n${activity.id.href}`;
379
- }
380
- if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
381
- }
382
- if (cacheKey != null) {
383
- if (await kv.get(cacheKey) === true) {
384
- logger.debug("Activity {activityId} has already been processed.", {
385
- activityId: activity.id?.href,
386
- activity: json,
387
- recipient
388
- });
389
- span.setStatus({
390
- code: SpanStatusCode.UNSET,
391
- message: `Activity ${activity.id?.href} has already been processed.`
392
- });
393
- recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
394
- return "alreadyProcessed";
395
- }
396
- }
397
- if (activity.actorId == null) {
398
- logger.error("Missing actor.", { activity: json });
399
- span.setStatus({
400
- code: SpanStatusCode.ERROR,
401
- message: "Missing actor."
402
- });
403
- recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
404
- return "missingActor";
405
- }
406
- span.setAttribute("activitypub.actor.id", activity.actorId.href);
407
- if (queue != null) {
408
- const carrier = {};
409
- propagation.inject(context.active(), carrier);
410
- try {
411
- await queue.enqueue({
412
- type: "inbox",
413
- id: crypto.randomUUID(),
414
- baseUrl: ctx.origin,
415
- activity: originalJson ?? json,
416
- ...normalizedActivity == null ? {} : { normalizedActivity },
417
- ...ldSignatureVerified == null ? {} : { ldSignatureVerified },
418
- identifier: recipient,
419
- attempt: 0,
420
- started: (/* @__PURE__ */ new Date()).toISOString(),
421
- traceContext: carrier
422
- });
423
- } catch (error) {
424
- logger.error("Failed to enqueue the incoming activity {activityId}:\n{error}", {
425
- error,
426
- activityId: activity.id?.href,
427
- activity: json,
428
- recipient
429
- });
430
- span.setStatus({
431
- code: SpanStatusCode.ERROR,
432
- message: `Failed to enqueue the incoming activity ${activity.id?.href}.`
433
- });
434
- throw error;
435
- }
436
- getFederationMetrics(meterProvider).recordQueueTaskEnqueued({
437
- role: "inbox",
438
- queue,
439
- activityType: getTypeId(activity).href
440
- }, 0);
441
- recordInboxActivity(meterProvider, "queued", getTypeId(activity).href);
442
- logger.info("Activity {activityId} is enqueued.", {
443
- activityId: activity.id?.href,
444
- activity: json,
445
- recipient
446
- });
447
- return "enqueued";
448
- }
449
- tracerProvider = tracerProvider ?? trace.getTracerProvider();
450
- return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
451
- const dispatched = inboxListeners?.dispatchWithClass(activity);
452
- if (dispatched == null) {
453
- logger.error("Unsupported activity type:\n{activity}", {
454
- activity: json,
455
- recipient
456
- });
457
- span.setStatus({
458
- code: SpanStatusCode.UNSET,
459
- message: `Unsupported activity type: ${getTypeId(activity).href}`
460
- });
461
- recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
462
- span.end();
463
- return "unsupportedActivity";
464
- }
465
- const { class: cls, listener } = dispatched;
466
- span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
467
- try {
468
- const activityType = getTypeId(activity).href;
469
- const started = performance.now();
470
- try {
471
- const contextFactory = listenerInboxContextFactory ?? inboxContextFactory;
472
- await listener(contextFactory(recipient, contextFactory === inboxContextFactory ? json : originalJson ?? json, activity.id?.href, activityType), activity);
473
- } finally {
474
- getFederationMetrics(meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
475
- }
476
- } catch (error) {
477
- try {
478
- await inboxErrorHandler?.(ctx, error);
479
- } catch (error) {
480
- logger.error("An unexpected error occurred in inbox error handler:\n{error}", {
481
- error,
482
- activityId: activity.id?.href,
483
- activity: json,
484
- recipient
485
- });
486
- }
487
- logger.error("Failed to process the incoming activity {activityId}:\n{error}", {
488
- error,
489
- activityId: activity.id?.href,
490
- activity: json,
491
- recipient
492
- });
493
- span.setStatus({
494
- code: SpanStatusCode.ERROR,
495
- message: String(error)
496
- });
497
- recordInboxActivity(meterProvider, "rejected", getTypeId(activity).href);
498
- span.end();
499
- return "error";
500
- }
501
- recordInboxActivity(meterProvider, "processed", getTypeId(activity).href);
502
- if (cacheKey != null) await kv.set(cacheKey, true, { ttl: Temporal.Duration.from({ days: 1 }) });
503
- logger.info("Activity {activityId} has been processed.", {
504
- activityId: activity.id?.href,
505
- activity: json,
506
- recipient
507
- });
508
- span.end();
509
- return "success";
510
- });
511
- }
512
- //#endregion
513
356
  //#region src/federation/handler.ts
514
357
  const rawInboxContextFactorySymbol = Symbol("fedify.rawInboxContextFactory");
515
358
  function isRemoteContextLoadingFailure$1(error) {
@@ -636,13 +479,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
636
479
  * @param parameters The parameters for handling the collection.
637
480
  * @returns A promise that resolves to an HTTP response.
638
481
  */
639
- async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
640
- const spanName = name$2.trim().replace(/\s+/g, "_");
482
+ async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
483
+ const spanName = name$1.trim().replace(/\s+/g, "_");
641
484
  tracerProvider = tracerProvider ?? trace.getTracerProvider();
642
485
  const tracer = tracerProvider.getTracer(name, version);
643
486
  const cursor = new URL(request.url).searchParams.get("cursor");
644
487
  const metricBase = {
645
- kind: getCollectionMetricKind(name$2),
488
+ kind: getCollectionMetricKind(name$1),
646
489
  page: cursor != null,
647
490
  dispatcher: "built_in"
648
491
  };
@@ -683,7 +526,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
683
526
  span.setStatus({ code: SpanStatusCode.ERROR });
684
527
  return await onNotFound(request);
685
528
  }
686
- const items = filterCollectionItems(page.items, name$2, filterPredicate);
529
+ const items = filterCollectionItems(page.items, name$1, filterPredicate);
687
530
  itemCount = items.length;
688
531
  span.setAttribute("fedify.collection.items", itemCount);
689
532
  return items;
@@ -723,7 +566,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
723
566
  } else {
724
567
  const uri = new URL(baseUri);
725
568
  uri.searchParams.set("cursor", cursor);
726
- const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
569
+ const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
727
570
  kind: SpanKind.SERVER,
728
571
  attributes: {
729
572
  "activitypub.collection.id": uri.href,
@@ -739,7 +582,7 @@ async function handleCollection(request, { name: name$2, identifier, uriGetter,
739
582
  span.setStatus({ code: SpanStatusCode.ERROR });
740
583
  return await onNotFound(request);
741
584
  }
742
- const items = filterCollectionItems(page.items, name$2, filterPredicate);
585
+ const items = filterCollectionItems(page.items, name$1, filterPredicate);
743
586
  itemCount = items.length;
744
587
  span.setAttribute("fedify.collection.items", itemCount);
745
588
  return {
@@ -1448,6 +1291,36 @@ async function handleInboxInternal(request, parameters, span) {
1448
1291
  return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
1449
1292
  }
1450
1293
  }
1294
+ if (activity.actorId == null) {
1295
+ logger.error("Missing actor.", {
1296
+ activity: json,
1297
+ recipient
1298
+ });
1299
+ span.setStatus({
1300
+ code: SpanStatusCode.ERROR,
1301
+ message: "Missing actor."
1302
+ });
1303
+ return new Response("Missing actor.", {
1304
+ status: 400,
1305
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
1306
+ });
1307
+ }
1308
+ if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
1309
+ logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
1310
+ activity: json,
1311
+ recipient,
1312
+ activityId: activity.id.href,
1313
+ actorIds: activity.actorIds.map((actor) => actor.href)
1314
+ });
1315
+ span.setStatus({
1316
+ code: SpanStatusCode.ERROR,
1317
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
1318
+ });
1319
+ return new Response("The activity and its actors do not have the same origin.", {
1320
+ status: 401,
1321
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
1322
+ });
1323
+ }
1451
1324
  const routeResult = await routeActivity({
1452
1325
  context: ctx,
1453
1326
  json,
@@ -1615,8 +1488,8 @@ var CustomCollectionHandler = class {
1615
1488
  * @param CollectionPage The CollectionPage constructor.
1616
1489
  * @param filterPredicate Optional filter predicate for items.
1617
1490
  */
1618
- constructor(name$1, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
1619
- this.name = name$1;
1491
+ constructor(name$2, values, context, callbacks, tracerProvider = trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
1492
+ this.name = name$2;
1620
1493
  this.values = values;
1621
1494
  this.context = context;
1622
1495
  this.callbacks = callbacks;
@@ -3281,6 +3154,35 @@ var FederationImpl = class extends FederationBuilderImpl {
3281
3154
  span.setAttribute("activitypub.activity.id", activity.id.href);
3282
3155
  listenerSpan.setAttribute("activitypub.activity.id", activity.id.href);
3283
3156
  }
3157
+ if (activity.actorId == null) {
3158
+ logger.error("Missing actor in queued incoming activity.", {
3159
+ activityId: activity.id?.href,
3160
+ activity: message.activity,
3161
+ recipient: message.identifier
3162
+ });
3163
+ listenerSpan.setStatus({
3164
+ code: SpanStatusCode.ERROR,
3165
+ message: "Missing actor."
3166
+ });
3167
+ recordInboxActivity(this.meterProvider, "rejected", activityType);
3168
+ listenerSpan.end();
3169
+ return;
3170
+ }
3171
+ if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
3172
+ logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
3173
+ activityId: activity.id.href,
3174
+ actorIds: activity.actorIds.map((actor) => actor.href),
3175
+ activity: message.activity,
3176
+ recipient: message.identifier
3177
+ });
3178
+ listenerSpan.setStatus({
3179
+ code: SpanStatusCode.ERROR,
3180
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
3181
+ });
3182
+ recordInboxActivity(this.meterProvider, "rejected", activityType);
3183
+ listenerSpan.end();
3184
+ return;
3185
+ }
3284
3186
  cacheKey = activity.id == null ? null : [
3285
3187
  ...this.kvPrefixes.activityIdempotence,
3286
3188
  context.origin,
@@ -4543,20 +4445,6 @@ var ContextImpl = class ContextImpl {
4543
4445
  activity: await fetched.toJsonLd({ contextLoader })
4544
4446
  });
4545
4447
  return false;
4546
- } else if (fetched.actorIds.length < 1) {
4547
- logger.debug("Fetched activity object is missing an actor; unable to verify.", {
4548
- recipient,
4549
- activity: await fetched.toJsonLd({ contextLoader })
4550
- });
4551
- return false;
4552
- }
4553
- const activityId = fetched.id;
4554
- if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
4555
- logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
4556
- recipient,
4557
- activity: await fetched.toJsonLd({ contextLoader })
4558
- });
4559
- return false;
4560
4448
  }
4561
4449
  logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
4562
4450
  activity = fetched;
@@ -4565,6 +4453,20 @@ var ContextImpl = class ContextImpl {
4565
4453
  recipient,
4566
4454
  activity: json
4567
4455
  });
4456
+ if (activity.actorId == null) {
4457
+ logger.debug("Activity is missing an actor; unable to verify.", {
4458
+ recipient,
4459
+ activity: json
4460
+ });
4461
+ return false;
4462
+ }
4463
+ if (activity.id != null && !actorsHaveSameOrigin(activity)) {
4464
+ logger.debug("Activity has actors from different origins; unable to verify.", {
4465
+ recipient,
4466
+ activity: json
4467
+ });
4468
+ return false;
4469
+ }
4568
4470
  const routeResult = await routeActivity({
4569
4471
  context: this,
4570
4472
  json,
@@ -1,5 +1,5 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-I-XlrRVl.mjs";
4
+ import { n as FederationImpl } from "./middleware-CZ8tI1qL.mjs";
5
5
  export { FederationImpl };
package/dist/mod.cjs CHANGED
@@ -4,11 +4,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  require("./chunk-DDcVe30Y.cjs");
5
5
  const require_transformers = require("./transformers-NeAONrAq.cjs");
6
6
  require("./compat/mod.cjs");
7
- const require_http = require("./http-D_Xrr6kp.cjs");
8
- const require_middleware = require("./middleware-DhOFTXmo.cjs");
7
+ const require_http = require("./http-D77Wjrcg.cjs");
8
+ const require_middleware = require("./middleware-BQUQ0pPl.cjs");
9
9
  const require_types = require("./types-DRPjmHVV.cjs");
10
- const require_proof = require("./proof-DBxu6g2K.cjs");
11
- const require_kv_cache = require("./kv-cache-BwnC6JGt.cjs");
10
+ const require_proof = require("./proof-CWTnYhjS.cjs");
11
+ const require_kv_cache = require("./kv-cache-Bg4utAuv.cjs");
12
12
  const require_federation_mod = require("./federation/mod.cjs");
13
13
  require("./nodeinfo/mod.cjs");
14
14
  require("./runtime/mod.cjs");
package/dist/mod.js CHANGED
@@ -3,11 +3,11 @@ import { URLPattern } from "urlpattern-polyfill";
3
3
  import "./chunk-CRNNMoPX.js";
4
4
  import { n as autoIdAssigner, r as getDefaultActivityTransformers, t as actorDehydrator } from "./transformers-BGMIq1cs.js";
5
5
  import "./compat/mod.js";
6
- import { F as validateAcceptSignature, M as formatAcceptSignature, N as fulfillAcceptSignature, P as parseAcceptSignature, a as verifyRequestDetailed, c as fetchKey, d as importJwk, i as verifyRequest, l as fetchKeyDetailed, o as exportJwk, r as signRequest, u as generateCryptoKeyPair } from "./http-DkyUBs_T.js";
7
- import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "./middleware-CnrzVu9i.js";
6
+ import { F as validateAcceptSignature, M as formatAcceptSignature, N as fulfillAcceptSignature, P as parseAcceptSignature, a as verifyRequestDetailed, c as fetchKey, d as importJwk, i as verifyRequest, l as fetchKeyDetailed, o as exportJwk, r as signRequest, u as generateCryptoKeyPair } from "./http-DNM9KyIO.js";
7
+ import { a as SendActivityError, c as buildCollectionSynchronizationHeader, d as normalizeCircuitBreakerOptions, f as parseCircuitBreakerKvState, i as createExponentialBackoffPolicy, l as digest, o as respondWithObject, p as createFederationBuilder, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as CircuitBreaker } from "./middleware-CRd1JmuL.js";
8
8
  import { n as getNodeInfo, r as parseNodeInfo, t as nodeInfoToJson } from "./types-miAYfiGO.js";
9
- import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "./proof-HU__qtUD.js";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-BhGeZk_o.js";
9
+ import { C as verifySignature, S as verifyJsonLd, _ as hasSignatureLike, a as verifyProof, b as signJsonLd, c as getKeyOwner, d as attachSignature, i as verifyObject, m as detachSignature, n as hasProofLike, p as createSignature, r as signObject, s as doesActorOwnKey, t as createProof } from "./proof-s9sy44kx.js";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-LBCwHNLu.js";
11
11
  import { InProcessMessageQueue, MemoryKvStore, ParallelMessageQueue, Router, RouterError } from "./federation/mod.js";
12
12
  import "./nodeinfo/mod.js";
13
13
  import "./runtime/mod.js";
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as esm_default } from "../esm-vrlUxr60.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
- import "../std__assert-BvGuO4xO.mjs";
7
- import { n as assertInstanceOf } from "../assert-jSdZMYam.mjs";
6
+ import "../std__assert-BjJn2daJ.mjs";
7
+ import { n as assertInstanceOf } from "../assert-CEO06XCw.mjs";
8
8
  import { a as parseProtocol, c as parseUsage, i as parseOutboundService, n as parseInboundService, o as parseServices, r as parseNodeInfo, s as parseSoftware, t as getNodeInfo } from "../client-1He2YuBF.mjs";
9
9
  import { configure, reset } from "@logtape/logtape";
10
10
  import { test } from "@fedify/fixture";
@@ -3,9 +3,9 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { r as createRequestContext } from "../context-CxbCIptr.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
- import "../std__assert-BvGuO4xO.mjs";
6
+ import "../std__assert-BjJn2daJ.mjs";
7
7
  import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
8
- import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-I-XlrRVl.mjs";
8
+ import { _ as handleNodeInfo, o as createFederation, v as handleNodeInfoJrd } from "../middleware-CZ8tI1qL.mjs";
9
9
  import { test } from "@fedify/fixture";
10
10
  //#region src/nodeinfo/handler.test.ts
11
11
  test("handleNodeInfo()", async () => {
@@ -2,8 +2,8 @@ import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
- import "../std__assert-BvGuO4xO.mjs";
6
- import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
5
+ import "../std__assert-BjJn2daJ.mjs";
6
+ import { t as assertThrows } from "../assert_throws-BbSMEFKo.mjs";
7
7
  import { t as nodeInfoToJson } from "../types-J53Kw7so.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/nodeinfo/types.test.ts
@@ -2,7 +2,7 @@ import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
- import "../std__assert-BvGuO4xO.mjs";
5
+ import "../std__assert-BjJn2daJ.mjs";
6
6
  import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { ExportResultCode } from "@opentelemetry/core";
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-D4dcoVfF.mjs";
5
- import { c as verifyKeyOwnership, n as fetchActorDocument, t as exportJwk } from "./key-Dg-NXm4K.mjs";
4
+ import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
5
+ import { c as verifyKeyOwnership, n as fetchActorDocument, t as exportJwk } from "./key-APURZ0ky.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  const require_chunk = require("./chunk-DDcVe30Y.cjs");
4
- const require_http = require("./http-D_Xrr6kp.cjs");
4
+ const require_http = require("./http-D77Wjrcg.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let _fedify_vocab = require("@fedify/vocab");
7
7
  let _opentelemetry_api = require("@opentelemetry/api");
@@ -1,9 +1,9 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-D4dcoVfF.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-cIaMxG0v.mjs";
6
- import { r as fetchKey, s as validateCryptoKey } from "./key-Dg-NXm4K.mjs";
4
+ import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-DBSl8wEr.mjs";
6
+ import { r as fetchKey, s as validateCryptoKey } from "./key-APURZ0ky.mjs";
7
7
  import { n as preloadedOnlyDocumentLoader } from "./public-audience-Dp4ZScSr.mjs";
8
8
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-D4iTv7uM.mjs";
9
9
  import { getLogger } from "@logtape/logtape";
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { I as name, L as version, c as fetchKey, f as validateCryptoKey, h as getFederationMetrics, m as getDurationMs, o as exportJwk, p as verifyKeyOwnership, s as fetchActorDocument, y as measureSignatureKeyFetch } from "./http-DkyUBs_T.js";
3
+ import { I as name, L as version, c as fetchKey, f as validateCryptoKey, h as getFederationMetrics, m as getDurationMs, o as exportJwk, p as verifyKeyOwnership, s as fetchActorDocument, y as measureSignatureKeyFetch } from "./http-DNM9KyIO.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, PUBLIC_COLLECTION, getTypeId, isActor } from "@fedify/vocab";
6
6
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,9 +1,9 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-D4dcoVfF.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics } from "./metrics-cIaMxG0v.mjs";
6
- import { n as doubleKnock } from "./http-HjidyDfF.mjs";
4
+ import { n as version, t as name } from "./deno-y3L4Oa94.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics } from "./metrics-DBSl8wEr.mjs";
6
+ import { n as doubleKnock } from "./http-BCSf1KIY.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
9
9
  import { FetchError, UrlError, validatePublicUrl } from "@fedify/vocab-runtime";
@@ -3,14 +3,14 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as esm_default } from "../esm-vrlUxr60.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
- import { n as assertExists, t as assertStringIncludes } from "../std__assert-BvGuO4xO.mjs";
7
- import { n as assertGreaterOrEqual, r as assertFalse, t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
8
- import { t as assert } from "../assert-jSdZMYam.mjs";
9
- import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
10
- import { t as exportJwk } from "../key-Dg-NXm4K.mjs";
11
- import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-HjidyDfF.mjs";
6
+ import { n as assertExists, t as assertStringIncludes } from "../std__assert-BjJn2daJ.mjs";
7
+ import { r as assertFalse, t as assertThrows } from "../assert_throws-BbSMEFKo.mjs";
8
+ import { n as assertGreaterOrEqual, t as assertRejects } from "../assert_rejects-D1HYAik3.mjs";
9
+ import { t as assert } from "../assert-CEO06XCw.mjs";
10
+ import { t as exportJwk } from "../key-APURZ0ky.mjs";
11
+ import { a as parseRfc9421Signature, c as timingSafeEqual, i as formatRfc9421SignatureParameters, l as verifyRequest, n as doubleKnock, o as parseRfc9421SignatureInput, r as formatRfc9421Signature, s as signRequest, t as createRfc9421SignatureBase, u as verifyRequestDetailed } from "../http-BCSf1KIY.mjs";
12
12
  import { i as rsaPrivateKey2, l as rsaPublicKey5, o as rsaPublicKey1, s as rsaPublicKey2 } from "../keys-BAK-tUlf.mjs";
13
- import { t as KvKeyCache } from "../keycache-Dkc_sflV.mjs";
13
+ import { t as KvKeyCache } from "../keycache-BimEQucx.mjs";
14
14
  import { t as MemoryKvStore } from "../kv-mI4Ix2EU.mjs";
15
15
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
16
16
  import { FetchError, UrlError, exportSpki } from "@fedify/vocab-runtime";