@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.mjs
CHANGED
|
@@ -551,6 +551,14 @@ function createRetryableMethod(method, retryOptions = {}) {
|
|
|
551
551
|
};
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
+
// src/http-client/path-segment.ts
|
|
555
|
+
function pathSegment(id) {
|
|
556
|
+
if (id === "" || id === "." || id === "..") {
|
|
557
|
+
throw new TypeError(`invalid request path segment: ${JSON.stringify(id)}`);
|
|
558
|
+
}
|
|
559
|
+
return encodeURIComponent(id);
|
|
560
|
+
}
|
|
561
|
+
|
|
554
562
|
// src/auth-api/auth-client.ts
|
|
555
563
|
var AuthApiClient = class {
|
|
556
564
|
constructor(httpClient) {
|
|
@@ -652,7 +660,7 @@ var AuthApiClient = class {
|
|
|
652
660
|
return response.data;
|
|
653
661
|
}
|
|
654
662
|
async deleteRootKey(keyId) {
|
|
655
|
-
return this.httpClient.delete(`/admin/keys/${keyId}`);
|
|
663
|
+
return this.httpClient.delete(`/admin/keys/${pathSegment(keyId)}`);
|
|
656
664
|
}
|
|
657
665
|
// Client Management Endpoints
|
|
658
666
|
async listClientKeys() {
|
|
@@ -669,18 +677,18 @@ var AuthApiClient = class {
|
|
|
669
677
|
}
|
|
670
678
|
async deleteClientKey(keyId, clientId) {
|
|
671
679
|
return this.httpClient.delete(
|
|
672
|
-
`/admin/keys/${keyId}/clients/${clientId}`
|
|
680
|
+
`/admin/keys/${pathSegment(keyId)}/clients/${pathSegment(clientId)}`
|
|
673
681
|
);
|
|
674
682
|
}
|
|
675
683
|
// Permission Management Endpoints
|
|
676
684
|
async getKeyPermissions(keyId) {
|
|
677
685
|
return this.httpClient.get(
|
|
678
|
-
`/admin/keys/${keyId}/permissions`
|
|
686
|
+
`/admin/keys/${pathSegment(keyId)}/permissions`
|
|
679
687
|
);
|
|
680
688
|
}
|
|
681
689
|
async updateKeyPermissions(keyId, changes) {
|
|
682
690
|
return this.httpClient.put(
|
|
683
|
-
`/admin/keys/${keyId}/permissions`,
|
|
691
|
+
`/admin/keys/${pathSegment(keyId)}/permissions`,
|
|
684
692
|
{ add: changes.add, remove: changes.remove }
|
|
685
693
|
);
|
|
686
694
|
}
|
|
@@ -1102,13 +1110,13 @@ var AdminApiClient = class {
|
|
|
1102
1110
|
return unwrap(await this.httpClient.post("/admin-api/install-dev-application", request));
|
|
1103
1111
|
}
|
|
1104
1112
|
async uninstallApplication(appId) {
|
|
1105
|
-
return unwrap(await this.httpClient.delete(`/admin-api/applications/${appId}`));
|
|
1113
|
+
return unwrap(await this.httpClient.delete(`/admin-api/applications/${pathSegment(appId)}`));
|
|
1106
1114
|
}
|
|
1107
1115
|
async listApplications() {
|
|
1108
1116
|
return unwrap(await this.httpClient.get("/admin-api/applications"));
|
|
1109
1117
|
}
|
|
1110
1118
|
async getApplication(appId) {
|
|
1111
|
-
return unwrap(await this.httpClient.get(`/admin-api/applications/${appId}`));
|
|
1119
|
+
return unwrap(await this.httpClient.get(`/admin-api/applications/${pathSegment(appId)}`));
|
|
1112
1120
|
}
|
|
1113
1121
|
/**
|
|
1114
1122
|
* Installed-blob inventory for an application — one entry per locally installed
|
|
@@ -1117,7 +1125,7 @@ var AdminApiClient = class {
|
|
|
1117
1125
|
*/
|
|
1118
1126
|
async listApplicationVersions(applicationId) {
|
|
1119
1127
|
return unwrap(
|
|
1120
|
-
await this.httpClient.get(`/admin-api/applications/${applicationId}/versions`)
|
|
1128
|
+
await this.httpClient.get(`/admin-api/applications/${pathSegment(applicationId)}/versions`)
|
|
1121
1129
|
);
|
|
1122
1130
|
}
|
|
1123
1131
|
/**
|
|
@@ -1128,7 +1136,7 @@ var AdminApiClient = class {
|
|
|
1128
1136
|
const query = serviceName ? `?service_name=${encodeURIComponent(serviceName)}` : "";
|
|
1129
1137
|
return unwrap(
|
|
1130
1138
|
await this.httpClient.get(
|
|
1131
|
-
`/admin-api/applications/${applicationId}/abi${query}`
|
|
1139
|
+
`/admin-api/applications/${pathSegment(applicationId)}/abi${query}`
|
|
1132
1140
|
)
|
|
1133
1141
|
);
|
|
1134
1142
|
}
|
|
@@ -1141,13 +1149,13 @@ var AdminApiClient = class {
|
|
|
1141
1149
|
}
|
|
1142
1150
|
async listPackageVersions(packageName) {
|
|
1143
1151
|
const r = await this.httpClient.get(
|
|
1144
|
-
`/admin-api/packages/${
|
|
1152
|
+
`/admin-api/packages/${pathSegment(packageName)}/versions`
|
|
1145
1153
|
);
|
|
1146
1154
|
return r?.data ?? r;
|
|
1147
1155
|
}
|
|
1148
1156
|
async getLatestPackageVersion(packageName) {
|
|
1149
1157
|
return this.httpClient.get(
|
|
1150
|
-
`/admin-api/packages/${
|
|
1158
|
+
`/admin-api/packages/${pathSegment(packageName)}/latest`
|
|
1151
1159
|
);
|
|
1152
1160
|
}
|
|
1153
1161
|
// ---- Context Management ----
|
|
@@ -1156,43 +1164,43 @@ var AdminApiClient = class {
|
|
|
1156
1164
|
return unwrap(await this.httpClient.post("/admin-api/contexts", body));
|
|
1157
1165
|
}
|
|
1158
1166
|
async deleteContext(contextId) {
|
|
1159
|
-
return unwrap(await this.httpClient.delete(`/admin-api/contexts/${contextId}`));
|
|
1167
|
+
return unwrap(await this.httpClient.delete(`/admin-api/contexts/${pathSegment(contextId)}`));
|
|
1160
1168
|
}
|
|
1161
1169
|
async getContexts() {
|
|
1162
1170
|
return unwrap(await this.httpClient.get("/admin-api/contexts"));
|
|
1163
1171
|
}
|
|
1164
1172
|
async getContext(contextId) {
|
|
1165
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}`));
|
|
1173
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}`));
|
|
1166
1174
|
}
|
|
1167
1175
|
async getContextsForApplication(applicationId) {
|
|
1168
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/for-application/${applicationId}`));
|
|
1176
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/for-application/${pathSegment(applicationId)}`));
|
|
1169
1177
|
}
|
|
1170
1178
|
// ---- Context Identity ----
|
|
1171
1179
|
async generateContextIdentity() {
|
|
1172
1180
|
return unwrap(await this.httpClient.post("/admin-api/identity/context", {}));
|
|
1173
1181
|
}
|
|
1174
1182
|
async getContextIdentities(contextId) {
|
|
1175
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities`));
|
|
1183
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/identities`));
|
|
1176
1184
|
}
|
|
1177
1185
|
async getContextIdentitiesOwned(contextId) {
|
|
1178
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities-owned`));
|
|
1186
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/identities-owned`));
|
|
1179
1187
|
}
|
|
1180
1188
|
// ---- Context join (group membership) ----
|
|
1181
1189
|
async joinContext(contextId) {
|
|
1182
1190
|
return unwrap(
|
|
1183
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/join`, {})
|
|
1191
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/join`, {})
|
|
1184
1192
|
);
|
|
1185
1193
|
}
|
|
1186
1194
|
// ---- Context group / storage / sync ----
|
|
1187
1195
|
async getContextGroup(contextId) {
|
|
1188
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/group`));
|
|
1196
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/group`));
|
|
1189
1197
|
}
|
|
1190
1198
|
async getContextStorage(contextId) {
|
|
1191
|
-
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/storage`));
|
|
1199
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${pathSegment(contextId)}/storage`));
|
|
1192
1200
|
}
|
|
1193
1201
|
/** Sync one context, or every context when `contextId` is omitted. */
|
|
1194
1202
|
async syncContext(contextId) {
|
|
1195
|
-
const path = contextId ? `/admin-api/contexts/sync/${contextId}` : "/admin-api/contexts/sync";
|
|
1203
|
+
const path = contextId ? `/admin-api/contexts/sync/${pathSegment(contextId)}` : "/admin-api/contexts/sync";
|
|
1196
1204
|
await this.httpClient.post(path, {});
|
|
1197
1205
|
}
|
|
1198
1206
|
/**
|
|
@@ -1202,7 +1210,7 @@ var AdminApiClient = class {
|
|
|
1202
1210
|
*/
|
|
1203
1211
|
async resyncContext(contextId, request = {}) {
|
|
1204
1212
|
const r = await this.httpClient.post(
|
|
1205
|
-
`/admin-api/contexts/${contextId}/resync`,
|
|
1213
|
+
`/admin-api/contexts/${pathSegment(contextId)}/resync`,
|
|
1206
1214
|
request
|
|
1207
1215
|
);
|
|
1208
1216
|
return r ?? { contextId, resyncStarted: true };
|
|
@@ -1216,10 +1224,10 @@ var AdminApiClient = class {
|
|
|
1216
1224
|
);
|
|
1217
1225
|
}
|
|
1218
1226
|
async updateContextApplication(contextId, request) {
|
|
1219
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/application`, request);
|
|
1227
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/application`, request);
|
|
1220
1228
|
}
|
|
1221
1229
|
async getContextsWithExecutorsForApplication(applicationId) {
|
|
1222
|
-
const r = await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${applicationId}`);
|
|
1230
|
+
const r = await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${pathSegment(applicationId)}`);
|
|
1223
1231
|
if (Array.isArray(r)) return r;
|
|
1224
1232
|
return r?.contexts ?? r?.data ?? [];
|
|
1225
1233
|
}
|
|
@@ -1241,7 +1249,7 @@ var AdminApiClient = class {
|
|
|
1241
1249
|
}
|
|
1242
1250
|
async deleteBlob(blobId) {
|
|
1243
1251
|
const body = await this.httpClient.delete(
|
|
1244
|
-
`/admin-api/blobs/${blobId}`
|
|
1252
|
+
`/admin-api/blobs/${pathSegment(blobId)}`
|
|
1245
1253
|
);
|
|
1246
1254
|
return { blobId: body.blob_id, deleted: body.deleted };
|
|
1247
1255
|
}
|
|
@@ -1259,9 +1267,9 @@ var AdminApiClient = class {
|
|
|
1259
1267
|
* side from drifting from the write side.
|
|
1260
1268
|
*/
|
|
1261
1269
|
blobPath(blobId, options) {
|
|
1262
|
-
if (!options?.contextId) return `/admin-api/blobs/${blobId}`;
|
|
1270
|
+
if (!options?.contextId) return `/admin-api/blobs/${pathSegment(blobId)}`;
|
|
1263
1271
|
const params = new URLSearchParams({ context_id: options.contextId });
|
|
1264
|
-
return `/admin-api/blobs/${blobId}?${params.toString()}`;
|
|
1272
|
+
return `/admin-api/blobs/${pathSegment(blobId)}?${params.toString()}`;
|
|
1265
1273
|
}
|
|
1266
1274
|
/**
|
|
1267
1275
|
* Download a blob's raw bytes. `GET /admin-api/blobs/:id` streams the blob
|
|
@@ -1326,7 +1334,7 @@ var AdminApiClient = class {
|
|
|
1326
1334
|
async lookupContextAlias(name) {
|
|
1327
1335
|
return unwrap(
|
|
1328
1336
|
await this.httpClient.post(
|
|
1329
|
-
`/admin-api/alias/lookup/context/${
|
|
1337
|
+
`/admin-api/alias/lookup/context/${pathSegment(name)}`,
|
|
1330
1338
|
{}
|
|
1331
1339
|
)
|
|
1332
1340
|
);
|
|
@@ -1334,7 +1342,7 @@ var AdminApiClient = class {
|
|
|
1334
1342
|
async lookupApplicationAlias(name) {
|
|
1335
1343
|
return unwrap(
|
|
1336
1344
|
await this.httpClient.post(
|
|
1337
|
-
`/admin-api/alias/lookup/application/${
|
|
1345
|
+
`/admin-api/alias/lookup/application/${pathSegment(name)}`,
|
|
1338
1346
|
{}
|
|
1339
1347
|
)
|
|
1340
1348
|
);
|
|
@@ -1342,7 +1350,7 @@ var AdminApiClient = class {
|
|
|
1342
1350
|
async deleteContextAlias(name) {
|
|
1343
1351
|
return unwrap(
|
|
1344
1352
|
await this.httpClient.post(
|
|
1345
|
-
`/admin-api/alias/delete/context/${
|
|
1353
|
+
`/admin-api/alias/delete/context/${pathSegment(name)}`,
|
|
1346
1354
|
{}
|
|
1347
1355
|
)
|
|
1348
1356
|
);
|
|
@@ -1350,7 +1358,7 @@ var AdminApiClient = class {
|
|
|
1350
1358
|
async deleteApplicationAlias(name) {
|
|
1351
1359
|
return unwrap(
|
|
1352
1360
|
await this.httpClient.post(
|
|
1353
|
-
`/admin-api/alias/delete/application/${
|
|
1361
|
+
`/admin-api/alias/delete/application/${pathSegment(name)}`,
|
|
1354
1362
|
{}
|
|
1355
1363
|
)
|
|
1356
1364
|
);
|
|
@@ -1372,7 +1380,7 @@ var AdminApiClient = class {
|
|
|
1372
1380
|
async lookupDeviceAlias(name) {
|
|
1373
1381
|
return unwrap(
|
|
1374
1382
|
await this.httpClient.post(
|
|
1375
|
-
`/admin-api/alias/lookup/device/${
|
|
1383
|
+
`/admin-api/alias/lookup/device/${pathSegment(name)}`,
|
|
1376
1384
|
{}
|
|
1377
1385
|
)
|
|
1378
1386
|
);
|
|
@@ -1380,7 +1388,7 @@ var AdminApiClient = class {
|
|
|
1380
1388
|
async deleteDeviceAlias(name) {
|
|
1381
1389
|
return unwrap(
|
|
1382
1390
|
await this.httpClient.post(
|
|
1383
|
-
`/admin-api/alias/delete/device/${
|
|
1391
|
+
`/admin-api/alias/delete/device/${pathSegment(name)}`,
|
|
1384
1392
|
{}
|
|
1385
1393
|
)
|
|
1386
1394
|
);
|
|
@@ -1393,7 +1401,7 @@ var AdminApiClient = class {
|
|
|
1393
1401
|
return unwrap(await this.httpClient.get("/admin-api/namespaces"));
|
|
1394
1402
|
}
|
|
1395
1403
|
async getNamespace(namespaceId) {
|
|
1396
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}`));
|
|
1404
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${pathSegment(namespaceId)}`));
|
|
1397
1405
|
}
|
|
1398
1406
|
/**
|
|
1399
1407
|
* Who this node is — the account it writes as, the device it is, the key it
|
|
@@ -1458,7 +1466,7 @@ var AdminApiClient = class {
|
|
|
1458
1466
|
async performIntent(contextId, request) {
|
|
1459
1467
|
return unwrap(
|
|
1460
1468
|
await this.httpClient.post(
|
|
1461
|
-
`/admin-api/contexts/${contextId}/intents`,
|
|
1469
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`,
|
|
1462
1470
|
request
|
|
1463
1471
|
)
|
|
1464
1472
|
);
|
|
@@ -1475,7 +1483,7 @@ var AdminApiClient = class {
|
|
|
1475
1483
|
async queryContext(contextId, request) {
|
|
1476
1484
|
return unwrap(
|
|
1477
1485
|
await this.httpClient.post(
|
|
1478
|
-
`/admin-api/contexts/${contextId}/query`,
|
|
1486
|
+
`/admin-api/contexts/${pathSegment(contextId)}/query`,
|
|
1479
1487
|
request
|
|
1480
1488
|
)
|
|
1481
1489
|
);
|
|
@@ -1504,12 +1512,12 @@ var AdminApiClient = class {
|
|
|
1504
1512
|
async getIntentRelay(contextId) {
|
|
1505
1513
|
return unwrap(
|
|
1506
1514
|
await this.httpClient.get(
|
|
1507
|
-
`/admin-api/contexts/${contextId}/intents`
|
|
1515
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`
|
|
1508
1516
|
)
|
|
1509
1517
|
);
|
|
1510
1518
|
}
|
|
1511
1519
|
async listNamespacesForApplication(applicationId) {
|
|
1512
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/for-application/${applicationId}`));
|
|
1520
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/for-application/${pathSegment(applicationId)}`));
|
|
1513
1521
|
}
|
|
1514
1522
|
async createNamespace(request) {
|
|
1515
1523
|
return unwrap(
|
|
@@ -1518,7 +1526,7 @@ var AdminApiClient = class {
|
|
|
1518
1526
|
}
|
|
1519
1527
|
async deleteNamespace(namespaceId) {
|
|
1520
1528
|
return unwrap(
|
|
1521
|
-
await this.httpClient.request(`/admin-api/namespaces/${namespaceId}`, {
|
|
1529
|
+
await this.httpClient.request(`/admin-api/namespaces/${pathSegment(namespaceId)}`, {
|
|
1522
1530
|
method: "DELETE",
|
|
1523
1531
|
body: "{}",
|
|
1524
1532
|
headers: { "Content-Type": "application/json" }
|
|
@@ -1528,7 +1536,7 @@ var AdminApiClient = class {
|
|
|
1528
1536
|
async createNamespaceInvitation(namespaceId, request) {
|
|
1529
1537
|
return unwrap(
|
|
1530
1538
|
await this.httpClient.post(
|
|
1531
|
-
`/admin-api/namespaces/${namespaceId}/invite`,
|
|
1539
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/invite`,
|
|
1532
1540
|
request ?? {}
|
|
1533
1541
|
)
|
|
1534
1542
|
);
|
|
@@ -1553,7 +1561,7 @@ var AdminApiClient = class {
|
|
|
1553
1561
|
async admitJoin(namespaceId, request) {
|
|
1554
1562
|
return unwrap(
|
|
1555
1563
|
await this.httpClient.post(
|
|
1556
|
-
`/admin-api/namespaces/${namespaceId}/admit`,
|
|
1564
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/admit`,
|
|
1557
1565
|
request,
|
|
1558
1566
|
{ timeoutMs: 65e3 }
|
|
1559
1567
|
)
|
|
@@ -1562,7 +1570,7 @@ var AdminApiClient = class {
|
|
|
1562
1570
|
async joinNamespace(namespaceId, request) {
|
|
1563
1571
|
const data = unwrap(
|
|
1564
1572
|
await this.httpClient.post(
|
|
1565
|
-
`/admin-api/namespaces/${namespaceId}/join`,
|
|
1573
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/join`,
|
|
1566
1574
|
request,
|
|
1567
1575
|
{ timeoutMs: 65e3 }
|
|
1568
1576
|
)
|
|
@@ -1609,13 +1617,13 @@ var AdminApiClient = class {
|
|
|
1609
1617
|
async createGroupInNamespace(namespaceId, request) {
|
|
1610
1618
|
return unwrap(
|
|
1611
1619
|
await this.httpClient.post(
|
|
1612
|
-
`/admin-api/namespaces/${namespaceId}/groups`,
|
|
1620
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/groups`,
|
|
1613
1621
|
request ?? {}
|
|
1614
1622
|
)
|
|
1615
1623
|
);
|
|
1616
1624
|
}
|
|
1617
1625
|
async listNamespaceGroups(namespaceId) {
|
|
1618
|
-
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}/groups`));
|
|
1626
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${pathSegment(namespaceId)}/groups`));
|
|
1619
1627
|
}
|
|
1620
1628
|
// ---- Account Devices & Pairing ----
|
|
1621
1629
|
/**
|
|
@@ -1677,7 +1685,7 @@ var AdminApiClient = class {
|
|
|
1677
1685
|
async relinkAccountDevice(deviceId, request) {
|
|
1678
1686
|
return unwrap(
|
|
1679
1687
|
await this.httpClient.post(
|
|
1680
|
-
`/admin-api/account/devices/${deviceId}/relink`,
|
|
1688
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/relink`,
|
|
1681
1689
|
request ?? {}
|
|
1682
1690
|
)
|
|
1683
1691
|
);
|
|
@@ -1692,7 +1700,7 @@ var AdminApiClient = class {
|
|
|
1692
1700
|
async rescopeAccountDevice(deviceId, request) {
|
|
1693
1701
|
return unwrap(
|
|
1694
1702
|
await this.httpClient.put(
|
|
1695
|
-
`/admin-api/account/devices/${
|
|
1703
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/scope`,
|
|
1696
1704
|
request
|
|
1697
1705
|
)
|
|
1698
1706
|
);
|
|
@@ -1743,7 +1751,7 @@ var AdminApiClient = class {
|
|
|
1743
1751
|
async labelAccountDevice(deviceId, request) {
|
|
1744
1752
|
return unwrap(
|
|
1745
1753
|
await this.httpClient.put(
|
|
1746
|
-
`/admin-api/account/devices/${
|
|
1754
|
+
`/admin-api/account/devices/${pathSegment(deviceId)}/label`,
|
|
1747
1755
|
request
|
|
1748
1756
|
)
|
|
1749
1757
|
);
|
|
@@ -1807,7 +1815,7 @@ var AdminApiClient = class {
|
|
|
1807
1815
|
async revokeAccountDevice(namespaceId, request) {
|
|
1808
1816
|
return unwrap(
|
|
1809
1817
|
await this.httpClient.post(
|
|
1810
|
-
`/admin-api/namespaces/${namespaceId}/account/revoke`,
|
|
1818
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/account/revoke`,
|
|
1811
1819
|
request
|
|
1812
1820
|
)
|
|
1813
1821
|
);
|
|
@@ -1830,14 +1838,14 @@ var AdminApiClient = class {
|
|
|
1830
1838
|
async linkAccountDevice(namespaceId, request) {
|
|
1831
1839
|
return unwrap(
|
|
1832
1840
|
await this.httpClient.post(
|
|
1833
|
-
`/admin-api/namespaces/${namespaceId}/account/link-device`,
|
|
1841
|
+
`/admin-api/namespaces/${pathSegment(namespaceId)}/account/link-device`,
|
|
1834
1842
|
request
|
|
1835
1843
|
)
|
|
1836
1844
|
);
|
|
1837
1845
|
}
|
|
1838
1846
|
// ---- Group Management ----
|
|
1839
1847
|
async getGroupInfo(groupId) {
|
|
1840
|
-
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}`));
|
|
1848
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}`));
|
|
1841
1849
|
}
|
|
1842
1850
|
/** Thin wrapper over {@link getGroupInfo}: returns the group's `defaultCapabilities` bitmask. */
|
|
1843
1851
|
async getDefaultCapabilities(groupId) {
|
|
@@ -1849,7 +1857,7 @@ var AdminApiClient = class {
|
|
|
1849
1857
|
}
|
|
1850
1858
|
async deleteGroup(groupId) {
|
|
1851
1859
|
return unwrap(
|
|
1852
|
-
await this.httpClient.request(`/admin-api/groups/${groupId}`, {
|
|
1860
|
+
await this.httpClient.request(`/admin-api/groups/${pathSegment(groupId)}`, {
|
|
1853
1861
|
method: "DELETE",
|
|
1854
1862
|
body: "{}",
|
|
1855
1863
|
headers: { "Content-Type": "application/json" }
|
|
@@ -1858,7 +1866,7 @@ var AdminApiClient = class {
|
|
|
1858
1866
|
}
|
|
1859
1867
|
async listGroupMembers(groupId) {
|
|
1860
1868
|
const response = await this.httpClient.get(
|
|
1861
|
-
`/admin-api/groups/${groupId}/members`
|
|
1869
|
+
`/admin-api/groups/${pathSegment(groupId)}/members`
|
|
1862
1870
|
);
|
|
1863
1871
|
if (!Array.isArray(response?.members)) {
|
|
1864
1872
|
const safeId = String(groupId).replace(/[\r\n\t\s]/g, "").slice(0, 64);
|
|
@@ -1896,7 +1904,7 @@ var AdminApiClient = class {
|
|
|
1896
1904
|
if (options?.offset !== void 0) params.set("offset", String(options.offset));
|
|
1897
1905
|
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
1898
1906
|
const query = params.toString();
|
|
1899
|
-
const base = `/admin-api/groups/${
|
|
1907
|
+
const base = `/admin-api/groups/${pathSegment(groupId)}/member-devices`;
|
|
1900
1908
|
const response = await this.httpClient.get(
|
|
1901
1909
|
query ? `${base}?${query}` : base
|
|
1902
1910
|
);
|
|
@@ -1948,7 +1956,7 @@ var AdminApiClient = class {
|
|
|
1948
1956
|
* hex (exactly 64). The node accepts either; the two never collide.
|
|
1949
1957
|
*/
|
|
1950
1958
|
async getWarrantNonce(contextId, authorDeviceKey) {
|
|
1951
|
-
const path = `/admin-api/contexts/${
|
|
1959
|
+
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce/${pathSegment(authorDeviceKey)}`;
|
|
1952
1960
|
let raw;
|
|
1953
1961
|
try {
|
|
1954
1962
|
raw = await this.httpClient.get(path, { parse: "text" });
|
|
@@ -1988,7 +1996,7 @@ var AdminApiClient = class {
|
|
|
1988
1996
|
* value passed as `authorProof` to the relay client.
|
|
1989
1997
|
*/
|
|
1990
1998
|
async getWarrantNonceAsAuthor(contextId, authorProof) {
|
|
1991
|
-
const path = `/admin-api/contexts/${
|
|
1999
|
+
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce`;
|
|
1992
2000
|
let raw;
|
|
1993
2001
|
try {
|
|
1994
2002
|
raw = await this.httpClient.post(path, { authorProof }, { parse: "text" });
|
|
@@ -2010,7 +2018,7 @@ var AdminApiClient = class {
|
|
|
2010
2018
|
if (options.offset !== void 0) params.set("offset", String(options.offset));
|
|
2011
2019
|
if (options.limit !== void 0) params.set("limit", String(options.limit));
|
|
2012
2020
|
const query = params.toString();
|
|
2013
|
-
const path = `/admin-api/groups/${groupId}/member-devices${query ? `?${query}` : ""}`;
|
|
2021
|
+
const path = `/admin-api/groups/${pathSegment(groupId)}/member-devices${query ? `?${query}` : ""}`;
|
|
2014
2022
|
return this.httpClient.get(path);
|
|
2015
2023
|
}
|
|
2016
2024
|
/**
|
|
@@ -2021,19 +2029,19 @@ var AdminApiClient = class {
|
|
|
2021
2029
|
async sealToAccount(groupId, account, request) {
|
|
2022
2030
|
return unwrap(
|
|
2023
2031
|
await this.httpClient.post(
|
|
2024
|
-
`/admin-api/groups/${groupId}/accounts/${account}/seal`,
|
|
2032
|
+
`/admin-api/groups/${pathSegment(groupId)}/accounts/${pathSegment(account)}/seal`,
|
|
2025
2033
|
request
|
|
2026
2034
|
)
|
|
2027
2035
|
);
|
|
2028
2036
|
}
|
|
2029
2037
|
async listGroupContexts(groupId) {
|
|
2030
|
-
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/contexts`));
|
|
2038
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/contexts`));
|
|
2031
2039
|
}
|
|
2032
2040
|
async addGroupMembers(groupId, request) {
|
|
2033
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/members`, request);
|
|
2041
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/members`, request);
|
|
2034
2042
|
}
|
|
2035
2043
|
async removeGroupMembers(groupId, request) {
|
|
2036
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/members/remove`, request);
|
|
2044
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/members/remove`, request);
|
|
2037
2045
|
}
|
|
2038
2046
|
/**
|
|
2039
2047
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2041,7 +2049,7 @@ var AdminApiClient = class {
|
|
|
2041
2049
|
* 64 hex, so nothing but the source tells them apart.
|
|
2042
2050
|
*/
|
|
2043
2051
|
async updateMemberRole(groupId, identity, request) {
|
|
2044
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/role`, request);
|
|
2052
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/role`, request);
|
|
2045
2053
|
}
|
|
2046
2054
|
/**
|
|
2047
2055
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2051,7 +2059,7 @@ var AdminApiClient = class {
|
|
|
2051
2059
|
async getMemberCapabilities(groupId, identity) {
|
|
2052
2060
|
return unwrap(
|
|
2053
2061
|
await this.httpClient.get(
|
|
2054
|
-
`/admin-api/groups/${groupId}/members/${identity}/capabilities`
|
|
2062
|
+
`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/capabilities`
|
|
2055
2063
|
)
|
|
2056
2064
|
);
|
|
2057
2065
|
}
|
|
@@ -2061,10 +2069,10 @@ var AdminApiClient = class {
|
|
|
2061
2069
|
* 64 hex, so nothing but the source tells them apart.
|
|
2062
2070
|
*/
|
|
2063
2071
|
async setMemberCapabilities(groupId, identity, request) {
|
|
2064
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/capabilities`, request);
|
|
2072
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/capabilities`, request);
|
|
2065
2073
|
}
|
|
2066
2074
|
async setDefaultCapabilities(groupId, request) {
|
|
2067
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/default-capabilities`, request);
|
|
2075
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/default-capabilities`, request);
|
|
2068
2076
|
}
|
|
2069
2077
|
/**
|
|
2070
2078
|
* Make every member admitted to `groupId` from now on able to relay a
|
|
@@ -2146,13 +2154,13 @@ var AdminApiClient = class {
|
|
|
2146
2154
|
return { changed: true, capabilities: next };
|
|
2147
2155
|
}
|
|
2148
2156
|
async setSubgroupVisibility(groupId, request) {
|
|
2149
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/subgroup-visibility`, request);
|
|
2157
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/subgroup-visibility`, request);
|
|
2150
2158
|
}
|
|
2151
2159
|
async setTeeAdmissionPolicy(groupId, request) {
|
|
2152
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-admission-policy`, request);
|
|
2160
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-admission-policy`, request);
|
|
2153
2161
|
}
|
|
2154
2162
|
async getTeeAdmissionPolicy(groupId) {
|
|
2155
|
-
const response = await this.httpClient.get(`/admin-api/groups/${groupId}/settings/tee-admission-policy`);
|
|
2163
|
+
const response = await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-admission-policy`);
|
|
2156
2164
|
return response.data ?? response;
|
|
2157
2165
|
}
|
|
2158
2166
|
/**
|
|
@@ -2162,7 +2170,7 @@ var AdminApiClient = class {
|
|
|
2162
2170
|
* route for this policy.
|
|
2163
2171
|
*/
|
|
2164
2172
|
async setTeeAuthoringPolicy(groupId, request) {
|
|
2165
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-authoring-policy`, request);
|
|
2173
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/settings/tee-authoring-policy`, request);
|
|
2166
2174
|
}
|
|
2167
2175
|
/**
|
|
2168
2176
|
* Turns TEE authorship off in the namespace: every TEE loses its authority,
|
|
@@ -2174,7 +2182,7 @@ var AdminApiClient = class {
|
|
|
2174
2182
|
* (`teeAuthoringPolicyOp([])`); omit it on a node that holds that root.
|
|
2175
2183
|
*/
|
|
2176
2184
|
async disableTeeAuthoringPolicy(groupId, options = {}) {
|
|
2177
|
-
const path = `/admin-api/groups/${groupId}/settings/tee-authoring-policy`;
|
|
2185
|
+
const path = `/admin-api/groups/${pathSegment(groupId)}/settings/tee-authoring-policy`;
|
|
2178
2186
|
if (options.rootProof === void 0) {
|
|
2179
2187
|
await this.httpClient.delete(path);
|
|
2180
2188
|
return;
|
|
@@ -2192,14 +2200,14 @@ var AdminApiClient = class {
|
|
|
2192
2200
|
* {@link RootGuardedOpRequest}.
|
|
2193
2201
|
*/
|
|
2194
2202
|
async transferOwnership(groupId, request) {
|
|
2195
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/transfer-ownership`, request);
|
|
2203
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/transfer-ownership`, request);
|
|
2196
2204
|
}
|
|
2197
2205
|
/**
|
|
2198
2206
|
* Repoint the namespace's admin pin at `newAdmin`, a member of its root.
|
|
2199
2207
|
* Owner-only, with the owner account's root proof; see {@link RootGuardedOpRequest}.
|
|
2200
2208
|
*/
|
|
2201
2209
|
async changeNamespaceAdmin(namespaceId, request) {
|
|
2202
|
-
await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/admin`, request);
|
|
2210
|
+
await this.httpClient.post(`/admin-api/namespaces/${pathSegment(namespaceId)}/admin`, request);
|
|
2203
2211
|
}
|
|
2204
2212
|
/**
|
|
2205
2213
|
* Delete a group through the owner-only path: it must hold no contexts, and
|
|
@@ -2207,20 +2215,20 @@ var AdminApiClient = class {
|
|
|
2207
2215
|
* admin-level cascading delete.
|
|
2208
2216
|
*/
|
|
2209
2217
|
async ownerDeleteGroup(groupId, request = {}) {
|
|
2210
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/owner-delete`, request);
|
|
2218
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/owner-delete`, request);
|
|
2211
2219
|
}
|
|
2212
2220
|
// ---- Group / member / context metadata ----
|
|
2213
2221
|
async setGroupMetadata(groupId, request) {
|
|
2214
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/metadata`, request);
|
|
2222
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/metadata`, request);
|
|
2215
2223
|
}
|
|
2216
2224
|
async getGroupMetadata(groupId) {
|
|
2217
2225
|
const response = await this.httpClient.get(
|
|
2218
|
-
`/admin-api/groups/${groupId}/metadata`
|
|
2226
|
+
`/admin-api/groups/${pathSegment(groupId)}/metadata`
|
|
2219
2227
|
);
|
|
2220
2228
|
return response?.data ?? null;
|
|
2221
2229
|
}
|
|
2222
2230
|
async setMemberMetadata(groupId, identity, request) {
|
|
2223
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/metadata`, request);
|
|
2231
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/metadata`, request);
|
|
2224
2232
|
}
|
|
2225
2233
|
/**
|
|
2226
2234
|
* `identity` is the member's ACCOUNT (64 hex), as returned by
|
|
@@ -2229,28 +2237,28 @@ var AdminApiClient = class {
|
|
|
2229
2237
|
*/
|
|
2230
2238
|
async getMemberMetadata(groupId, identity) {
|
|
2231
2239
|
const response = await this.httpClient.get(
|
|
2232
|
-
`/admin-api/groups/${groupId}/members/${identity}/metadata`
|
|
2240
|
+
`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/metadata`
|
|
2233
2241
|
);
|
|
2234
2242
|
return response?.data ?? null;
|
|
2235
2243
|
}
|
|
2236
2244
|
async setContextMetadata(groupId, contextId, request) {
|
|
2237
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`, request);
|
|
2245
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/metadata`, request);
|
|
2238
2246
|
}
|
|
2239
2247
|
async getContextMetadata(groupId, contextId) {
|
|
2240
2248
|
const response = await this.httpClient.get(
|
|
2241
|
-
`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`
|
|
2249
|
+
`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/metadata`
|
|
2242
2250
|
);
|
|
2243
2251
|
return response?.data ?? null;
|
|
2244
2252
|
}
|
|
2245
2253
|
async syncGroup(groupId) {
|
|
2246
|
-
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/sync`, {}));
|
|
2254
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/sync`, {}));
|
|
2247
2255
|
}
|
|
2248
2256
|
async upgradeGroup(groupId, request) {
|
|
2249
|
-
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/upgrade`, request));
|
|
2257
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/upgrade`, request));
|
|
2250
2258
|
}
|
|
2251
2259
|
async getGroupUpgradeStatus(groupId) {
|
|
2252
2260
|
return unwrap(
|
|
2253
|
-
await this.httpClient.get(`/admin-api/groups/${groupId}/upgrade/status`)
|
|
2261
|
+
await this.httpClient.get(`/admin-api/groups/${pathSegment(groupId)}/upgrade/status`)
|
|
2254
2262
|
);
|
|
2255
2263
|
}
|
|
2256
2264
|
/**
|
|
@@ -2259,43 +2267,41 @@ var AdminApiClient = class {
|
|
|
2259
2267
|
* envelope to unwrap here (unlike most admin reads).
|
|
2260
2268
|
*/
|
|
2261
2269
|
async getMigrationStatus(namespaceId) {
|
|
2262
|
-
|
|
2263
|
-
return this.httpClient.get(`/admin-api/groups/${id}/migration-status`);
|
|
2270
|
+
return this.httpClient.get(`/admin-api/groups/${pathSegment(namespaceId)}/migration-status`);
|
|
2264
2271
|
}
|
|
2265
2272
|
/** Per-group cascade-migration snapshots for a namespace. */
|
|
2266
2273
|
async getCascadeStatus(namespaceId) {
|
|
2267
|
-
const id = encodeURIComponent(namespaceId);
|
|
2268
2274
|
return unwrap(
|
|
2269
|
-
await this.httpClient.get(`/admin-api/groups/${
|
|
2275
|
+
await this.httpClient.get(`/admin-api/groups/${pathSegment(namespaceId)}/cascade-status`)
|
|
2270
2276
|
);
|
|
2271
2277
|
}
|
|
2272
2278
|
async retryGroupUpgrade(groupId) {
|
|
2273
2279
|
return unwrap(
|
|
2274
2280
|
await this.httpClient.post(
|
|
2275
|
-
`/admin-api/groups/${groupId}/upgrade/retry`,
|
|
2281
|
+
`/admin-api/groups/${pathSegment(groupId)}/upgrade/retry`,
|
|
2276
2282
|
{}
|
|
2277
2283
|
)
|
|
2278
2284
|
);
|
|
2279
2285
|
}
|
|
2280
2286
|
/** Move `childGroupId` under `request.newParentId`. */
|
|
2281
2287
|
async reparentGroup(childGroupId, request) {
|
|
2282
|
-
const r = await this.httpClient.post(`/admin-api/groups/${childGroupId}/reparent`, request);
|
|
2288
|
+
const r = await this.httpClient.post(`/admin-api/groups/${pathSegment(childGroupId)}/reparent`, request);
|
|
2283
2289
|
return r?.data ?? r;
|
|
2284
2290
|
}
|
|
2285
2291
|
async listSubgroups(groupId) {
|
|
2286
2292
|
const response = await this.httpClient.get(
|
|
2287
|
-
`/admin-api/groups/${groupId}/subgroups`
|
|
2293
|
+
`/admin-api/groups/${pathSegment(groupId)}/subgroups`
|
|
2288
2294
|
);
|
|
2289
2295
|
return response.subgroups ?? response.data ?? [];
|
|
2290
2296
|
}
|
|
2291
2297
|
async detachContextFromGroup(groupId, contextId) {
|
|
2292
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/contexts/${contextId}/remove`, {});
|
|
2298
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/contexts/${pathSegment(contextId)}/remove`, {});
|
|
2293
2299
|
}
|
|
2294
2300
|
// ---- Group Invitation & Join ----
|
|
2295
2301
|
async createGroupInvitation(groupId, request) {
|
|
2296
2302
|
return unwrap(
|
|
2297
2303
|
await this.httpClient.post(
|
|
2298
|
-
`/admin-api/groups/${groupId}/invite`,
|
|
2304
|
+
`/admin-api/groups/${pathSegment(groupId)}/invite`,
|
|
2299
2305
|
request ?? {}
|
|
2300
2306
|
)
|
|
2301
2307
|
);
|
|
@@ -2308,7 +2314,7 @@ var AdminApiClient = class {
|
|
|
2308
2314
|
async joinSubgroupInheritance(groupId) {
|
|
2309
2315
|
return unwrap(
|
|
2310
2316
|
await this.httpClient.post(
|
|
2311
|
-
`/admin-api/groups/${groupId}/join-via-inheritance`,
|
|
2317
|
+
`/admin-api/groups/${pathSegment(groupId)}/join-via-inheritance`,
|
|
2312
2318
|
{}
|
|
2313
2319
|
)
|
|
2314
2320
|
);
|
|
@@ -2350,27 +2356,27 @@ var AdminApiClient = class {
|
|
|
2350
2356
|
}
|
|
2351
2357
|
/** Leave a group (POST /admin-api/groups/:group_id/leave). */
|
|
2352
2358
|
async leaveGroup(groupId) {
|
|
2353
|
-
await this.httpClient.post(`/admin-api/groups/${groupId}/leave`, {});
|
|
2359
|
+
await this.httpClient.post(`/admin-api/groups/${pathSegment(groupId)}/leave`, {});
|
|
2354
2360
|
}
|
|
2355
2361
|
/** Leave a context (POST /admin-api/contexts/:context_id/leave). */
|
|
2356
2362
|
async leaveContext(contextId) {
|
|
2357
|
-
await this.httpClient.post(`/admin-api/contexts/${contextId}/leave`, {});
|
|
2363
|
+
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/leave`, {});
|
|
2358
2364
|
}
|
|
2359
2365
|
/** Leave a namespace (POST /admin-api/namespaces/:namespace_id/leave). */
|
|
2360
2366
|
async leaveNamespace(namespaceId) {
|
|
2361
|
-
await this.httpClient.post(`/admin-api/namespaces/${namespaceId}/leave`, {});
|
|
2367
|
+
await this.httpClient.post(`/admin-api/namespaces/${pathSegment(namespaceId)}/leave`, {});
|
|
2362
2368
|
}
|
|
2363
2369
|
/** Issue a group ownership proof (POST /admin-api/groups/:group_id/issue-ownership-proof). */
|
|
2364
2370
|
async issueOwnershipProof(groupId, request) {
|
|
2365
2371
|
return this.httpClient.post(
|
|
2366
|
-
`/admin-api/groups/${groupId}/issue-ownership-proof`,
|
|
2372
|
+
`/admin-api/groups/${pathSegment(groupId)}/issue-ownership-proof`,
|
|
2367
2373
|
request
|
|
2368
2374
|
);
|
|
2369
2375
|
}
|
|
2370
2376
|
/** Issue a namespace ownership proof (POST /admin-api/groups/:group_id/issue-namespace-ownership-proof). */
|
|
2371
2377
|
async issueNamespaceOwnershipProof(groupId, request) {
|
|
2372
2378
|
return this.httpClient.post(
|
|
2373
|
-
`/admin-api/groups/${groupId}/issue-namespace-ownership-proof`,
|
|
2379
|
+
`/admin-api/groups/${pathSegment(groupId)}/issue-namespace-ownership-proof`,
|
|
2374
2380
|
request
|
|
2375
2381
|
);
|
|
2376
2382
|
}
|
|
@@ -2383,11 +2389,11 @@ var AdminApiClient = class {
|
|
|
2383
2389
|
* 64 hex, so nothing but the source tells them apart.
|
|
2384
2390
|
*/
|
|
2385
2391
|
async setMemberAutoFollow(groupId, identity, request) {
|
|
2386
|
-
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/auto-follow`, request);
|
|
2392
|
+
await this.httpClient.put(`/admin-api/groups/${pathSegment(groupId)}/members/${pathSegment(identity)}/auto-follow`, request);
|
|
2387
2393
|
}
|
|
2388
2394
|
/** Abort a namespace migration (POST /admin-api/groups/:namespace_id/migration/abort). */
|
|
2389
2395
|
async abortMigration(namespaceId) {
|
|
2390
|
-
return this.httpClient.post(`/admin-api/groups/${namespaceId}/migration/abort`, {});
|
|
2396
|
+
return this.httpClient.post(`/admin-api/groups/${pathSegment(namespaceId)}/migration/abort`, {});
|
|
2391
2397
|
}
|
|
2392
2398
|
};
|
|
2393
2399
|
|
|
@@ -7926,7 +7932,7 @@ var RelayClient = class {
|
|
|
7926
7932
|
async describe(contextId) {
|
|
7927
7933
|
const body = await this.json(
|
|
7928
7934
|
"GET",
|
|
7929
|
-
`/admin-api/contexts/${
|
|
7935
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`
|
|
7930
7936
|
);
|
|
7931
7937
|
return body.data;
|
|
7932
7938
|
}
|
|
@@ -7963,7 +7969,7 @@ var RelayClient = class {
|
|
|
7963
7969
|
});
|
|
7964
7970
|
const body = await this.json(
|
|
7965
7971
|
"POST",
|
|
7966
|
-
`/admin-api/contexts/${
|
|
7972
|
+
`/admin-api/contexts/${pathSegment(contextId)}/intents`,
|
|
7967
7973
|
{ method, argsJson, warrant, authorProof: this.config.authorProof }
|
|
7968
7974
|
);
|
|
7969
7975
|
return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
|
|
@@ -7977,7 +7983,7 @@ var RelayClient = class {
|
|
|
7977
7983
|
async presenceIntent(contextId, body) {
|
|
7978
7984
|
await this.jsonOnce(
|
|
7979
7985
|
"POST",
|
|
7980
|
-
`/admin-api/contexts/${
|
|
7986
|
+
`/admin-api/contexts/${pathSegment(contextId)}/presence-intents`,
|
|
7981
7987
|
body
|
|
7982
7988
|
);
|
|
7983
7989
|
}
|
|
@@ -7991,7 +7997,7 @@ var RelayClient = class {
|
|
|
7991
7997
|
const query = opts.author ? `?author=${encodeURIComponent(opts.author)}` : "";
|
|
7992
7998
|
const body = await this.json(
|
|
7993
7999
|
"GET",
|
|
7994
|
-
`/admin-api/groups/${
|
|
8000
|
+
`/admin-api/groups/${pathSegment(groupId)}/context-intents${query}`
|
|
7995
8001
|
);
|
|
7996
8002
|
return body.data;
|
|
7997
8003
|
}
|
|
@@ -8055,7 +8061,7 @@ var RelayClient = class {
|
|
|
8055
8061
|
});
|
|
8056
8062
|
const body = await this.json(
|
|
8057
8063
|
"POST",
|
|
8058
|
-
`/admin-api/groups/${
|
|
8064
|
+
`/admin-api/groups/${pathSegment(input.groupId)}/context-intents`,
|
|
8059
8065
|
{ warrant, authorProof: this.config.authorProof, initArgs }
|
|
8060
8066
|
);
|
|
8061
8067
|
return {
|
|
@@ -8071,7 +8077,7 @@ var RelayClient = class {
|
|
|
8071
8077
|
async describeGovernance(groupId) {
|
|
8072
8078
|
const body = await this.json(
|
|
8073
8079
|
"GET",
|
|
8074
|
-
`/admin-api/groups/${
|
|
8080
|
+
`/admin-api/groups/${pathSegment(groupId)}/governance-intents`
|
|
8075
8081
|
);
|
|
8076
8082
|
return body.data;
|
|
8077
8083
|
}
|
|
@@ -8203,7 +8209,7 @@ var RelayClient = class {
|
|
|
8203
8209
|
return result;
|
|
8204
8210
|
}
|
|
8205
8211
|
async postGovernance(groupId, op, warrant) {
|
|
8206
|
-
const body = await this.json("POST", `/admin-api/groups/${
|
|
8212
|
+
const body = await this.json("POST", `/admin-api/groups/${pathSegment(groupId)}/governance-intents`, {
|
|
8207
8213
|
warrant,
|
|
8208
8214
|
authorProof: this.config.authorProof,
|
|
8209
8215
|
op: hex(op.bytes)
|
|
@@ -9906,15 +9912,70 @@ function base643(bytes) {
|
|
|
9906
9912
|
return btoa(binary);
|
|
9907
9913
|
}
|
|
9908
9914
|
|
|
9915
|
+
// src/cloud/link-state.ts
|
|
9916
|
+
var KEY2 = "calimero.cloud.link.pending";
|
|
9917
|
+
var STATE_PARAM = "link_state";
|
|
9918
|
+
var LIFETIME_MS = 10 * 60 * 1e3;
|
|
9919
|
+
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
9920
|
+
var MAX_PENDING = 20;
|
|
9921
|
+
function readPending(now) {
|
|
9922
|
+
try {
|
|
9923
|
+
const raw = localStorage.getItem(KEY2);
|
|
9924
|
+
const pending = raw ? JSON.parse(raw) : {};
|
|
9925
|
+
return Object.fromEntries(
|
|
9926
|
+
Object.entries(pending).filter(
|
|
9927
|
+
([, p]) => p && typeof p.expiresAt === "number" && p.expiresAt > now
|
|
9928
|
+
)
|
|
9929
|
+
);
|
|
9930
|
+
} catch {
|
|
9931
|
+
return {};
|
|
9932
|
+
}
|
|
9933
|
+
}
|
|
9934
|
+
function writePending(pending) {
|
|
9935
|
+
try {
|
|
9936
|
+
localStorage.setItem(KEY2, JSON.stringify(pending));
|
|
9937
|
+
} catch {
|
|
9938
|
+
}
|
|
9939
|
+
}
|
|
9940
|
+
function beginLinkState(account, returnTo) {
|
|
9941
|
+
if (!ACCOUNT_HEX.test(account)) {
|
|
9942
|
+
throw new Error("accountId must be 64 lowercase hex characters");
|
|
9943
|
+
}
|
|
9944
|
+
const url = new URL(returnTo);
|
|
9945
|
+
const now = Date.now();
|
|
9946
|
+
const pending = readPending(now);
|
|
9947
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
9948
|
+
const state = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
|
|
9949
|
+
""
|
|
9950
|
+
);
|
|
9951
|
+
pending[state] = { account, expiresAt: now + LIFETIME_MS };
|
|
9952
|
+
writePending(Object.fromEntries(Object.entries(pending).slice(-MAX_PENDING)));
|
|
9953
|
+
url.searchParams.set(STATE_PARAM, state);
|
|
9954
|
+
return url.toString();
|
|
9955
|
+
}
|
|
9956
|
+
function takeLinkState(search) {
|
|
9957
|
+
const state = new URLSearchParams(search).get(STATE_PARAM);
|
|
9958
|
+
const pending = readPending(Date.now());
|
|
9959
|
+
if (!state || !Object.prototype.hasOwnProperty.call(pending, state))
|
|
9960
|
+
return null;
|
|
9961
|
+
const entry = pending[state];
|
|
9962
|
+
delete pending[state];
|
|
9963
|
+
writePending(pending);
|
|
9964
|
+
return entry;
|
|
9965
|
+
}
|
|
9966
|
+
function withoutLinkState(search) {
|
|
9967
|
+
const params = new URLSearchParams(search);
|
|
9968
|
+
params.delete(STATE_PARAM);
|
|
9969
|
+
const rest = params.toString();
|
|
9970
|
+
return rest ? `?${rest}` : "";
|
|
9971
|
+
}
|
|
9972
|
+
|
|
9909
9973
|
// src/cloud/link-redirect.ts
|
|
9910
9974
|
var DEFAULT_CLOUD_WEB_URL = "https://cloud.calimero.network";
|
|
9911
9975
|
function cloudLinkUrl(options) {
|
|
9912
|
-
if (!/^[0-9a-f]{64}$/.test(options.accountId)) {
|
|
9913
|
-
throw new Error("accountId must be 64 lowercase hex characters");
|
|
9914
|
-
}
|
|
9915
9976
|
const url = new URL(options.cloudWebUrl ?? DEFAULT_CLOUD_WEB_URL);
|
|
9916
9977
|
url.searchParams.set("link-account", options.accountId);
|
|
9917
|
-
url.searchParams.set("callback-url", options.returnTo);
|
|
9978
|
+
url.searchParams.set("callback-url", beginLinkState(options.accountId, options.returnTo));
|
|
9918
9979
|
return url.toString();
|
|
9919
9980
|
}
|
|
9920
9981
|
function beginCloudLink(options) {
|
|
@@ -9925,6 +9986,7 @@ function readCloudLinkCallback(location2 = window.location) {
|
|
|
9925
9986
|
const params = new URLSearchParams(location2.hash.replace(/^#/, ""));
|
|
9926
9987
|
const error = params.get("error");
|
|
9927
9988
|
if (error) {
|
|
9989
|
+
takeLinkState(location2.search ?? "");
|
|
9928
9990
|
stripFragment();
|
|
9929
9991
|
throw new Error(
|
|
9930
9992
|
error === "denied" ? "the account link was declined at the cloud" : `the cloud refused this link: ${error}`
|
|
@@ -9933,12 +9995,18 @@ function readCloudLinkCallback(location2 = window.location) {
|
|
|
9933
9995
|
const grant = params.get("grant");
|
|
9934
9996
|
const account = params.get("account");
|
|
9935
9997
|
if (!grant || !account) return null;
|
|
9998
|
+
if (takeLinkState(location2.search ?? "")?.account !== account) {
|
|
9999
|
+
stripFragment();
|
|
10000
|
+
throw new Error(
|
|
10001
|
+
"this account link answers a request this browser did not make - start the link again from here"
|
|
10002
|
+
);
|
|
10003
|
+
}
|
|
9936
10004
|
stripFragment();
|
|
9937
10005
|
return { grant, account };
|
|
9938
10006
|
}
|
|
9939
10007
|
function stripFragment() {
|
|
9940
10008
|
if (typeof history === "undefined" || !history.replaceState) return;
|
|
9941
|
-
history.replaceState(null, "", location.pathname + location.search);
|
|
10009
|
+
history.replaceState(null, "", location.pathname + withoutLinkState(location.search));
|
|
9942
10010
|
}
|
|
9943
10011
|
async function completeCloudLink(options) {
|
|
9944
10012
|
const root = await resolveRoot(options.root);
|
|
@@ -9958,7 +10026,7 @@ async function completeCloudLink(options) {
|
|
|
9958
10026
|
var DEVICE_PARAM = "enrol-device";
|
|
9959
10027
|
var KEM_PARAM = "enrol-kem";
|
|
9960
10028
|
var CALLBACK_PARAM = "callback-url";
|
|
9961
|
-
var
|
|
10029
|
+
var STATE_PARAM2 = "state";
|
|
9962
10030
|
function deviceEnrolmentUrl(options) {
|
|
9963
10031
|
assertHex(options.devicePublicKey, "devicePublicKey");
|
|
9964
10032
|
assertHex(options.kemPublicKey, "kemPublicKey");
|
|
@@ -9968,7 +10036,7 @@ function deviceEnrolmentUrl(options) {
|
|
|
9968
10036
|
url.searchParams.set(DEVICE_PARAM, options.devicePublicKey);
|
|
9969
10037
|
url.searchParams.set(KEM_PARAM, options.kemPublicKey);
|
|
9970
10038
|
url.searchParams.set(CALLBACK_PARAM, options.returnTo);
|
|
9971
|
-
if (options.state) url.searchParams.set(
|
|
10039
|
+
if (options.state) url.searchParams.set(STATE_PARAM2, options.state);
|
|
9972
10040
|
return url.toString();
|
|
9973
10041
|
}
|
|
9974
10042
|
function beginDeviceEnrolment(options) {
|
|
@@ -10135,7 +10203,7 @@ async function resolveRelayFromInvitation(input) {
|
|
|
10135
10203
|
relayUrl: chosen.relayUrl,
|
|
10136
10204
|
// The cloud's ready-made URL when it gave one, so the path is never rebuilt
|
|
10137
10205
|
// from a guess; the fallback is the documented route on the same origin.
|
|
10138
|
-
admitUrl: chosen.admitUrl ?? `${chosen.relayUrl.replace(/\/+$/, "")}/admin-api/namespaces/${input.namespaceId}/admit`,
|
|
10206
|
+
admitUrl: chosen.admitUrl ?? `${chosen.relayUrl.replace(/\/+$/, "")}/admin-api/namespaces/${pathSegment(input.namespaceId)}/admit`,
|
|
10139
10207
|
admitterAccount: chosen.account,
|
|
10140
10208
|
peerId: chosen.peerId,
|
|
10141
10209
|
writable: chosen.canExecute,
|
|
@@ -10373,7 +10441,7 @@ async function joinWithNode(input) {
|
|
|
10373
10441
|
};
|
|
10374
10442
|
}
|
|
10375
10443
|
const body = { invitation: input.invitation, signedOp };
|
|
10376
|
-
const url = input.admitUrl ?? `${origin(input.nodeUrl)}/admin-api/namespaces/${input.namespaceId}/admit`;
|
|
10444
|
+
const url = input.admitUrl ?? `${origin(input.nodeUrl)}/admin-api/namespaces/${pathSegment(input.namespaceId)}/admit`;
|
|
10377
10445
|
const doFetch = input.deps?.fetch ?? fetch;
|
|
10378
10446
|
let response;
|
|
10379
10447
|
try {
|
|
@@ -11066,7 +11134,6 @@ function joinOf(row) {
|
|
|
11066
11134
|
reportedAt: typeof join.reported_at === "string" ? join.reported_at : null
|
|
11067
11135
|
};
|
|
11068
11136
|
}
|
|
11069
|
-
var ACCOUNT_HEX = /^[0-9a-f]{64}$/;
|
|
11070
11137
|
function accountHexOrNull(value) {
|
|
11071
11138
|
return typeof value === "string" && ACCOUNT_HEX.test(value) ? value : null;
|
|
11072
11139
|
}
|
|
@@ -11286,7 +11353,7 @@ var CloudClient = class {
|
|
|
11286
11353
|
async getNamespaceRelays(namespaceId) {
|
|
11287
11354
|
const body = await this.request(
|
|
11288
11355
|
"GET",
|
|
11289
|
-
`/api/cloud/me/namespaces/${
|
|
11356
|
+
`/api/cloud/me/namespaces/${pathSegment(namespaceId)}/relays`
|
|
11290
11357
|
);
|
|
11291
11358
|
return (body.relays ?? []).map((row) => {
|
|
11292
11359
|
const relayUrl = row.relay_url ?? null;
|
|
@@ -11344,7 +11411,7 @@ var CloudClient = class {
|
|
|
11344
11411
|
* a node holding the namespace, so there is no hosted admitter.
|
|
11345
11412
|
*/
|
|
11346
11413
|
async getNamespaceRouting(namespaceId) {
|
|
11347
|
-
const body = await this.request("GET", `/api/cloud/namespaces/${
|
|
11414
|
+
const body = await this.request("GET", `/api/cloud/namespaces/${pathSegment(namespaceId)}/admitters`, {
|
|
11348
11415
|
anonymous: true,
|
|
11349
11416
|
headers: await this.routingProof(namespaceId)
|
|
11350
11417
|
});
|
|
@@ -11388,7 +11455,7 @@ var CloudClient = class {
|
|
|
11388
11455
|
* challenge somewhere this client cannot reach the key.
|
|
11389
11456
|
*/
|
|
11390
11457
|
async getRoutingChallenge(namespaceId) {
|
|
11391
|
-
const body = await this.request("GET", `/api/cloud/namespaces/${
|
|
11458
|
+
const body = await this.request("GET", `/api/cloud/namespaces/${pathSegment(namespaceId)}/challenge`, {
|
|
11392
11459
|
anonymous: true
|
|
11393
11460
|
});
|
|
11394
11461
|
return {
|
|
@@ -11419,7 +11486,7 @@ var CloudClient = class {
|
|
|
11419
11486
|
* the account from the certificate and refuses a mismatch.
|
|
11420
11487
|
*/
|
|
11421
11488
|
async getAccountRelaysChallenge(accountId) {
|
|
11422
|
-
const body = await this.request("GET", `/api/cloud/accounts/${
|
|
11489
|
+
const body = await this.request("GET", `/api/cloud/accounts/${pathSegment(accountId)}/challenge`, {
|
|
11423
11490
|
anonymous: true
|
|
11424
11491
|
});
|
|
11425
11492
|
return {
|
|
@@ -11455,7 +11522,7 @@ var CloudClient = class {
|
|
|
11455
11522
|
);
|
|
11456
11523
|
}
|
|
11457
11524
|
const challenge = await this.getAccountRelaysChallenge(accountId);
|
|
11458
|
-
const body = await this.request("GET", `/api/cloud/accounts/${
|
|
11525
|
+
const body = await this.request("GET", `/api/cloud/accounts/${pathSegment(accountId)}/relays`, {
|
|
11459
11526
|
anonymous: true,
|
|
11460
11527
|
headers: await routingProofHeaders(challenge, this.routingCredential)
|
|
11461
11528
|
});
|
|
@@ -11579,7 +11646,7 @@ var CloudClient = class {
|
|
|
11579
11646
|
const body = options.admitterAddrs === void 0 ? {} : { admitter_addrs: [...options.admitterAddrs] };
|
|
11580
11647
|
return this.request(
|
|
11581
11648
|
"POST",
|
|
11582
|
-
`/api/cloud/namespaces/${
|
|
11649
|
+
`/api/cloud/namespaces/${pathSegment(namespaceId)}/enable-ha`,
|
|
11583
11650
|
{ body }
|
|
11584
11651
|
);
|
|
11585
11652
|
}
|
|
@@ -11592,7 +11659,7 @@ var CloudClient = class {
|
|
|
11592
11659
|
async enableFoundedNamespaceHa(namespaceId, ownershipProof) {
|
|
11593
11660
|
return this.request(
|
|
11594
11661
|
"POST",
|
|
11595
|
-
`/api/cloud/me/namespaces/${
|
|
11662
|
+
`/api/cloud/me/namespaces/${pathSegment(namespaceId)}/enable-ha`,
|
|
11596
11663
|
{ body: { groups: [], ownership_proof: ownershipProof } }
|
|
11597
11664
|
);
|
|
11598
11665
|
}
|
|
@@ -11629,7 +11696,7 @@ var CloudClient = class {
|
|
|
11629
11696
|
try {
|
|
11630
11697
|
return await this.request(
|
|
11631
11698
|
"POST",
|
|
11632
|
-
`/api/cloud/accounts/${
|
|
11699
|
+
`/api/cloud/accounts/${pathSegment(account)}/namespaces/${pathSegment(namespace)}/enable-ha`,
|
|
11633
11700
|
{ body: { ownership_proof: proof }, anonymous: true }
|
|
11634
11701
|
);
|
|
11635
11702
|
} catch (err) {
|
|
@@ -11654,7 +11721,7 @@ var CloudClient = class {
|
|
|
11654
11721
|
async disableNamespaceHa(namespaceId) {
|
|
11655
11722
|
return this.request(
|
|
11656
11723
|
"POST",
|
|
11657
|
-
`/api/cloud/namespaces/${
|
|
11724
|
+
`/api/cloud/namespaces/${pathSegment(namespaceId)}/disable-ha`,
|
|
11658
11725
|
{ body: {} }
|
|
11659
11726
|
);
|
|
11660
11727
|
}
|
|
@@ -11794,7 +11861,7 @@ var CloudClient = class {
|
|
|
11794
11861
|
const portal = options.portalUrl.replace(/\/+$/, "");
|
|
11795
11862
|
const query = new URLSearchParams({
|
|
11796
11863
|
"link-account": options.accountId,
|
|
11797
|
-
"callback-url": options.callbackUrl
|
|
11864
|
+
"callback-url": beginLinkState(options.accountId, options.callbackUrl)
|
|
11798
11865
|
});
|
|
11799
11866
|
return { url: `${portal}/?${query.toString()}`, accountId: options.accountId };
|
|
11800
11867
|
}
|
|
@@ -11804,14 +11871,19 @@ var CloudClient = class {
|
|
|
11804
11871
|
* Returns `{}` when there is nothing to read, so it is safe to call on every
|
|
11805
11872
|
* load — which is how a redirected app finds out it has been sent back.
|
|
11806
11873
|
*
|
|
11874
|
+
* A grant is only returned when it answers a handoff this browser began, for the
|
|
11875
|
+
* account that handoff named; anything else comes back as
|
|
11876
|
+
* `error: 'unexpected_callback'`, because the redirect URL can be forwarded.
|
|
11877
|
+
*
|
|
11807
11878
|
* @param href defaults to the current location, when there is one.
|
|
11808
11879
|
*/
|
|
11809
11880
|
static readAccountLinkCallback(href) {
|
|
11810
11881
|
const source = href ?? (typeof window === "undefined" ? "" : window.location.href);
|
|
11811
11882
|
if (!source) return {};
|
|
11812
11883
|
let hash;
|
|
11884
|
+
let search;
|
|
11813
11885
|
try {
|
|
11814
|
-
hash = new URL(source)
|
|
11886
|
+
({ hash, search } = new URL(source));
|
|
11815
11887
|
} catch {
|
|
11816
11888
|
return {};
|
|
11817
11889
|
}
|
|
@@ -11820,6 +11892,10 @@ var CloudClient = class {
|
|
|
11820
11892
|
const accountId = params.get("account");
|
|
11821
11893
|
const error = params.get("error");
|
|
11822
11894
|
const out = {};
|
|
11895
|
+
if (error) takeLinkState(search);
|
|
11896
|
+
if (grant && takeLinkState(search)?.account !== accountId) {
|
|
11897
|
+
return { error: "unexpected_callback" };
|
|
11898
|
+
}
|
|
11823
11899
|
if (grant) out.grant = grant;
|
|
11824
11900
|
if (accountId) out.accountId = accountId;
|
|
11825
11901
|
if (error) out.error = error;
|