@fedify/vocab 2.2.18 → 2.2.20

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.
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { C as Question, D as Source, O as Tombstone, S as PropertyValue, T as QuoteRequest, _ as Object$1, a as Collection, b as Person, c as Delete, f as Hashtag, g as Note, h as Link, j as vocab_exports, l as Endpoints, m as InteractionRule, n as Activity, o as Create, p as InteractionPolicy, r as Announce, s as CryptographicKey, t as Accept, u as Follow, v as OrderedCollectionPage, w as QuoteAuthorization, x as Place } from "./vocab-CCpnNoho.mjs";
3
+ import { C as Question, D as Source, O as Tombstone, S as PropertyValue, T as QuoteRequest, _ as Object$1, a as Collection, b as Person, c as Delete, f as Hashtag, g as Note, h as Link, j as vocab_exports, l as Endpoints, m as InteractionRule, n as Activity, o as Create, p as InteractionPolicy, r as Announce, s as CryptographicKey, t as Accept, u as Follow, v as OrderedCollectionPage, w as QuoteAuthorization, x as Place } from "./vocab-C6G3QtaR.mjs";
4
4
  import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
5
5
  import { mockDocumentLoader, test } from "@fedify/fixture";
6
6
  import { deepStrictEqual, notDeepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
@@ -424,7 +424,11 @@ test({
424
424
  }
425
425
  }
426
426
  });
