@fedify/fedify 2.2.18-dev.2386 → 2.2.19

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 (65) hide show
  1. package/dist/{assert_rejects-B-qJtC9Z.mjs → assert_rejects-WyYSTDDX.mjs} +2 -20
  2. package/dist/{assert_throws-4NwKEy2q.mjs → assert_throws-D4DNWrux.mjs} +19 -1
  3. package/dist/{builder-CiKYvR0I.mjs → builder-UmydCxtK.mjs} +2 -2
  4. package/dist/compat/public-audience.test.mjs +1 -1
  5. package/dist/compat/transformers.test.mjs +1 -1
  6. package/dist/{deno-CkabM5bf.mjs → deno-CD-8UlUi.mjs} +1 -1
  7. package/dist/{docloader-B4Hk3LSj.mjs → docloader-D1ghurDJ.mjs} +6 -2
  8. package/dist/federation/builder.test.mjs +3 -3
  9. package/dist/federation/collection.test.mjs +1 -1
  10. package/dist/federation/handler.test.mjs +261 -8
  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 +18 -7
  14. package/dist/federation/kv.test.mjs +1 -1
  15. package/dist/federation/middleware.test.mjs +128 -10
  16. package/dist/federation/mod.cjs +1 -1
  17. package/dist/federation/mod.js +1 -1
  18. package/dist/federation/mq.test.mjs +2 -2
  19. package/dist/federation/negotiation.test.mjs +3 -3
  20. package/dist/federation/retry.test.mjs +2 -2
  21. package/dist/federation/router.test.mjs +2 -3
  22. package/dist/federation/send.test.mjs +7 -6
  23. package/dist/federation/temporal.test.mjs +3 -3
  24. package/dist/federation/webfinger.test.mjs +2 -2
  25. package/dist/{http-DovhI1VM.mjs → http-BBBUbwKh.mjs} +2 -2
  26. package/dist/{http-DP-vbG4o.js → http-DJK2udgX.js} +17 -3
  27. package/dist/{http-C_Qq0cNx.cjs → http-DrUG4fPS.cjs} +17 -3
  28. package/dist/inbox-Dca_0fwc.mjs +162 -0
  29. package/dist/{key-BtVvc9pe.mjs → key-DolXUaLH.mjs} +17 -3
  30. package/dist/{keycache-Dkc_sflV.mjs → keycache-BimEQucx.mjs} +1 -1
  31. package/dist/{kv-cache-Ds_adaor.cjs → kv-cache-Bk3V1Tiu.cjs} +5 -1
  32. package/dist/{kv-cache-D8yJIXRo.js → kv-cache-DDm80t1K.js} +5 -1
  33. package/dist/{ld-1J9cdTp0.mjs → ld-rTdIfZ63.mjs} +2 -2
  34. package/dist/{middleware-B_M6lcay.cjs → middleware-B4-Rzdi3.cjs} +1 -1
  35. package/dist/{middleware-BWXhlsuq.cjs → middleware-BWOwEGpy.cjs} +97 -27
  36. package/dist/{middleware-BrFMyQSp.js → middleware-BimXKBcP.js} +96 -26
  37. package/dist/{middleware-ruFPV2xR.mjs → middleware-CpXoRHs3.mjs} +85 -168
  38. package/dist/{middleware-DMkt5ShX.mjs → middleware-DYK_res8.mjs} +1 -1
  39. package/dist/mod.cjs +4 -4
  40. package/dist/mod.js +4 -4
  41. package/dist/nodeinfo/client.test.mjs +1 -1
  42. package/dist/nodeinfo/handler.test.mjs +2 -2
  43. package/dist/nodeinfo/types.test.mjs +2 -2
  44. package/dist/otel/exporter.test.mjs +1 -1
  45. package/dist/{owner-CgurOfJ9.mjs → owner-CVfzyM5V.mjs} +2 -2
  46. package/dist/{proof-BJ332wO_.js → proof-CaQ4KG6y.js} +1 -1
  47. package/dist/{proof-C6uAR-Hj.cjs → proof-DhaTTn-P.cjs} +1 -1
  48. package/dist/{proof-Dn4nm7pr.mjs → proof-gOGM-sJS.mjs} +2 -2
  49. package/dist/{send-iVwnK504.mjs → send-D35Va72B.mjs} +2 -2
  50. package/dist/sig/http.test.mjs +6 -6
  51. package/dist/sig/key.test.mjs +199 -5
  52. package/dist/sig/ld.test.mjs +49 -4
  53. package/dist/sig/mod.cjs +2 -2
  54. package/dist/sig/mod.js +2 -2
  55. package/dist/sig/owner.test.mjs +48 -3
  56. package/dist/sig/proof.test.mjs +55 -3
  57. package/dist/{std__assert-BVFj8-_V.mjs → std__assert-DNZ4Liil.mjs} +2 -2
  58. package/dist/{temporal-BZrzDMq2.mjs → temporal-CA4Y9hBJ.mjs} +1 -1
  59. package/dist/utils/docloader.test.mjs +178 -39
  60. package/dist/utils/mod.cjs +1 -1
  61. package/dist/utils/mod.js +1 -1
  62. package/package.json +5 -5
  63. /package/dist/{assert_not_equals--wG9hV7u.mjs → assert_not_equals-BkxW5QJI.mjs} +0 -0
  64. /package/dist/{negotiation-BHtZN6Y1.mjs → negotiation-SQvQgUqe.mjs} +0 -0
  65. /package/dist/{retry-bMXBL97A.mjs → retry-v_sGLH1d.mjs} +0 -0
