@tinycloud/node-sdk 3.0.1-beta.0 → 3.1.0-beta.10
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/{core-DufYfxi-.d.cts → core-CC7uDKZP.d.cts} +84 -7
- package/dist/{core-DufYfxi-.d.ts → core-CC7uDKZP.d.ts} +84 -7
- package/dist/core.cjs +344 -120
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +351 -121
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +402 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +409 -154
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -4404,19 +4404,19 @@ var init_lib4 = __esm({
|
|
|
4404
4404
|
resolve(value);
|
|
4405
4405
|
});
|
|
4406
4406
|
}
|
|
4407
|
-
return new (P || (P = Promise))(function(resolve,
|
|
4407
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
4408
4408
|
function fulfilled(value) {
|
|
4409
4409
|
try {
|
|
4410
4410
|
step(generator.next(value));
|
|
4411
4411
|
} catch (e) {
|
|
4412
|
-
|
|
4412
|
+
reject2(e);
|
|
4413
4413
|
}
|
|
4414
4414
|
}
|
|
4415
4415
|
function rejected(value) {
|
|
4416
4416
|
try {
|
|
4417
4417
|
step(generator["throw"](value));
|
|
4418
4418
|
} catch (e) {
|
|
4419
|
-
|
|
4419
|
+
reject2(e);
|
|
4420
4420
|
}
|
|
4421
4421
|
}
|
|
4422
4422
|
function step(result) {
|
|
@@ -8040,19 +8040,19 @@ var init_typed_data = __esm({
|
|
|
8040
8040
|
resolve(value);
|
|
8041
8041
|
});
|
|
8042
8042
|
}
|
|
8043
|
-
return new (P || (P = Promise))(function(resolve,
|
|
8043
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
8044
8044
|
function fulfilled(value) {
|
|
8045
8045
|
try {
|
|
8046
8046
|
step(generator.next(value));
|
|
8047
8047
|
} catch (e) {
|
|
8048
|
-
|
|
8048
|
+
reject2(e);
|
|
8049
8049
|
}
|
|
8050
8050
|
}
|
|
8051
8051
|
function rejected(value) {
|
|
8052
8052
|
try {
|
|
8053
8053
|
step(generator["throw"](value));
|
|
8054
8054
|
} catch (e) {
|
|
8055
|
-
|
|
8055
|
+
reject2(e);
|
|
8056
8056
|
}
|
|
8057
8057
|
}
|
|
8058
8058
|
function step(result) {
|
|
@@ -14898,14 +14898,14 @@ var require_scrypt = __commonJS({
|
|
|
14898
14898
|
}
|
|
14899
14899
|
const lib = {
|
|
14900
14900
|
scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
|
|
14901
|
-
return new Promise(function(resolve,
|
|
14901
|
+
return new Promise(function(resolve, reject2) {
|
|
14902
14902
|
let lastProgress = 0;
|
|
14903
14903
|
if (progressCallback) {
|
|
14904
14904
|
progressCallback(0);
|
|
14905
14905
|
}
|
|
14906
14906
|
_scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
|
|
14907
14907
|
if (error) {
|
|
14908
|
-
|
|
14908
|
+
reject2(error);
|
|
14909
14909
|
} else if (key2) {
|
|
14910
14910
|
if (progressCallback && lastProgress !== 1) {
|
|
14911
14911
|
progressCallback(1);
|
|
@@ -15294,19 +15294,19 @@ var init_keystore = __esm({
|
|
|
15294
15294
|
resolve(value);
|
|
15295
15295
|
});
|
|
15296
15296
|
}
|
|
15297
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15297
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15298
15298
|
function fulfilled(value) {
|
|
15299
15299
|
try {
|
|
15300
15300
|
step(generator.next(value));
|
|
15301
15301
|
} catch (e) {
|
|
15302
|
-
|
|
15302
|
+
reject2(e);
|
|
15303
15303
|
}
|
|
15304
15304
|
}
|
|
15305
15305
|
function rejected(value) {
|
|
15306
15306
|
try {
|
|
15307
15307
|
step(generator["throw"](value));
|
|
15308
15308
|
} catch (e) {
|
|
15309
|
-
|
|
15309
|
+
reject2(e);
|
|
15310
15310
|
}
|
|
15311
15311
|
}
|
|
15312
15312
|
function step(result) {
|
|
@@ -15607,19 +15607,19 @@ var init_lib25 = __esm({
|
|
|
15607
15607
|
resolve(value);
|
|
15608
15608
|
});
|
|
15609
15609
|
}
|
|
15610
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15610
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15611
15611
|
function fulfilled(value) {
|
|
15612
15612
|
try {
|
|
15613
15613
|
step(generator.next(value));
|
|
15614
15614
|
} catch (e) {
|
|
15615
|
-
|
|
15615
|
+
reject2(e);
|
|
15616
15616
|
}
|
|
15617
15617
|
}
|
|
15618
15618
|
function rejected(value) {
|
|
15619
15619
|
try {
|
|
15620
15620
|
step(generator["throw"](value));
|
|
15621
15621
|
} catch (e) {
|
|
15622
|
-
|
|
15622
|
+
reject2(e);
|
|
15623
15623
|
}
|
|
15624
15624
|
}
|
|
15625
15625
|
function step(result) {
|
|
@@ -15689,19 +15689,19 @@ var init_lib26 = __esm({
|
|
|
15689
15689
|
resolve(value);
|
|
15690
15690
|
});
|
|
15691
15691
|
}
|
|
15692
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15692
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15693
15693
|
function fulfilled(value) {
|
|
15694
15694
|
try {
|
|
15695
15695
|
step(generator.next(value));
|
|
15696
15696
|
} catch (e) {
|
|
15697
|
-
|
|
15697
|
+
reject2(e);
|
|
15698
15698
|
}
|
|
15699
15699
|
}
|
|
15700
15700
|
function rejected(value) {
|
|
15701
15701
|
try {
|
|
15702
15702
|
step(generator["throw"](value));
|
|
15703
15703
|
} catch (e) {
|
|
15704
|
-
|
|
15704
|
+
reject2(e);
|
|
15705
15705
|
}
|
|
15706
15706
|
}
|
|
15707
15707
|
function step(result) {
|
|
@@ -16011,19 +16011,19 @@ var init_lib27 = __esm({
|
|
|
16011
16011
|
resolve(value);
|
|
16012
16012
|
});
|
|
16013
16013
|
}
|
|
16014
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16014
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16015
16015
|
function fulfilled(value) {
|
|
16016
16016
|
try {
|
|
16017
16017
|
step(generator.next(value));
|
|
16018
16018
|
} catch (e) {
|
|
16019
|
-
|
|
16019
|
+
reject2(e);
|
|
16020
16020
|
}
|
|
16021
16021
|
}
|
|
16022
16022
|
function rejected(value) {
|
|
16023
16023
|
try {
|
|
16024
16024
|
step(generator["throw"](value));
|
|
16025
16025
|
} catch (e) {
|
|
16026
|
-
|
|
16026
|
+
reject2(e);
|
|
16027
16027
|
}
|
|
16028
16028
|
}
|
|
16029
16029
|
function step(result) {
|
|
@@ -16249,19 +16249,19 @@ var init_geturl = __esm({
|
|
|
16249
16249
|
resolve(value);
|
|
16250
16250
|
});
|
|
16251
16251
|
}
|
|
16252
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16252
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16253
16253
|
function fulfilled(value) {
|
|
16254
16254
|
try {
|
|
16255
16255
|
step(generator.next(value));
|
|
16256
16256
|
} catch (e) {
|
|
16257
|
-
|
|
16257
|
+
reject2(e);
|
|
16258
16258
|
}
|
|
16259
16259
|
}
|
|
16260
16260
|
function rejected(value) {
|
|
16261
16261
|
try {
|
|
16262
16262
|
step(generator["throw"](value));
|
|
16263
16263
|
} catch (e) {
|
|
16264
|
-
|
|
16264
|
+
reject2(e);
|
|
16265
16265
|
}
|
|
16266
16266
|
}
|
|
16267
16267
|
function step(result) {
|
|
@@ -16402,14 +16402,14 @@ function _fetchData(connection, body, processFunc) {
|
|
|
16402
16402
|
options.headers = flatHeaders;
|
|
16403
16403
|
const runningTimeout = (function() {
|
|
16404
16404
|
let timer = null;
|
|
16405
|
-
const promise = new Promise(function(resolve,
|
|
16405
|
+
const promise = new Promise(function(resolve, reject2) {
|
|
16406
16406
|
if (timeout) {
|
|
16407
16407
|
timer = setTimeout(() => {
|
|
16408
16408
|
if (timer == null) {
|
|
16409
16409
|
return;
|
|
16410
16410
|
}
|
|
16411
16411
|
timer = null;
|
|
16412
|
-
|
|
16412
|
+
reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
|
|
16413
16413
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
|
16414
16414
|
requestMethod: options.method,
|
|
16415
16415
|
timeout,
|
|
@@ -16572,7 +16572,7 @@ function poll(func, options) {
|
|
|
16572
16572
|
if (options.interval == null) {
|
|
16573
16573
|
options.interval = 250;
|
|
16574
16574
|
}
|
|
16575
|
-
return new Promise(function(resolve,
|
|
16575
|
+
return new Promise(function(resolve, reject2) {
|
|
16576
16576
|
let timer = null;
|
|
16577
16577
|
let done = false;
|
|
16578
16578
|
const cancel = () => {
|
|
@@ -16588,7 +16588,7 @@ function poll(func, options) {
|
|
|
16588
16588
|
if (options.timeout) {
|
|
16589
16589
|
timer = setTimeout(() => {
|
|
16590
16590
|
if (cancel()) {
|
|
16591
|
-
|
|
16591
|
+
reject2(new Error("timeout"));
|
|
16592
16592
|
}
|
|
16593
16593
|
}, options.timeout);
|
|
16594
16594
|
}
|
|
@@ -16608,7 +16608,7 @@ function poll(func, options) {
|
|
|
16608
16608
|
attempt++;
|
|
16609
16609
|
if (attempt > retryLimit) {
|
|
16610
16610
|
if (cancel()) {
|
|
16611
|
-
|
|
16611
|
+
reject2(new Error("retry limit reached"));
|
|
16612
16612
|
}
|
|
16613
16613
|
return;
|
|
16614
16614
|
}
|
|
@@ -16624,7 +16624,7 @@ function poll(func, options) {
|
|
|
16624
16624
|
return null;
|
|
16625
16625
|
}, function(error) {
|
|
16626
16626
|
if (cancel()) {
|
|
16627
|
-
|
|
16627
|
+
reject2(error);
|
|
16628
16628
|
}
|
|
16629
16629
|
});
|
|
16630
16630
|
}
|
|
@@ -16648,19 +16648,19 @@ var init_lib28 = __esm({
|
|
|
16648
16648
|
resolve(value);
|
|
16649
16649
|
});
|
|
16650
16650
|
}
|
|
16651
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16651
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16652
16652
|
function fulfilled(value) {
|
|
16653
16653
|
try {
|
|
16654
16654
|
step(generator.next(value));
|
|
16655
16655
|
} catch (e) {
|
|
16656
|
-
|
|
16656
|
+
reject2(e);
|
|
16657
16657
|
}
|
|
16658
16658
|
}
|
|
16659
16659
|
function rejected(value) {
|
|
16660
16660
|
try {
|
|
16661
16661
|
step(generator["throw"](value));
|
|
16662
16662
|
} catch (e) {
|
|
16663
|
-
|
|
16663
|
+
reject2(e);
|
|
16664
16664
|
}
|
|
16665
16665
|
}
|
|
16666
16666
|
function step(result) {
|
|
@@ -17072,9 +17072,13 @@ __export(index_exports, {
|
|
|
17072
17072
|
PrefixedKVService: () => import_sdk_core13.PrefixedKVService,
|
|
17073
17073
|
PrivateKeySigner: () => PrivateKeySigner,
|
|
17074
17074
|
ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
|
|
17075
|
+
RUNTIME_DELEGATION_REJECTIONS: () => RUNTIME_DELEGATION_REJECTIONS,
|
|
17076
|
+
RuntimeDelegationRejectedError: () => RuntimeDelegationRejectedError,
|
|
17075
17077
|
SECRET_NAME_RE: () => import_sdk_core16.SECRET_NAME_RE,
|
|
17076
17078
|
SQLAction: () => import_sdk_core14.SQLAction,
|
|
17077
17079
|
SQLService: () => import_sdk_core14.SQLService,
|
|
17080
|
+
STORAGE_FULL_MESSAGE: () => import_sdk_core11.STORAGE_FULL_MESSAGE,
|
|
17081
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE: () => import_sdk_core11.STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
17078
17082
|
SecretsService: () => import_sdk_core16.SecretsService,
|
|
17079
17083
|
ServiceContext: () => import_sdk_core23.ServiceContext,
|
|
17080
17084
|
SessionExpiredError: () => import_sdk_core12.SessionExpiredError,
|
|
@@ -17150,6 +17154,7 @@ __export(index_exports, {
|
|
|
17150
17154
|
isCapabilitySubset: () => import_sdk_core12.isCapabilitySubset,
|
|
17151
17155
|
isEvmAddress: () => import_sdk_core11.isEvmAddress,
|
|
17152
17156
|
isNetworkId: () => import_sdk_core17.isNetworkId,
|
|
17157
|
+
isStorageFullError: () => import_sdk_core11.isStorageFullError,
|
|
17153
17158
|
loadManifest: () => import_sdk_core12.loadManifest,
|
|
17154
17159
|
makePkhSpaceId: () => import_sdk_core11.makePkhSpaceId,
|
|
17155
17160
|
makePublicSpaceId: () => import_sdk_core21.makePublicSpaceId,
|
|
@@ -17210,6 +17215,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17210
17215
|
validatePersistedSession(proof) {
|
|
17211
17216
|
return (0, import_node_sdk_wasm.validatePersistedSession)(proof);
|
|
17212
17217
|
}
|
|
17218
|
+
validateSessionGrant(proof) {
|
|
17219
|
+
return (0, import_node_sdk_wasm.validateSessionGrant)(proof);
|
|
17220
|
+
}
|
|
17213
17221
|
createSessionManager() {
|
|
17214
17222
|
return new import_node_sdk_wasm.TCWSessionManager();
|
|
17215
17223
|
}
|
|
@@ -17368,6 +17376,10 @@ var MemorySessionStorage = class {
|
|
|
17368
17376
|
// src/authorization/NodeUserAuthorization.ts
|
|
17369
17377
|
var DECRYPT_ACTION = import_sdk_core2.ENCRYPTION.DECRYPT;
|
|
17370
17378
|
var NETWORK_CREATE_ACTION = import_sdk_core2.ENCRYPTION.NETWORK_CREATE;
|
|
17379
|
+
function describeHostFailure(result) {
|
|
17380
|
+
const text = result.error?.trim();
|
|
17381
|
+
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
17382
|
+
}
|
|
17371
17383
|
function canonicalizeOpenKeyManifestJson(value) {
|
|
17372
17384
|
const json = JSON.stringify(value);
|
|
17373
17385
|
if (json === void 0) {
|
|
@@ -17832,21 +17844,28 @@ var NodeUserAuthorization = class {
|
|
|
17832
17844
|
});
|
|
17833
17845
|
const signature2 = await this.signMessage(siwe, purpose);
|
|
17834
17846
|
const headers = this.wasm.siweToDelegationHeaders({ siwe, signature: signature2 });
|
|
17835
|
-
|
|
17836
|
-
return result.success;
|
|
17847
|
+
return (0, import_sdk_core2.submitHostDelegation)(host, headers);
|
|
17837
17848
|
}
|
|
17838
17849
|
/**
|
|
17839
17850
|
* Create a specific space on the server via host delegation.
|
|
17840
17851
|
* Used for lazy creation of additional spaces (e.g., public).
|
|
17841
17852
|
*/
|
|
17842
17853
|
async hostPublicSpace(spaceId) {
|
|
17843
|
-
return this.hostSpace(spaceId);
|
|
17854
|
+
return (await this.hostSpace(spaceId)).success;
|
|
17844
17855
|
}
|
|
17845
17856
|
/**
|
|
17846
17857
|
* Create a specific owned space on the server via host delegation.
|
|
17847
17858
|
* Used by manifest registry setup for the account space.
|
|
17848
17859
|
*/
|
|
17849
17860
|
async hostOwnedSpace(spaceId, purpose) {
|
|
17861
|
+
return (await this.hostOwnedSpaceResult(spaceId, purpose)).success;
|
|
17862
|
+
}
|
|
17863
|
+
/**
|
|
17864
|
+
* {@link hostOwnedSpace} with the full host-delegation result, so a failure
|
|
17865
|
+
* keeps its HTTP status (e.g. a typed 401/403) instead of collapsing to
|
|
17866
|
+
* `false`.
|
|
17867
|
+
*/
|
|
17868
|
+
async hostOwnedSpaceResult(spaceId, purpose) {
|
|
17850
17869
|
return this.hostSpace(spaceId, purpose);
|
|
17851
17870
|
}
|
|
17852
17871
|
/**
|
|
@@ -17890,9 +17909,11 @@ var NodeUserAuthorization = class {
|
|
|
17890
17909
|
}
|
|
17891
17910
|
try {
|
|
17892
17911
|
const created = await this.hostSpace();
|
|
17893
|
-
if (!created) {
|
|
17894
|
-
const err =
|
|
17895
|
-
|
|
17912
|
+
if (!created.success) {
|
|
17913
|
+
const err = Object.assign(
|
|
17914
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17915
|
+
{ cause: created }
|
|
17916
|
+
);
|
|
17896
17917
|
throw err;
|
|
17897
17918
|
}
|
|
17898
17919
|
} catch (error) {
|
|
@@ -17908,8 +17929,9 @@ var NodeUserAuthorization = class {
|
|
|
17908
17929
|
this._tinyCloudSession.delegationHeader
|
|
17909
17930
|
);
|
|
17910
17931
|
if (!retryResult.success) {
|
|
17911
|
-
const err =
|
|
17912
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17932
|
+
const err = Object.assign(
|
|
17933
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17934
|
+
{ cause: retryResult }
|
|
17913
17935
|
);
|
|
17914
17936
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17915
17937
|
throw err;
|
|
@@ -17927,9 +17949,11 @@ var NodeUserAuthorization = class {
|
|
|
17927
17949
|
}
|
|
17928
17950
|
try {
|
|
17929
17951
|
const created = await this.hostSpace();
|
|
17930
|
-
if (!created) {
|
|
17931
|
-
const err =
|
|
17932
|
-
|
|
17952
|
+
if (!created.success) {
|
|
17953
|
+
const err = Object.assign(
|
|
17954
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17955
|
+
{ cause: created }
|
|
17956
|
+
);
|
|
17933
17957
|
throw err;
|
|
17934
17958
|
}
|
|
17935
17959
|
} catch (error) {
|
|
@@ -17945,8 +17969,9 @@ var NodeUserAuthorization = class {
|
|
|
17945
17969
|
this._tinyCloudSession.delegationHeader
|
|
17946
17970
|
);
|
|
17947
17971
|
if (!retryResult.success) {
|
|
17948
|
-
const err =
|
|
17949
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17972
|
+
const err = Object.assign(
|
|
17973
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17974
|
+
{ cause: retryResult }
|
|
17950
17975
|
);
|
|
17951
17976
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17952
17977
|
throw err;
|
|
@@ -17954,7 +17979,10 @@ var NodeUserAuthorization = class {
|
|
|
17954
17979
|
handler.onSpaceCreated?.(creationContext);
|
|
17955
17980
|
return;
|
|
17956
17981
|
}
|
|
17957
|
-
throw
|
|
17982
|
+
throw Object.assign(
|
|
17983
|
+
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
17984
|
+
{ cause: result }
|
|
17985
|
+
);
|
|
17958
17986
|
}
|
|
17959
17987
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
17960
17988
|
if (result.success) {
|
|
@@ -18744,14 +18772,14 @@ var NodeUserAuthorization = class {
|
|
|
18744
18772
|
* Request signature via event emitter with timeout.
|
|
18745
18773
|
*/
|
|
18746
18774
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18747
|
-
return new Promise((resolve,
|
|
18775
|
+
return new Promise((resolve, reject2) => {
|
|
18748
18776
|
const timeoutId = setTimeout(() => {
|
|
18749
|
-
|
|
18777
|
+
reject2(new Error("Sign request timed out"));
|
|
18750
18778
|
}, timeout);
|
|
18751
18779
|
const respond = async (response) => {
|
|
18752
18780
|
clearTimeout(timeoutId);
|
|
18753
18781
|
if (!response.approved) {
|
|
18754
|
-
|
|
18782
|
+
reject2(
|
|
18755
18783
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18756
18784
|
);
|
|
18757
18785
|
} else {
|
|
@@ -19330,6 +19358,25 @@ function jsonFromVerifier(value) {
|
|
|
19330
19358
|
function verifierRecapEntries(entries) {
|
|
19331
19359
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19332
19360
|
}
|
|
19361
|
+
function exactVerifiedRecap(verified) {
|
|
19362
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19363
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19364
|
+
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
19365
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19366
|
+
)
|
|
19367
|
+
)) {
|
|
19368
|
+
throw new UnsupportedSessionRestoreError(
|
|
19369
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19370
|
+
);
|
|
19371
|
+
}
|
|
19372
|
+
return exactRecap.map((entry) => ({
|
|
19373
|
+
service: entry.service,
|
|
19374
|
+
space: entry.space,
|
|
19375
|
+
path: entry.path,
|
|
19376
|
+
actions: [...entry.actions],
|
|
19377
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19378
|
+
}));
|
|
19379
|
+
}
|
|
19333
19380
|
var ServiceGraphLifetime = class {
|
|
19334
19381
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19335
19382
|
this.invokeFn = invokeFn;
|
|
@@ -19425,6 +19472,10 @@ function persistedExpiry(value) {
|
|
|
19425
19472
|
function sameInstant(left, right) {
|
|
19426
19473
|
return left.getTime() === right.getTime();
|
|
19427
19474
|
}
|
|
19475
|
+
function describeHostFailure2(result) {
|
|
19476
|
+
const text = result.error?.trim();
|
|
19477
|
+
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
19478
|
+
}
|
|
19428
19479
|
function ownerDelegationPermissions(params) {
|
|
19429
19480
|
const hasPermissions = Object.prototype.hasOwnProperty.call(params, "permissions");
|
|
19430
19481
|
const hasLegacy = Object.prototype.hasOwnProperty.call(params, "path") || Object.prototype.hasOwnProperty.call(params, "actions");
|
|
@@ -20228,7 +20279,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20228
20279
|
marker
|
|
20229
20280
|
);
|
|
20230
20281
|
if (!written.ok) {
|
|
20231
|
-
throw
|
|
20282
|
+
throw Object.assign(
|
|
20283
|
+
new Error(`Failed to write bootstrap completion marker: ${written.error.message}`),
|
|
20284
|
+
{ cause: written.error }
|
|
20285
|
+
);
|
|
20232
20286
|
}
|
|
20233
20287
|
}
|
|
20234
20288
|
isAcceptedBootstrapCompletionMarker(value) {
|
|
@@ -20274,17 +20328,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20274
20328
|
rawAbilities
|
|
20275
20329
|
});
|
|
20276
20330
|
} catch (err) {
|
|
20277
|
-
throw
|
|
20278
|
-
|
|
20331
|
+
throw Object.assign(
|
|
20332
|
+
new Error(
|
|
20333
|
+
`Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
|
|
20334
|
+
),
|
|
20335
|
+
{ cause: err }
|
|
20279
20336
|
);
|
|
20280
20337
|
}
|
|
20281
20338
|
sessions.set(step.space, session);
|
|
20282
20339
|
}
|
|
20283
20340
|
for (const step of steps) {
|
|
20284
20341
|
if (step.kind !== "host") continue;
|
|
20285
|
-
const hosted = await auth.
|
|
20286
|
-
if (!hosted) {
|
|
20287
|
-
throw
|
|
20342
|
+
const hosted = await auth.hostOwnedSpaceResult(step.spaceId, "bootstrap-host");
|
|
20343
|
+
if (!hosted.success) {
|
|
20344
|
+
throw Object.assign(
|
|
20345
|
+
new Error(`Failed to host bootstrap space ${step.spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20346
|
+
{ cause: hosted }
|
|
20347
|
+
);
|
|
20288
20348
|
}
|
|
20289
20349
|
}
|
|
20290
20350
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -20296,8 +20356,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20296
20356
|
}
|
|
20297
20357
|
const activated = await (0, import_sdk_core7.activateSessionWithHost)(host, session.delegationHeader);
|
|
20298
20358
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
20299
|
-
throw
|
|
20300
|
-
|
|
20359
|
+
throw Object.assign(
|
|
20360
|
+
new Error(
|
|
20361
|
+
`Failed to activate bootstrap session for ${step.spaceId}: ${activated.success ? "space was skipped" : describeHostFailure2(activated)}`
|
|
20362
|
+
),
|
|
20363
|
+
{ cause: activated }
|
|
20301
20364
|
);
|
|
20302
20365
|
}
|
|
20303
20366
|
this.registerBootstrapRuntimeGrant(
|
|
@@ -20310,7 +20373,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20310
20373
|
if (step.kind === "account-index-schema") {
|
|
20311
20374
|
const ensured = await this.account.index.ensure();
|
|
20312
20375
|
if (!ensured.ok) {
|
|
20313
|
-
throw new Error(`Failed to create account index schema: ${ensured.error.message}`);
|
|
20376
|
+
throw Object.assign(new Error(`Failed to create account index schema: ${ensured.error.message}`), { cause: ensured.error });
|
|
20314
20377
|
}
|
|
20315
20378
|
}
|
|
20316
20379
|
if (step.kind === "seed-spaces") {
|
|
@@ -20325,8 +20388,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20325
20388
|
}))
|
|
20326
20389
|
);
|
|
20327
20390
|
if (!registered.ok) {
|
|
20328
|
-
throw
|
|
20329
|
-
`Failed to seed account spaces: ${registered.error.message}`
|
|
20391
|
+
throw Object.assign(
|
|
20392
|
+
new Error(`Failed to seed account spaces: ${registered.error.message}`),
|
|
20393
|
+
{ cause: registered.error }
|
|
20330
20394
|
);
|
|
20331
20395
|
}
|
|
20332
20396
|
const batchError = registered.data.recoveredFromBatchError;
|
|
@@ -20347,7 +20411,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20347
20411
|
{ assumeUnregistered: true }
|
|
20348
20412
|
);
|
|
20349
20413
|
if (!registered.ok) {
|
|
20350
|
-
throw new Error(`Failed to seed bootstrap applications: ${registered.error.message}`);
|
|
20414
|
+
throw Object.assign(new Error(`Failed to seed bootstrap applications: ${registered.error.message}`), { cause: registered.error });
|
|
20351
20415
|
}
|
|
20352
20416
|
}
|
|
20353
20417
|
if (step.kind === "encryption-network-create") {
|
|
@@ -20365,8 +20429,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20365
20429
|
]
|
|
20366
20430
|
});
|
|
20367
20431
|
if (!migrated.ok) {
|
|
20368
|
-
throw
|
|
20369
|
-
`Failed to create secret_records schema: ${migrated.error.message}`
|
|
20432
|
+
throw Object.assign(
|
|
20433
|
+
new Error(`Failed to create secret_records schema: ${migrated.error.message}`),
|
|
20434
|
+
{ cause: migrated.error }
|
|
20370
20435
|
);
|
|
20371
20436
|
}
|
|
20372
20437
|
}
|
|
@@ -20538,8 +20603,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20538
20603
|
await this.ensureOwnedSpaceHostedById(accountSpaceId);
|
|
20539
20604
|
const result = await this.account.applications.register(request.manifests);
|
|
20540
20605
|
if (!result.ok) {
|
|
20541
|
-
throw
|
|
20542
|
-
`Failed to write manifest registry records: ${result.error.message}`
|
|
20606
|
+
throw Object.assign(
|
|
20607
|
+
new Error(`Failed to write manifest registry records: ${result.error.message}`),
|
|
20608
|
+
{ cause: result.error }
|
|
20543
20609
|
);
|
|
20544
20610
|
}
|
|
20545
20611
|
}
|
|
@@ -20564,7 +20630,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20564
20630
|
if (this.currentSessionCanListSpaces()) {
|
|
20565
20631
|
const spaces = await this.account.spaces.syncAccessible();
|
|
20566
20632
|
if (!spaces.ok) {
|
|
20567
|
-
throw
|
|
20633
|
+
throw Object.assign(
|
|
20634
|
+
new Error(`Failed to sync account spaces: ${spaces.error.message}`),
|
|
20635
|
+
{ cause: spaces.error }
|
|
20636
|
+
);
|
|
20568
20637
|
}
|
|
20569
20638
|
}
|
|
20570
20639
|
});
|
|
@@ -20619,14 +20688,20 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20619
20688
|
await task();
|
|
20620
20689
|
return;
|
|
20621
20690
|
} catch (error) {
|
|
20691
|
+
const verdict = (0, import_sdk_core7.authorizationVerdictOf)(error);
|
|
20622
20692
|
const message = error instanceof Error ? error.message : String(error);
|
|
20623
|
-
|
|
20693
|
+
const isAuthorizationVerdict = verdict === void 0 ? /Unauthorized Action|\b(?:401|403)\b/.test(message) : verdict !== "other";
|
|
20694
|
+
if (isAuthorizationVerdict) {
|
|
20624
20695
|
console.warn(
|
|
20625
20696
|
"TinyCloud account registry sync stopped: authorization verdict is not retryable",
|
|
20626
20697
|
error
|
|
20627
20698
|
);
|
|
20628
20699
|
return;
|
|
20629
20700
|
}
|
|
20701
|
+
if ((0, import_sdk_core7.isStorageFullError)(error) || (0, import_sdk_core7.isStorageFullError)(error?.cause) || message.includes(import_sdk_core7.STORAGE_FULL_MESSAGE) || message.includes(import_sdk_core7.STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
|
|
20702
|
+
console.warn("TinyCloud account registry sync stopped: storage is full", error);
|
|
20703
|
+
return;
|
|
20704
|
+
}
|
|
20630
20705
|
lastError = error;
|
|
20631
20706
|
if (attempt < delays.length - 1) {
|
|
20632
20707
|
await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
|
|
@@ -20700,19 +20775,26 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20700
20775
|
return;
|
|
20701
20776
|
}
|
|
20702
20777
|
if (!activation.success && activation.status !== 404) {
|
|
20703
|
-
throw
|
|
20704
|
-
`Failed to check owned space ${spaceId}: ${activation
|
|
20778
|
+
throw Object.assign(
|
|
20779
|
+
new Error(`Failed to check owned space ${spaceId}: ${describeHostFailure2(activation)}`),
|
|
20780
|
+
{ cause: activation }
|
|
20705
20781
|
);
|
|
20706
20782
|
}
|
|
20707
|
-
const created = await this.auth.
|
|
20708
|
-
if (!created) {
|
|
20709
|
-
throw
|
|
20783
|
+
const created = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20784
|
+
if (!created.success) {
|
|
20785
|
+
throw Object.assign(
|
|
20786
|
+
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
20787
|
+
{ cause: created }
|
|
20788
|
+
);
|
|
20710
20789
|
}
|
|
20711
20790
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
20712
20791
|
const retry = await (0, import_sdk_core7.activateSessionWithHost)(host, session.delegationHeader);
|
|
20713
20792
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
20714
|
-
throw
|
|
20715
|
-
|
|
20793
|
+
throw Object.assign(
|
|
20794
|
+
new Error(
|
|
20795
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" : describeHostFailure2(retry)}`
|
|
20796
|
+
),
|
|
20797
|
+
{ cause: retry }
|
|
20716
20798
|
);
|
|
20717
20799
|
}
|
|
20718
20800
|
this.confirmedHostedSpaceIds.add(spaceId);
|
|
@@ -20747,19 +20829,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20747
20829
|
if (!host) {
|
|
20748
20830
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
20749
20831
|
}
|
|
20750
|
-
const hosted = await this.auth.
|
|
20751
|
-
|
|
20752
|
-
|
|
20753
|
-
|
|
20754
|
-
|
|
20832
|
+
const hosted = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20833
|
+
if (!hosted.success) {
|
|
20834
|
+
throw Object.assign(
|
|
20835
|
+
new Error(`Failed to host owned space ${spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20836
|
+
{ cause: hosted }
|
|
20837
|
+
);
|
|
20755
20838
|
}
|
|
20756
20839
|
const activation = await (0, import_sdk_core7.activateSessionWithHost)(
|
|
20757
20840
|
host,
|
|
20758
20841
|
session.delegationHeader
|
|
20759
20842
|
);
|
|
20760
20843
|
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
20761
|
-
throw
|
|
20762
|
-
|
|
20844
|
+
throw Object.assign(
|
|
20845
|
+
new Error(
|
|
20846
|
+
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
20847
|
+
),
|
|
20848
|
+
{ cause: activation }
|
|
20763
20849
|
);
|
|
20764
20850
|
}
|
|
20765
20851
|
try {
|
|
@@ -20955,23 +21041,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20955
21041
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
20956
21042
|
}
|
|
20957
21043
|
})();
|
|
20958
|
-
|
|
20959
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
20960
|
-
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
20961
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
20962
|
-
)
|
|
20963
|
-
)) {
|
|
20964
|
-
throw new UnsupportedSessionRestoreError(
|
|
20965
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
20966
|
-
);
|
|
20967
|
-
}
|
|
20968
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
20969
|
-
service: entry.service,
|
|
20970
|
-
space: entry.space,
|
|
20971
|
-
path: entry.path,
|
|
20972
|
-
actions: [...entry.actions],
|
|
20973
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
20974
|
-
}));
|
|
21044
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
20975
21045
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
20976
21046
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
20977
21047
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -21775,7 +21845,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21775
21845
|
if (cached) return cached;
|
|
21776
21846
|
const response = await fetch(`${this.config.host}/info`);
|
|
21777
21847
|
if (!response.ok) {
|
|
21778
|
-
throw
|
|
21848
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, "Failed to fetch node info");
|
|
21779
21849
|
}
|
|
21780
21850
|
const info = await response.json();
|
|
21781
21851
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -21825,9 +21895,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21825
21895
|
);
|
|
21826
21896
|
if (response.status === 404) return null;
|
|
21827
21897
|
if (!response.ok) {
|
|
21828
|
-
throw
|
|
21829
|
-
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
21830
|
-
);
|
|
21898
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, `Failed to fetch encryption network ${networkId}`);
|
|
21831
21899
|
}
|
|
21832
21900
|
const body = await response.json();
|
|
21833
21901
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -22260,7 +22328,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22260
22328
|
const activation = await (0, import_sdk_core7.activateSessionWithHost)(host, delegationSession.delegationHeader);
|
|
22261
22329
|
assertOwnerGraphActive();
|
|
22262
22330
|
if (!activation.success) {
|
|
22263
|
-
throw
|
|
22331
|
+
throw Object.assign(
|
|
22332
|
+
new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim()),
|
|
22333
|
+
{ cause: activation }
|
|
22334
|
+
);
|
|
22264
22335
|
}
|
|
22265
22336
|
const delegation = {
|
|
22266
22337
|
cid: delegationSession.delegationCid,
|
|
@@ -22325,7 +22396,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22325
22396
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
22326
22397
|
body: (0, import_sdk_core7.canonicalizeEncryptionJson)(request)
|
|
22327
22398
|
});
|
|
22328
|
-
if (!response.ok) throw
|
|
22399
|
+
if (!response.ok) throw await (0, import_sdk_core7.httpResponseError)(response, "V3 share delivery authorization failed");
|
|
22329
22400
|
const verified = (0, import_sdk_core7.validateShareDeliveryAuthorizationV3Bytes)(new Uint8Array(await response.arrayBuffer()), {
|
|
22330
22401
|
request,
|
|
22331
22402
|
senderKeyDid: this.credentialHolderDid,
|
|
@@ -22547,9 +22618,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22547
22618
|
);
|
|
22548
22619
|
}
|
|
22549
22620
|
if (!response.ok) {
|
|
22550
|
-
throw
|
|
22551
|
-
`Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
22552
|
-
);
|
|
22621
|
+
throw await (0, import_sdk_core7.httpResponseError)(response, `Failed to create encryption network ${networkId}`);
|
|
22553
22622
|
}
|
|
22554
22623
|
const created = await response.json();
|
|
22555
22624
|
return created.descriptor;
|
|
@@ -22833,6 +22902,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22833
22902
|
(left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0"))
|
|
22834
22903
|
);
|
|
22835
22904
|
}
|
|
22905
|
+
/**
|
|
22906
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22907
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22908
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22909
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22910
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22911
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22912
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22913
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22914
|
+
* which also refuses decrypt-only grants.
|
|
22915
|
+
*/
|
|
22916
|
+
verifySessionGrant(grant) {
|
|
22917
|
+
const bindings = this.wasmBindings;
|
|
22918
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22919
|
+
if (validate5 === void 0) {
|
|
22920
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22921
|
+
}
|
|
22922
|
+
const verified = validate5({
|
|
22923
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22924
|
+
delegationCid: grant.delegationCid,
|
|
22925
|
+
spaceId: grant.spaceId,
|
|
22926
|
+
jwk: this.sessionKeyJwk,
|
|
22927
|
+
address: (0, import_sdk_core7.canonicalizeAddress)(grant.address),
|
|
22928
|
+
chainId: grant.chainId,
|
|
22929
|
+
siwe: grant.siwe,
|
|
22930
|
+
signature: grant.signature
|
|
22931
|
+
});
|
|
22932
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22933
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22934
|
+
}
|
|
22935
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22936
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22937
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22938
|
+
}
|
|
22939
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22940
|
+
}
|
|
22836
22941
|
/**
|
|
22837
22942
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22838
22943
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -22857,8 +22962,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22857
22962
|
delegation.delegationHeader
|
|
22858
22963
|
);
|
|
22859
22964
|
if (!activateResult.success) {
|
|
22860
|
-
throw
|
|
22861
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
22965
|
+
throw Object.assign(
|
|
22966
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
22967
|
+
{ cause: activateResult }
|
|
22862
22968
|
);
|
|
22863
22969
|
}
|
|
22864
22970
|
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
@@ -22954,8 +23060,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22954
23060
|
delegatedSession.delegationHeader
|
|
22955
23061
|
);
|
|
22956
23062
|
if (!activateResult.success) {
|
|
22957
|
-
throw
|
|
22958
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
23063
|
+
throw Object.assign(
|
|
23064
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
23065
|
+
{ cause: activateResult }
|
|
22959
23066
|
);
|
|
22960
23067
|
}
|
|
22961
23068
|
const delegation = this.runtimeDelegationFromSession(
|
|
@@ -22963,7 +23070,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22963
23070
|
delegatedEntries,
|
|
22964
23071
|
spaceId,
|
|
22965
23072
|
session,
|
|
22966
|
-
expiresAt
|
|
23073
|
+
expiresAt,
|
|
23074
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
22967
23075
|
);
|
|
22968
23076
|
this.runtimePermissionGrants.push({
|
|
22969
23077
|
session: {
|
|
@@ -23140,7 +23248,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23140
23248
|
delegationSession.delegationHeader
|
|
23141
23249
|
);
|
|
23142
23250
|
if (!activateResult.success) {
|
|
23143
|
-
throw
|
|
23251
|
+
throw Object.assign(
|
|
23252
|
+
new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
|
|
23253
|
+
{ cause: activateResult }
|
|
23254
|
+
);
|
|
23144
23255
|
}
|
|
23145
23256
|
if (this._capabilityRegistry && this.session) {
|
|
23146
23257
|
const sessionKey = {
|
|
@@ -23493,8 +23604,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23493
23604
|
delegationHeader
|
|
23494
23605
|
);
|
|
23495
23606
|
if (!activateResult.success) {
|
|
23496
|
-
throw
|
|
23497
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23607
|
+
throw Object.assign(
|
|
23608
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23609
|
+
{ cause: activateResult }
|
|
23498
23610
|
);
|
|
23499
23611
|
}
|
|
23500
23612
|
return {
|
|
@@ -23530,8 +23642,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23530
23642
|
delegationHeader
|
|
23531
23643
|
);
|
|
23532
23644
|
if (!activateResult.success) {
|
|
23533
|
-
throw
|
|
23534
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23645
|
+
throw Object.assign(
|
|
23646
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23647
|
+
{ cause: activateResult }
|
|
23535
23648
|
);
|
|
23536
23649
|
}
|
|
23537
23650
|
return {
|
|
@@ -23744,7 +23857,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23744
23857
|
}
|
|
23745
23858
|
return grants;
|
|
23746
23859
|
}
|
|
23747
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23860
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23748
23861
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23749
23862
|
const primary = resources[0];
|
|
23750
23863
|
return {
|
|
@@ -23759,7 +23872,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23759
23872
|
delegateDID: session.verificationMethod,
|
|
23760
23873
|
ownerAddress: session.address,
|
|
23761
23874
|
chainId: session.chainId,
|
|
23762
|
-
host: this.config.host
|
|
23875
|
+
host: this.config.host,
|
|
23876
|
+
siweProof
|
|
23763
23877
|
};
|
|
23764
23878
|
}
|
|
23765
23879
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -23952,6 +24066,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23952
24066
|
if (grantedAction === requestedAction) {
|
|
23953
24067
|
return true;
|
|
23954
24068
|
}
|
|
24069
|
+
if ((0, import_sdk_core7.isExplicitOnlyAction)(requestedAction)) {
|
|
24070
|
+
return false;
|
|
24071
|
+
}
|
|
23955
24072
|
if (grantedAction.endsWith("/*")) {
|
|
23956
24073
|
const prefix = grantedAction.slice(0, -2);
|
|
23957
24074
|
return requestedAction.startsWith(`${prefix}/`);
|
|
@@ -24138,7 +24255,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24138
24255
|
delegationSession.delegationHeader
|
|
24139
24256
|
);
|
|
24140
24257
|
if (!activateResult.success) {
|
|
24141
|
-
throw
|
|
24258
|
+
throw Object.assign(
|
|
24259
|
+
new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
|
|
24260
|
+
{ cause: activateResult }
|
|
24261
|
+
);
|
|
24142
24262
|
}
|
|
24143
24263
|
const result = {
|
|
24144
24264
|
cid: delegationSession.delegationCid,
|
|
@@ -24288,7 +24408,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24288
24408
|
invokerSession.delegationHeader
|
|
24289
24409
|
);
|
|
24290
24410
|
if (!activateResult.success) {
|
|
24291
|
-
throw
|
|
24411
|
+
throw Object.assign(
|
|
24412
|
+
new Error(`Failed to activate delegated session: ${describeHostFailure2(activateResult)}`),
|
|
24413
|
+
{ cause: activateResult }
|
|
24414
|
+
);
|
|
24292
24415
|
}
|
|
24293
24416
|
const session = {
|
|
24294
24417
|
address: mySession.address,
|
|
@@ -24405,7 +24528,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24405
24528
|
subDelegationSession.delegationHeader
|
|
24406
24529
|
);
|
|
24407
24530
|
if (!activateResult.success) {
|
|
24408
|
-
throw
|
|
24531
|
+
throw Object.assign(
|
|
24532
|
+
new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
|
|
24533
|
+
{ cause: activateResult }
|
|
24534
|
+
);
|
|
24409
24535
|
}
|
|
24410
24536
|
return {
|
|
24411
24537
|
cid: subDelegationSession.delegationCid,
|
|
@@ -24620,6 +24746,29 @@ var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
|
24620
24746
|
|
|
24621
24747
|
// src/delegation.ts
|
|
24622
24748
|
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
24749
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24750
|
+
"host_mismatch",
|
|
24751
|
+
"expired",
|
|
24752
|
+
"cid_mismatch",
|
|
24753
|
+
"authority_invalid",
|
|
24754
|
+
"proof_missing",
|
|
24755
|
+
"proof_invalid",
|
|
24756
|
+
"owner_mismatch",
|
|
24757
|
+
"audience_mismatch",
|
|
24758
|
+
"resources_mismatch",
|
|
24759
|
+
"unsupported",
|
|
24760
|
+
"activation_rejected"
|
|
24761
|
+
];
|
|
24762
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24763
|
+
constructor(reason, message) {
|
|
24764
|
+
super(message);
|
|
24765
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24766
|
+
this.reason = reason;
|
|
24767
|
+
}
|
|
24768
|
+
};
|
|
24769
|
+
function reject(reason, message) {
|
|
24770
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24771
|
+
}
|
|
24623
24772
|
var SERVICE_BY_SHORT_NAME = {
|
|
24624
24773
|
kv: "tinycloud.kv",
|
|
24625
24774
|
sql: "tinycloud.sql",
|
|
@@ -24766,6 +24915,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24766
24915
|
abilities
|
|
24767
24916
|
));
|
|
24768
24917
|
}
|
|
24918
|
+
return canonicalSignedAuthority({
|
|
24919
|
+
issuer: payload.iss,
|
|
24920
|
+
audience: payload.aud,
|
|
24921
|
+
expiry,
|
|
24922
|
+
proofs: [...payload.prf],
|
|
24923
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24924
|
+
}, permissions);
|
|
24925
|
+
}
|
|
24926
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24769
24927
|
if (permissions.length === 0) {
|
|
24770
24928
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24771
24929
|
}
|
|
@@ -24777,15 +24935,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24777
24935
|
actions: [...permission.actions],
|
|
24778
24936
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24779
24937
|
}));
|
|
24780
|
-
return {
|
|
24781
|
-
|
|
24782
|
-
|
|
24783
|
-
|
|
24784
|
-
|
|
24785
|
-
|
|
24786
|
-
|
|
24787
|
-
|
|
24788
|
-
|
|
24938
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24939
|
+
}
|
|
24940
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24941
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24942
|
+
function comparableSpace(space) {
|
|
24943
|
+
const match = PKH_SPACE.exec(space);
|
|
24944
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24945
|
+
}
|
|
24946
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
24947
|
+
const proof = delegation.siweProof;
|
|
24948
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
24949
|
+
reject(
|
|
24950
|
+
"proof_missing",
|
|
24951
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
24952
|
+
);
|
|
24953
|
+
}
|
|
24954
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
24955
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
24956
|
+
}
|
|
24957
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
24958
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
24959
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
24960
|
+
}
|
|
24961
|
+
let verified;
|
|
24962
|
+
try {
|
|
24963
|
+
verified = node.verifySessionGrant({
|
|
24964
|
+
delegationHeader: { Authorization: authorization },
|
|
24965
|
+
delegationCid: cid,
|
|
24966
|
+
spaceId: delegation.spaceId,
|
|
24967
|
+
address: delegation.ownerAddress,
|
|
24968
|
+
chainId: delegation.chainId,
|
|
24969
|
+
siwe: proof.siwe,
|
|
24970
|
+
signature: proof.signature
|
|
24971
|
+
});
|
|
24972
|
+
} catch (error) {
|
|
24973
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
24974
|
+
}
|
|
24975
|
+
const space = comparableSpace(delegation.spaceId);
|
|
24976
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
24977
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
24978
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
24979
|
+
}
|
|
24980
|
+
const groups = /* @__PURE__ */ new Map();
|
|
24981
|
+
for (const entry of verified.recap) {
|
|
24982
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
24983
|
+
const raw = entry.space === "encryption";
|
|
24984
|
+
if (raw) {
|
|
24985
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
24986
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
24987
|
+
}
|
|
24988
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
24989
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
24990
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
24991
|
+
}
|
|
24992
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
24993
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
24994
|
+
}
|
|
24995
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
24996
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, (0, import_sdk_core9.canonicalizeRecapCaveats)(caveats)]);
|
|
24997
|
+
const group = groups.get(key2) ?? {
|
|
24998
|
+
service,
|
|
24999
|
+
...raw ? {} : { space: entry.space },
|
|
25000
|
+
path: entry.path,
|
|
25001
|
+
actions: [],
|
|
25002
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25003
|
+
};
|
|
25004
|
+
for (const action of entry.actions) {
|
|
25005
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25006
|
+
}
|
|
25007
|
+
groups.set(key2, group);
|
|
25008
|
+
}
|
|
25009
|
+
return canonicalSignedAuthority({
|
|
25010
|
+
issuer: owner,
|
|
25011
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25012
|
+
audience: node.sessionDid,
|
|
25013
|
+
expiry: verified.expiresAt,
|
|
25014
|
+
proofs: []
|
|
25015
|
+
}, [...groups.values()]);
|
|
24789
25016
|
}
|
|
24790
25017
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24791
25018
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24821,46 +25048,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24821
25048
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24822
25049
|
const host = normalizedHost(options.host);
|
|
24823
25050
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24824
|
-
|
|
25051
|
+
reject(
|
|
25052
|
+
"host_mismatch",
|
|
24825
25053
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24826
25054
|
);
|
|
24827
25055
|
}
|
|
24828
25056
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24829
|
-
|
|
25057
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24830
25058
|
}
|
|
24831
25059
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24832
|
-
|
|
25060
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24833
25061
|
}
|
|
24834
25062
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24835
25063
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24836
|
-
|
|
25064
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24837
25065
|
}
|
|
24838
25066
|
const cid = node.computeDelegationCid(authorization);
|
|
24839
25067
|
if (cid !== delegation.cid) {
|
|
24840
|
-
|
|
25068
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25069
|
+
}
|
|
25070
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25071
|
+
let signed2;
|
|
25072
|
+
try {
|
|
25073
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25074
|
+
} catch (error) {
|
|
25075
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25076
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24841
25077
|
}
|
|
24842
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24843
25078
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24844
|
-
|
|
25079
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24845
25080
|
}
|
|
24846
25081
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24847
|
-
|
|
25082
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24848
25083
|
}
|
|
24849
25084
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24850
|
-
|
|
25085
|
+
reject(
|
|
25086
|
+
"audience_mismatch",
|
|
24851
25087
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24852
25088
|
);
|
|
24853
25089
|
}
|
|
24854
25090
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24855
|
-
|
|
25091
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
25092
|
+
}
|
|
25093
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25094
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
24856
25095
|
}
|
|
24857
|
-
|
|
24858
|
-
|
|
24859
|
-
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
25096
|
+
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
25097
|
+
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24860
25098
|
}
|
|
24861
25099
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24862
25100
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24863
|
-
|
|
25101
|
+
reject(
|
|
25102
|
+
"cid_mismatch",
|
|
24864
25103
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24865
25104
|
);
|
|
24866
25105
|
}
|
|
@@ -24890,22 +25129,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
24890
25129
|
})),
|
|
24891
25130
|
expiry: new Date(signed2.expiry),
|
|
24892
25131
|
delegateDID: signed2.audience,
|
|
24893
|
-
host
|
|
25132
|
+
host,
|
|
25133
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
24894
25134
|
};
|
|
24895
|
-
|
|
24896
|
-
|
|
24897
|
-
|
|
24898
|
-
|
|
25135
|
+
try {
|
|
25136
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && (0, import_sdk_core9.principalDidEquals)(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25137
|
+
await node.useDelegation(installedCandidate);
|
|
25138
|
+
} else {
|
|
25139
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25140
|
+
}
|
|
25141
|
+
} catch (error) {
|
|
25142
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
24899
25143
|
}
|
|
24900
25144
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24901
25145
|
if (!installed) {
|
|
24902
|
-
|
|
25146
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
24903
25147
|
}
|
|
24904
25148
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
24905
25149
|
canonicalResourcesFromPortableDelegation(installed),
|
|
24906
25150
|
signed2.resources
|
|
24907
25151
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
24908
|
-
|
|
25152
|
+
reject(
|
|
25153
|
+
"activation_rejected",
|
|
24909
25154
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
24910
25155
|
);
|
|
24911
25156
|
}
|
|
@@ -25054,9 +25299,13 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
25054
25299
|
PrefixedKVService,
|
|
25055
25300
|
PrivateKeySigner,
|
|
25056
25301
|
ProtocolMismatchError,
|
|
25302
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25303
|
+
RuntimeDelegationRejectedError,
|
|
25057
25304
|
SECRET_NAME_RE,
|
|
25058
25305
|
SQLAction,
|
|
25059
25306
|
SQLService,
|
|
25307
|
+
STORAGE_FULL_MESSAGE,
|
|
25308
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
25060
25309
|
SecretsService,
|
|
25061
25310
|
ServiceContext,
|
|
25062
25311
|
SessionExpiredError,
|
|
@@ -25132,6 +25381,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
25132
25381
|
isCapabilitySubset,
|
|
25133
25382
|
isEvmAddress,
|
|
25134
25383
|
isNetworkId,
|
|
25384
|
+
isStorageFullError,
|
|
25135
25385
|
loadManifest,
|
|
25136
25386
|
makePkhSpaceId,
|
|
25137
25387
|
makePublicSpaceId,
|