cojson 0.8.39 → 0.8.41

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 (36) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/native/coValueCore.js +22 -5
  3. package/dist/native/coValueCore.js.map +1 -1
  4. package/dist/native/coValues/coMap.js +98 -103
  5. package/dist/native/coValues/coMap.js.map +1 -1
  6. package/dist/native/coValues/coStream.js +17 -6
  7. package/dist/native/coValues/coStream.js.map +1 -1
  8. package/dist/native/coValues/group.js +127 -39
  9. package/dist/native/coValues/group.js.map +1 -1
  10. package/dist/native/localNode.js +5 -2
  11. package/dist/native/localNode.js.map +1 -1
  12. package/dist/native/permissions.js +51 -3
  13. package/dist/native/permissions.js.map +1 -1
  14. package/dist/web/coValueCore.js +22 -5
  15. package/dist/web/coValueCore.js.map +1 -1
  16. package/dist/web/coValues/coMap.js +98 -103
  17. package/dist/web/coValues/coMap.js.map +1 -1
  18. package/dist/web/coValues/coStream.js +17 -6
  19. package/dist/web/coValues/coStream.js.map +1 -1
  20. package/dist/web/coValues/group.js +127 -39
  21. package/dist/web/coValues/group.js.map +1 -1
  22. package/dist/web/localNode.js +5 -2
  23. package/dist/web/localNode.js.map +1 -1
  24. package/dist/web/permissions.js +51 -3
  25. package/dist/web/permissions.js.map +1 -1
  26. package/package.json +3 -5
  27. package/src/coValueCore.ts +37 -9
  28. package/src/coValues/coMap.ts +126 -127
  29. package/src/coValues/coStream.ts +27 -10
  30. package/src/coValues/group.ts +218 -50
  31. package/src/localNode.ts +5 -2
  32. package/src/permissions.ts +71 -8
  33. package/src/tests/coMap.test.ts +2 -2
  34. package/src/tests/group.test.ts +332 -38
  35. package/src/tests/permissions.test.ts +324 -0
  36. package/src/tests/testUtils.ts +18 -13
@@ -1574,6 +1574,330 @@ test("ReaderInvites can not invite writers", () => {
1574
1574
  expect(groupAsInvite.get(invitedWriterID)).toBeUndefined();
1575
1575
  });
1576
1576
 