@@ -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-CkabM5bf.mjs";
5
- import { r as fetchKey, s as validateCryptoKey } from "./key-BtVvc9pe.mjs";
4
+ import { n as version, t as name } from "./deno-CD-8UlUi.mjs";
5
+ import { r as fetchKey, s as validateCryptoKey } from "./key-DolXUaLH.mjs";
6
6
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
7
7
  import { SpanStatusCode, trace } from "@opentelemetry/api";
8
8
  import { getDocumentLoader } from "@fedify/vocab-runtime";
@@ -1,4 +1,4 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
- const require_middleware = require("./middleware-BWXhlsuq.cjs");
3
+ const require_middleware = require("./middleware-BWOwEGpy.cjs");
4
4
  exports.FederationImpl = require_middleware.FederationImpl;
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  const require_chunk = require("./chunk-DDcVe30Y.cjs");
4
4
  const require_transformers = require("./transformers-NeAONrAq.cjs");
5
- const require_http = require("./http-C_Qq0cNx.cjs");
5
+ const require_http = require("./http-DrUG4fPS.cjs");
6
6
  const require_types = require("./types-DRPjmHVV.cjs");
7
- const require_proof = require("./proof-C6uAR-Hj.cjs");
8
- const require_kv_cache = require("./kv-cache-Ds_adaor.cjs");
7
+ const require_proof = require("./proof-DhaTTn-P.cjs");
8
+ const require_kv_cache = require("./kv-cache-Bk3V1Tiu.cjs");
9
9
  let _logtape_logtape = require("@logtape/logtape");
10
10
  let _fedify_vocab = require("@fedify/vocab");
11
11
  let _opentelemetry_api = require("@opentelemetry/api");
@@ -213,7 +213,7 @@ var FederationBuilderImpl = class {
213
213
  this.collectionTypeIds = {};
214
214
  }
215
215
  async build(options) {
216
- const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-B_M6lcay.cjs"));
216
+ const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-B4-Rzdi3.cjs"));
217
217
  const f = new FederationImpl(options);
218
218
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
219
219
  f.router = this.router.clone();
@@ -782,12 +782,33 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
782
782
  }
783
783
  //#endregion
784
784
  //#region src/federation/inbox.ts
785
+ /**
786
+ * Checks whether an activity's ID and all of its actor IDs have the same
787
+ * non-opaque origin. Activities without an ID have no origin to authenticate.
788
+ *
789
+ * The caller is responsible for rejecting a missing primary actor ID before
790
+ * relying on this check.
791
+ * @internal
792
+ */
793
+ function actorsHaveSameOrigin(activity) {
794
+ if (activity.id == null) return true;
795
+ const origin = activity.id.origin;
796
+ return origin !== "null" && activity.actorIds.every((actor) => actor.origin === origin);
797
+ }
785
798
  async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
786
799
  const logger = (0, _logtape_logtape.getLogger)([
787
800
  "fedify",
788
801
  "federation",
789
802
  "inbox"
790
803
  ]);
804
+ if (activity.actorId == null) {
805
+ logger.error("Missing actor.", { activity: json });
806
+ span.setStatus({
807
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
808
+ message: "Missing actor."
809
+ });
810
+ return "missingActor";
811
+ }
791
812
  let cacheKey = null;
