@fedify/fedify 1.5.0-dev.672 → 1.5.0-dev.679

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.
package/CHANGES.md CHANGED
@@ -8,6 +8,14 @@ Version 1.5.0
8
8
 
9
9
  To be released.
10
10
 
11
+ - A `Federation` object now can have a canonical origin for web URLs and
12
+ a canonical host for fediverse handles. This affects the URLs constructed
13
+ by `Context` objects, and the WebFinger responses.
14
+
15
+ - Added `CreateFederationOptions.origin` option.
16
+ - Added `FederationOrigin` interface.
17
+ - Added `Context.canonicalOrigin` property.
18
+
11
19
  - Fedify now accepts PEM-PKCS#1 besides PEM-SPKI for RSA public keys.
12
20
  [[#209]]
13
21
 
@@ -16,8 +24,8 @@ To be released.
16
24
  - Added `importPkcs1()` function.
17
25
  - Added `importPem()` function.
18
26
 
19
- - Fedify became to choose the public key of the actor if `keyId` has no
20
- fragment and the actor has only one public key. [[#211]]
27
+ - The `fetchKey()` function became to choose the public key of the actor
28
+ if `keyId` has no fragment and the actor has only one public key. [[#211]]
21
29
 
22
30
  - Fixed a bug of the `fedify inbox` command where it had failed to render
23
31
  the web interface when the `fedify` command was installed using
@@ -33,6 +41,19 @@ To be released.
33
41
  [#211]: https://github.com/fedify-dev/fedify/issues/211
34
42
 
35
43
 
44
+ Version 1.4.3
45
+ -------------
46
+
47
+ Released on February 22, 2025.
48
+
49
+ - Added the following default contexts to `Follow`, `Undo`, and `Update`
50
+ classes:
51
+
52
+ - <https://w3id.org/security/v1>
53
+ - <https://www.w3.org/ns/did/v1>
54
+ - <https://w3id.org/security/multikey/v1>
55
+
56
+
36
57
  Version 1.4.2
37
58
  -------------
38
59
 
@@ -144,6 +165,19 @@ Released on February 5, 2025.
144
165
  [#195]: https://github.com/fedify-dev/fedify/issues/195
145
166
 
146
167
 
168
+ Version 1.3.10
169
+ --------------
170
+
171
+ Released on February 22, 2025.
172
+
173
+ - Added the following default contexts to `Follow`, `Undo`, and `Update`
174
+ classes:
175
+
176
+ - <https://w3id.org/security/v1>
177
+ - <https://www.w3.org/ns/did/v1>
178
+ - <https://w3id.org/security/multikey/v1>
179
+
180
+
147
181
  Version 1.3.9
148
182
  -------------
149
183
 
@@ -371,6 +405,19 @@ Released on November 30, 2024.
371
405
  [#193]: https://github.com/fedify-dev/fedify/issues/193
372
406
 
373
407
 
408
+ Version 1.2.14
409
+ --------------
410
+
411
+ Released on February 22, 2025.
412
+
413
+ - Added the following default contexts to `Follow`, `Undo`, and `Update`
414
+ classes:
415
+
416
+ - <https://w3id.org/security/v1>
417
+ - <https://www.w3.org/ns/did/v1>
418
+ - <https://w3id.org/security/multikey/v1>
419
+
420
+
374
421
  Version 1.2.13
375
422
  --------------
376
423
 
@@ -644,6 +691,19 @@ Released on October 31, 2024.
644
691
  [#118]: https://github.com/fedify-dev/fedify/issues/118
645
692
 
646
693
 
694
+ Version 1.1.14
695
+ --------------
696
+
697
+ Released on February 22, 2025.
698
+
699
+ - Added the following default contexts to `Follow`, `Undo`, and `Update`
700
+ classes:
701
+
702
+ - <https://w3id.org/security/v1>
703
+ - <https://www.w3.org/ns/did/v1>
704
+ - <https://w3id.org/security/multikey/v1>
705
+
706
+
647
707
  Version 1.1.13
648
708
  --------------
649
709
 
@@ -958,6 +1018,19 @@ Released on October 20, 2024.
958
1018
  [#150]: https://github.com/fedify-dev/fedify/issues/150
959
1019
 
960
1020
 
1021
+ Version 1.0.17
1022
+ --------------
1023
+
1024
+ Released on February 22, 2025.
1025
+
1026
+ - Added the following default contexts to `Follow`, `Undo`, and `Update`
1027
+ classes:
1028
+
1029
+ - <https://w3id.org/security/v1>
1030
+ - <https://www.w3.org/ns/did/v1>
1031
+ - <https://w3id.org/security/multikey/v1>
1032
+
1033
+
961
1034
  Version 1.0.16
962
1035
  --------------
963
1036
 
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "@fedify/fedify",
3
- "version": "1.5.0-dev.672+6a6ed659",
3
+ "version": "1.5.0-dev.679+0f44ca2e",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./mod.ts",
@@ -40,6 +40,7 @@ export class FederationImpl {
40
40
  inboxQueueStarted;
41
41
  outboxQueueStarted;
42
42
  manuallyStartQueue;
43
+ origin;
43
44
  router;
44
45
  nodeInfoDispatcher;
45
46
  actorCallbacks;
@@ -94,6 +95,37 @@ export class FederationImpl {
94
95
  this.inboxQueueStarted = false;
95
96
  this.outboxQueueStarted = false;
96
97
  this.manuallyStartQueue = options.manuallyStartQueue ?? false;
98
+ if (options.origin != null) {
99
+ if (typeof options.origin === "string") {
100
+ if (!URL.canParse(options.origin) || !options.origin.match(/^https?:\/\//)) {
101
+ throw new TypeError(`Invalid origin: ${JSON.stringify(options.origin)}`);
102
+ }
103
+ const origin = new URL(options.origin);
104
+ if (!origin.pathname.match(/^\/*$/) || origin.search !== "" ||
105
+ origin.hash !== "") {
106
+ throw new TypeError(`Invalid origin: ${JSON.stringify(options.origin)}`);
107
+ }
108
+ this.origin = { handleHost: origin.host, webOrigin: origin.origin };
109
+ }
110
+ else {
111
+ const { handleHost, webOrigin } = options.origin;
112
+ if (!URL.canParse(`https://${handleHost}/`) || handleHost.includes("/")) {
113
+ throw new TypeError(`Invalid origin.handleHost: ${JSON.stringify(handleHost)}`);
114
+ }
115
+ if (!URL.canParse(webOrigin) || !webOrigin.match(/^https?:\/\//)) {
116
+ throw new TypeError(`Invalid origin.webOrigin: ${JSON.stringify(webOrigin)}`);
117
+ }
118
+ const webOriginUrl = new URL(webOrigin);
119
+ if (!webOriginUrl.pathname.match(/^\/*$/) || webOriginUrl.search !== "" ||
120
+ webOriginUrl.hash !== "") {
121
+ throw new TypeError(`Invalid origin.webOrigin: ${JSON.stringify(webOrigin)}`);
122
+ }
123
+ this.origin = {
124
+ handleHost: new URL(`https://${handleHost}/`).host,
125
+ webOrigin: webOriginUrl.origin,
126
+ };
127
+ }
128
+ }
97
129
  this.router = new Router({
98
130
  trailingSlashInsensitive: options.trailingSlashInsensitive,
99
131
  });
@@ -1318,6 +1350,7 @@ export class FederationImpl {
1318
1350
  case "webfinger":
1319
1351
  return await handleWebFinger(request, {
1320
1352
  context,
1353
+ host: this.origin?.handleHost,
1321
1354
  actorDispatcher: this.actorCallbacks?.dispatcher,
1322
1355
  actorHandleMapper: this.actorCallbacks?.handleMapper,
1323
1356
  actorAliasMapper: this.actorCallbacks?.aliasMapper,
@@ -1536,6 +1569,9 @@ export class ContextImpl {
1536
1569
  get origin() {
1537
1570
  return this.url.origin;
1538
1571
  }
1572
+ get canonicalOrigin() {
1573
+ return this.federation.origin?.webOrigin ?? this.origin;
1574
+ }
1539
1575
  get tracerProvider() {
1540
1576
  return this.federation.tracerProvider;
1541
1577
  }
@@ -1544,14 +1580,14 @@ export class ContextImpl {
1544
1580
  if (path == null) {
1545
1581
  throw new RouterError("No NodeInfo dispatcher registered.");
1546
1582
  }
1547
- return new URL(path, this.url);
1583
+ return new URL(path, this.canonicalOrigin);
1548
1584
  }
1549
1585
  getActorUri(identifier) {
1550
1586
  const path = this.federation.router.build("actor", { identifier, handle: identifier });
1551
1587
  if (path == null) {
1552
1588
  throw new RouterError("No actor dispatcher registered.");
1553
1589
  }
1554
- return new URL(path, this.url);
1590
+ return new URL(path, this.canonicalOrigin);
1555
1591
  }
1556
1592
  getObjectUri(
1557
1593
  // deno-lint-ignore no-explicit-any
@@ -1569,14 +1605,14 @@ export class ContextImpl {
1569
1605
  if (path == null) {
1570
1606
  throw new RouterError("No object dispatcher registered.");
1571
1607
  }
1572
- return new URL(path, this.url);
1608
+ return new URL(path, this.canonicalOrigin);
1573
1609
  }
1574
1610
  getOutboxUri(identifier) {
1575
1611
  const path = this.federation.router.build("outbox", { identifier, handle: identifier });
1576
1612
  if (path == null) {
1577
1613
  throw new RouterError("No outbox dispatcher registered.");
1578
1614
  }
1579
- return new URL(path, this.url);
1615
+ return new URL(path, this.canonicalOrigin);
1580
1616
  }
1581
1617
  getInboxUri(identifier) {
1582
1618
  if (identifier == null) {
@@ -1584,54 +1620,55 @@ export class ContextImpl {
1584
1620
  if (path == null) {
1585
1621
  throw new RouterError("No shared inbox path registered.");
1586
1622
  }
1587
- return new URL(path, this.url);
1623
+ return new URL(path, this.canonicalOrigin);
1588
1624
  }
1589
1625
  const path = this.federation.router.build("inbox", { identifier, handle: identifier });
1590
1626
  if (path == null) {
1591
1627
  throw new RouterError("No inbox path registered.");
1592
1628
  }
1593
- return new URL(path, this.url);
1629
+ return new URL(path, this.canonicalOrigin);
1594
1630
  }
1595
1631
  getFollowingUri(identifier) {
1596
1632
  const path = this.federation.router.build("following", { identifier, handle: identifier });
1597
1633
  if (path == null) {
1598
1634
  throw new RouterError("No following collection path registered.");
1599
1635
  }
1600
- return new URL(path, this.url);
1636
+ return new URL(path, this.canonicalOrigin);
1601
1637
  }
1602
1638
  getFollowersUri(identifier) {
1603
1639
  const path = this.federation.router.build("followers", { identifier, handle: identifier });
1604
1640
  if (path == null) {
1605
1641
  throw new RouterError("No followers collection path registered.");
1606
1642
  }
1607
- return new URL(path, this.url);
1643
+ return new URL(path, this.canonicalOrigin);
1608
1644
  }
1609
1645
  getLikedUri(identifier) {
1610
1646
  const path = this.federation.router.build("liked", { identifier, handle: identifier });
1611
1647
  if (path == null) {
1612
1648
  throw new RouterError("No liked collection path registered.");
1613
1649
  }
1614
- return new URL(path, this.url);
1650
+ return new URL(path, this.canonicalOrigin);
1615
1651
  }
1616
1652
  getFeaturedUri(identifier) {
1617
1653
  const path = this.federation.router.build("featured", { identifier, handle: identifier });
1618
1654
  if (path == null) {
1619
1655
  throw new RouterError("No featured collection path registered.");
1620
1656
  }
1621
- return new URL(path, this.url);
1657
+ return new URL(path, this.canonicalOrigin);
1622
1658
  }
1623
1659
  getFeaturedTagsUri(identifier) {
1624
1660
  const path = this.federation.router.build("featuredTags", { identifier, handle: identifier });
1625
1661
  if (path == null) {
1626
1662
  throw new RouterError("No featured tags collection path registered.");
1627
1663
  }
1628
- return new URL(path, this.url);
1664
+ return new URL(path, this.canonicalOrigin);
1629
1665
  }
1630
1666
  parseUri(uri) {
1631
1667
  if (uri == null)
1632
1668
  return null;
1633
- if (uri.origin !== this.url.origin)
1669
+ if (uri.origin !== this.origin && uri.origin !== this.canonicalOrigin) {
1634
1670
  return null;
1671
+ }
1635
1672
  const route = this.federation.router.route(uri.pathname);
1636
1673
  const logger = getLogger(["fedify", "federation"]);
1637
1674
  if (route == null)
@@ -1798,7 +1835,7 @@ export class ContextImpl {
1798
1835
  logger.warn("No actor dispatcher registered.");
1799
1836
  return [];
1800
1837
  }
1801
- const actorUri = new URL(path, this.url);
1838
+ const actorUri = new URL(path, this.canonicalOrigin);
1802
1839
  const keyPairs = await this.federation.actorCallbacks?.keyPairsDispatcher(new ContextImpl({
1803
1840
  ...this,
1804
1841
  invokedFromActorKeyPairsDispatcher: { identifier },
@@ -1994,7 +2031,7 @@ export class ContextImpl {
1994
2031
  const collectionId = this.federation.router.build("followers", { identifier, handle: identifier });
1995
2032
  opts.collectionSync = collectionId == null
1996
2033
  ? undefined
1997
- : new URL(collectionId, this.url).href;
2034
+ : new URL(collectionId, this.canonicalOrigin).href;
1998
2035
  }
1999
2036
  else {
2000
2037
  expandedRecipients = [recipients];
@@ -12,5 +12,8 @@ description: |
12
12
  defaultContext:
13
13
  - "https://w3id.org/identity/v1"
14
14
  - "https://www.w3.org/ns/activitystreams"
15
+ - "https://w3id.org/security/v1"
15
16
  - "https://w3id.org/security/data-integrity/v1"
17
+ - "https://www.w3.org/ns/did/v1"
18
+ - "https://w3id.org/security/multikey/v1"
16
19
  properties: []
@@ -15,5 +15,8 @@ description: |
15
15
  defaultContext:
16
16
  - "https://w3id.org/identity/v1"
17
17
  - "https://www.w3.org/ns/activitystreams"
18
+ - "https://w3id.org/security/v1"
18
19
  - "https://w3id.org/security/data-integrity/v1"
20
+ - "https://www.w3.org/ns/did/v1"
21
+ - "https://w3id.org/security/multikey/v1"
19
22
  properties: []
@@ -13,7 +13,10 @@ description: |
13
13
  defaultContext:
14
14
  - "https://w3id.org/identity/v1"
15
15
  - "https://www.w3.org/ns/activitystreams"
16
+ - "https://w3id.org/security/v1"
16
17
  - "https://w3id.org/security/data-integrity/v1"
18
+ - "https://www.w3.org/ns/did/v1"
19
+ - "https://w3id.org/security/multikey/v1"
17
20
  - alsoKnownAs:
18
21
  "@id": "as:alsoKnownAs"
19
22
  "@type": "@id"