1577
+ test("WriteOnlyInvites can not invite writers", () => {
1578
+ const { groupCore, admin } = newGroup();
1579
+
1580
+ const inviteSecret = Crypto.newRandomAgentSecret();
1581
+ const inviteID = Crypto.getAgentID(inviteSecret);
1582
+
1583
+ const group = expectGroup(groupCore.getCurrentContent());
1584
+
1585
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1586
+ const revelation = Crypto.seal({
1587
+ message: readKey,
1588
+ from: admin.currentSealerSecret(),
1589
+ to: admin.currentSealerID()._unsafeUnwrap(),
1590
+ nOnceMaterial: {
1591
+ in: groupCore.id,
1592
+ tx: groupCore.nextTransactionID(),
1593
+ },
1594
+ });
1595
+
1596
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1597
+ group.set("readKey", readKeyID, "trusting");
1598
+
1599
+ group.set(inviteID, "writeOnlyInvite", "trusting");
1600
+
1601
+ expect(group.get(inviteID)).toEqual("writeOnlyInvite");
1602
+
1603
+ const revelationForInvite = Crypto.seal({
1604
+ message: readKey,
1605
+ from: admin.currentSealerSecret(),
1606
+ to: Crypto.getAgentSealerID(inviteID),
1607
+ nOnceMaterial: {
1608
+ in: groupCore.id,
1609
+ tx: groupCore.nextTransactionID(),
1610
+ },
1611
+ });
1612
+
1613
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1614
+
1615
+ const groupAsInvite = expectGroup(
1616
+ groupCore
1617
+ .testWithDifferentAccount(
1618
+ new ControlledAgent(inviteSecret, Crypto),
1619
+ Crypto.newRandomSessionID(inviteID),
1620
+ )
1621
+ .getCurrentContent(),
1622
+ );
1623
+
1624
+ const invitedWriterSecret = Crypto.newRandomAgentSecret();
1625
+ const invitedWriterID = Crypto.getAgentID(invitedWriterSecret);
1626
+
1627
+ groupAsInvite.set(invitedWriterID, "writer", "trusting");
1628
+ expect(groupAsInvite.get(invitedWriterID)).toBeUndefined();
1629
+ });
1630
+
1631
+ test("WriteOnlyInvites can not invite admins", () => {
1632
+ const { groupCore, admin } = newGroup();
1633
+
1634
+ const inviteSecret = Crypto.newRandomAgentSecret();
1635
+ const inviteID = Crypto.getAgentID(inviteSecret);
1636
+
1637
+ const group = expectGroup(groupCore.getCurrentContent());
1638
+
1639
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1640
+ const revelation = Crypto.seal({
1641
+ message: readKey,
1642
+ from: admin.currentSealerSecret(),
1643
+ to: admin.currentSealerID()._unsafeUnwrap(),
1644
+ nOnceMaterial: {
1645
+ in: groupCore.id,
1646
+ tx: groupCore.nextTransactionID(),
1647
+ },
1648
+ });
1649
+
1650
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1651
+ group.set("readKey", readKeyID, "trusting");
1652
+
1653
+ group.set(inviteID, "writeOnlyInvite", "trusting");
1654
+
1655
+ expect(group.get(inviteID)).toEqual("writeOnlyInvite");
1656
+
1657
+ const revelationForInvite = Crypto.seal({
1658
+ message: readKey,
1659
+ from: admin.currentSealerSecret(),
1660
+ to: Crypto.getAgentSealerID(inviteID),
1661
+ nOnceMaterial: {
1662
+ in: groupCore.id,
1663
+ tx: groupCore.nextTransactionID(),
1664
+ },
1665
+ });
1666
+
1667
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1668
+
1669
+ const groupAsInvite = expectGroup(
1670
+ groupCore
1671
+ .testWithDifferentAccount(
1672
+ new ControlledAgent(inviteSecret, Crypto),
1673
+ Crypto.newRandomSessionID(inviteID),
1674
+ )
1675
+ .getCurrentContent(),
1676
+ );
1677
+
1678
+ const invitedWriterSecret = Crypto.newRandomAgentSecret();
1679
+ const invitedWriterID = Crypto.getAgentID(invitedWriterSecret);
1680
+
1681
+ groupAsInvite.set(invitedWriterID, "admin", "trusting");
1682
+ expect(groupAsInvite.get(invitedWriterID)).toBeUndefined();
1683
+ });
1684
+
1685
+ test("WriteOnlyInvites can invite writeOnly", () => {
1686
+ const { groupCore, admin } = newGroup();
1687
+
1688
+ const inviteSecret = Crypto.newRandomAgentSecret();
1689
+ const inviteID = Crypto.getAgentID(inviteSecret);
1690
+
1691
+ const group = expectGroup(groupCore.getCurrentContent());
1692
+
1693
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1694
+ const revelation = Crypto.seal({
1695
+ message: readKey,
1696
+ from: admin.currentSealerSecret(),
1697
+ to: admin.currentSealerID()._unsafeUnwrap(),
1698
+ nOnceMaterial: {
1699
+ in: groupCore.id,
1700
+ tx: groupCore.nextTransactionID(),
1701
+ },
1702
+ });
1703
+
1704
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1705
+ group.set("readKey", readKeyID, "trusting");
1706
+
1707
+ group.set(inviteID, "writeOnlyInvite", "trusting");
1708
+
1709
+ expect(group.get(inviteID)).toEqual("writeOnlyInvite");
1710
+
1711
+ const revelationForInvite = Crypto.seal({
1712
+ message: readKey,
1713
+ from: admin.currentSealerSecret(),
1714
+ to: Crypto.getAgentSealerID(inviteID),
1715
+ nOnceMaterial: {
1716
+ in: groupCore.id,
1717
+ tx: groupCore.nextTransactionID(),
1718
+ },
1719
+ });
1720
+
1721
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1722
+
1723
+ const groupAsInvite = expectGroup(
1724
+ groupCore
1725
+ .testWithDifferentAccount(
1726
+ new ControlledAgent(inviteSecret, Crypto),
1727
+ Crypto.newRandomSessionID(inviteID),
1728
+ )
1729
+ .getCurrentContent(),
1730
+ );
1731
+
1732
+ const invitedWriterSecret = Crypto.newRandomAgentSecret();
1733
+ const invitedWriterID = Crypto.getAgentID(invitedWriterSecret);
1734
+
1735
+ groupAsInvite.set(invitedWriterID, "writeOnly", "trusting");
1736
+ expect(groupAsInvite.get(invitedWriterID)).toEqual("writeOnly");
1737
+ });
1738
+
1739
+ test("WriteOnlyInvites can set writeKeys", () => {
1740
+ const { groupCore, admin } = newGroup();
1741
+
1742
+ const inviteSecret = Crypto.newRandomAgentSecret();
1743
+ const inviteID = Crypto.getAgentID(inviteSecret);
1744
+
1745
+ const group = expectGroup(groupCore.getCurrentContent());
1746
+
1747
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1748
+ const revelation = Crypto.seal({
1749
+ message: readKey,
1750
+ from: admin.currentSealerSecret(),
1751
+ to: admin.currentSealerID()._unsafeUnwrap(),
1752
+ nOnceMaterial: {
1753
+ in: groupCore.id,
1754
+ tx: groupCore.nextTransactionID(),
1755
+ },
1756
+ });
1757
+
1758
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1759
+ group.set("readKey", readKeyID, "trusting");
1760
+
1761
+ group.set(inviteID, "writeOnlyInvite", "trusting");
1762
+
1763
+ expect(group.get(inviteID)).toEqual("writeOnlyInvite");
1764
+
1765
+ const revelationForInvite = Crypto.seal({
1766
+ message: readKey,
1767
+ from: admin.currentSealerSecret(),
1768
+ to: Crypto.getAgentSealerID(inviteID),
1769
+ nOnceMaterial: {
1770
+ in: groupCore.id,
1771
+ tx: groupCore.nextTransactionID(),
1772
+ },
1773
+ });
1774
+
1775
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1776
+
1777
+ const groupAsInvite = expectGroup(
1778
+ groupCore
1779
+ .testWithDifferentAccount(
1780
+ new ControlledAgent(inviteSecret, Crypto),
1781
+ Crypto.newRandomSessionID(inviteID),
1782
+ )
1783
+ .getCurrentContent(),
1784
+ );
1785
+
1786
+ groupAsInvite.set(`writeKeyFor_${admin.id}`, readKeyID, "trusting");
1787
+ expect(groupAsInvite.get(`writeKeyFor_${admin.id}`)).toEqual(readKeyID);
1788
+ });
1789
+
1790
+ test("Invites can't override key revelations", () => {
1791
+ const { groupCore, admin } = newGroup();
1792
+
1793
+ const inviteSecret = Crypto.newRandomAgentSecret();
1794
+ const inviteID = Crypto.getAgentID(inviteSecret);
1795
+
1796
+ const group = expectGroup(groupCore.getCurrentContent());
1797
+
1798
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1799
+ const revelation = Crypto.seal({
1800
+ message: readKey,
1801
+ from: admin.currentSealerSecret(),
1802
+ to: admin.currentSealerID()._unsafeUnwrap(),
1803
+ nOnceMaterial: {
1804
+ in: groupCore.id,
1805
+ tx: groupCore.nextTransactionID(),
1806
+ },
1807
+ });
1808
+
1809
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1810
+ group.set("readKey", readKeyID, "trusting");
1811
+
1812
+ group.set(inviteID, "readerInvite", "trusting");
1813
+
1814
+ expect(group.get(inviteID)).toEqual("readerInvite");
1815
+
1816
+ const revelationForInvite = Crypto.seal({
1817
+ message: readKey,
1818
+ from: admin.currentSealerSecret(),
1819
+ to: Crypto.getAgentSealerID(inviteID),
1820
+ nOnceMaterial: {
1821
+ in: groupCore.id,
1822
+ tx: groupCore.nextTransactionID(),
1823
+ },
1824
+ });
1825
+
1826
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1827
+
1828
+ const groupAsInvite = expectGroup(
1829
+ groupCore
1830
+ .testWithDifferentAccount(
1831
+ new ControlledAgent(inviteSecret, Crypto),
1832
+ Crypto.newRandomSessionID(inviteID),
1833
+ )
1834
+ .getCurrentContent(),
1835
+ );
1836
+
1837
+ groupAsInvite.set(
1838
+ `${readKeyID}_for_${admin.id}`,
1839
+ "Evil change" as any,
1840
+ "trusting",
1841
+ );
1842
+ expect(groupAsInvite.get(`${readKeyID}_for_${admin.id}`)).toBe(revelation);
1843
+ });
1844
+
1845
+ test("WriteOnlyInvites can't override writeKeys", () => {
1846
+ const { groupCore, admin } = newGroup();
1847
+
1848
+ const inviteSecret = Crypto.newRandomAgentSecret();
1849
+ const inviteID = Crypto.getAgentID(inviteSecret);
1850
+
1851
+ const group = expectGroup(groupCore.getCurrentContent());
1852
+
1853
+ const { secret: readKey, id: readKeyID } = Crypto.newRandomKeySecret();
1854
+ const revelation = Crypto.seal({
1855
+ message: readKey,
1856
+ from: admin.currentSealerSecret(),
1857
+ to: admin.currentSealerID()._unsafeUnwrap(),
1858
+ nOnceMaterial: {
1859
+ in: groupCore.id,
1860
+ tx: groupCore.nextTransactionID(),
1861
+ },
1862
+ });
1863
+
1864
+ group.set(`${readKeyID}_for_${admin.id}`, revelation, "trusting");
1865
+ group.set("readKey", readKeyID, "trusting");
1866
+
1867
+ group.set(inviteID, "writeOnlyInvite", "trusting");
1868
+
1869
+ expect(group.get(inviteID)).toEqual("writeOnlyInvite");
1870
+
1871
+ const revelationForInvite = Crypto.seal({
1872
+ message: readKey,
1873
+ from: admin.currentSealerSecret(),
1874
+ to: Crypto.getAgentSealerID(inviteID),
1875
+ nOnceMaterial: {
1876
+ in: groupCore.id,
1877
+ tx: groupCore.nextTransactionID(),
1878
+ },
1879
+ });
1880
+
1881
+ group.set(`${readKeyID}_for_${inviteID}`, revelationForInvite, "trusting");
1882
+
1883
+ const groupAsInvite = expectGroup(
1884
+ groupCore
1885
+ .testWithDifferentAccount(
1886
+ new ControlledAgent(inviteSecret, Crypto),
1887
+ Crypto.newRandomSessionID(inviteID),
1888
+ )
1889
+ .getCurrentContent(),
1890
+ );
1891
+
1892
+ groupAsInvite.set(`writeKeyFor_${admin.id}`, readKeyID, "trusting");
1893
+ groupAsInvite.set(
1894
+ `writeKeyFor_${admin.id}`,
1895
+ "Evil change" as any,
1896
+ "trusting",
1897
+ );
1898
+ expect(groupAsInvite.get(`writeKeyFor_${admin.id}`)).toEqual(readKeyID);
1899
+ });
1900
+
1577
1901
  test("Can give read permission to 'everyone'", () => {
1578
1902
  const { node, groupCore } = newGroup();
1579
1903
 
@@ -67,17 +67,11 @@ export async function createTwoConnectedNodes(
67
67
  };
68
68
  }
69
69
 
70
- export function createThreeConnectedNodes(
70
+ export async function createThreeConnectedNodes(
71
71
  node1Role: Peer["role"],
72
72
  node2Role: Peer["role"],
73
73
  node3Role: Peer["role"],
74
74
  ) {
75
- // Setup nodes
76
- const node1 = createTestNode();
77
- const node2 = createTestNode();
78
- const node3 = createTestNode();
79
-
80
- // Connect nodes initially
81
75
  const [node1ToNode2Peer, node2ToNode1Peer] = connectedPeers(
82
76
  "node1ToNode2",
83
77
  "node2ToNode1",
@@ -105,12 +99,23 @@ export function createThreeConnectedNodes(
105
99
  },
106
100
  );
107
101
 
108
- node1.syncManager.addPeer(node1ToNode2Peer);
109
- node1.syncManager.addPeer(node1ToNode3Peer);
110
- node2.syncManager.addPeer(node2ToNode1Peer);
111
- node2.syncManager.addPeer(node2ToNode3Peer);
112
- node3.syncManager.addPeer(node3ToNode1Peer);
113
- node3.syncManager.addPeer(node3ToNode2Peer);
102
+ const node1 = await LocalNode.withNewlyCreatedAccount({
103
+ peersToLoadFrom: [node1ToNode2Peer, node1ToNode3Peer],
104
+ crypto: Crypto,
105
+ creationProps: { name: "Node 1" },
106
+ });
107
+
108
+ const node2 = await LocalNode.withNewlyCreatedAccount({
109
+ peersToLoadFrom: [node2ToNode1Peer, node2ToNode3Peer],
110
+ crypto: Crypto,
111
+ creationProps: { name: "Node 2" },
112
+ });
113
+
114
+ const node3 = await LocalNode.withNewlyCreatedAccount({
115
+ peersToLoadFrom: [node3ToNode1Peer, node3ToNode2Peer],
116
+ crypto: Crypto,
117
+ creationProps: { name: "Node 3" },
118
+ });
114
119
 
115
120
  return {
116
121
  node1,