@calimero-network/mero-js 25.0.3 → 25.0.5
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/dist/account/join-with-node.js +2 -1
- package/dist/account/relay-from-invitation.js +2 -1
- package/dist/admin-api/admin-client.js +91 -92
- package/dist/auth-api/auth-client.js +5 -4
- package/dist/cloud/cloud-client.d.ts +5 -1
- package/dist/cloud/cloud-client.js +23 -12
- package/dist/cloud/link-redirect.d.ts +4 -3
- package/dist/cloud/link-redirect.js +11 -8
- package/dist/cloud/link-state.d.ts +13 -0
- package/dist/cloud/link-state.js +60 -0
- package/dist/http-client/path-segment.d.ts +1 -0
- package/dist/http-client/path-segment.js +8 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +200 -124
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +200 -124
- package/dist/index.mjs.map +4 -4
- package/dist/relay/relay-client.js +8 -7
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -836,6 +836,14 @@ function createRetryableMethod(method, retryOptions = {}) {
|
|
|
836
836
|
};
|
|
837
837
|
}
|
|
838
838
|
|
|
839
|
+
// src/http-client/path-segment.ts
|
|
840
|
+
function pathSegment(id) {
|
|
841
|
+
if (id === "" || id === "." || id === "..") {
|
|
842
|
+
throw new TypeError(`invalid request path segment: ${JSON.stringify(id)}`);
|
|
843
|
+
}
|
|
844
|
+
return encodeURIComponent(id);
|
|
845
|
+
}
|
|
846
|
+
|
|
839
847
|
// src/auth-api/auth-client.ts
|
|
840
848
|
var AuthApiClient = class {
|
|
841
849
|
constructor(httpClient) {
|
|
@@ -937,7 +945,7 @@ var AuthApiClient = class {
|
|
|
937
945
|
return response.data;
|
|
938
946
|
}
|
|
939
947
|
async deleteRootKey(keyId) {
|
|
940
|
-
return this.httpClient.delete(`/admin/keys/${keyId}`);
|
|
948
|
+
return this.httpClient.delete(`/admin/keys/${pathSegment(keyId)}`);
|
|
941
949
|
}
|
|
942
950
|
// Client Management Endpoints
|
|
943
951
|
async listClientKeys() {
|
|
@@ -954,18 +962,18 @@ var AuthApiClient = class {
|
|
|
954
962
|
}
|
|
955
963
|
async deleteClientKey(keyId, clientId) {
|
|
956
964
|
return this.httpClient.delete(
|
|
957
|
-
`/admin/keys/${keyId}/clients/${clientId}`
|
|
965
|
+
`/admin/keys/${pathSegment(keyId)}/clients/${pathSegment(clientId)}`
|
|
958
966
|
);
|
|
959
967
|
}
|
|
960
968
|
// Permission Management Endpoints
|
|
961
969
|
async getKeyPermissions(keyId) {
|
|
962
970
|
return this.httpClient.get(
|
|
963
|
-
`/admin/keys/${keyId}/permissions`
|
|
971
|
+
`/admin/keys/${pathSegment(keyId)}/permissions`
|
|
964
972
|
);
|
|
965
973
|
}
|
|
966
974
|
async updateKeyPermissions(keyId, changes) {
|
|
967
975
|
return this.httpClient.put(
|
|
968
|
-
`/admin/keys/${keyId}/permissions`,
|
|
976
|
+
`/admin/keys/${pathSegment(keyId)}/permissions`,
|
|
969
977
|
{ add: changes.add, remove: changes.remove }
|
|
970
978
|
);
|
|
971
979
|
}
|
|
@@ -1387,13 +1395,13 @@ var AdminApiClient = class {
|
|
|
1387
1395
|
return unwrap(await this.httpClient.post("/admin-api/install-dev-application", request));
|
|
1388
1396
|
}
|
|
1389
1397
|
async uninstallApplication(appId) {
|
|
1390
|
-
return unwrap(await this.httpClient.delete(`/admin-api/applications/${appId}`));
|
|
1398
|
+
return unwrap(await this.httpClient.delete(`/admin-api/applications/${pathSegment(appId)}`));
|
|
1391
1399
|
}
|
|
1392
1400
|
async listApplications() {
|
|
1393
1401
|
return unwrap(await this.httpClient.get("/admin-api/applications"));
|
|
1394
1402
|
}
|
|
1395
1403
|
async getApplication(appId) {
|
|
1396
|
-
return unwrap(await this.httpClient.get(`/admin-api/applications/${appId}`));
|
|
1404
|
+
return unwrap(await this.httpClient.get(`/admin-api/applications/${pathSegment(appId)}`));
|
|
1397
1405
|
}
|
|
1398
1406
|
/**
|
|
1399
1407
|
* Installed-blob inventory for an application — one entry per locally installed
|
|
@@ -1402,7 +1410,7 @@ var AdminApiClient = class {
|
|
|
1402
1410
|
*/
|
|
1403
1411
|
async listApplicationVersions(applicationId) {
|
|
1404
1412
|
return unwrap(
|
|
1405
|
-
await this.httpClient.get(`/admin-api/applications/${applicationId}/versions`)
|
|
1413
|
+
await this.httpClient.get(`/admin-api/applications/${pathSegment(applicationId)}/versions`)
|
|
1406
1414
|
);
|
|
1407
1415
|
}
|
|
1408
1416
|
/**
|
|
@@ -1413,7 +1421,7 @@ var AdminApiClient = class {
|
|
|
1413
1421
|
const query = serviceName ? `?service_name=${encodeURIComponent(serviceName)}` : "";
|
|
1414
1422
|
return unwrap(
|
|
1415
1423
|
await this.httpClient.get(
|
|
1416
|
-
`/admin-api/applications/${applicationId}/abi${query}`
|
|
1424
|
+
`/admin-api/applications/${pathSegment(applicationId)}/abi${query}`
|
|
1417
1425
|
)
|
|
1418
1426
|
);
|
|
1419
1427
|
}
|
|
@@ -1426,13 +1434,13 @@ var AdminApiClient = class {
|
|
|
1426
1434
|
}
|
|
1427
1435
|
async listPackageVersions(packageName) {
|
|
1428
1436
|
const r = await this.httpClient.get(
|
|
1429
|
-
`/admin-api/packages/${
|
|
1437
|
+
`/admin-api/packages/${pathSegment(packageName)}/versions`
|
|
1430
1438
|
);
|
|
1431
1439
|
return r?.data ?? r;
|
|
1432
1440
|
}
|
|
1433
1441
|
async getLatestPackageVersion(packageName) {
|
|
1434
1442
|
return this.httpClient.get(
|
|
1435
|
-
`/admin-api/packages/${
|
|
1443
|
+
`/admin-api/packages/${pathSegment(packageName)}/latest`
|
|
1436
1444
|
);
|
|
1437
1445
|
}
|
|
1438
1446
|
// ---- Context Management ----
|
|
@@ -1441,43 +1449,43 @@ var AdminApiClient = class {
|
|
|
1441
1449
|
return unwrap(await this.httpClient.post("/admin-api/contexts", body));
|
|
1442
1450
|
}
|
|
1443
1451
|
async deleteContext(contextId) {
|
|
1444
|
-
return unwrap(await this.httpClient.delete(`/admin-api/contexts/${contextId}`));
|
|
1452
|
+
return unwrap(await this.httpClient.delete(`/admin-api/contexts/${pathSegment(contextId)}`));
|
|
1445
1453
|
}
|
|
1446
1454
|
async getContexts() {
|
|
1447
1455
|
return unwrap(await this.httpClient.get("/admin-api/contexts"));
|
|
1448
1456
|
}
|
|
1449
1457
|
async getContext(contextId) {
|
|
1450
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}`));
|
|
1458
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}`));
|
|
1451
1459
|
}
|
|
1452
1460
|
async getContextsForApplication(applicationId) {
|
|
1453
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/for-application/${applicationId}`));
|
|
1461
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/for-application/${pathSegment(applicationId)}`));
|
|
1454
1462
|
}
|
|
1455
1463
|
// ---- Context Identity ----
|
|
1456
1464
|
async generateContextIdentity() {
|
|
1457
1465
|
return unwrap(await this.httpClient.post("/admin-api/identity/context", {}));
|
|
1458
1466
|
}
|
|
1459
1467
|
async getContextIdentities(contextId) {
|
|
1460
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities`));
|
|
1468
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/identities`));
|
|
1461
1469
|
}
|
|
1462
1470
|
async getContextIdentitiesOwned(contextId) {
|
|
1463
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities-owned`));
|
|
1471
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/identities-owned`));
|
|
1464
1472
|
}
|
|
1465
1473
|
// ---- Context join (group membership) ----
|
|
1466
1474
|
async joinContext(contextId) {
|
|
1467
1475
|
return unwrap(
|
|
1468
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/join`, {})
|
|
1476
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/join`, {})
|
|
1469
1477
|
);
|
|
1470
1478
|
}
|
|
1471
1479
|
// ---- Context group / storage / sync ----
|
|
1472
1480
|
async getContextGroup(contextId) {
|
|
1473
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/group`));
|
|
1481
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/group`));
|
|
1474
1482
|
}
|
|
1475
1483
|
async getContextStorage(contextId) {
|
|
1476
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/storage`));
|
|
1484
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/storage`));
|
|
1477
1485
|
}
|
|
1478
1486
|
/** Sync one context, or every context when `contextId` is omitted. */
|
|
1479
1487
|
async syncContext(contextId) {
|
|
1480
|
-
const path = contextId ? `/admin-api/contexts/sync/${contextId}` : "/admin-api/contexts/sync";
|
|
1488
|
+
const path = contextId ? `/admin-api/contexts/sync/${pathSegment(contextId)}` : "/admin-api/contexts/sync";
|
|
1481
1489
|
await this.httpClient.post(path, {});
|
|
1482
1490
|
}
|
|
1483
1491
|
/**
|
|
@@ -1487,7 +1495,7 @@ var AdminApiClient = class {
|
|
|
1487
1495
|
*/
|
|
1488
1496
|
async resyncContext(contextId, request = {}) {
|
|
1489
1497
|
const r = await this.httpClient.post(
|
|
1490
|
-
`/admin-api/contexts/${contextId}/resync`,
|
|
1498
|
+
`/admin-api/contexts/${pathSegment(contextId)}/resync`,
|
|
1491
1499
|
request
|
|
1492
1500
|
);
|
|
1493
1501
|
return r ?? { contextId, resyncStarted: true };
|
|
@@ -1501,10 +1509,10 @@ var AdminApiClient = class {
|
|
|
1501
1509
|
);
|
|
1502
1510
|
}
|
|
1503
1511
|
async updateContextApplication(contextId, request) {
|
|
1504
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/application`, request);
|
|
1512
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/application`, request);
|
|
1505
1513
|
}
|
|
1506
1514
|
async getContextsWithExecutorsForApplication(applicationId) {
|
|
1507
|
-
const r = await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${applicationId}`);
|
|
1515
|
+
const r = await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${pathSegment(applicationId)}`);
|
|
1508
1516
|
if (Array.isArray(r)) return r;
|
|
1509
1517
|
return r?.contexts ?? r?.data ?? [];
|
|
1510
1518
|
}
|
|
@@ -1526,7 +1534,7 @@ var AdminApiClient = class {
|
|
|
1526
1534
|
}
|
|
1527
1535
|
async deleteBlob(blobId) {
|
|
1528
1536
|
const body = await this.httpClient.delete(
|
|
1529
|
-
`/admin-api/blobs/${blobId}`
|
|
1537
|
+
`/admin-api/blobs/${pathSegment(blobId)}`
|
|
1530
1538
|
);
|
|
1531
1539
|
return { blobId: body.blob_id, deleted: body.deleted };
|
|
1532
1540
|
}
|
|
@@ -1544,9 +1552,9 @@ var AdminApiClient = class {
|
|
|
1544
1552
|
* side from drifting from the write side.
|
|
1545
1553
|
*/
|
|
1546
1554
|
blobPath(blobId, options) {
|
|
1547
|
-
if (!options?.contextId) return `/admin-api/blobs/${blobId}`;
|
|
1555
|
+
if (!options?.contextId) return `/admin-api/blobs/${pathSegment(blobId)}`;
|
|
1548
1556
|
const params = new URLSearchParams({ context_id: options.contextId });
|
|
1549
|
-
return `/admin-api/blobs/${blobId}?${params.toString()}`;
|
|
1557
|
+
return `/admin-api/blobs/${pathSegment(blobId)}?${params.toString()}`;
|
|
1550
1558
|
}
|
|
1551
1559
|
/**
|
|
1552
1560
|
* Download a blob's raw bytes. `GET /admin-api/blobs/:id` streams the blob
|
|
@@ -1611,7 +1619,7 @@ var AdminApiClient = class {
|
|
|
1611
1619
|
async lookupContextAlias(name) {
|
|
1612
1620
|
return unwrap(
|
|
1613
1621
|
await this.httpClient.post(
|
|
1614
|
-
`/admin-api/alias/lookup/context/${
|
|
1622
|
+
`/admin-api/alias/lookup/context/${pathSegment(name)}`,
|
|
1615
1623
|
{}
|
|
1616
1624
|
)
|
|
1617
1625
|
);
|
|
@@ -1619,7 +1627,7 @@ var AdminApiClient = class {
|
|
|
1619
1627
|
async lookupApplicationAlias(name) {
|
|
1620
1628
|
return unwrap(
|
|
1621
1629
|
await this.httpClient.post(
|
|
1622
|
-
`/admin-api/alias/lookup/application/${
|
|
1630
|
+
`/admin-api/alias/lookup/application/${pathSegment(name)}`,
|
|
1623
1631
|
{}
|
|
1624
1632
|
)
|
|
1625
1633
|
);
|
|
@@ -1627,7 +1635,7 @@ var AdminApiClient = class {
|
|
|
1627
1635
|
async deleteContextAlias(name) {
|
|
1628
1636
|
return unwrap(
|
|
1629
1637
|
await this.httpClient.post(
|
|
1630
|
-
`/admin-api/alias/delete/context/${
|
|
1638
|
+
`/admin-api/alias/delete/context/${pathSegment(name)}`,
|
|
1631
1639
|
{}
|
|
1632
1640
|
)
|
|
1633
1641
|
);
|
|
@@ -1635,7 +1643,7 @@ var AdminApiClient = class {
|
|
|
1635
1643
|
async deleteApplicationAlias(name) {
|
|
1636
1644
|
return unwrap(
|
|
1637
1645
|
await this.httpClient.post(
|
|
1638
|
-
`/admin-api/alias/delete/application/${
|
|
1646
|
+
`/admin-api/alias/delete/application/${pathSegment(name)}`,
|
|
1639
1647
|
{}
|
|
1640
1648
|
)
|
|
1641
1649
|
);
|
|
@@ -1657,7 +1665,7 @@ var AdminApiClient = class {
|
|
|
1657
1665
|
async lookupDeviceAlias(name) {
|
|
1658
1666
|
return unwrap(
|
|
1659
1667
|
await this.httpClient.post(
|
|
1660
|
-
`/admin-api/alias/lookup/device/${
|
|
1668
|
+
`/admin-api/alias/lookup/device/${pathSegment(name)}`,
|
|
1661
1669
|
{}
|
|
1662
1670
|
)
|
|
1663
1671
|
);
|
|
@@ -1665,7 +1673,7 @@ var AdminApiClient = class {
|
|
|
1665
1673
|
async deleteDeviceAlias(name) {
|
|
1666
1674
|
return unwrap(
|
|
1667
1675
|
await this.httpClient.post(
|
|
1668
|
-
`/admin-api/alias/delete/device/${
|
|
1676
|
+
`/admin-api/alias/delete/device/${pathSegment(name)}`,
|
|
1669
1677
|
{}
|
|
1670
1678
|
)
|
|
1671
1679
|
);
|
|
@@ -1678,7 +1686,7 @@ var AdminApiClient = class {
|
|
|
1678
1686
|
return unwrap(await this.httpClient.get("/admin-api/namespaces"));
|
|
1679
1687
|
}
|
|
1680
1688
|
async getNamespace(namespaceId) {
|
|
1681
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}`));
|
|
1689
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${pathSegment(namespaceId)}`));
|
|
1682
1690
|
}
|
|
1683
1691
|
/**
|
|
1684
1692
|
* Who this node is — the account it writes as, the device it is, the key it
|
|
@@ -1743,7 +1751,7 @@ var AdminApiClient = class {
|
|
|
1743
1751
|
async performIntent(contextId, request) {
|
|
1744
1752
|
return unwrap(
|
|
1745
1753
|
await this.httpClient.post(
|
|
1746
|
-
`/admin-api/contexts/${contextId}/intents`,
|
|
1754
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`,
|
|
1747
1755
|
request
|
|
1748
1756
|
)
|
|
1749
1757
|
);
|
|
@@ -1760,7 +1768,7 @@ var AdminApiClient = class {
|
|
|
1760
1768
|
async queryContext(contextId, request) {
|
|
1761
1769
|
return unwrap(
|
|
1762
1770
|
await this.httpClient.post(
|
|
1763
|
-
`/admin-api/contexts/${contextId}/query`,
|
|
1771
|
+
`/admin-api/contexts/${pathSegment(contextId)}/query`,
|
|
1764
1772
|
request
|
|
1765
1773
|
)
|
|
1766
1774
|
);
|
|
@@ -1789,12 +1797,12 @@ var AdminApiClient = class {
|
|
|
1789
1797
|
async getIntentRelay(contextId) {
|
|
1790
1798
|
return unwrap(
|
|
1791
1799
|
await this.httpClient.get(
|
|
1792
|
-
`/admin-api/contexts/${contextId}/intents`
|
|
1800
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`
|
|
1793
1801
|
)
|
|
1794
1802
|
);
|
|
1795
1803
|
}
|
|
1796
1804
|
async listNamespacesForApplication(applicationId) {
|
|
1797
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/for-application/${applicationId}`));
|
|
1805
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/for-application/${pathSegment(applicationId)}`));
|
|
1798
1806
|
}
|
|
1799
1807
|
async createNamespace(request) {
|
|
1800
1808
|
return unwrap(
|
|
@@ -1803,7 +1811,7 @@ var AdminApiClient = class {
|
|
|
1803
1811
|
}
|
|
1804
1812
|
async deleteNamespace(namespaceId) {
|
|
1805
1813
|
return unwrap(
|
|
1806
|
-
await this.httpClient.request(`/admin-api/namespaces/${namespaceId}`, {
|
|
1814
|
+
await this.httpClient.request(`/admin-api/namespaces/${pathSegment(namespaceId)}`, {
|
|
1807
1815
|
method: "DELETE",
|
|
1808
1816
|
body: "{}",
|
|
1809
1817
|
headers: { "Content-Type": "application/json" }
|
|
@@ -1813,7 +1821,7 @@ var AdminApiClient = class {
|
|
|
1813
1821
|
async createNamespaceInvitation(namespaceId, request) {
|
|
1814
1822
|
return unwrap(
|
|
1815
1823
|
await this.httpClient.post(
|
|
1816
|
-
`/admin-api/namespaces/${namespaceId}/invite`,
|
|
1824
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/invite`,
|
|
1817
1825
|
request ?? {}
|
|
1818
1826
|
)
|
|
1819
1827
|
);
|
|
@@ -1838,7 +1846,7 @@ var AdminApiClient = class {
|
|
|
1838
1846
|
async admitJoin(namespaceId, request) {
|
|
1839
1847
|
return unwrap(
|
|
1840
1848
|
await this.httpClient.post(
|
|
1841
|
-
`/admin-api/namespaces/${namespaceId}/admit`,
|
|
1849
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/admit`,
|
|
1842
1850
|
request,
|
|
1843
1851
|
{ timeoutMs: 65e3 }
|
|
1844
1852
|
)
|
|
@@ -1847,7 +1855,7 @@ var AdminApiClient = class {
|
|
|
1847
1855
|
async joinNamespace(namespaceId, request) {
|
|
1848
1856
|
const data = unwrap(
|
|
1849
1857
|
await this.httpClient.post(
|
|
1850
|
-
`/admin-api/namespaces/${namespaceId}/join`,
|
|
1858
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/join`,
|
|
1851
1859
|
request,
|
|
1852
1860
|
{ timeoutMs: 65e3 }
|
|
1853
1861
|
)
|
|
@@ -1894,13 +1902,13 @@ var AdminApiClient = class {
|
|
|
1894
1902
|
async createGroupInNamespace(namespaceId, request) {
|
|
1895
1903
|
return unwrap(
|
|
1896
1904
|
await this.httpClient.post(
|
|
1897
|
-
`/admin-api/namespaces/${namespaceId}/groups`,
|
|
1905
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/groups`,
|
|
1898
1906
|
request ?? {}
|
|
1899
1907
|
)
|
|
1900
1908
|
);
|
|
1901
1909
|
}
|
|
1902
1910
|
async listNamespaceGroups(namespaceId) {
|
|
1903
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}/groups`));
|
|
1911
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${pathSegment(namespaceId)}/groups`));
|
|
1904
1912
|
}
|
|
1905
1913
|
// ---- Account Devices & Pairing ----
|
|
1906
1914
|
/**
|
|
@@ -1962,7 +1970,7 @@ var AdminApiClient = class {
|
|
|
1962
1970
|
async relinkAccountDevice(deviceId, request) {
|
|
1963
1971
|
return unwrap(
|
|
1964
1972
|
await this.httpClient.post(
|
|
1965
|
-
`/admin-api/account/devices/${deviceId}/relink`,
|
|
1973
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/relink`,
|
|
1966
1974
|
request ?? {}
|
|
1967
1975
|
)
|
|
1968
1976
|
);
|
|
@@ -1977,7 +1985,7 @@ var AdminApiClient = class {
|
|
|
1977
1985
|
async rescopeAccountDevice(deviceId, request) {
|
|
1978
1986
|
return unwrap(
|
|
1979
1987
|
await this.httpClient.put(
|
|
1980
|
-
`/admin-api/account/devices/${
|
|
1988
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/scope`,
|
|
1981
1989
|
request
|
|
1982
1990
|
)
|
|
1983
1991
|
);
|
|
@@ -2028,7 +2036,7 @@ var AdminApiClient = class {
|
|
|
2028
2036
|
async labelAccountDevice(deviceId, request) {
|
|
2029
2037
|
return unwrap(
|
|
2030
2038
|
await this.httpClient.put(
|
|
2031
|
-
`/admin-api/account/devices/${
|
|
2039
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/label`,
|
|
2032
2040
|
request
|
|
2033
2041
|
)
|
|
2034
2042
|
);
|
|
@@ -2092,7 +2100,7 @@ var AdminApiClient = class {
|
|
|
2092
2100
|
async revokeAccountDevice(namespaceId, request) {
|
|
2093
2101
|
return unwrap(
|
|
2094
2102
|
await this.httpClient.post(
|
|
2095
|
-
`/admin-api/namespaces/${namespaceId}/account/revoke`,
|
|
2103
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/account/revoke`,
|
|
2096
2104
|
request
|
|
2097
2105
|
)
|
|
2098
2106
|
);
|
|
@@ -2115,14 +2123,14 @@ var AdminApiClient = class {
|
|
|
2115
2123
|
async linkAccountDevice(namespaceId, request) {
|
|
2116
2124
|
return unwrap(
|
|
2117
2125
|
await this.httpClient.post(
|
|
2118
|
-
`/admin-api/namespaces/${namespaceId}/account/link-device`,
|
|
2126
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/account/link-device`,
|
|
2119
2127
|
request
|
|
2120
2128
|
)
|
|
2121
2129
|
);
|
|
2122
2130
|
}
|
|
2123
2131
|
// ---- Group Management ----
|
|
2124
2132
|
async getGroupInfo(groupId) {
|
|
2125
|
-
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}`));
|
|
2133
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}`));
|
|
2126
2134
|
}
|
|
2127
2135
|
/** Thin wrapper over {@link getGroupInfo}: returns the group's `defaultCapabilities` bitmask. */
|
|
2128
2136
|
async getDefaultCapabilities(groupId) {
|
|
@@ -2134,7 +2142,7 @@ var AdminApiClient = class {
|
|
|
2134
2142
|
}
|
|
2135
2143
|
async deleteGroup(groupId) {
|
|
2136
2144
|
return unwrap(
|
|
2137
|
-
await this.httpClient.request(`/admin-api/groups/${groupId}`, {
|
|
2145
|
+
await this.httpClient.request(`/admin-api/groups/${pathSegment(groupId)}`, {
|
|
2138
2146
|
method: "DELETE",
|
|
2139
2147
|
body: "{}",
|
|
2140
2148
|
headers: { "Content-Type": "application/json" }
|
|
@@ -2143,7 +2151,7 @@ var AdminApiClient = class {
|
|
|
2143
2151
|
}
|
|
2144
2152
|
async listGroupMembers(groupId) {
|
|
2145
2153
|
const response = await this.httpClient.get(
|
|
2146
|
-
`/admin-api/groups/${groupId}/members`
|
|
2154
|
+
`/admin-api/groups/${pathSegment(groupId)}/members`
|
|
2147
2155
|
);
|
|
2148
2156
|
if (!Array.isArray(response?.members)) {
|
|
2149
2157
|
const safeId = String(groupId).replace(/[\r\n\t\s]/g, "").slice(0, 64);
|
|
@@ -2181,7 +2189,7 @@ var AdminApiClient = class {
|
|
|
2181
2189
|
if (options?.offset !== void 0) params.set("offset", String(options.offset));
|
|
2182
2190
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
2183
2191
|
const query = params.toString();
|
|
2184
|
-
const base = `/admin-api/groups/${
|
|
2192
|
+
const base = `/admin-api/groups/${pathSegment(groupId)}/member-devices`;
|
|
2185
2193
|
const response = await this.httpClient.get(
|
|
2186
2194
|
query ? `${base}?${query}` : base
|
|
2187
2195
|
);
|
|
@@ -2233,7 +2241,7 @@ var AdminApiClient = class {
|
|
|
2233
2241
|
* hex (exactly 64). The node accepts either; the two never collide.
|
|
2234
2242
|
*/
|
|
2235
2243
|
async getWarrantNonce(contextId, authorDeviceKey) {
|
|
2236
|
-
const path = `/admin-api/contexts/${
|
|
2244
|
+
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce/${pathSegment(authorDeviceKey)}`;
|
|
2237
2245
|
let raw;
|
|
2238
2246
|
try {
|
|
2239
2247
|
raw = await this.httpClient.get(path, { parse: "text" });
|
|
@@ -2273,7 +2281,7 @@ var AdminApiClient = class {
|
|
|
2273
2281
|
* value passed as `authorProof` to the relay client.
|
|
2274
2282
|
*/
|
|
2275
2283
|
async getWarrantNonceAsAuthor(contextId, authorProof) {
|
|
2276
|
-
const path = `/admin-api/contexts/${
|
|
2284
|
+
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce`;
|
|
2277
2285
|
let raw;
|
|
2278
2286
|
try {
|
|
2279
2287
|
raw = await this.httpClient.post(path, { authorProof }, { parse: "text" });
|
|
@@ -2295,7 +2303,7 @@ var AdminApiClient = class {
|
|
|
2295
2303
|
if (options.offset !== void 0) params.set("offset", String(options.offset));
|
|
2296
2304
|
if (options.limit !== void 0) params.set("limit", String(options.limit));
|
|
2297
2305
|
const query = params.toString();
|
|
2298
|
-
const path = `/admin-api/groups/${groupId}/member-devices${query ? `?${query}` : ""}`;
|
|
2306
|
+
const path = `/admin-api/groups/${pathSegment(groupId)}/member-devices${query ? `?${query}` : ""}`;
|
|
2299
2307
|
return this.httpClient.get(path);
|
|
2300
2308
|
}
|
|
2301
2309
|
/**
|
|
@@ -2306,19 +2314,19 @@ var AdminApiClient = class {
|
|
|
2306
2314
|
async sealToAccount(groupId, account, request) {
|
|
2307
2315
|
return unwrap(
|
|
2308
2316
|
await this.httpClient.post(
|
|
2309
|
-
`/admin-api/groups/${groupId}/accounts/${account}/seal`,
|
|
2317
|
+
`/admin-api/groups/${pathSegment(groupId)}/accounts/${pathSegment(account)}/seal`,
|
|
2310
2318
|
request
|
|
2311
2319
|
)
|
|
2312
2320
|
);
|
|
2313
2321
|
}
|
|
2314
2322
|
async listGroupContexts(groupId) {
|
|
2315
|
-
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/contexts`));
|
|
2323
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/contexts`));
|
|
2316
2324
|
}
|
|
2317
2325
|
async addGroupMembers(groupId, request) {
|
|
2318
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/members`, request);
|
|
2326
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/members`, request);
|
|
2319
2327
|
}
|
|
2320
2328
|
async removeGroupMembers(groupId, request) {
|
|
2321
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/members/remove`, request);
|
|
2329
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/members/remove`, request);
|
|
2322
2330
|
}
|
|
2323
2331
|
/**
|
|
2324
2332
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2326,7 +2334,7 @@ var AdminApiClient = class {
|
|
|
2326
2334
|
* 64 hex, so nothing but the source tells them apart.
|
|
2327
2335
|
*/
|
|
2328
2336
|
async updateMemberRole(groupId, identity, request) {
|
|
2329
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/role`, request);
|
|
2337
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/role`, request);
|
|
2330
2338
|
}
|
|
2331
2339
|
/**
|
|
2332
2340
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2336,7 +2344,7 @@ var AdminApiClient = class {
|
|
|
2336
2344
|
async getMemberCapabilities(groupId, identity) {
|
|
2337
2345
|
return unwrap(
|
|
2338
2346
|
await this.httpClient.get(
|
|
2339
|
-
`/admin-api/groups/${groupId}/members/${identity}/capabilities`
|
|
2347
|
+
`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/capabilities`
|
|
2340
2348
|
)
|
|
2341
2349
|
);
|
|
2342
2350
|
}
|
|
@@ -2346,10 +2354,10 @@ var AdminApiClient = class {
|
|
|
2346
2354
|
* 64 hex, so nothing but the source tells them apart.
|
|
2347
2355
|
*/
|
|
2348
2356
|
async setMemberCapabilities(groupId, identity, request) {
|
|
2349
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/capabilities`, request);
|
|
2357
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/capabilities`, request);
|
|
2350
2358
|
}
|
|
2351
2359
|
async setDefaultCapabilities(groupId, request) {
|
|
2352
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/default-capabilities`, request);
|
|
2360
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/default-capabilities`, request);
|
|
2353
2361
|
}
|
|
2354
2362
|
/**
|
|
2355
2363
|
* Make every member admitted to `groupId` from now on able to relay a
|
|
@@ -2431,13 +2439,13 @@ var AdminApiClient = class {
|
|
|
2431
2439
|
return { changed: true, capabilities: next };
|
|
2432
2440
|
}
|
|
2433
2441
|
async setSubgroupVisibility(groupId, request) {
|
|
2434
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/subgroup-visibility`, request);
|
|
2442
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/subgroup-visibility`, request);
|
|
2435
2443
|
}
|
|
2436
2444
|
async setTeeAdmissionPolicy(groupId, request) {
|
|
2437
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-admission-policy`, request);
|
|
2445
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-admission-policy`, request);
|
|
2438
2446
|
}
|
|
2439
2447
|
async getTeeAdmissionPolicy(groupId) {
|
|
2440
|
-
const response = await this.httpClient.get(`/admin-api/groups/${groupId}/settings/tee-admission-policy`);
|
|
2448
|
+
const response = await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-admission-policy`);
|
|
2441
2449
|
return response.data ?? response;
|
|
2442
2450
|
}
|
|
2443
2451
|
/**
|
|
@@ -2447,7 +2455,7 @@ var AdminApiClient = class {
|
|
|
2447
2455
|
* route for this policy.
|
|
2448
2456
|
*/
|
|
2449
2457
|
async setTeeAuthoringPolicy(groupId, request) {
|
|
2450
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-authoring-policy`, request);
|
|
2458
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-authoring-policy`, request);
|
|
2451
2459
|
}
|
|
2452
2460
|
/**
|
|
2453
2461
|
* Turns TEE authorship off in the namespace: every TEE loses its authority,
|
|
@@ -2459,7 +2467,7 @@ var AdminApiClient = class {
|
|
|
2459
2467
|
* (`teeAuthoringPolicyOp([])`); omit it on a node that holds that root.
|
|
2460
2468
|
*/
|
|
2461
2469
|
async disableTeeAuthoringPolicy(groupId, options = {}) {
|
|
2462
|
-
const path = `/admin-api/groups/${groupId}/settings/tee-authoring-policy`;
|
|
2470
|
+
const path = `/admin-api/groups/${pathSegment(groupId)}/settings/tee-authoring-policy`;
|
|
2463
2471
|
if (options.rootProof === void 0) {
|
|
2464
2472
|
await this.httpClient.delete(path);
|
|
2465
2473
|
return;
|
|
@@ -2477,14 +2485,14 @@ var AdminApiClient = class {
|
|
|
2477
2485
|
* {@link RootGuardedOpRequest}.
|
|
2478
2486
|
*/
|
|
2479
2487
|
async transferOwnership(groupId, request) {
|
|
2480
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/transfer-ownership`, request);
|
|
2488
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/transfer-ownership`, request);
|
|
2481
2489
|
}
|
|
2482
2490
|
/**
|
|
2483
2491
|
* Repoint the namespace's admin pin at `newAdmin`, a member of its root.
|
|
2484
2492
|
* Owner-only, with the owner account's root proof; see {@link RootGuardedOpRequest}.
|
|
2485
2493
|
*/
|
|
2486
2494
|
async changeNamespaceAdmin(namespaceId, request) {
|
|
2487
|
-
await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/admin`, request);
|
|
2495
|
+
await this.httpClient.post(`/admin-api/namespaces/${pathSegment(namespaceId)}/admin`, request);
|
|
2488
2496
|
}
|
|
2489
2497
|
/**
|
|
2490
2498
|
* Delete a group through the owner-only path: it must hold no contexts, and
|
|
@@ -2492,20 +2500,20 @@ var AdminApiClient = class {
|
|
|
2492
2500
|
* admin-level cascading delete.
|
|
2493
2501
|
*/
|
|
2494
2502
|
async ownerDeleteGroup(groupId, request = {}) {
|
|
2495
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/owner-delete`, request);
|
|
2503
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/owner-delete`, request);
|
|
2496
2504
|
}
|
|
2497
2505
|
// ---- Group / member / context metadata ----
|
|
2498
2506
|
async setGroupMetadata(groupId, request) {
|
|
2499
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/metadata`, request);
|
|
2507
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/metadata`, request);
|
|
2500
2508
|
}
|
|
2501
2509
|
async getGroupMetadata(groupId) {
|
|
2502
2510
|
const response = await this.httpClient.get(
|
|
2503
|
-
`/admin-api/groups/${groupId}/metadata`
|
|
2511
|
+
`/admin-api/groups/${pathSegment(groupId)}/metadata`
|
|
2504
2512
|
);
|
|
2505
2513
|
return response?.data ?? null;
|
|
2506
2514
|
}
|
|
2507
2515
|
async setMemberMetadata(groupId, identity, request) {
|
|
2508
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/metadata`, request);
|
|
2516
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/metadata`, request);
|
|
2509
2517
|
}
|
|
2510
2518
|
/**
|
|
2511
2519
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2514,28 +2522,28 @@ var AdminApiClient = class {
|
|
|
2514
2522
|
*/
|
|
2515
2523
|
async getMemberMetadata(groupId, identity) {
|
|
2516
2524
|
const response = await this.httpClient.get(
|
|
2517
|
-
`/admin-api/groups/${groupId}/members/${identity}/metadata`
|
|
2525
|
+
`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/metadata`
|
|
2518
2526
|
);
|
|
2519
2527
|
return response?.data ?? null;
|
|
2520
2528
|
}
|
|
2521
2529
|
async setContextMetadata(groupId, contextId, request) {
|
|
2522
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`, request);
|
|
2530
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/metadata`, request);
|
|
2523
2531
|
}
|
|
2524
2532
|
async getContextMetadata(groupId, contextId) {
|
|
2525
2533
|
const response = await this.httpClient.get(
|
|
2526
|
-
`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`
|
|
2534
|
+
`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/metadata`
|
|
2527
2535
|
);
|
|
2528
2536
|
return response?.data ?? null;
|
|
2529
2537
|
}
|
|
2530
2538
|
async syncGroup(groupId) {
|
|
2531
|
-
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/sync`, {}));
|
|
2539
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/sync`, {}));
|
|
2532
2540
|
}
|
|
2533
2541
|
async upgradeGroup(groupId, request) {
|
|
2534
|
-
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/upgrade`, request));
|
|
2542
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/upgrade`, request));
|
|
2535
2543
|
}
|
|
2536
2544
|
async getGroupUpgradeStatus(groupId) {
|
|
2537
2545
|
return unwrap(
|
|
2538
|
-
await this.httpClient.get(`/admin-api/groups/${groupId}/upgrade/status`)
|
|
2546
|
+
await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/upgrade/status`)
|
|
2539
2547
|
);
|
|
2540
2548
|
}
|
|
2541
2549
|
/**
|
|
@@ -2544,43 +2552,41 @@ var AdminApiClient = class {
|
|
|
2544
2552
|
* envelope to unwrap here (unlike most admin reads).
|
|
2545
2553
|
*/
|
|
2546
2554
|
async getMigrationStatus(namespaceId) {
|
|
2547
|
-
|
|
2548
|
-
return this.httpClient.get(`/admin-api/groups/${id}/migration-status`);
|
|
2555
|
+
return this.httpClient.get(`/admin-api/groups/${pathSegment(namespaceId)}/migration-status`);
|
|
2549
2556
|
}
|
|
2550
2557
|
/** Per-group cascade-migration snapshots for a namespace. */
|
|
2551
2558
|
async getCascadeStatus(namespaceId) {
|
|
2552
|
-
const id = encodeURIComponent(namespaceId);
|
|
2553
2559
|
return unwrap(
|
|
2554
|
-
await this.httpClient.get(`/admin-api/groups/${
|
|
2560
|
+
await this.httpClient.get(`/admin-api/groups/${pathSegment(namespaceId)}/cascade-status`)
|
|
2555
2561
|
);
|
|
2556
2562
|
}
|
|
2557
2563
|
async retryGroupUpgrade(groupId) {
|
|
2558
2564
|
return unwrap(
|
|
2559
2565
|
await this.httpClient.post(
|
|
2560
|
-
`/admin-api/groups/${groupId}/upgrade/retry`,
|
|
2566
|
+
`/admin-api/groups/${pathSegment(groupId)}/upgrade/retry`,
|
|
2561
2567
|
{}
|
|
2562
2568
|
)
|
|
2563
2569
|
);
|
|
2564
2570
|
}
|
|
2565
2571
|
/** Move `childGroupId` under `request.newParentId`. */
|
|
2566
2572
|
async reparentGroup(childGroupId, request) {
|
|
2567
|
-
const r = await this.httpClient.post(`/admin-api/groups/${childGroupId}/reparent`, request);
|
|
2573
|
+
const r = await this.httpClient.post(`/admin-api/groups/${pathSegment(childGroupId)}/reparent`, request);
|
|
2568
2574
|
return r?.data ?? r;
|
|
2569
2575
|
}
|
|
2570
2576
|
async listSubgroups(groupId) {
|
|
2571
2577
|
const response = await this.httpClient.get(
|
|
2572
|
-
`/admin-api/groups/${groupId}/subgroups`
|
|
2578
|
+
`/admin-api/groups/${pathSegment(groupId)}/subgroups`
|
|
2573
2579
|
);
|
|
2574
2580
|
return response.subgroups ?? response.data ?? [];
|
|
2575
2581
|
}
|
|
2576
2582
|
async detachContextFromGroup(groupId, contextId) {
|
|
2577
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/contexts/${contextId}/remove`, {});
|
|
2583
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/remove`, {});
|
|
2578
2584
|
}
|
|
2579
2585
|
// ---- Group Invitation & Join ----
|
|
2580
2586
|
async createGroupInvitation(groupId, request) {
|
|
2581
2587
|
return unwrap(
|
|
2582
2588
|
await this.httpClient.post(
|
|
2583
|
-
`/admin-api/groups/${groupId}/invite`,
|
|
2589
|
+
`/admin-api/groups/${pathSegment(groupId)}/invite`,
|
|
2584
2590
|
request ?? {}
|
|
2585
2591
|
)
|
|
2586
2592
|
);
|
|
@@ -2593,7 +2599,7 @@ var AdminApiClient = class {
|
|
|
2593
2599
|
async joinSubgroupInheritance(groupId) {
|
|
2594
2600
|
return unwrap(
|
|
2595
2601
|
await this.httpClient.post(
|
|
2596
|
-
`/admin-api/groups/${groupId}/join-via-inheritance`,
|
|
2602
|
+
`/admin-api/groups/${pathSegment(groupId)}/join-via-inheritance`,
|
|
2597
2603
|
{}
|
|
2598
2604
|
)
|
|
2599
2605
|
);
|
|
@@ -2635,27 +2641,27 @@ var AdminApiClient = class {
|
|
|
2635
2641
|
}
|
|
2636
2642
|
/** Leave a group (POST /admin-api/groups/:group_id/leave). */
|
|
2637
2643
|
async leaveGroup(groupId) {
|
|
2638
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/leave`, {});
|
|
2644
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/leave`, {});
|
|
2639
2645
|
}
|
|
2640
2646
|
/** Leave a context (POST /admin-api/contexts/:context_id/leave). */
|
|
2641
2647
|
async leaveContext(contextId) {
|
|
2642
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/leave`, {});
|
|
2648
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/leave`, {});
|
|
2643
2649
|
}
|
|
2644
2650
|
/** Leave a namespace (POST /admin-api/namespaces/:namespace_id/leave). */
|
|
2645
2651
|
async leaveNamespace(namespaceId) {
|
|
2646
|
-
await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/leave`, {});
|
|
2652
|
+
await this.httpClient.post(`/admin-api/namespaces/${pathSegment(namespaceId)}/leave`, {});
|
|
2647
2653
|
}
|
|
2648
2654
|
/** Issue a group ownership proof (POST /admin-api/groups/:group_id/issue-ownership-proof). */
|
|
2649
2655
|
async issueOwnershipProof(groupId, request) {
|
|
2650
2656
|
return this.httpClient.post(
|
|
2651
|
-
`/admin-api/groups/${groupId}/issue-ownership-proof`,
|
|
2657
|
+
`/admin-api/groups/${pathSegment(groupId)}/issue-ownership-proof`,
|
|
2652
2658
|
request
|
|
2653
2659
|
);
|
|
2654
2660
|
}
|
|
2655
2661
|
/** Issue a namespace ownership proof (POST /admin-api/groups/:group_id/issue-namespace-ownership-proof). */
|
|
2656
2662
|
async issueNamespaceOwnershipProof(groupId, request) {
|
|
2657
2663
|
return this.httpClient.post(
|
|
2658
|
-
`/admin-api/groups/${groupId}/issue-namespace-ownership-proof`,
|
|
2664
|
+
`/admin-api/groups/${pathSegment(groupId)}/issue-namespace-ownership-proof`,
|
|
2659
2665
|
request
|
|
2660
2666
|
);
|
|
2661
2667
|
}
|
|
@@ -2668,11 +2674,11 @@ var AdminApiClient = class {
|
|
|
2668
2674
|
* 64 hex, so nothing but the source tells them apart.
|
|
2669
2675
|
*/
|
|
2670
2676
|
async setMemberAutoFollow(groupId, identity, request) {
|
|
2671
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/auto-follow`, request);
|
|
2677
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/auto-follow`, request);
|
|
2672
2678
|
}
|
|
2673
2679
|
/** Abort a namespace migration (POST /admin-api/groups/:namespace_id/migration/abort). */
|
|
2674
2680
|
async abortMigration(namespaceId) {
|
|
2675
|
-
return this.httpClient.post(`/admin-api/groups/${namespaceId}/migration/abort`, {});
|
|
2681
|
+
return this.httpClient.post(`/admin-api/groups/${pathSegment(namespaceId)}/migration/abort`, {});
|
|
2676
2682
|
}
|
|
2677
2683
|
};
|
|
2678
2684
|
|
|
@@ -8211,7 +8217,7 @@ var RelayClient = class {
|
|
|
8211
8217
|
async describe(contextId) {
|
|
8212
8218
|
const body = await this.json(
|
|
8213
8219
|
"GET",
|
|
8214
|
-
`/admin-api/contexts/${
|
|
8220
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`
|
|
8215
8221
|
);
|
|
8216
8222
|
return body.data;
|
|
8217
8223
|
}
|
|
@@ -8248,7 +8254,7 @@ var RelayClient = class {
|
|
|
8248
8254
|
});
|
|
8249
8255
|
const body = await this.json(
|
|
8250
8256
|
"POST",
|
|
8251
|
-
`/admin-api/contexts/${
|
|
8257
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`,
|
|
8252
8258
|
{ method, argsJson, warrant, authorProof: this.config.authorProof }
|
|
8253
8259
|
);
|
|
8254
8260
|
return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
|
|
@@ -8262,7 +8268,7 @@ var RelayClient = class {
|
|
|
8262
8268
|
async presenceIntent(contextId, body) {
|
|
8263
8269
|
await this.jsonOnce(
|
|
8264
8270
|
"POST",
|
|
8265
|
-
`/admin-api/contexts/${
|
|
8271
|
+
`/admin-api/contexts/${pathSegment(contextId)}/presence-intents`,
|
|
8266
8272
|
body
|
|
8267
8273
|
);
|
|
8268
8274
|
}
|
|
@@ -8276,7 +8282,7 @@ var RelayClient = class {
|
|
|
8276
8282
|
const query = opts.author ? `?author=${encodeURIComponent(opts.author)}` : "";
|
|
8277
8283
|
const body = await this.json(
|
|
8278
8284
|
"GET",
|
|
8279
|
-
`/admin-api/groups/${
|
|
8285
|
+
`/admin-api/groups/${pathSegment(groupId)}/context-intents${query}`
|
|
8280
8286
|
);
|
|
8281
8287
|
return body.data;
|
|
8282
8288
|
}
|
|
@@ -8340,7 +8346,7 @@ var RelayClient = class {
|
|
|
8340
8346
|
});
|
|
8341
8347
|
const body = await this.json(
|
|
8342
8348
|
"POST",
|
|
8343
|
-
`/admin-api/groups/${
|
|
8349
|
+
`/admin-api/groups/${pathSegment(input.groupId)}/context-intents`,
|
|
8344
8350
|
{ warrant, authorProof: this.config.authorProof, initArgs }
|
|
8345
8351
|
);
|
|
8346
8352
|
return {
|
|
@@ -8356,7 +8362,7 @@ var RelayClient = class {
|
|
|
8356
8362
|
async describeGovernance(groupId) {
|
|
8357
8363
|
const body = await this.json(
|
|
8358
8364
|
"GET",
|
|
8359
|
-
`/admin-api/groups/${
|
|
8365
|
+
`/admin-api/groups/${pathSegment(groupId)}/governance-intents`
|
|
8360
8366
|
);
|
|
8361
8367
|
return body.data;
|
|
8362
8368
|
}
|
|
@@ -8488,7 +8494,7 @@ var RelayClient = class {
|
|
|
8488
8494
|
return result;
|
|
8489
8495
|
}
|
|
8490
8496
|
async postGovernance(groupId, op, warrant) {
|
|
8491
|
-
const body = await this.json("POST", `/admin-api/groups/${
|
|
8497
|
+
const body = await this.json("POST", `/admin-api/groups/${pathSegment(groupId)}/governance-intents`, {
|
|
8492
8498
|
warrant,
|
|
8493
8499
|
authorProof: this.config.authorProof,
|
|
8494
8500
|
op: hex(op.bytes)
|
|
@@ -10191,15 +10197,70 @@ function base643(bytes) {
|
|
|
10191
10197
|
return btoa(binary);
|
|
10192
10198
|
}
|
|
10193
10199
|
|
|
10200
|
+
// src/cloud/link-state.ts
|
|
10201
|
+
var KEY2 = "calimero.cloud.link.pending";
|
|
10202
|
+
var STATE_PARAM = "link_state";
|
|
10203
|
+
var LIFETIME_MS = 10 * 60 * 1e3;
|
|
10204
|
+
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
10205
|
+
var MAX_PENDING = 20;
|
|
10206
|
+
function readPending(now) {
|
|
10207
|
+
try {
|
|
10208
|
+
const raw = localStorage.getItem(KEY2);
|
|
10209
|
+
const pending = raw ? JSON.parse(raw) : {};
|
|
10210
|
+
return Object.fromEntries(
|
|
10211
|
+
Object.entries(pending).filter(
|
|
10212
|
+
([, p]) => p && typeof p.expiresAt === "number" && p.expiresAt > now
|
|
10213
|
+
)
|
|
10214
|
+
);
|
|
10215
|
+
} catch {
|
|
10216
|
+
return {};
|
|
10217
|
+
}
|
|
10218
|
+
}
|
|
10219
|
+
function writePending(pending) {
|
|
10220
|
+
try {
|
|
10221
|
+
localStorage.setItem(KEY2, JSON.stringify(pending));
|
|
10222
|
+
} catch {
|
|
10223
|
+
}
|
|
10224
|
+
}
|
|
10225
|
+
function beginLinkState(account, returnTo) {
|
|
10226
|
+
if (!ACCOUNT_HEX.test(account)) {
|
|
10227
|
+
throw new Error("accountId must be 64 lowercase hex characters");
|
|
10228
|
+
}
|
|
10229
|
+
const url = new URL(returnTo);
|
|
10230
|
+
const now = Date.now();
|
|
10231
|
+
const pending = readPending(now);
|
|
10232
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
10233
|
+
const state = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
|
|
10234
|
+
""
|
|
10235
|
+
);
|
|
10236
|
+
pending[state] = { account, expiresAt: now + LIFETIME_MS };
|
|
10237
|
+
writePending(Object.fromEntries(Object.entries(pending).slice(-MAX_PENDING)));
|
|
10238
|
+
url.searchParams.set(STATE_PARAM, state);
|
|
10239
|
+
return url.toString();
|
|
10240
|
+
}
|
|
10241
|
+
function takeLinkState(search) {
|
|
10242
|
+
const state = new URLSearchParams(search).get(STATE_PARAM);
|
|
10243
|
+
const pending = readPending(Date.now());
|
|
10244
|
+
if (!state || !Object.prototype.hasOwnProperty.call(pending, state))
|
|
10245
|
+
return null;
|
|
10246
|
+
const entry = pending[state];
|
|
10247
|
+
delete pending[state];
|
|
10248
|
+
writePending(pending);
|
|
10249
|
+
return entry;
|
|
10250
|
+
}
|
|
10251
|
+
function withoutLinkState(search) {
|
|
10252
|
+
const params = new URLSearchParams(search);
|
|
10253
|
+
params.delete(STATE_PARAM);
|
|
10254
|
+
const rest = params.toString();
|
|
10255
|
+
return rest ? `?${rest}` : "";
|
|
10256
|
+
}
|
|
10257
|
+
|
|
10194
10258
|
// src/cloud/link-redirect.ts
|
|
10195
10259
|
var DEFAULT_CLOUD_WEB_URL = "https://cloud.calimero.network";
|
|
10196
10260
|
function cloudLinkUrl(options) {
|
|
10197
|
-
if (!/^[0-9a-f]{64}$/.test(options.accountId)) {
|
|
10198
|
-
throw new Error("accountId must be 64 lowercase hex characters");
|
|
10199
|
-
}
|
|
10200
10261
|
const url = new URL(options.cloudWebUrl ?? DEFAULT_CLOUD_WEB_URL);
|
|
10201
10262
|
url.searchParams.set("link-account", options.accountId);
|
|
10202
|
-
url.searchParams.set("callback-url", options.returnTo);
|
|
10263
|
+
url.searchParams.set("callback-url", beginLinkState(options.accountId, options.returnTo));
|
|
10203
10264
|
return url.toString();
|
|
10204
10265
|
}
|
|
10205
10266
|
function beginCloudLink(options) {
|
|
@@ -10210,6 +10271,7 @@ function readCloudLinkCallback(location2 = window.location) {
|
|
|
10210
10271
|
const params = new URLSearchParams(location2.hash.replace(/^#/, ""));
|
|
10211
10272
|
const error = params.get("error");
|
|
10212
10273
|
if (error) {
|
|
10274
|
+
takeLinkState(location2.search ?? "");
|
|
10213
10275
|
stripFragment();
|
|
10214
10276
|
throw new Error(
|
|
10215
10277
|
error === "denied" ? "the account link was declined at the cloud" : `the cloud refused this link: ${error}`
|
|
@@ -10218,12 +10280,18 @@ function readCloudLinkCallback(location2 = window.location) {
|
|
|
10218
10280
|
const grant = params.get("grant");
|
|
10219
10281
|
const account = params.get("account");
|
|
10220
10282
|
if (!grant || !account) return null;
|
|
10283
|
+
if (takeLinkState(location2.search ?? "")?.account !== account) {
|
|
10284
|
+
stripFragment();
|
|
10285
|
+
throw new Error(
|
|
10286
|
+
"this account link answers a request this browser did not make - start the link again from here"
|
|
10287
|
+
);
|
|
10288
|
+
}
|
|
10221
10289
|
stripFragment();
|
|
10222
10290
|
return { grant, account };
|
|
10223
10291
|
}
|
|
10224
10292
|
function stripFragment() {
|
|
10225
10293
|
if (typeof history === "undefined" || !history.replaceState) return;
|
|
10226
|
-
history.replaceState(null, "", location.pathname + location.search);
|
|
10294
|
+
history.replaceState(null, "", location.pathname + withoutLinkState(location.search));
|
|
10227
10295
|
}
|
|
10228
10296
|
async function completeCloudLink(options) {
|
|
10229
10297
|
const root = await resolveRoot(options.root);
|
|
@@ -10243,7 +10311,7 @@ async function completeCloudLink(options) {
|
|
|
10243
10311
|
var DEVICE_PARAM = "enrol-device";
|
|
10244
10312
|
var KEM_PARAM = "enrol-kem";
|
|
10245
10313
|
var CALLBACK_PARAM = "callback-url";
|
|
10246
|
-
var
|
|
10314
|
+
var STATE_PARAM2 = "state";
|
|
10247
10315
|
function deviceEnrolmentUrl(options) {
|
|
10248
10316
|
assertHex(options.devicePublicKey, "devicePublicKey");
|
|
10249
10317
|
assertHex(options.kemPublicKey, "kemPublicKey");
|
|
@@ -10253,7 +10321,7 @@ function deviceEnrolmentUrl(options) {
|
|
|
10253
10321
|
url.searchParams.set(DEVICE_PARAM, options.devicePublicKey);
|
|
10254
10322
|
url.searchParams.set(KEM_PARAM, options.kemPublicKey);
|
|
10255
10323
|
url.searchParams.set(CALLBACK_PARAM, options.returnTo);
|
|
10256
|
-
if (options.state) url.searchParams.set(
|
|
10324
|
+
if (options.state) url.searchParams.set(STATE_PARAM2, options.state);
|
|
10257
10325
|
return url.toString();
|
|
10258
10326
|
}
|
|
10259
10327
|
function beginDeviceEnrolment(options) {
|
|
@@ -10420,7 +10488,7 @@ async function resolveRelayFromInvitation(input) {
|
|
|
10420
10488
|
relayUrl: chosen.relayUrl,
|
|
10421
10489
|
// The cloud's ready-made URL when it gave one, so the path is never rebuilt
|
|
10422
10490
|
// from a guess; the fallback is the documented route on the same origin.
|
|
10423
|
-
admitUrl: chosen.admitUrl ?? `${chosen.relayUrl.replace(/\/+$/, "")}/admin-api/namespaces/${input.namespaceId}/admit`,
|
|
10491
|
+
admitUrl: chosen.admitUrl ?? `${chosen.relayUrl.replace(/\/+$/, "")}/admin-api/namespaces/${pathSegment(input.namespaceId)}/admit`,
|
|
10424
10492
|
admitterAccount: chosen.account,
|
|
10425
10493
|
peerId: chosen.peerId,
|
|
10426
10494
|
writable: chosen.canExecute,
|
|
@@ -10658,7 +10726,7 @@ async function joinWithNode(input) {
|
|
|
10658
10726
|
};
|
|
10659
10727
|
}
|
|
10660
10728
|
const body = { invitation: input.invitation, signedOp };
|
|
10661
|
-
const url = input.admitUrl ?? `${origin(input.nodeUrl)}/admin-api/namespaces/${input.namespaceId}/admit`;
|
|
10729
|
+
const url = input.admitUrl ?? `${origin(input.nodeUrl)}/admin-api/namespaces/${pathSegment(input.namespaceId)}/admit`;
|
|
10662
10730
|
const doFetch = input.deps?.fetch ?? fetch;
|
|
10663
10731
|
let response;
|
|
10664
10732
|
try {
|
|
@@ -11351,7 +11419,6 @@ function joinOf(row) {
|
|
|
11351
11419
|
reportedAt: typeof join.reported_at === "string" ? join.reported_at : null
|
|
11352
11420
|
};
|
|
11353
11421
|
}
|
|
11354
|
-
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
11355
11422
|
function accountHexOrNull(value) {
|
|
11356
11423
|
return typeof value === "string" && ACCOUNT_HEX.test(value) ? value : null;
|
|
11357
11424
|
}
|
|
@@ -11571,7 +11638,7 @@ var CloudClient = class {
|
|
|
11571
11638
|
async getNamespaceRelays(namespaceId) {
|
|
11572
11639
|
const body = await this.request(
|
|
11573
11640
|
"GET",
|
|
11574
|
-
`/api/cloud/me/namespaces/${
|
|
11641
|
+
`/api/cloud/me/namespaces/${pathSegment(namespaceId)}/relays`
|
|
11575
11642
|
);
|
|
11576
11643
|
return (body.relays ?? []).map((row) => {
|
|
11577
11644
|
const relayUrl = row.relay_url ?? null;
|
|
@@ -11629,7 +11696,7 @@ var CloudClient = class {
|
|
|
11629
11696
|
* a node holding the namespace, so there is no hosted admitter.
|
|
11630
11697
|
*/
|
|
11631
11698
|
async getNamespaceRouting(namespaceId) {
|
|
11632
|
-
const body = await this.request("GET", `/api/cloud/namespaces/${
|
|
11699
|
+
const body = await this.request("GET", `/api/cloud/namespaces/${pathSegment(namespaceId)}/admitters`, {
|
|
11633
11700
|
anonymous: true,
|
|
11634
11701
|
headers: await this.routingProof(namespaceId)
|
|
11635
11702
|
});
|
|
@@ -11673,7 +11740,7 @@ var CloudClient = class {
|
|
|
11673
11740
|
* challenge somewhere this client cannot reach the key.
|
|
11674
11741
|
*/
|
|
11675
11742
|
async getRoutingChallenge(namespaceId) {
|
|
11676
|
-
const body = await this.request("GET", `/api/cloud/namespaces/${
|
|
11743
|
+
const body = await this.request("GET", `/api/cloud/namespaces/${pathSegment(namespaceId)}/challenge`, {
|
|
11677
11744
|
anonymous: true
|
|
11678
11745
|
});
|
|
11679
11746
|
return {
|
|
@@ -11704,7 +11771,7 @@ var CloudClient = class {
|
|
|
11704
11771
|
* the account from the certificate and refuses a mismatch.
|
|
11705
11772
|
*/
|
|
11706
11773
|
async getAccountRelaysChallenge(accountId) {
|
|
11707
|
-
const body = await this.request("GET", `/api/cloud/accounts/${
|
|
11774
|
+
const body = await this.request("GET", `/api/cloud/accounts/${pathSegment(accountId)}/challenge`, {
|
|
11708
11775
|
anonymous: true
|
|
11709
11776
|
});
|
|
11710
11777
|
return {
|
|
@@ -11740,7 +11807,7 @@ var CloudClient = class {
|
|
|
11740
11807
|
);
|
|
11741
11808
|
}
|
|
11742
11809
|
const challenge = await this.getAccountRelaysChallenge(accountId);
|
|
11743
|
-
const body = await this.request("GET", `/api/cloud/accounts/${
|
|
11810
|
+
const body = await this.request("GET", `/api/cloud/accounts/${pathSegment(accountId)}/relays`, {
|
|
11744
11811
|
anonymous: true,
|
|
11745
11812
|
headers: await routingProofHeaders(challenge, this.routingCredential)
|
|
11746
11813
|
});
|
|
@@ -11864,7 +11931,7 @@ var CloudClient = class {
|
|
|
11864
11931
|
const body = options.admitterAddrs === void 0 ? {} : { admitter_addrs: [...options.admitterAddrs] };
|
|
11865
11932
|
return this.request(
|
|
11866
11933
|
"POST",
|
|
11867
|
-
`/api/cloud/namespaces/${
|
|
11934
|
+
`/api/cloud/namespaces/${pathSegment(namespaceId)}/enable-ha`,
|
|
11868
11935
|
{ body }
|
|
11869
11936
|
);
|
|
11870
11937
|
}
|
|
@@ -11877,7 +11944,7 @@ var CloudClient = class {
|
|
|
11877
11944
|
async enableFoundedNamespaceHa(namespaceId, ownershipProof) {
|
|
11878
11945
|
return this.request(
|
|
11879
11946
|
"POST",
|
|
11880
|
-
`/api/cloud/me/namespaces/${
|
|
11947
|
+
`/api/cloud/me/namespaces/${pathSegment(namespaceId)}/enable-ha`,
|
|
11881
11948
|
{ body: { groups: [], ownership_proof: ownershipProof } }
|
|
11882
11949
|
);
|
|
11883
11950
|
}
|
|
@@ -11914,7 +11981,7 @@ var CloudClient = class {
|
|
|
11914
11981
|
try {
|
|
11915
11982
|
return await this.request(
|
|
11916
11983
|
"POST",
|
|
11917
|
-
`/api/cloud/accounts/${
|
|
11984
|
+
`/api/cloud/accounts/${pathSegment(account)}/namespaces/${pathSegment(namespace)}/enable-ha`,
|
|
11918
11985
|
{ body: { ownership_proof: proof }, anonymous: true }
|
|
11919
11986
|
);
|
|
11920
11987
|
} catch (err) {
|
|
@@ -11939,7 +12006,7 @@ var CloudClient = class {
|
|
|
11939
12006
|
async disableNamespaceHa(namespaceId) {
|
|
11940
12007
|
return this.request(
|
|
11941
12008
|
"POST",
|
|
11942
|
-
`/api/cloud/namespaces/${
|
|
12009
|
+
`/api/cloud/namespaces/${pathSegment(namespaceId)}/disable-ha`,
|
|
11943
12010
|
{ body: {} }
|
|
11944
12011
|
);
|
|
11945
12012
|
}
|
|
@@ -12079,7 +12146,7 @@ var CloudClient = class {
|
|
|
12079
12146
|
const portal = options.portalUrl.replace(/\/+$/, "");
|
|
12080
12147
|
const query = new URLSearchParams({
|
|
12081
12148
|
"link-account": options.accountId,
|
|
12082
|
-
"callback-url": options.callbackUrl
|
|
12149
|
+
"callback-url": beginLinkState(options.accountId, options.callbackUrl)
|
|
12083
12150
|
});
|
|
12084
12151
|
return { url: `${portal}/?${query.toString()}`, accountId: options.accountId };
|
|
12085
12152
|
}
|
|
@@ -12089,14 +12156,19 @@ var CloudClient = class {
|
|
|
12089
12156
|
* Returns `{}` when there is nothing to read, so it is safe to call on every
|
|
12090
12157
|
* load — which is how a redirected app finds out it has been sent back.
|
|
12091
12158
|
*
|
|
12159
|
+
* A grant is only returned when it answers a handoff this browser began, for the
|
|
12160
|
+
* account that handoff named; anything else comes back as
|
|
12161
|
+
* `error: 'unexpected_callback'`, because the redirect URL can be forwarded.
|
|
12162
|
+
*
|
|
12092
12163
|
* @param href defaults to the current location, when there is one.
|
|
12093
12164
|
*/
|
|
12094
12165
|
static readAccountLinkCallback(href) {
|
|
12095
12166
|
const source = href ?? (typeof window === "undefined" ? "" : window.location.href);
|
|
12096
12167
|
if (!source) return {};
|
|
12097
12168
|
let hash;
|
|
12169
|
+
let search;
|
|
12098
12170
|
try {
|
|
12099
|
-
hash = new URL(source)
|
|
12171
|
+
({ hash, search } = new URL(source));
|
|
12100
12172
|
} catch {
|
|
12101
12173
|
return {};
|
|
12102
12174
|
}
|
|
@@ -12105,6 +12177,10 @@ var CloudClient = class {
|
|
|
12105
12177
|
const accountId = params.get("account");
|
|
12106
12178
|
const error = params.get("error");
|
|
12107
12179
|
const out = {};
|
|
12180
|
+
if (error) takeLinkState(search);
|
|
12181
|
+
if (grant && takeLinkState(search)?.account !== accountId) {
|
|
12182
|
+
return { error: "unexpected_callback" };
|
|
12183
|
+
}
|
|
12108
12184
|
if (grant) out.grant = grant;
|
|
12109
12185
|
if (accountId) out.accountId = accountId;
|
|
12110
12186
|
if (error) out.error = error;
|