427
- deepStrictEqual(await new Activity({ object: new URL("https://example.com/not-found") }).getObject({ suppressError: true }), null);
427
+ deepStrictEqual(await new Activity({ object: new URL("https://example.com/not-found") }).getObject({
428
+ documentLoader: mockDocumentLoader,
429
+ contextLoader: mockDocumentLoader,
430
+ suppressError: true
431
+ }), null);
428
432
  const object3 = await (await Activity.fromJsonLd({
429
433
  "@context": "https://www.w3.org/ns/activitystreams",
430
434
  type: "Create",
@@ -461,7 +465,11 @@ test({
461
465
  assertInstanceOf(objects[1], Object$1);
462
466
  deepStrictEqual(objects[1].name, "Second object");
463
467
  const activity2 = new Activity({ objects: [new URL("https://example.com/not-found"), new Object$1({ name: "Second object" })] });
464
- const objects2 = await Array.fromAsync(activity2.getObjects({ suppressError: true }));
468
+ const objects2 = await Array.fromAsync(activity2.getObjects({
469
+ documentLoader: mockDocumentLoader,
470
+ contextLoader: mockDocumentLoader,
471
+ suppressError: true
472
+ }));
465
473
  deepStrictEqual(objects2.length, 1);
466
474
  assertInstanceOf(objects2[0], Object$1);
467
475
  deepStrictEqual(objects2[0].name, "Second object");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab",
3
- "version": "2.2.18",
3
+ "version": "2.2.20",
4
4
  "homepage": "https://fedify.dev/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,14 +41,14 @@
41
41
  "@js-temporal/polyfill": "^0.5.1",
42
42
  "@multiformats/base-x": "^4.0.1",
43
43
  "@logtape/logtape": "^2.0.5",
44
- "@opentelemetry/api": "^1.9.0",
44
+ "@opentelemetry/api": "~1.9.0",
45
45
  "asn1js": "^3.0.6",
46
46
  "es-toolkit": "1.43.0",
47
47
  "jsonld": "^9.0.0",
48
48
  "pkijs": "^3.3.3",
49
- "@fedify/vocab-tools": "2.2.18",
50
- "@fedify/vocab-runtime": "2.2.18",
51
- "@fedify/webfinger": "2.2.18"
49
+ "@fedify/webfinger": "2.2.20",
50
+ "@fedify/vocab-tools": "2.2.20",
51
+ "@fedify/vocab-runtime": "2.2.20"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^22.17.0",
@@ -9,10 +9,17 @@ import { lookupObject, traverseCollection } from "./lookup.ts";
9
9
  import { assertInstanceOf } from "./utils.ts";
10
10
  import { Collection, Note, Object, Person } from "./vocab.ts";
11
11
 
12
+ // lookupObject() accepts this option without declaring it, since Fedify's
13
+ // Context passes it. It makes WebFinger lookups use the global fetch()
14
+ // (fetch-mock here) without resolving hostnames, so that the tests do not
15
+ // depend on the real DNS:
16
+ const allowPrivateAddress = { allowPrivateAddress: true };
17
+
12
18
  test("lookupObject()", {
13
19
  sanitizeResources: false,
14
20
  sanitizeOps: false,
15
21
  }, async (t) => {
22
+ const responseTimers: ReturnType<typeof setTimeout>[] = [];
16
23
  fetchMock.spyGlobal();
17
24
 
18
25
  fetchMock.get(
@@ -42,6 +49,7 @@ test("lookupObject()", {
42
49
  const options = {
43
50
  documentLoader: mockDocumentLoader,
44
51
  contextLoader: mockDocumentLoader,
52
+ ...allowPrivateAddress,
45
53
  };
46
54
 
47
55
  await t.step("actor", async () => {
@@ -105,7 +113,7 @@ test("lookupObject()", {
105
113
  "begin:https://example.com/.well-known/webfinger",
106
114
  () =>
107
115
  new Promise((resolve) => {
108
- setTimeout(() => {
116
+ responseTimers.push(setTimeout(() => {
109
117
  resolve({
110
118
  subject: "acct:johndoe@example.com",
111
119
  links: [
@@ -116,7 +124,7 @@ test("lookupObject()", {
116
124
  },
117
125
  ],
118
126
  });
119
- }, 1000);
127
+ }, 1000));
120
128
  }),
121
129
  );
122
130
 
@@ -161,7 +169,7 @@ test("lookupObject()", {
161
169
  "begin:https://example.com/.well-known/webfinger",
162
170
  () =>
163
171
  new Promise((resolve) => {
164
- setTimeout(() => {
172
+ responseTimers.push(setTimeout(() => {
165
173
  resolve({
166
174
  subject: "acct:johndoe@example.com",
167
175
  links: [
@@ -172,7 +180,7 @@ test("lookupObject()", {
172
180
  },
173
181
  ],
174
182
  });
175
- }, 500);
183
+ }, 500));
176
184
  }),
177
185
  );
178
186
 
@@ -192,7 +200,7 @@ test("lookupObject()", {
192
200
  "https://example.com/slow-object",
193
201
  () =>
194
202
  new Promise((resolve) => {
195
- setTimeout(() => {
203
+ responseTimers.push(setTimeout(() => {
196
204
  resolve({
197
205
  status: 200,
198
206
  headers: { "Content-Type": "application/activity+json" },
@@ -202,7 +210,7 @@ test("lookupObject()", {
202
210
  content: "Slow response",
203
211
  },
204
212
  });
205
- }, 1000);
213
+ }, 1000));
206
214
  }),
207
215
  );
208
216
 
@@ -217,6 +225,7 @@ test("lookupObject()", {
217
225
  deepStrictEqual(await promise, null);
218
226
  });
219
227
 
228
+ for (const timer of responseTimers) clearTimeout(timer);
220
229
  fetchMock.hardReset();
221
230
  fetchMock.removeRoutes();
222
231
  });
@@ -479,6 +488,7 @@ test("FEP-fe34: lookupObject() cross-origin security", {
479
488
 
480
489
  // Default behavior should return null
481
490
  const result1 = await lookupObject("@user@example.com", {
491
+ ...allowPrivateAddress,
482
492
  documentLoader: webfingerDocumentLoader,
483
493
  contextLoader: mockDocumentLoader,
484
494
  });
@@ -488,6 +498,7 @@ test("FEP-fe34: lookupObject() cross-origin security", {
488
498
  await rejects(
489
499
  () =>
490
500
  lookupObject("@user@example.com", {
501
+ ...allowPrivateAddress,
491
502
  documentLoader: webfingerDocumentLoader,
492
503
  contextLoader: mockDocumentLoader,
493
504
  crossOrigin: "throw",
@@ -498,6 +509,7 @@ test("FEP-fe34: lookupObject() cross-origin security", {
498
509
 
499
510
  // With crossOrigin: trust, should return the object
500
511
  const result2 = await lookupObject("@user@example.com", {
512
+ ...allowPrivateAddress,
501
513
  documentLoader: webfingerDocumentLoader,
502
514
  contextLoader: mockDocumentLoader,
503
515
  crossOrigin: "trust",
@@ -597,12 +609,22 @@ test("FEP-fe34: lookupObject() cross-origin security", {
597
609
  throw new Error("Network error");
598
610
  };
599
611
 
612
+ // The WebFinger fallback must not reach the network:
613
+ fetchMock.spyGlobal();
614
+ fetchMock.get("begin:https://example.com/.well-known/webfinger", 404);
615
+
600
616
  // Network errors should not be confused with cross-origin errors
601
- const result = await lookupObject("https://example.com/note", {
602
- documentLoader: errorDocumentLoader,
603
- contextLoader: mockDocumentLoader,
604
- crossOrigin: "throw",
605
- });
617
+ let result;
618
+ try {
619
+ result = await lookupObject("https://example.com/note", {
620
+ ...allowPrivateAddress,
621
+ documentLoader: errorDocumentLoader,
622
+ contextLoader: mockDocumentLoader,
623
+ crossOrigin: "throw",
624
+ });
625
+ } finally {
626
+ fetchMock.hardReset();
627
+ }
606
628
 
607
629
  // Should return null because the document loader failed,
608
630
  // not because of cross-origin policy
package/src/vocab.test.ts CHANGED
@@ -623,7 +623,14 @@ test({
623
623
  const activity2 = new Activity({
624
624
  object: new URL("https://example.com/not-found"),
625
625
  });
626
- deepStrictEqual(await activity2.getObject({ suppressError: true }), null);
626
+ deepStrictEqual(
627
+ await activity2.getObject({
628
+ documentLoader: mockDocumentLoader,
629
+ contextLoader: mockDocumentLoader,
630
+ suppressError: true,
631
+ }),
632
+ null,
633
+ );
627
634
 
628
635
  const activity3 = await Activity.fromJsonLd({
629
636
  "@context": "https://www.w3.org/ns/activitystreams",
@@ -678,7 +685,11 @@ test({
678
685
  ],
679
686
  });
680
687
  const objects2 = await Array.fromAsync(
681
- activity2.getObjects({ suppressError: true }),
688
+ activity2.getObjects({
689
+ documentLoader: mockDocumentLoader,
690
+ contextLoader: mockDocumentLoader,
691
+ suppressError: true,
692
+ }),
682
693
  );
683
694
  deepStrictEqual(objects2.length, 1);
684
695
  assertInstanceOf(objects2[0], Object);