792
813
  if (activity.id != null) {
793
814
  const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href);
@@ -822,14 +843,6 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
822
843
  return "alreadyProcessed";
823
844
  }
824
845
  }
825
- if (activity.actorId == null) {
826
- logger.error("Missing actor.", { activity: json });
827
- span.setStatus({
828
- code: _opentelemetry_api.SpanStatusCode.ERROR,
829
- message: "Missing actor."
830
- });
831
- return "missingActor";
832
- }
833
846
  span.setAttribute("activitypub.actor.id", activity.actorId.href);
834
847
  if (queue != null) {
835
848
  const carrier = {};
@@ -923,7 +936,7 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
923
936
  }
924
937
  //#endregion
925
938
  //#region src/federation/keycache.ts
926
- const KEY_CACHE_GENERATION = "2";
939
+ const KEY_CACHE_GENERATION = "3";
927
940
  var KvKeyCache = class {
928
941
  kv;
929
942
  prefix;
@@ -2059,6 +2072,36 @@ async function handleInboxInternal(request, parameters, span) {
2059
2072
  return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
2060
2073
  }
2061
2074
  }
2075
+ if (activity.actorId == null) {
2076
+ logger.error("Missing actor.", {
2077
+ activity: json,
2078
+ recipient
2079
+ });
2080
+ span.setStatus({
2081
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
2082
+ message: "Missing actor."
2083
+ });
2084
+ return new Response("Missing actor.", {
2085
+ status: 400,
2086
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
2087
+ });
2088
+ }
2089
+ if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
2090
+ logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
2091
+ activity: json,
2092
+ recipient,
2093
+ activityId: activity.id.href,
2094
+ actorIds: activity.actorIds.map((actor) => actor.href)
2095
+ });
2096
+ span.setStatus({
2097
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
2098
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
2099
+ });
2100
+ return new Response("The activity and its actors do not have the same origin.", {
2101
+ status: 401,
2102
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
2103
+ });
2104
+ }
2062
2105
  const routeResult = await routeActivity({
2063
2106
  context: ctx,
2064
2107
  json,
@@ -3575,6 +3618,33 @@ var FederationImpl = class extends FederationBuilderImpl {
3575
3618
  activity = await _fedify_vocab.Activity.fromJsonLd(parseInput, parseContext);
3576
3619
  span.setAttribute("activitypub.activity.type", (0, _fedify_vocab.getTypeId)(activity).href);
3577
3620
  if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
3621
+ if (activity.actorId == null) {
3622
+ logger.error("Missing actor in queued incoming activity.", {
3623
+ activityId: activity.id?.href,
3624
+ activity: message.activity,
3625
+ recipient: message.identifier
3626
+ });
3627
+ span.setStatus({
3628
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
3629
+ message: "Missing actor."
3630
+ });
3631
+ span.end();
3632
+ return;
3633
+ }
3634
+ if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
3635
+ logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
3636
+ activityId: activity.id.href,
3637
+ actorIds: activity.actorIds.map((actor) => actor.href),
3638
+ activity: message.activity,
3639
+ recipient: message.identifier
3640
+ });
3641
+ span.setStatus({
3642
+ code: _opentelemetry_api.SpanStatusCode.ERROR,
3643
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
3644
+ });
3645
+ span.end();
3646
+ return;
3647
+ }
3578
3648
  cacheKey = activity.id == null ? null : [
3579
3649
  ...this.kvPrefixes.activityIdempotence,
3580
3650
  context.origin,
@@ -4736,20 +4806,6 @@ var ContextImpl = class ContextImpl {
4736
4806
  activity: await fetched.toJsonLd({ contextLoader })
4737
4807
  });
4738
4808
  return false;
4739
- } else if (fetched.actorIds.length < 1) {
4740
- logger.debug("Fetched activity object is missing an actor; unable to verify.", {
4741
- recipient,
4742
- activity: await fetched.toJsonLd({ contextLoader })
4743
- });
4744
- return false;
4745
- }
4746
- const activityId = fetched.id;
4747
- if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
4748
- logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
4749
- recipient,
4750
- activity: await fetched.toJsonLd({ contextLoader })
4751
- });
4752
- return false;
4753
4809
  }
4754
4810
  logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
4755
4811
  activity = fetched;
