@fedify/fedify 2.2.0-dev.924 → 2.2.0-dev.938

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 (86) hide show
  1. package/dist/assert_strict_equals-Dmjbg-bA.mjs +41 -0
  2. package/dist/{builder-FoLsluZw.mjs → builder-Dq6ijpsL.mjs} +3 -3
  3. package/dist/compat/mod.d.cts +1 -1
  4. package/dist/compat/mod.d.ts +1 -1
  5. package/dist/compat/outgoing-jsonld.test.d.mts +2 -0
  6. package/dist/compat/outgoing-jsonld.test.mjs +189 -0
  7. package/dist/compat/public-audience.test.mjs +1 -1
  8. package/dist/compat/transformers.test.mjs +3 -3
  9. package/dist/{context-BGrYMSTk.d.ts → context-BzH2-ajs.d.ts} +22 -0
  10. package/dist/{context-CMUd4wy0.d.cts → context-DJGagtNd.d.cts} +22 -0
  11. package/dist/{deno-BukNyK1t.mjs → deno-sVjM503s.mjs} +1 -1
  12. package/dist/{docloader-BgBM76TI.mjs → docloader-C5hOIM67.mjs} +2 -2
  13. package/dist/federation/builder.test.mjs +3 -3
  14. package/dist/federation/collection.test.mjs +2 -2
  15. package/dist/federation/handler.test.mjs +8 -8
  16. package/dist/federation/idempotency.test.mjs +5 -5
  17. package/dist/federation/inbox.test.mjs +1 -1
  18. package/dist/federation/keycache.test.mjs +3 -3
  19. package/dist/federation/kv.test.mjs +2 -2
  20. package/dist/federation/middleware.test.mjs +150 -10
  21. package/dist/federation/mod.cjs +1 -1
  22. package/dist/federation/mod.d.cts +2 -2
  23. package/dist/federation/mod.d.ts +2 -2
  24. package/dist/federation/mod.js +1 -1
  25. package/dist/federation/mq.test.mjs +2 -2
  26. package/dist/federation/negotiation.test.mjs +3 -3
  27. package/dist/federation/retry.test.mjs +1 -1
  28. package/dist/federation/router.test.mjs +2 -2
  29. package/dist/federation/send.test.mjs +6 -6
  30. package/dist/federation/webfinger.test.mjs +3 -3
  31. package/dist/{http-DiNUVHGB.js → http-DMkdP3lE.js} +1 -1
  32. package/dist/{http-1uLerNXX.cjs → http-De4te5mA.cjs} +1 -1
  33. package/dist/{http-DSghOjS0.mjs → http-pO-cqL07.mjs} +3 -3
  34. package/dist/{key-DAfSmMg7.mjs → key-Ch1SiRyF.mjs} +1 -1
  35. package/dist/{kv-cache-ia7oECIG.cjs → kv-cache-BM50uOpt.cjs} +1 -1
  36. package/dist/{kv-cache-Dq9VS_Jn.js → kv-cache-D7IdkIte.js} +1 -1
  37. package/dist/{ld-DYpo7uUC.mjs → ld-DkpX94b7.mjs} +2 -2
  38. package/dist/{middleware-rZ0jYYM9.cjs → middleware-0gXHFt3T.cjs} +1 -1
  39. package/dist/{middleware-aawr753E.mjs → middleware-BOshhaxP.mjs} +34 -24
  40. package/dist/{middleware-CjJ_aBdD.mjs → middleware-BqT40f_u.mjs} +1 -1
  41. package/dist/{middleware-Dt0fC6dK.cjs → middleware-CSKiL4bq.cjs} +20 -10
  42. package/dist/{middleware-olp7n2S4.js → middleware-T1_RW8x2.js} +19 -9
  43. package/dist/{mod-CJXfyw7v.d.ts → mod-2d12ffz3.d.ts} +1 -1
  44. package/dist/{mod-BcJHeuv1.d.cts → mod-D35TRn09.d.cts} +1 -1
  45. package/dist/mod.cjs +4 -4
  46. package/dist/mod.d.cts +2 -2
  47. package/dist/mod.d.ts +2 -2
  48. package/dist/mod.js +4 -4
  49. package/dist/nodeinfo/client.test.mjs +2 -2
  50. package/dist/nodeinfo/handler.test.mjs +3 -3
  51. package/dist/nodeinfo/types.test.mjs +2 -2
  52. package/dist/otel/exporter.test.mjs +2 -2
  53. package/dist/outgoing-jsonld-CNmZLixq.mjs +203 -0
  54. package/dist/{owner-B0_w8O-Y.mjs → owner-uOWCZ4oR.mjs} +2 -2
  55. package/dist/{proof-DDZ2W7TX.mjs → proof-B9ynOKyy.mjs} +12 -10
  56. package/dist/{proof-DgRfG4AE.cjs → proof-Bku-2gS1.cjs} +249 -42
  57. package/dist/{proof-DdnQ5edt.js → proof-DONzhIHm.js} +248 -41
  58. package/dist/{public-audience-eovWqzOF.mjs → public-audience-DYFHzm_c.mjs} +20 -9
  59. package/dist/{send-DMLb0UwP.mjs → send-D-qKOq3i.mjs} +2 -2
  60. package/dist/sig/accept.test.mjs +1 -1
  61. package/dist/sig/http.test.mjs +5 -5
  62. package/dist/sig/key.test.mjs +3 -3
  63. package/dist/sig/ld.test.mjs +4 -4
  64. package/dist/sig/mod.cjs +2 -2
  65. package/dist/sig/mod.js +2 -2
  66. package/dist/sig/owner.test.mjs +4 -4
  67. package/dist/sig/proof.test.mjs +25 -10
  68. package/dist/{std__assert-Duiq_YC9.mjs → std__assert-CRDpx_HF.mjs} +3 -38
  69. package/dist/testing/mod.d.mts +22 -0
  70. package/dist/utils/docloader.test.mjs +4 -4
  71. package/dist/utils/kv-cache.test.mjs +1 -1
  72. package/dist/utils/mod.cjs +1 -1
  73. package/dist/utils/mod.js +1 -1
  74. package/package.json +5 -5
  75. /package/dist/{accept-Dd__NiUL.mjs → accept-CPkZzmGN.mjs} +0 -0
  76. /package/dist/{activity-listener-CFzUqoCS.mjs → activity-listener-ell7W1s9.mjs} +0 -0
  77. /package/dist/{assert-ddO5KLpe.mjs → assert-DikXweDx.mjs} +0 -0
  78. /package/dist/{client-DVu6Fmom.mjs → client-D_1QpnWt.mjs} +0 -0
  79. /package/dist/{collection-BQRKGS7L.mjs → collection-D-HqUuA2.mjs} +0 -0
  80. /package/dist/{keycache-C2t1kvP5.mjs → keycache-EGATflN-.mjs} +0 -0
  81. /package/dist/{keys-BAK-tUlf.mjs → keys-DGu1NFwu.mjs} +0 -0
  82. /package/dist/{kv-cache-B01V7s3h.mjs → kv-cache-U__xU4qR.mjs} +0 -0
  83. /package/dist/{kv-C-TG81Sv.mjs → kv-rV3vodCc.mjs} +0 -0
  84. /package/dist/{negotiation-xb0QR3u_.mjs → negotiation-SQvQgUqe.mjs} +0 -0
  85. /package/dist/{retry-CJL0poaU.mjs → retry-bMXBL97A.mjs} +0 -0
  86. /package/dist/{types-CGUnLkU3.mjs → types-J53Kw7so.mjs} +0 -0
