@fedify/fedify 2.4.0-dev.2256 → 2.4.0-dev.2260

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 (105) hide show
  1. package/dist/{builder-DvSQqk2l.mjs → builder-BK8HfSUm.mjs} +8 -2
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{compound-proof-5bg_j_ye.mjs → compound-proof-D--HeIbV.mjs} +41 -4
  6. package/dist/{context-CtI307_A.d.ts → context-7NyiqIcg.d.ts} +111 -2
  7. package/dist/{context-B6X-t8gI.d.cts → context-tsYPJ2Ew.d.cts} +111 -2
  8. package/dist/{deno-AmcRMq5z.mjs → deno-DVP7DGJC.mjs} +1 -1
  9. package/dist/{docloader-CIP_SG39.mjs → docloader-Dv1JJl37.mjs} +2 -2
  10. package/dist/federation/builder.test.mjs +1 -1
  11. package/dist/federation/compound-fanout.test.mjs +3 -3
  12. package/dist/federation/handler-compound-proof.test.mjs +3 -3
  13. package/dist/federation/handler.test.mjs +76 -5
  14. package/dist/federation/hashlink-media.test.mjs +2 -2
  15. package/dist/federation/idempotency.test.mjs +2 -2
  16. package/dist/federation/inbox-report.test.d.mts +2 -0
  17. package/dist/federation/inbox-report.test.mjs +475 -0
  18. package/dist/federation/metrics.test.mjs +1 -1
  19. package/dist/federation/middleware.test.mjs +7 -7
  20. package/dist/federation/mod.cjs +1 -1
  21. package/dist/federation/mod.d.cts +4 -3
  22. package/dist/federation/mod.d.ts +4 -3
  23. package/dist/federation/mod.js +1 -1
  24. package/dist/federation/outgoing-proof.test.mjs +54 -10
  25. package/dist/federation/portable-actor.test.mjs +3 -3
  26. package/dist/federation/portable-chain.test.mjs +3 -3
  27. package/dist/federation/portable-collection.test.mjs +66 -4
  28. package/dist/federation/portable-delivery.test.mjs +2 -2
  29. package/dist/federation/portable-gateway-keys.test.mjs +4 -4
  30. package/dist/federation/portable-inbox.test.mjs +67 -6
  31. package/dist/federation/portable-parse-uri.test.mjs +1 -1
  32. package/dist/federation/portable-route-activity.test.mjs +2 -2
  33. package/dist/federation/portable.test.mjs +3 -3
  34. package/dist/federation/send.test.mjs +3 -3
  35. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  36. package/dist/federation/tasks/tasks.test.mjs +2 -2
  37. package/dist/federation/temporal.test.mjs +1 -1
  38. package/dist/federation/webfinger.test.mjs +1 -1
  39. package/dist/{federation-BDzIgqOd.cjs → federation-Bo5z395X.cjs} +552 -122
  40. package/dist/{http-1fZ83jj7.cjs → http-BIhWdDf5.cjs} +447 -110
  41. package/dist/{http-BGb3QioZ.js → http-DRMu1C2T.js} +430 -111
  42. package/dist/{http-DkqWu-sm.mjs → http-DvpuyDJB.mjs} +141 -98
  43. package/dist/{key-CEsu7oaD.mjs → key-B7N8mNoY.mjs} +30 -3
  44. package/dist/{http-BrwKINQn.d.cts → key-C1nv7_jD.d.ts} +638 -229
  45. package/dist/{http-DGx0KOws.d.ts → key-DYxuyd-s.d.cts} +638 -229
  46. package/dist/{kv-cache-CJS4mImS.mjs → kv-cache-D0kA0rml.mjs} +1 -1
  47. package/dist/{kv-cache-CGhEgt98.js → kv-cache-DZLpqhW9.js} +1 -1
  48. package/dist/{kv-cache-BEWuZSB4.cjs → kv-cache-mF8Zmjix.cjs} +1 -1
  49. package/dist/{ld-Cf4CPWN_.mjs → ld-BDMNyM2M.mjs} +40 -5
  50. package/dist/{metrics-CocsZP0E.mjs → metrics-BbBj-VZN.mjs} +2 -1
  51. package/dist/{middleware-Cne_jMZo.mjs → middleware-CE1X7-UM.mjs} +1 -1
  52. package/dist/{middleware-Dxn0E9ES.mjs → middleware-DAA7wDdS.mjs} +520 -131
  53. package/dist/{middleware-BfYke3YQ.js → middleware-DfUWPAa-.js} +552 -122
  54. package/dist/{mod-C7_2j7VT.d.cts → mod-BojP2Bw3.d.cts} +1 -1
  55. package/dist/{mod-BlLwewYe.d.ts → mod-CavhAgLw.d.cts} +5 -255
  56. package/dist/{mod-VHYh1lTK.d.cts → mod-CtpF2BU5.d.ts} +5 -255
  57. package/dist/{mod-B8MI1mpi.d.ts → mod-DEZXwV6J.d.ts} +1 -1
  58. package/dist/{mod-DFL6IxYQ.d.cts → mod-Dw-nPxQh.d.cts} +1 -1
  59. package/dist/{mod-BhTaDR5H.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
  60. package/dist/mod.cjs +4 -4
  61. package/dist/mod.d.cts +7 -7
  62. package/dist/mod.d.ts +7 -7
  63. package/dist/mod.js +4 -4
  64. package/dist/nodeinfo/handler.test.mjs +1 -1
  65. package/dist/{owner-DSJ7nFgy.mjs → owner-CzUycuhd.mjs} +3 -3
  66. package/dist/{portable-collection-BuBV6xTo.js → portable-collection-COcJxZg_.js} +1 -1
  67. package/dist/{portable-collection-qskqXJrH.mjs → portable-collection-CTcNJiAa.mjs} +2 -2
  68. package/dist/{portable-collection-r-mHg1PV.cjs → portable-collection-cPMffcHJ.cjs} +1 -1
  69. package/dist/{portable-key-woGH_1nn.mjs → portable-key-B4QN3OzR.mjs} +1 -1
  70. package/dist/{proof-8WiH_-Gq.mjs → proof-nce4pf5S.mjs} +133 -16
  71. package/dist/{send-JKzZBgPU.mjs → send-4Idpe2z0.mjs} +3 -3
  72. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  73. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  74. package/dist/sig/compound-proof-verification.test.mjs +19 -2
  75. package/dist/sig/compound-proof.test.mjs +2 -2
  76. package/dist/sig/http.test.mjs +2 -2
  77. package/dist/sig/key.test.mjs +1 -1
  78. package/dist/sig/ld.test.mjs +2 -2
  79. package/dist/sig/mitra-receive-interop.test.mjs +4 -4
  80. package/dist/sig/mitra-send-interop.test.mjs +3 -3
  81. package/dist/sig/mod.cjs +2 -2
  82. package/dist/sig/mod.d.cts +2 -2
  83. package/dist/sig/mod.d.ts +2 -2
  84. package/dist/sig/mod.js +2 -2
  85. package/dist/sig/owner.test.mjs +1 -1
  86. package/dist/sig/portable-collection.test.mjs +1 -1
  87. package/dist/sig/portable-interop.test.mjs +3 -3
  88. package/dist/sig/portable-key.test.mjs +6 -6
  89. package/dist/sig/proof.test.mjs +76 -3
  90. package/dist/sig/tootik-request-interop.test.mjs +4 -4
  91. package/dist/sig/tootik-send-interop.test.mjs +3 -3
  92. package/dist/sig/verification.test.d.mts +2 -0
  93. package/dist/sig/verification.test.mjs +310 -0
  94. package/dist/{temporal-CT3fRaMH.mjs → temporal-BbjmPHYn.mjs} +1 -1
  95. package/dist/testing/kv.test.mjs +1 -1
  96. package/dist/testing/mod.d.mts +315 -28
  97. package/dist/utils/docloader.test.mjs +2 -2
  98. package/dist/utils/kv-cache.test.mjs +1 -1
  99. package/dist/utils/mod.cjs +1 -1
  100. package/dist/utils/mod.d.cts +1 -1
  101. package/dist/utils/mod.d.ts +1 -1
  102. package/dist/utils/mod.js +1 -1
  103. package/dist/verification-C3954hQh.mjs +5 -0
  104. package/dist/verification-Dpfcw8ml.mjs +105 -0
  105. package/package.json +7 -7
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-CocsZP0E.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-BbBj-VZN.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { G as validateCryptoKey, ot as recordDocumentCache, t as doubleKnock } from "./http-BGb3QioZ.js";
3
+ import { G as validateCryptoKey, ot as recordDocumentCache, t as doubleKnock } from "./http-DRMu1C2T.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { FetchError, UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, resolveDocumentLoaderTimeout, validatePublicUrl, withDocumentLoaderTimeout } from "@fedify/vocab-runtime";
6
6
  import { curry } from "es-toolkit";
@@ -1,5 +1,5 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
- const require_http = require("./http-1fZ83jj7.cjs");
2
+ const require_http = require("./http-BIhWdDf5.cjs");
3
3
  let _logtape_logtape = require("@logtape/logtape");
4
4
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
5
5
  let es_toolkit = require("es-toolkit");
@@ -1,9 +1,10 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-AmcRMq5z.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CocsZP0E.mjs";
6
- import { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-CEsu7oaD.mjs";
4
+ import { a as verificationObservation, i as triedKey, n as observeCheck, t as observeAttempt } from "./verification-Dpfcw8ml.mjs";
5
+ import { n as version, t as name } from "./deno-DVP7DGJC.mjs";
6
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BbBj-VZN.mjs";
7
+ import { c as validateCryptoKey, i as fetchKey, t as bypassKeyCacheReads } from "./key-B7N8mNoY.mjs";
7
8
  import { getLogger } from "@logtape/logtape";
8
9
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
9
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -450,6 +451,13 @@ function detachSignature(jsonLd) {
450
451
  */
451
452
  async function verifySignature(jsonLd, options = {}) {
452
453
  if (!hasSignature(jsonLd)) return null;
454
+ if (options[verificationObservation]?.attempt != null && options[verificationObservation]?.check == null) {
455
+ const declared = getLdSignatureObject(jsonLd)?.creator;
456
+ return await observeCheck(options, { mechanism: "linkedData" }, typeof declared === "string" ? declared : null, (observation) => verifySignature(jsonLd, {
457
+ ...options,
458
+ [verificationObservation]: observation
459
+ }));
460
+ }
453
461
  const sig = jsonLd.signature;
454
462
  let signature;
455
463
  try {
@@ -495,6 +503,7 @@ async function verifySignature(jsonLd, options = {}) {
495
503
  const encoder = new TextEncoder();
496
504
  const message = sigOptsHash + docHash;
497
505
  const messageBytes = encoder.encode(message);
506
+ triedKey(options, key);
498
507
  if (await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes)) return key;
499
508
  if (cached) {
500
509
  logger.debug("Failed to verify with the cached key {keyId}; signature {signatureValue} is invalid. Retrying with the freshly fetched key...", {
@@ -506,6 +515,7 @@ async function verifySignature(jsonLd, options = {}) {
506
515
  keyCache: bypassKeyCacheReads(options.keyCache)
507
516
  }));
508
517
  if (key == null) return null;
518
+ triedKey(options, key);
509
519
  return await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, signature.slice(), messageBytes) ? key : null;
510
520
  }
511
521
  logger.debug("Failed to verify with the fetched key {keyId}; signature {signatureValue} is invalid. Check if the key is correct or if the signed message is correct. The message to sign is:\n{message}", {
@@ -559,6 +569,14 @@ async function verifyCompactJsonLd(jsonLd, options = {}) {
559
569
  return await verifyJsonLdInternal(jsonLd, options, false);
560
570
  }
561
571
  async function verifyJsonLdInternal(jsonLd, options, compact) {
572
+ if (options[verificationObservation]?.attempt == null) return await observeAttempt({
573
+ ...options,
574
+ [verificationObservation]: options[verificationObservation] ?? { attempts: [] }
575
+ }, "linkedData", (observation) => verifyJsonLdInternal(jsonLd, {
576
+ ...options,
577
+ [verificationObservation]: observation
578
+ }, compact), (value) => value);
579
+ const observation = options[verificationObservation];
562
580
  return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("ld_signatures.verify", async (span) => {
563
581
  const start = performance.now();
564
582
  let verified = false;
@@ -571,6 +589,8 @@ async function verifyJsonLdInternal(jsonLd, options, compact) {
571
589
  } : options;
572
590
  const compacted = compact ? hasSignature(jsonLd) ? await compactJsonLd(jsonLd, options.contextLoader) : jsonLd : jsonLd;
573
591
  const object = await Object$1.fromJsonLd(compacted, verificationOptions);
592
+ observation?.parsedObject?.(object);
593
+ if (observation?.subject != null) observation.subject.id = object.id == null ? null : new URL(object.id.href);
574
594
  if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
575
595
  span.setAttribute("activitypub.object.type", getTypeId(object).href);
576
596
  const sig = getLdSignatureObject(jsonLd);
@@ -585,13 +605,21 @@ async function verifyJsonLdInternal(jsonLd, options, compact) {
585
605
  const attributions = new Set(object.attributionIds.map((uri) => uri.href));
586
606
  if (object instanceof Activity) for (const uri of object.actorIds) attributions.add(uri.href);
587
607
  const key = await verifySignature(compacted, verificationOptions);
588
- if (key == null) return false;
608
+ if (key == null) {
609
+ if (observation?.attempt != null && !hasLdSignatureProperty(jsonLd)) observation.attempt.reason = { type: "noSignature" };
610
+ return false;
611
+ }
589
612
  if (key.ownerId == null) {
613
+ if (observation?.attempt != null) observation.attempt.reason = { type: "missingOwner" };
590
614
  logger.debug("Key {keyId} has no owner.", { keyId: key.id?.href });
591
615
  return false;
592
616
  }
593
617
  attributions.delete(key.ownerId.href);
594
618
  if (attributions.size > 0) {
619
+ if (observation?.attempt != null) observation.attempt.reason = {
620
+ type: "uncoveredAttribution",
621
+ attributionIds: [...attributions].map((id) => new URL(id))
622
+ };
595
623
  logger.debug("Some attributions are not authenticated by the Linked Data Signatures: {attributions}.", { attributions: [...attributions] });
596
624
  return false;
597
625
  }
@@ -605,8 +633,15 @@ async function verifyJsonLdInternal(jsonLd, options, compact) {
605
633
  });
606
634
  throw error;
607
635
  } finally {
636
+ if (observation?.attempt?.reason != null) {
637
+ span.setAttribute("activitypub.verification.failure_reason", observation.attempt.reason.type);
638
+ span.setStatus({ code: SpanStatusCode.ERROR });
639
+ }
608
640
  const classified = threw ? "error" : verified ? "verified" : hasLdSignatureProperty(jsonLd) ? "rejected" : "missing";
609
- getFederationMetrics(options.meterProvider).recordSignatureVerificationDuration(getDurationMs(start), "linked_data", classified, { ldType: signatureType });
641
+ getFederationMetrics(options.meterProvider).recordSignatureVerificationDuration(getDurationMs(start), "linked_data", classified, {
642
+ ldType: signatureType,
643
+ verificationFailureReason: verified || threw ? void 0 : observation?.attempt?.reason?.type ?? (hasLdSignatureProperty(jsonLd) ? "signatureVerificationFailed" : "noSignature")
644
+ });
610
645
  span.end();
611
646
  }
612
647
  });
@@ -1,7 +1,7 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-AmcRMq5z.mjs";
4
+ import { n as version, t as name } from "./deno-DVP7DGJC.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -302,6 +302,7 @@ var FederationMetrics = class {
302
302
  };
303
303
  if (extra.algorithm != null) attributes["http_signatures.algorithm"] = extra.algorithm;
304
304
  if (extra.failureReason != null) attributes["http_signatures.failure_reason"] = extra.failureReason;
305
+ if (extra.verificationFailureReason != null) attributes["activitypub.verification.failure_reason"] = extra.verificationFailureReason;
305
306
  if (extra.ldType != null) attributes["ld_signatures.type"] = extra.ldType;
306
307
  if (extra.cryptosuite != null) attributes["object_integrity_proofs.cryptosuite"] = extra.cryptosuite;
307
308
  this.signatureVerificationDuration.record(durationMs, attributes);
@@ -1,5 +1,5 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-Dxn0E9ES.mjs";
4
+ import { n as FederationImpl } from "./middleware-DAA7wDdS.mjs";
5
5
  export { FederationImpl };