@@ -4758,6 +4814,20 @@ var ContextImpl = class ContextImpl {
4758
4814
  recipient,
4759
4815
  activity: json
4760
4816
  });
4817
+ if (activity.actorId == null) {
4818
+ logger.debug("Activity is missing an actor; unable to verify.", {
4819
+ recipient,
4820
+ activity: json
4821
+ });
4822
+ return false;
4823
+ }
4824
+ if (activity.id != null && !actorsHaveSameOrigin(activity)) {
4825
+ logger.debug("Activity has actors from different origins; unable to verify.", {
4826
+ recipient,
4827
+ activity: json
4828
+ });
4829
+ return false;
4830
+ }
4761
4831
  const routeResult = await routeActivity({
4762
4832
  context: this,
4763
4833
  json,
@@ -2,10 +2,10 @@ import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { t as __exportAll } from "./chunk-CRNNMoPX.js";
4
4
  import { r as getDefaultActivityTransformers } from "./transformers-BGMIq1cs.js";
5
- import { a as verifyRequestDetailed, d as importJwk, f as validateCryptoKey, i as verifyRequest, m as formatAcceptSignature, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as name, y as version } from "./http-DP-vbG4o.js";
5
+ import { a as verifyRequestDetailed, d as importJwk, f as validateCryptoKey, i as verifyRequest, m as formatAcceptSignature, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, v as name, y as version } from "./http-DJK2udgX.js";
6
6
  import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-miAYfiGO.js";
7
- import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-BJ332wO_.js";
8
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-D8yJIXRo.js";
7
+ import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-CaQ4KG6y.js";
8
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-DDm80t1K.js";
9
9
  import { getLogger, withContext } from "@logtape/logtape";
10
10
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
11
11
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
@@ -781,12 +781,33 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
781
781
  }
782
782
  //#endregion
783
783
  //#region src/federation/inbox.ts
784
+ /**
785
+ * Checks whether an activity's ID and all of its actor IDs have the same
786
+ * non-opaque origin. Activities without an ID have no origin to authenticate.
787
+ *
788
+ * The caller is responsible for rejecting a missing primary actor ID before
789
+ * relying on this check.
790
+ * @internal
791
+ */
792
+ function actorsHaveSameOrigin(activity) {
793
+ if (activity.id == null) return true;
794
+ const origin = activity.id.origin;
795
+ return origin !== "null" && activity.actorIds.every((actor) => actor.origin === origin);
796
+ }
784
797
  async function routeActivity({ context: ctx, json, originalJson, normalizedActivity, ldSignatureVerified, activity, recipient, inboxListeners, inboxContextFactory, listenerInboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
785
798
  const logger = getLogger([
786
799
  "fedify",
787
800
  "federation",
788
801
  "inbox"
789
802
  ]);
803
+ if (activity.actorId == null) {
804
+ logger.error("Missing actor.", { activity: json });
805
+ span.setStatus({
806
+ code: SpanStatusCode.ERROR,
807
+ message: "Missing actor."
808
+ });
809
+ return "missingActor";
810
+ }
790
811
  let cacheKey = null;
791
812
  if (activity.id != null) {
792
813
  const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
@@ -821,14 +842,6 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
821
842
  return "alreadyProcessed";
822
843
  }
823
844
  }
824
- if (activity.actorId == null) {
825
- logger.error("Missing actor.", { activity: json });
826
- span.setStatus({
827
- code: SpanStatusCode.ERROR,
828
- message: "Missing actor."
829
- });
830
- return "missingActor";
831
- }
832
845
  span.setAttribute("activitypub.actor.id", activity.actorId.href);
833
846
  if (queue != null) {
834
847
  const carrier = {};
@@ -922,7 +935,7 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
922
935
  }
923
936
  //#endregion
924
937
  //#region src/federation/keycache.ts
925
- const KEY_CACHE_GENERATION = "2";
938
+ const KEY_CACHE_GENERATION = "3";
926
939
  var KvKeyCache = class {
927
940
  kv;
928
941
  prefix;
@@ -2058,6 +2071,36 @@ async function handleInboxInternal(request, parameters, span) {
2058
2071
  return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
2059
2072
  }
2060
2073
  }
2074
+ if (activity.actorId == null) {
2075
+ logger.error("Missing actor.", {
2076
+ activity: json,
2077
+ recipient
2078
+ });
2079
+ span.setStatus({
2080
+ code: SpanStatusCode.ERROR,
2081
+ message: "Missing actor."
2082
+ });
2083
+ return new Response("Missing actor.", {
2084
+ status: 400,
2085
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
2086
+ });
2087
+ }
2088
+ if (!skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
2089
+ logger.error("The activity ({activityId}) and its actors do not have the same origin.", {
2090
+ activity: json,
2091
+ recipient,
2092
+ activityId: activity.id.href,
2093
+ actorIds: activity.actorIds.map((actor) => actor.href)
2094
+ });
2095
+ span.setStatus({
2096
+ code: SpanStatusCode.ERROR,
2097
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
2098
+ });
2099
+ return new Response("The activity and its actors do not have the same origin.", {
2100
+ status: 401,
2101
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
2102
+ });
2103
+ }
2061
2104
  const routeResult = await routeActivity({
2062
2105
  context: ctx,
2063
2106
  json,
@@ -3582,6 +3625,33 @@ var FederationImpl = class extends FederationBuilderImpl {
3582
3625
  activity = await Activity.fromJsonLd(parseInput, parseContext);
3583
3626
  span.setAttribute("activitypub.activity.type", getTypeId(activity).href);
3584
3627
  if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
3628
+ if (activity.actorId == null) {
3629
+ logger.error("Missing actor in queued incoming activity.", {
3630
+ activityId: activity.id?.href,
3631
+ activity: message.activity,
3632
+ recipient: message.identifier
3633
+ });
3634
+ span.setStatus({
3635
+ code: SpanStatusCode.ERROR,
3636
+ message: "Missing actor."
3637
+ });
3638
+ span.end();
3639
+ return;
3640
+ }
3641
+ if (!this.skipSignatureVerification && activity.id != null && !actorsHaveSameOrigin(activity)) {
3642
+ logger.error("The queued activity ({activityId}) and its actors do not have the same origin.", {
3643
+ activityId: activity.id.href,
3644
+ actorIds: activity.actorIds.map((actor) => actor.href),
3645
+ activity: message.activity,
3646
+ recipient: message.identifier
3647
+ });
3648
+ span.setStatus({
3649
+ code: SpanStatusCode.ERROR,
3650
+ message: `The activity (${activity.id.href}) and its actors do not have the same origin.`
3651
+ });
3652
+ span.end();
3653
+ return;
3654
+ }
3585
3655
  cacheKey = activity.id == null ? null : [
3586
3656
  ...this.kvPrefixes.activityIdempotence,
3587
3657
  context.origin,
@@ -4743,20 +4813,6 @@ var ContextImpl = class ContextImpl {
4743
4813
  activity: await fetched.toJsonLd({ contextLoader })
4744
4814
  });
4745
4815
  return false;
4746
- } else if (fetched.actorIds.length < 1) {
4747
- logger.debug("Fetched activity object is missing an actor; unable to verify.", {
4748
- recipient,
4749
- activity: await fetched.toJsonLd({ contextLoader })
4750
- });
4751
- return false;
4752
- }
4753
- const activityId = fetched.id;
4754
- if (!fetched.actorIds.every((actor) => actor.origin === activityId.origin)) {
4755
- logger.debug("Fetched activity object has actors from different origins; unable to verify.", {
4756
- recipient,
4757
- activity: await fetched.toJsonLd({ contextLoader })
4758
- });
4759
- return false;
4760
4816
  }
4761
4817
  logger.debug("Successfully fetched the remote activity object {activityId}; ignore the original activity and use the fetched one, which is trustworthy.");
4762
4818
  activity = fetched;
@@ -4765,6 +4821,20 @@ var ContextImpl = class ContextImpl {
4765
4821
  recipient,
4766
4822
  activity: json
4767
4823
  });
4824
+ if (activity.actorId == null) {
4825
+ logger.debug("Activity is missing an actor; unable to verify.", {
4826
+ recipient,
4827
+ activity: json
4828
+ });
4829
+ return false;
4830
+ }
4831
+ if (activity.id != null && !actorsHaveSameOrigin(activity)) {
4832
+ logger.debug("Activity has actors from different origins; unable to verify.", {
4833
+ recipient,
4834
+ activity: json
4835
+ });
4836
+ return false;
4837
+ }
4768
4838
  const routeResult = await routeActivity({
4769
4839
  context: this,
4770
4840
  json,