@@ -2,15 +2,15 @@ import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
- import "../std__assert-Duiq_YC9.mjs";
5
+ import "../std__assert-CRDpx_HF.mjs";
6
6
  import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
7
7
  import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
8
- import { t as assert } from "../assert-ddO5KLpe.mjs";
9
- import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-BAK-tUlf.mjs";
10
- import { t as normalizePublicAudience } from "../public-audience-eovWqzOF.mjs";
11
- import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-DDZ2W7TX.mjs";
8
+ import { t as assert } from "../assert-DikXweDx.mjs";
9
+ import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
10
+ import { r as normalizeOutgoingActivityJsonLd } from "../outgoing-jsonld-CNmZLixq.mjs";
11
+ import { a as verifyProof, i as verifyObject, n as hasProofLike, r as signObject, t as createProof } from "../proof-B9ynOKyy.mjs";
12
12
  import { mockDocumentLoader, test } from "@fedify/fixture";
13
- import { Create, DataIntegrityProof, Multikey, Note, PUBLIC_COLLECTION, Place } from "@fedify/vocab";
13
+ import { Create, DataIntegrityProof, Document, Multikey, Note, PUBLIC_COLLECTION, Place } from "@fedify/vocab";
14
14
  import { decodeMultibase, importMultibaseKey } from "@fedify/vocab-runtime";
