@fedify/vocab 2.4.0-dev.2054 → 2.4.0-dev.2063

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-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { H as Service, N as Organization, P as Person, a as Application, y as Group } from "./vocab-BJGPw--L.mjs";
3
+ import { F as Person, P as Organization, U as Service, a as Application, b as Group } from "./vocab-DZq1JW3s.mjs";
4
4
  import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
5
5
  import { canonicalizePortableUri, formatIri, fromCompatibleEf61Id, isGatewayUrl } from "@fedify/vocab-runtime";
6
6
  import { lookupWebFinger } from "@fedify/webfinger";
@@ -8,7 +8,7 @@ import { SpanStatusCode, trace } from "@opentelemetry/api";
8
8
  import { domainToASCII, domainToUnicode } from "node:url";
9
9
  //#region deno.json
10
10
  var name = "@fedify/vocab";
11
- var version = "2.4.0-dev.2054+1756e190";
11
+ var version = "2.4.0-dev.2063+366c0362";
12
12
  //#endregion
13
13
  //#region src/actor.ts
14
14
  const ACTOR_DISCOVERY_HISTOGRAM_BUCKETS = [
@@ -1,8 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { H as Service, N as Organization, P as Person, Z as __exportAll, a as Application, y as Group } from "./vocab-BJGPw--L.mjs";
4
- import { t as esm_default } from "./esm-Df0Yo-Tp.mjs";
5
- import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-DT_jVPKe.mjs";
3
+ import { F as Person, P as Organization, Q as __exportAll, U as Service, a as Application, b as Group } from "./vocab-DZq1JW3s.mjs";
4
+ import { t as esm_default } from "./esm-CuilqPDu.mjs";
5
+ import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-hpNVHQvY.mjs";
6
6
  import { createTestMeterProvider, test } from "@fedify/fixture";
7
7
  import { deepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
8
8
  //#region ../../node_modules/.pnpm/fast-check@3.23.2/node_modules/fast-check/lib/esm/check/precondition/PreconditionFailure.js
@@ -1,6 +1,6 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { Q as __toESM, X as __commonJSMin } from "./vocab-BJGPw--L.mjs";
3
+ import { $ as __toESM, Z as __commonJSMin } from "./vocab-DZq1JW3s.mjs";
4
4
  //#endregion
5
5
  //#region ../../node_modules/.pnpm/regexparam@3.0.0/node_modules/regexparam/dist/index.mjs
6
6
  var import_glob_to_regexp = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -1,7 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { O as Note, l as Create } from "./vocab-BJGPw--L.mjs";
4
- import { t as esm_default } from "./esm-Df0Yo-Tp.mjs";
3
+ import { F as Person, M as OrderedCollection, c as CollectionPage, k as Note, s as Collection, u as Create } from "./vocab-DZq1JW3s.mjs";
4
+ import { t as esm_default } from "./esm-CuilqPDu.mjs";
5
+ import { n as traverseCollection } from "./lookup-Bi6dOTm_.mjs";
5
6
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
6
7
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
7
8
  import { deepStrictEqual, ok, rejects } from "node:assert/strict";
@@ -600,5 +601,241 @@ test("getObject() sends the ActivityStreams Accept header to gateways", {
600
601
  esm_default.hardReset();
601
602
  }
602
603
  });
604
+ const AS = "https://www.w3.org/ns/activitystreams#";
605
+ function gatewayUrl(gateway, path) {
606
+ return `${gateway}/.well-known/apgateway/${did}${path}`;
607
+ }
608
+ function createRecordingVerifier(decide = () => ({ verified: true })) {
609
+ const calls = [];
610
+ const verifier = async (document, options) => {
611
+ calls.push({
612
+ document,
613
+ options
614
+ });
615
+ return decide(document, options);
616
+ };
617
+ return Object.assign(verifier, { calls });
618
+ }
619
+ function portableCollection(path, extra = {}) {
620
+ return {
621
+ "@context": "https://www.w3.org/ns/activitystreams",
622
+ id: `ap://${did}${path}`,
623
+ type: "OrderedCollection",
624
+ totalItems: 0,
625
+ ...extra
626
+ };
627
+ }
628
+ test("getOutbox() passes the fetch source and referrer to the verifier", async () => {
629
+ const person = await Person.fromJsonLd({
630
+ "@context": "https://www.w3.org/ns/activitystreams",
631
+ id: `ap://${did}/actor`,
632
+ type: "Person",
633
+ inbox: `ap://${did}/actor/inbox`,
634
+ outbox: `ap://${did}/actor/outbox?@gateway=${encodeURIComponent("https://hint.example")}`
635
+ }, { contextLoader: mockDocumentLoader });
636
+ const documentLoader = createLoader({ [gatewayUrl("https://hint.example", "/actor/outbox")]: portableCollection("/actor/outbox") });
637
+ const verifier = createRecordingVerifier();
638
+ assertInstanceOf(await person.getOutbox({
639
+ documentLoader,
640
+ contextLoader: mockDocumentLoader,
641
+ verifyPortableObject: verifier
642
+ }), Collection);
643
+ deepStrictEqual(verifier.calls.length, 1);
644
+ const { options } = verifier.calls[0];
645
+ deepStrictEqual(options.documentUrl, new URL(gatewayUrl("https://hint.example", "/actor/outbox")));
646
+ deepStrictEqual(options.gateways, void 0);
647
+ deepStrictEqual(options.gatewayHints, [new URL("https://hint.example")]);
648
+ ok(options.referrer?.object === person);
649
+ deepStrictEqual(options.referrer?.property, `${AS}outbox`);
650
+ deepStrictEqual(options.referrer?.acceptance, void 0);
651
+ const person2 = await Person.fromJsonLd({
652
+ "@context": "https://www.w3.org/ns/activitystreams",
653
+ id: `ap://${did}/actor`,
654
+ type: "Person",
655
+ inbox: `ap://${did}/actor/inbox`,
656
+ outbox: `ap://${did}/actor/outbox`
657
+ }, { contextLoader: mockDocumentLoader });
658
+ const verifier2 = createRecordingVerifier();
659
+ await person2.getOutbox({
660
+ documentLoader: createLoader({ [gatewayUrl("https://gw.example", "/actor/outbox")]: portableCollection("/actor/outbox") }),
661
+ contextLoader: mockDocumentLoader,
662
+ gateways: ["https://gw.example"],
663
+ verifyPortableObject: verifier2
664
+ });
665
+ deepStrictEqual(verifier2.calls[0].options.gateways, [new URL("https://gw.example")]);
666
+ deepStrictEqual(verifier2.calls[0].options.gatewayHints, void 0);
667
+ });
668
+ test("getFirst() passes the referrer chain and collection context", async () => {
669
+ const context = Object.freeze({});
670
+ const documentLoader = createLoader({
671
+ [gatewayUrl("https://gw.example", "/actor")]: {
672
+ "@context": "https://www.w3.org/ns/activitystreams",
673
+ id: `ap://${did}/actor`,
674
+ type: "Person",
675
+ inbox: `ap://${did}/actor/inbox`,
676
+ outbox: `ap://${did}/actor/outbox`
677
+ },
678
+ [gatewayUrl("https://gw.example", "/actor/outbox")]: portableCollection("/actor/outbox", { first: {
679
+ id: `ap://${did}/actor/outbox?page=1`,
680
+ type: "OrderedCollectionPage",
681
+ next: `ap://${did}/actor/outbox?page=2`
682
+ } }),
683
+ [gatewayUrl("https://gw.example", "/actor/outbox?page=2")]: {
684
+ "@context": "https://www.w3.org/ns/activitystreams",
685
+ id: `ap://${did}/actor/outbox?page=2`,
686
+ type: "OrderedCollectionPage",
687
+ orderedItems: []
688
+ }
689
+ });
690
+ const verifier = createRecordingVerifier((document) => document.type === "OrderedCollection" ? {
691
+ verified: true,
692
+ collectionContext: context
693
+ } : { verified: true });
694
+ const options = {
695
+ documentLoader,
696
+ contextLoader: mockDocumentLoader,
697
+ gateways: ["https://gw.example"],
698
+ verifyPortableObject: verifier
699
+ };
700
+ const create = await createActivity(`ap://${did}/actor`);
701
+ const actor = await create.getObject(options);
702
+ assertInstanceOf(actor, Person);
703
+ const outbox = await actor.getOutbox(options);
704
+ assertInstanceOf(outbox, Collection);
705
+ const first = await outbox.getFirst(options);
706
+ assertInstanceOf(first, CollectionPage);
707
+ assertInstanceOf(await first.getNext(options), CollectionPage);
708
+ const { referrer } = verifier.calls[verifier.calls.length - 1].options;
709
+ ok(referrer?.object === first);
710
+ deepStrictEqual(referrer?.property, `${AS}next`);
711
+ deepStrictEqual(referrer?.acceptance, void 0);
712
+ ok(referrer?.referrer?.object === outbox);
713
+ deepStrictEqual(referrer?.referrer?.property, `${AS}first`);
714
+ deepStrictEqual(referrer?.referrer?.acceptance, "verified");
715
+ ok(referrer?.referrer?.collectionContext === context);
716
+ ok(referrer?.referrer?.referrer?.object === actor);
717
+ deepStrictEqual(referrer?.referrer?.referrer?.property, `${AS}outbox`);
718
+ deepStrictEqual(referrer?.referrer?.referrer?.acceptance, "verified");
719
+ ok(referrer?.referrer?.referrer?.referrer?.object === create);
720
+ });
721
+ test("accessors do not trust objects embedded in unsecured collections", async () => {
722
+ const itemPath = "/objects/1";
723
+ const options = {
724
+ documentLoader: createLoader({
725
+ [gatewayUrl("https://gw.example", "/actor/outbox")]: portableCollection("/actor/outbox", { orderedItems: [{
726
+ id: `ap://${did}${itemPath}`,
727
+ type: "Note",
728
+ content: "Forged"
729
+ }, {
730
+ type: "Note",
731
+ content: "Anonymous"
732
+ }] }),
733
+ [gatewayUrl("https://gw.example", itemPath)]: note()
734
+ }),
735
+ contextLoader: mockDocumentLoader,
736
+ gateways: ["https://gw.example"],
737
+ verifyPortableObject: createRecordingVerifier((document) => document.type === "OrderedCollection" ? {
738
+ verified: true,
739
+ unsecured: true
740
+ } : { verified: true })
741
+ };
742
+ const createPerson = () => Person.fromJsonLd({
743
+ "@context": "https://www.w3.org/ns/activitystreams",
744
+ id: `ap://${did}/actor`,
745
+ type: "Person",
746
+ inbox: `ap://${did}/actor/inbox`,
747
+ outbox: `ap://${did}/actor/outbox`
748
+ }, { contextLoader: mockDocumentLoader });
749
+ const outbox = await (await createPerson()).getOutbox(options);
750
+ assertInstanceOf(outbox, Collection);
751
+ deepStrictEqual((await Array.fromAsync(outbox.getItems(options))).map((item) => item instanceof Note ? item.content : null), ["Portable note"]);
752
+ const outbox2 = await (await createPerson()).getOutbox(options);
753
+ assertInstanceOf(outbox2, Collection);
754
+ deepStrictEqual((await Array.fromAsync(outbox2.getItems({
755
+ ...options,
756
+ crossOrigin: "trust"
757
+ }))).length, 1);
758
+ const outbox3 = await (await createPerson()).getOutbox(options);
759
+ assertInstanceOf(outbox3, Collection);
760
+ deepStrictEqual(await Array.fromAsync(outbox3.clone().getItems({
761
+ ...options,
762
+ documentLoader: createLoader({}),
763
+ suppressError: true
764
+ })), []);
765
+ });
766
+ test("accessors reject compatible identifiers from portable objects", async () => {
767
+ const compatibleId = gatewayUrl("https://evil.example", "/actor/outbox");
768
+ const collection = (id) => ({
769
+ "@context": "https://www.w3.org/ns/activitystreams",
770
+ id,
771
+ type: "OrderedCollection",
772
+ totalItems: 0
773
+ });
774
+ const person = (outbox) => Person.fromJsonLd({
775
+ "@context": "https://www.w3.org/ns/activitystreams",
776
+ id: `ap://${did}/actor`,
777
+ type: "Person",
778
+ inbox: `ap://${did}/actor/inbox`,
779
+ outbox
780
+ }, { contextLoader: mockDocumentLoader });
781
+ const redirectingLoader = (url) => Promise.resolve({
782
+ contextUrl: null,
783
+ documentUrl: url === "https://example.com/outbox" ? compatibleId : url,
784
+ document: collection(url === "https://example.com/outbox" ? compatibleId : url)
785
+ });
786
+ for (const crossOrigin of [void 0, "trust"]) {
787
+ const options = {
788
+ documentLoader: redirectingLoader,
789
+ contextLoader: mockDocumentLoader,
790
+ verifyPortableObject: createRecordingVerifier(),
791
+ crossOrigin
792
+ };
793
+ deepStrictEqual(await (await person(compatibleId)).getOutbox(options), null);
794
+ deepStrictEqual(await (await person("https://example.com/outbox")).getOutbox(options), null);
795
+ deepStrictEqual(await (await person(collection(compatibleId))).getOutbox(options), null);
796
+ }
797
+ await rejects(async () => await (await person(compatibleId)).getOutbox({
798
+ documentLoader: redirectingLoader,
799
+ contextLoader: mockDocumentLoader,
800
+ crossOrigin: "throw"
801
+ }), /portable object/);
802
+ assertInstanceOf(await (await Person.fromJsonLd({
803
+ "@context": "https://www.w3.org/ns/activitystreams",
804
+ id: "https://evil.example/actor",
805
+ type: "Person",
806
+ inbox: "https://evil.example/actor/inbox",
807
+ outbox: compatibleId
808
+ }, { contextLoader: mockDocumentLoader })).getOutbox({
809
+ documentLoader: redirectingLoader,
810
+ contextLoader: mockDocumentLoader
811
+ }), OrderedCollection);
812
+ });
813
+ test("singular accessors drop anonymous objects embedded in unsecured collections", async () => {
814
+ const options = {
815
+ documentLoader: createLoader({ [gatewayUrl("https://gw.example", "/actor/outbox")]: portableCollection("/actor/outbox", { first: {
816
+ type: "OrderedCollectionPage",
817
+ orderedItems: [{
818
+ type: "Note",
819
+ content: "Anonymous"
820
+ }]
821
+ } }) }),
822
+ contextLoader: mockDocumentLoader,
823
+ gateways: ["https://gw.example"],
824
+ verifyPortableObject: createRecordingVerifier(() => ({
825
+ verified: true,
826
+ unsecured: true
827
+ }))
828
+ };
829
+ const outbox = await (await Person.fromJsonLd({
830
+ "@context": "https://www.w3.org/ns/activitystreams",
831
+ id: `ap://${did}/actor`,
832
+ type: "Person",
833
+ inbox: `ap://${did}/actor/inbox`,
834
+ outbox: `ap://${did}/actor/outbox`
835
+ }, { contextLoader: mockDocumentLoader })).getOutbox(options);
836
+ assertInstanceOf(outbox, OrderedCollection);
837
+ deepStrictEqual(await outbox.getFirst(options), null);
838
+ deepStrictEqual(await Array.fromAsync(traverseCollection(outbox, options)), []);
839
+ });
603
840
  //#endregion
604
841
  export {};
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { k as Object$1 } from "./vocab-BJGPw--L.mjs";
4
- import { i as isActor, o as name, s as version } from "./actor-DT_jVPKe.mjs";
3
+ import { A as Object$1 } from "./vocab-DZq1JW3s.mjs";
4
+ import { i as isActor, o as name, s as version } from "./actor-hpNVHQvY.mjs";
5
5
  import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
6
6
  import { canonicalizePortableUri, formatIri, fromCompatibleEf61Id, getDocumentLoader, haveSameFe34Origin, haveSameIriOrigin, parseIri } from "@fedify/vocab-runtime";
7
7
  import { lookupWebFinger } from "@fedify/webfinger";
@@ -1,9 +1,9 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { O as Note, P as Person, k as Object$1, s as Collection } from "./vocab-BJGPw--L.mjs";
4
- import { t as esm_default } from "./esm-Df0Yo-Tp.mjs";
3
+ import { A as Object$1, F as Person, k as Note, s as Collection } from "./vocab-DZq1JW3s.mjs";
4
+ import { t as esm_default } from "./esm-CuilqPDu.mjs";
5
+ import { n as traverseCollection, t as lookupObject } from "./lookup-Bi6dOTm_.mjs";
5
6
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
6
- import { n as traverseCollection, t as lookupObject } from "./lookup-4fEg7Ybl.mjs";
7
7
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
8
8
  import { deepStrictEqual, equal, ok, rejects } from "node:assert/strict";
9
9
  //#region src/lookup.test.ts
@@ -1,10 +1,10 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { P as Person } from "./vocab-BJGPw--L.mjs";
4
- import { t as esm_default } from "./esm-Df0Yo-Tp.mjs";
5
- import { n as getActorHandle } from "./actor-DT_jVPKe.mjs";
3
+ import { F as Person } from "./vocab-DZq1JW3s.mjs";
4
+ import { t as esm_default } from "./esm-CuilqPDu.mjs";
5
+ import { n as getActorHandle } from "./actor-hpNVHQvY.mjs";
6
+ import { t as lookupObject } from "./lookup-Bi6dOTm_.mjs";
6
7
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
7
- import { t as lookupObject } from "./lookup-4fEg7Ybl.mjs";
8
8
  import { mockDocumentLoader, test } from "@fedify/fixture";
9
9
  import { deepStrictEqual, equal, rejects } from "node:assert/strict";
10
10
  import { FetchError, parseIri } from "@fedify/vocab-runtime";
@@ -1,6 +1,6 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { O as Note, R as Question, Y as vocab_exports, i as Announce, j as OrderedCollection, l as Create } from "./vocab-BJGPw--L.mjs";
3
+ import { M as OrderedCollection, X as vocab_exports, i as Announce, k as Note, u as Create, z as Question } from "./vocab-DZq1JW3s.mjs";
4
4
  import { mockDocumentLoader, test } from "@fedify/fixture";
5
5
  import { deepStrictEqual, ok } from "node:assert/strict";
6
6
  import { isMarkerSafeContext, retainSignedRepresentation } from "@fedify/vocab-runtime/internal/signed-representation";
@@ -1,8 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { G as Translation, H as Service, I as PropertyValue, K as Update, N as Organization, O as Note, P as Person, T as Link, a as Application, k as Object$1, l as Create, o as Article, s as Collection, y as Group } from "./vocab-BJGPw--L.mjs";
4
- import "./actor-DT_jVPKe.mjs";
5
- import "./lookup-4fEg7Ybl.mjs";
3
+ import { A as Object$1, E as Link, F as Person, K as Translation, L as PropertyValue, P as Organization, U as Service, a as Application, b as Group, k as Note, o as Article, q as Update, s as Collection, u as Create } from "./vocab-DZq1JW3s.mjs";
4
+ import "./actor-hpNVHQvY.mjs";
5
+ import "./lookup-Bi6dOTm_.mjs";
6
6
  import { test } from "@fedify/fixture";
7
7
  import { deepStrictEqual, ok, rejects } from "node:assert/strict";
8
8
  import { LanguageString as LanguageString$1, getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
@@ -1,6 +1,6 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { J as isEntityType, P as Person, T as Link, q as getEntityTypeById } from "./vocab-BJGPw--L.mjs";
3
+ import { E as Link, F as Person, J as getEntityTypeById, Y as isEntityType } from "./vocab-DZq1JW3s.mjs";
4
4
  import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
5
5
  import { test } from "@fedify/fixture";
6
6
  import { deepStrictEqual } from "node:assert/strict";