15
15
  import { decodeHex } from "byte-encodings/hex";
16
16
  //#region src/sig/proof.test.ts
@@ -158,7 +158,11 @@ test("signObject()", async () => {
158
158
  object: new Note({
159
159
  id: new URL("https://server.example/objects/2"),
160
160
  attribution: new URL("https://server.example/users/alice"),
161
- content: "Hello public"
161
+ content: "Hello public",
162
+ attachments: [new Document({
163
+ mediaType: "image/png",
164
+ url: new URL("https://server.example/objects/2/image.png")
165
+ })]
162
166
  }),
163
167
  tos: [PUBLIC_COLLECTION]
164
168
  }), fep8b32TestVectorPrivateKey, fep8b32TestVectorKeyId, {
@@ -167,8 +171,10 @@ test("signObject()", async () => {
167
171
  });
168
172
  const [proof] = await Array.fromAsync(signed.getProofs(options));
169
173
  assertInstanceOf(proof, DataIntegrityProof);
170
- const signedJson = await normalizePublicAudience(await signed.toJsonLd(options), mockDocumentLoader);
174
+ const signedJson = await normalizeOutgoingActivityJsonLd(await signed.toJsonLd(options), mockDocumentLoader);
171
175
  assertEquals(signedJson.to, PUBLIC_COLLECTION.href);
176
+ const signedJsonObject = signedJson.object;
177
+ assertEquals(Array.isArray(signedJsonObject.attachment), true);
172
178
  const verifyCache = {};
173
179
  const verifyOptions = {
174
180
  contextLoader: mockDocumentLoader,
@@ -184,6 +190,8 @@ test("signObject()", async () => {
184
190
  assertInstanceOf(await verifyProof(signedJson, proof, verifyOptions), Multikey);
185
191
  const signedJsonWithCurie = await signed.toJsonLd(options);
186
192
  assertEquals(signedJsonWithCurie.to, "as:Public");
193
+ const signedJsonWithCurieObject = signedJsonWithCurie.object;
194
+ assertEquals(Array.isArray(signedJsonWithCurieObject.attachment), false);
187
195
  assertInstanceOf(await verifyProof(signedJsonWithCurie, proof, verifyOptions), Multikey);
188
196
  });
189
197
  test("hasProofLike()", () => {
@@ -294,7 +302,7 @@ test("verifyProof()", async () => {
294
302
  }
295
303
  }, proof, options), expectedKey);
296
304
  assertEquals(await verifyProof([jsonLd], proof, options), null);
297
- assertEquals(await verifyProof({
305
+ const attackerInput = {
298
306
  "@context": ["https://www.w3.org/ns/activitystreams", "https://attacker.example/ctx"],
299
307
  id: "https://server.example/activities/attacker",
300
308
  type: "Create",
@@ -306,10 +314,17 @@ test("verifyProof()", async () => {
306
314
  content: "n/a",
307
315
  to: "as:Public"
308
316
  }
309
- }, proof, {
317
+ };
318
+ const contextLoaderCalls = [];
319
+ assertEquals(await verifyProof(attackerInput, proof, {
320
+ contextLoader: async (url) => {
321
+ contextLoaderCalls.push(url);
322
+ return await mockDocumentLoader(url);
323
+ },
310
324
  documentLoader: mockDocumentLoader,
311
325
  keyCache: options.keyCache
312
326
  }), null);
327
+ assertFalse(contextLoaderCalls.includes("https://attacker.example/ctx"));
313
328
  });
314
329
  test("verifyObject()", async () => {
315
330
  const options = {
@@ -1,9 +1,10 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { a as red, i as buildMessage, l as AssertionError, n as diffStr, r as diff, s as format } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { l as AssertionError, s as format } from "./assert_equals-Ew3jOFa3.mjs";
5
5
  import "./assert_rejects-B-qJtC9Z.mjs";
6
6
  import "./assert_throws-4NwKEy2q.mjs";
7
+ import "./assert_strict_equals-Dmjbg-bA.mjs";
7
8
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_exists.js
8
9
  /**
9
10
  * Make an assertion that actual is not null or undefined.
@@ -77,42 +78,6 @@ import "./assert_throws-4NwKEy2q.mjs";
77
78
  throw new AssertionError(msg ?? `Expect ${actualString} > ${expectedString}`);
78
79
  }
79
80
  //#endregion
80
- //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_strict_equals.js
81
- /**
82
- * Make an assertion that `actual` and `expected` are equal using
83
- * {@linkcode Object.is} for equality comparison. If not, then throw.
84
- *
85
- * @example Usage
86
- * ```ts no-eval
87
- * import { assertStrictEquals } from "@std/assert/assert-strict-equals";
88
- *
89
- * const a = {};
90
- * const b = a;
91
- * assertStrictEquals(a, b); // Doesn't throw
92
- *
93
- * const c = {};
94
- * const d = {};
95
- * assertStrictEquals(c, d); // Throws
96
- * ```
97
- *
98
- * @typeParam T The type of the expected value.
99
- * @param actual The actual value to compare.
100
- * @param expected The expected value to compare.
101
- * @param msg The optional message to display if the assertion fails.
102
- */ function assertStrictEquals(actual, expected, msg) {
103
- if (Object.is(actual, expected)) return;
104
- const msgSuffix = msg ? `: ${msg}` : ".";
105
- let message;
106
- const actualString = format(actual);
107
- const expectedString = format(expected);
108
- if (actualString === expectedString) message = `Values have the same structure but are not reference-equal${msgSuffix}\n\n${red(actualString.split("\n").map((l) => ` ${l}`).join("\n"))}\n`;
109
- else {
110
- const stringDiff = typeof actual === "string" && typeof expected === "string";
111
- message = `Values are not strictly equal${msgSuffix}\n${buildMessage(stringDiff ? diffStr(actual, expected) : diff(actualString.split("\n"), expectedString.split("\n")), { stringDiff }).join("\n")}`;
112
- }
113
- throw new AssertionError(message);
114
- }
115
- //#endregion
116
81
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_string_includes.js
117
82
  /**
118
83
  * Make an assertion that actual includes expected. If not
@@ -136,4 +101,4 @@ import "./assert_throws-4NwKEy2q.mjs";
136
101
  }
137
102
  }
138
103
  //#endregion
139
- export { assertExists as a, assertGreaterOrEqual as i, assertStrictEquals as n, assertGreater as r, assertStringIncludes as t };
104
+ export { assertExists as i, assertGreater as n, assertGreaterOrEqual as r, assertStringIncludes as t };
@@ -584,6 +584,15 @@ interface FanoutMessage {
584
584
  readonly activityType: string;
585
585
  readonly collectionSync?: string;
586
586
  readonly orderingKey?: string;
587
+ /**
588
+ * Whether to apply outgoing JSON-LD wire-format normalization to queued
589
+ * activities that already carry Object Integrity Proofs.
590
+ *
591
+ * `true` is used for proofs Fedify created before fanout, or when callers
592
+ * explicitly request normalization for locally pre-signed activities.
593
+ * `false`/`undefined` preserves existing proofs as-is.
594
+ */
595
+ readonly normalizeExistingProofs?: boolean;
587
596
  readonly traceContext: Readonly<Record<string, string>>;
588
597
  }
589
598
  interface OutboxMessage {
@@ -2215,6 +2224,19 @@ interface SendActivityOptions {
2215
2224
  * @since 1.5.0
2216
2225
  */
2217
2226
  readonly fanout?: "auto" | "skip" | "force";
2227
+ /**
2228
+ * Whether to apply Fedify's outgoing JSON-LD wire-format compatibility fixes
2229
+ * to activities that already carry Object Integrity Proofs.
2230
+ *
2231
+ * By default, Fedify preserves existing proofs byte-for-byte because it
2232
+ * cannot know whether they were created for the normalized outgoing wire
2233
+ * form. Set this to `true` when sending an activity that was pre-signed
2234
+ * locally with `signObject()` or `createProof()`, so the emitted
2235
+ * compact JSON-LD matches the bytes covered by the proof.
2236
+ *
2237
+ * @since 2.2.0
2238
+ */
2239
+ readonly normalizeExistingProofs?: boolean;
2218
2240
  /**
2219
2241
  * The base URIs to exclude from the recipients' inboxes. It is useful
2220
2242
  * for excluding the recipients having the same shared inbox with the sender.
@@ -3,11 +3,11 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { t as esm_default } from "../esm-DVILvP5e.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
- import "../std__assert-Duiq_YC9.mjs";
6
+ import "../std__assert-CRDpx_HF.mjs";
7
7
  import { t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
8
- import { l as verifyRequest } from "../http-DSghOjS0.mjs";
9
- import { i as rsaPrivateKey2 } from "../keys-BAK-tUlf.mjs";
10
- import { t as getAuthenticatedDocumentLoader } from "../docloader-BgBM76TI.mjs";
8
+ import { l as verifyRequest } from "../http-pO-cqL07.mjs";
9
+ import { i as rsaPrivateKey2 } from "../keys-DGu1NFwu.mjs";
10
+ import { t as getAuthenticatedDocumentLoader } from "../docloader-C5hOIM67.mjs";
11
11
  import { mockDocumentLoader, test } from "@fedify/fixture";
12
12
  import { UrlError } from "@fedify/vocab-runtime";
13
13
  //#region src/utils/docloader.test.ts
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as kvCache, t as MockKvStore } from "../kv-cache-B01V7s3h.mjs";
4
+ import { n as kvCache, t as MockKvStore } from "../kv-cache-U__xU4qR.mjs";
5
5
  import { mockDocumentLoader, test } from "@fedify/fixture";
6
6
  import { deepStrictEqual, throws } from "node:assert";
7
7
  import { preloadedContexts } from "@fedify/vocab-runtime";
@@ -1,6 +1,6 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
- const require_kv_cache = require("../kv-cache-ia7oECIG.cjs");
4
+ const require_kv_cache = require("../kv-cache-BM50uOpt.cjs");
5
5
  exports.getAuthenticatedDocumentLoader = require_kv_cache.getAuthenticatedDocumentLoader;
6
6
  exports.kvCache = require_kv_cache.kvCache;
package/dist/utils/mod.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-Dq9VS_Jn.js";
3
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "../kv-cache-D7IdkIte.js";
4
4
  export { getAuthenticatedDocumentLoader, kvCache };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/fedify",
3
- "version": "2.2.0-dev.924+c82ee90a",
3
+ "version": "2.2.0-dev.938+94d98c0c",
4
4
  "description": "An ActivityPub server framework",
5
5
  "keywords": [
6
6
  "ActivityPub",
@@ -153,9 +153,9 @@
153
153
  "uri-template-router": "^1.0.0",
154
154
  "url-template": "^3.1.1",
155
155
  "urlpattern-polyfill": "^10.1.0",
156
- "@fedify/vocab": "2.2.0-dev.924+c82ee90a",
157
- "@fedify/webfinger": "2.2.0-dev.924+c82ee90a",
158
- "@fedify/vocab-runtime": "2.2.0-dev.924+c82ee90a"
156
+ "@fedify/vocab": "2.2.0-dev.938+94d98c0c",
157
+ "@fedify/vocab-runtime": "2.2.0-dev.938+94d98c0c",
158
+ "@fedify/webfinger": "2.2.0-dev.938+94d98c0c"
159
159
  },
160
160
  "devDependencies": {
161
161
  "@std/assert": "npm:@jsr/std__assert@^0.226.0",
@@ -168,7 +168,7 @@
168
168
  "typescript": "^5.9.2",
169
169
  "wrangler": "^4.17.0",
170
170
  "@fedify/fixture": "2.0.0",
171
- "@fedify/vocab-tools": "^2.2.0-dev.924+c82ee90a"
171
+ "@fedify/vocab-tools": "^2.2.0-dev.938+94d98c0c"
172
172
  },
173
173
  "scripts": {
174
174
  "build:self": "tsdown",
File without changes
File without changes
File without changes
File without changes