@tinycloud/node-sdk 3.1.0-beta.1 → 3.1.0-beta.11
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-Bm76PnOz.d.cts → core-CJiLya1s.d.cts} +80 -6
- package/dist/{core-Bm76PnOz.d.ts → core-CJiLya1s.d.ts} +80 -6
- package/dist/core.cjs +348 -137
- 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 +354 -138
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +406 -169
- 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 +412 -171
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -4409,19 +4409,19 @@ var init_lib4 = __esm({
|
|
|
4409
4409
|
resolve(value);
|
|
4410
4410
|
});
|
|
4411
4411
|
}
|
|
4412
|
-
return new (P || (P = Promise))(function(resolve,
|
|
4412
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
4413
4413
|
function fulfilled(value) {
|
|
4414
4414
|
try {
|
|
4415
4415
|
step(generator.next(value));
|
|
4416
4416
|
} catch (e) {
|
|
4417
|
-
|
|
4417
|
+
reject2(e);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
function rejected(value) {
|
|
4421
4421
|
try {
|
|
4422
4422
|
step(generator["throw"](value));
|
|
4423
4423
|
} catch (e) {
|
|
4424
|
-
|
|
4424
|
+
reject2(e);
|
|
4425
4425
|
}
|
|
4426
4426
|
}
|
|
4427
4427
|
function step(result) {
|
|
@@ -8045,19 +8045,19 @@ var init_typed_data = __esm({
|
|
|
8045
8045
|
resolve(value);
|
|
8046
8046
|
});
|
|
8047
8047
|
}
|
|
8048
|
-
return new (P || (P = Promise))(function(resolve,
|
|
8048
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
8049
8049
|
function fulfilled(value) {
|
|
8050
8050
|
try {
|
|
8051
8051
|
step(generator.next(value));
|
|
8052
8052
|
} catch (e) {
|
|
8053
|
-
|
|
8053
|
+
reject2(e);
|
|
8054
8054
|
}
|
|
8055
8055
|
}
|
|
8056
8056
|
function rejected(value) {
|
|
8057
8057
|
try {
|
|
8058
8058
|
step(generator["throw"](value));
|
|
8059
8059
|
} catch (e) {
|
|
8060
|
-
|
|
8060
|
+
reject2(e);
|
|
8061
8061
|
}
|
|
8062
8062
|
}
|
|
8063
8063
|
function step(result) {
|
|
@@ -14903,14 +14903,14 @@ var require_scrypt = __commonJS({
|
|
|
14903
14903
|
}
|
|
14904
14904
|
const lib = {
|
|
14905
14905
|
scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
|
|
14906
|
-
return new Promise(function(resolve,
|
|
14906
|
+
return new Promise(function(resolve, reject2) {
|
|
14907
14907
|
let lastProgress = 0;
|
|
14908
14908
|
if (progressCallback) {
|
|
14909
14909
|
progressCallback(0);
|
|
14910
14910
|
}
|
|
14911
14911
|
_scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
|
|
14912
14912
|
if (error) {
|
|
14913
|
-
|
|
14913
|
+
reject2(error);
|
|
14914
14914
|
} else if (key2) {
|
|
14915
14915
|
if (progressCallback && lastProgress !== 1) {
|
|
14916
14916
|
progressCallback(1);
|
|
@@ -15299,19 +15299,19 @@ var init_keystore = __esm({
|
|
|
15299
15299
|
resolve(value);
|
|
15300
15300
|
});
|
|
15301
15301
|
}
|
|
15302
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15302
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15303
15303
|
function fulfilled(value) {
|
|
15304
15304
|
try {
|
|
15305
15305
|
step(generator.next(value));
|
|
15306
15306
|
} catch (e) {
|
|
15307
|
-
|
|
15307
|
+
reject2(e);
|
|
15308
15308
|
}
|
|
15309
15309
|
}
|
|
15310
15310
|
function rejected(value) {
|
|
15311
15311
|
try {
|
|
15312
15312
|
step(generator["throw"](value));
|
|
15313
15313
|
} catch (e) {
|
|
15314
|
-
|
|
15314
|
+
reject2(e);
|
|
15315
15315
|
}
|
|
15316
15316
|
}
|
|
15317
15317
|
function step(result) {
|
|
@@ -15612,19 +15612,19 @@ var init_lib25 = __esm({
|
|
|
15612
15612
|
resolve(value);
|
|
15613
15613
|
});
|
|
15614
15614
|
}
|
|
15615
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15615
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15616
15616
|
function fulfilled(value) {
|
|
15617
15617
|
try {
|
|
15618
15618
|
step(generator.next(value));
|
|
15619
15619
|
} catch (e) {
|
|
15620
|
-
|
|
15620
|
+
reject2(e);
|
|
15621
15621
|
}
|
|
15622
15622
|
}
|
|
15623
15623
|
function rejected(value) {
|
|
15624
15624
|
try {
|
|
15625
15625
|
step(generator["throw"](value));
|
|
15626
15626
|
} catch (e) {
|
|
15627
|
-
|
|
15627
|
+
reject2(e);
|
|
15628
15628
|
}
|
|
15629
15629
|
}
|
|
15630
15630
|
function step(result) {
|
|
@@ -15694,19 +15694,19 @@ var init_lib26 = __esm({
|
|
|
15694
15694
|
resolve(value);
|
|
15695
15695
|
});
|
|
15696
15696
|
}
|
|
15697
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15697
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15698
15698
|
function fulfilled(value) {
|
|
15699
15699
|
try {
|
|
15700
15700
|
step(generator.next(value));
|
|
15701
15701
|
} catch (e) {
|
|
15702
|
-
|
|
15702
|
+
reject2(e);
|
|
15703
15703
|
}
|
|
15704
15704
|
}
|
|
15705
15705
|
function rejected(value) {
|
|
15706
15706
|
try {
|
|
15707
15707
|
step(generator["throw"](value));
|
|
15708
15708
|
} catch (e) {
|
|
15709
|
-
|
|
15709
|
+
reject2(e);
|
|
15710
15710
|
}
|
|
15711
15711
|
}
|
|
15712
15712
|
function step(result) {
|
|
@@ -16016,19 +16016,19 @@ var init_lib27 = __esm({
|
|
|
16016
16016
|
resolve(value);
|
|
16017
16017
|
});
|
|
16018
16018
|
}
|
|
16019
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16019
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16020
16020
|
function fulfilled(value) {
|
|
16021
16021
|
try {
|
|
16022
16022
|
step(generator.next(value));
|
|
16023
16023
|
} catch (e) {
|
|
16024
|
-
|
|
16024
|
+
reject2(e);
|
|
16025
16025
|
}
|
|
16026
16026
|
}
|
|
16027
16027
|
function rejected(value) {
|
|
16028
16028
|
try {
|
|
16029
16029
|
step(generator["throw"](value));
|
|
16030
16030
|
} catch (e) {
|
|
16031
|
-
|
|
16031
|
+
reject2(e);
|
|
16032
16032
|
}
|
|
16033
16033
|
}
|
|
16034
16034
|
function step(result) {
|
|
@@ -16254,19 +16254,19 @@ var init_geturl = __esm({
|
|
|
16254
16254
|
resolve(value);
|
|
16255
16255
|
});
|
|
16256
16256
|
}
|
|
16257
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16257
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16258
16258
|
function fulfilled(value) {
|
|
16259
16259
|
try {
|
|
16260
16260
|
step(generator.next(value));
|
|
16261
16261
|
} catch (e) {
|
|
16262
|
-
|
|
16262
|
+
reject2(e);
|
|
16263
16263
|
}
|
|
16264
16264
|
}
|
|
16265
16265
|
function rejected(value) {
|
|
16266
16266
|
try {
|
|
16267
16267
|
step(generator["throw"](value));
|
|
16268
16268
|
} catch (e) {
|
|
16269
|
-
|
|
16269
|
+
reject2(e);
|
|
16270
16270
|
}
|
|
16271
16271
|
}
|
|
16272
16272
|
function step(result) {
|
|
@@ -16407,14 +16407,14 @@ function _fetchData(connection, body, processFunc) {
|
|
|
16407
16407
|
options.headers = flatHeaders;
|
|
16408
16408
|
const runningTimeout = (function() {
|
|
16409
16409
|
let timer = null;
|
|
16410
|
-
const promise = new Promise(function(resolve,
|
|
16410
|
+
const promise = new Promise(function(resolve, reject2) {
|
|
16411
16411
|
if (timeout) {
|
|
16412
16412
|
timer = setTimeout(() => {
|
|
16413
16413
|
if (timer == null) {
|
|
16414
16414
|
return;
|
|
16415
16415
|
}
|
|
16416
16416
|
timer = null;
|
|
16417
|
-
|
|
16417
|
+
reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
|
|
16418
16418
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
|
16419
16419
|
requestMethod: options.method,
|
|
16420
16420
|
timeout,
|
|
@@ -16577,7 +16577,7 @@ function poll(func, options) {
|
|
|
16577
16577
|
if (options.interval == null) {
|
|
16578
16578
|
options.interval = 250;
|
|
16579
16579
|
}
|
|
16580
|
-
return new Promise(function(resolve,
|
|
16580
|
+
return new Promise(function(resolve, reject2) {
|
|
16581
16581
|
let timer = null;
|
|
16582
16582
|
let done = false;
|
|
16583
16583
|
const cancel = () => {
|
|
@@ -16593,7 +16593,7 @@ function poll(func, options) {
|
|
|
16593
16593
|
if (options.timeout) {
|
|
16594
16594
|
timer = setTimeout(() => {
|
|
16595
16595
|
if (cancel()) {
|
|
16596
|
-
|
|
16596
|
+
reject2(new Error("timeout"));
|
|
16597
16597
|
}
|
|
16598
16598
|
}, options.timeout);
|
|
16599
16599
|
}
|
|
@@ -16613,7 +16613,7 @@ function poll(func, options) {
|
|
|
16613
16613
|
attempt++;
|
|
16614
16614
|
if (attempt > retryLimit) {
|
|
16615
16615
|
if (cancel()) {
|
|
16616
|
-
|
|
16616
|
+
reject2(new Error("retry limit reached"));
|
|
16617
16617
|
}
|
|
16618
16618
|
return;
|
|
16619
16619
|
}
|
|
@@ -16629,7 +16629,7 @@ function poll(func, options) {
|
|
|
16629
16629
|
return null;
|
|
16630
16630
|
}, function(error) {
|
|
16631
16631
|
if (cancel()) {
|
|
16632
|
-
|
|
16632
|
+
reject2(error);
|
|
16633
16633
|
}
|
|
16634
16634
|
});
|
|
16635
16635
|
}
|
|
@@ -16653,19 +16653,19 @@ var init_lib28 = __esm({
|
|
|
16653
16653
|
resolve(value);
|
|
16654
16654
|
});
|
|
16655
16655
|
}
|
|
16656
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16656
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16657
16657
|
function fulfilled(value) {
|
|
16658
16658
|
try {
|
|
16659
16659
|
step(generator.next(value));
|
|
16660
16660
|
} catch (e) {
|
|
16661
|
-
|
|
16661
|
+
reject2(e);
|
|
16662
16662
|
}
|
|
16663
16663
|
}
|
|
16664
16664
|
function rejected(value) {
|
|
16665
16665
|
try {
|
|
16666
16666
|
step(generator["throw"](value));
|
|
16667
16667
|
} catch (e) {
|
|
16668
|
-
|
|
16668
|
+
reject2(e);
|
|
16669
16669
|
}
|
|
16670
16670
|
}
|
|
16671
16671
|
function step(result) {
|
|
@@ -17035,6 +17035,7 @@ import {
|
|
|
17035
17035
|
prepareSession,
|
|
17036
17036
|
completeSessionSetup,
|
|
17037
17037
|
validatePersistedSession,
|
|
17038
|
+
validateSessionGrant,
|
|
17038
17039
|
ensureEip55,
|
|
17039
17040
|
makeSpaceId,
|
|
17040
17041
|
createDelegation,
|
|
@@ -17084,6 +17085,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17084
17085
|
validatePersistedSession(proof) {
|
|
17085
17086
|
return validatePersistedSession(proof);
|
|
17086
17087
|
}
|
|
17088
|
+
validateSessionGrant(proof) {
|
|
17089
|
+
return validateSessionGrant(proof);
|
|
17090
|
+
}
|
|
17087
17091
|
createSessionManager() {
|
|
17088
17092
|
return new TCWSessionManager();
|
|
17089
17093
|
}
|
|
@@ -17163,6 +17167,7 @@ import {
|
|
|
17163
17167
|
TinyCloud,
|
|
17164
17168
|
activateSessionWithHost as activateSessionWithHost2,
|
|
17165
17169
|
authorizationVerdictOf,
|
|
17170
|
+
httpResponseError,
|
|
17166
17171
|
KVService as KVService2,
|
|
17167
17172
|
SQLService as SQLService2,
|
|
17168
17173
|
DuckDbService as DuckDbService2,
|
|
@@ -17196,6 +17201,7 @@ import {
|
|
|
17196
17201
|
recapCaveatsEqual,
|
|
17197
17202
|
expandPermissionEntries as expandPermissionEntriesCore,
|
|
17198
17203
|
isCapabilitySubset,
|
|
17204
|
+
isExplicitOnlyAction,
|
|
17199
17205
|
parseRecapCapabilities,
|
|
17200
17206
|
SERVICE_LONG_TO_SHORT,
|
|
17201
17207
|
SERVICE_SHORT_TO_LONG,
|
|
@@ -17218,7 +17224,10 @@ import {
|
|
|
17218
17224
|
CREDENTIAL_INVITATION_REQUEST_DOMAIN,
|
|
17219
17225
|
validateShareDeliveryAuthorizationV3Bytes,
|
|
17220
17226
|
verifyEip191MessageSignature,
|
|
17221
|
-
signCompactUcanRootAuthorization
|
|
17227
|
+
signCompactUcanRootAuthorization,
|
|
17228
|
+
isStorageFullError,
|
|
17229
|
+
STORAGE_FULL_MESSAGE,
|
|
17230
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE
|
|
17222
17231
|
} from "@tinycloud/sdk-core";
|
|
17223
17232
|
import {
|
|
17224
17233
|
parsePermissionHint
|
|
@@ -17338,6 +17347,10 @@ var MemorySessionStorage = class {
|
|
|
17338
17347
|
// src/authorization/NodeUserAuthorization.ts
|
|
17339
17348
|
var DECRYPT_ACTION = ENCRYPTION.DECRYPT;
|
|
17340
17349
|
var NETWORK_CREATE_ACTION = ENCRYPTION.NETWORK_CREATE;
|
|
17350
|
+
function describeHostFailure(result) {
|
|
17351
|
+
const text = result.error?.trim();
|
|
17352
|
+
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
17353
|
+
}
|
|
17341
17354
|
function canonicalizeOpenKeyManifestJson(value) {
|
|
17342
17355
|
const json = JSON.stringify(value);
|
|
17343
17356
|
if (json === void 0) {
|
|
@@ -17866,10 +17879,12 @@ var NodeUserAuthorization = class {
|
|
|
17866
17879
|
return;
|
|
17867
17880
|
}
|
|
17868
17881
|
try {
|
|
17869
|
-
const created =
|
|
17870
|
-
if (!created) {
|
|
17871
|
-
const err =
|
|
17872
|
-
|
|
17882
|
+
const created = await this.hostSpace();
|
|
17883
|
+
if (!created.success) {
|
|
17884
|
+
const err = Object.assign(
|
|
17885
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17886
|
+
{ cause: created }
|
|
17887
|
+
);
|
|
17873
17888
|
throw err;
|
|
17874
17889
|
}
|
|
17875
17890
|
} catch (error) {
|
|
@@ -17885,8 +17900,9 @@ var NodeUserAuthorization = class {
|
|
|
17885
17900
|
this._tinyCloudSession.delegationHeader
|
|
17886
17901
|
);
|
|
17887
17902
|
if (!retryResult.success) {
|
|
17888
|
-
const err =
|
|
17889
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17903
|
+
const err = Object.assign(
|
|
17904
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17905
|
+
{ cause: retryResult }
|
|
17890
17906
|
);
|
|
17891
17907
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17892
17908
|
throw err;
|
|
@@ -17903,10 +17919,12 @@ var NodeUserAuthorization = class {
|
|
|
17903
17919
|
return;
|
|
17904
17920
|
}
|
|
17905
17921
|
try {
|
|
17906
|
-
const created =
|
|
17907
|
-
if (!created) {
|
|
17908
|
-
const err =
|
|
17909
|
-
|
|
17922
|
+
const created = await this.hostSpace();
|
|
17923
|
+
if (!created.success) {
|
|
17924
|
+
const err = Object.assign(
|
|
17925
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
17926
|
+
{ cause: created }
|
|
17927
|
+
);
|
|
17910
17928
|
throw err;
|
|
17911
17929
|
}
|
|
17912
17930
|
} catch (error) {
|
|
@@ -17922,8 +17940,9 @@ var NodeUserAuthorization = class {
|
|
|
17922
17940
|
this._tinyCloudSession.delegationHeader
|
|
17923
17941
|
);
|
|
17924
17942
|
if (!retryResult.success) {
|
|
17925
|
-
const err =
|
|
17926
|
-
`Failed to activate session after creating space: ${retryResult
|
|
17943
|
+
const err = Object.assign(
|
|
17944
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
17945
|
+
{ cause: retryResult }
|
|
17927
17946
|
);
|
|
17928
17947
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
17929
17948
|
throw err;
|
|
@@ -17931,7 +17950,10 @@ var NodeUserAuthorization = class {
|
|
|
17931
17950
|
handler.onSpaceCreated?.(creationContext);
|
|
17932
17951
|
return;
|
|
17933
17952
|
}
|
|
17934
|
-
throw
|
|
17953
|
+
throw Object.assign(
|
|
17954
|
+
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
17955
|
+
{ cause: result }
|
|
17956
|
+
);
|
|
17935
17957
|
}
|
|
17936
17958
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
17937
17959
|
if (result.success) {
|
|
@@ -18721,14 +18743,14 @@ var NodeUserAuthorization = class {
|
|
|
18721
18743
|
* Request signature via event emitter with timeout.
|
|
18722
18744
|
*/
|
|
18723
18745
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18724
|
-
return new Promise((resolve,
|
|
18746
|
+
return new Promise((resolve, reject2) => {
|
|
18725
18747
|
const timeoutId = setTimeout(() => {
|
|
18726
|
-
|
|
18748
|
+
reject2(new Error("Sign request timed out"));
|
|
18727
18749
|
}, timeout);
|
|
18728
18750
|
const respond = async (response) => {
|
|
18729
18751
|
clearTimeout(timeoutId);
|
|
18730
18752
|
if (!response.approved) {
|
|
18731
|
-
|
|
18753
|
+
reject2(
|
|
18732
18754
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18733
18755
|
);
|
|
18734
18756
|
} else {
|
|
@@ -19323,6 +19345,25 @@ function jsonFromVerifier(value) {
|
|
|
19323
19345
|
function verifierRecapEntries(entries) {
|
|
19324
19346
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19325
19347
|
}
|
|
19348
|
+
function exactVerifiedRecap(verified) {
|
|
19349
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19350
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19351
|
+
(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(
|
|
19352
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19353
|
+
)
|
|
19354
|
+
)) {
|
|
19355
|
+
throw new UnsupportedSessionRestoreError(
|
|
19356
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19357
|
+
);
|
|
19358
|
+
}
|
|
19359
|
+
return exactRecap.map((entry) => ({
|
|
19360
|
+
service: entry.service,
|
|
19361
|
+
space: entry.space,
|
|
19362
|
+
path: entry.path,
|
|
19363
|
+
actions: [...entry.actions],
|
|
19364
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19365
|
+
}));
|
|
19366
|
+
}
|
|
19326
19367
|
var ServiceGraphLifetime = class {
|
|
19327
19368
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19328
19369
|
this.invokeFn = invokeFn;
|
|
@@ -19418,7 +19459,7 @@ function persistedExpiry(value) {
|
|
|
19418
19459
|
function sameInstant(left, right) {
|
|
19419
19460
|
return left.getTime() === right.getTime();
|
|
19420
19461
|
}
|
|
19421
|
-
function
|
|
19462
|
+
function describeHostFailure2(result) {
|
|
19422
19463
|
const text = result.error?.trim();
|
|
19423
19464
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
19424
19465
|
}
|
|
@@ -20164,12 +20205,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20164
20205
|
if (!auth) {
|
|
20165
20206
|
throw new Error("Account bootstrap requires an active wallet session");
|
|
20166
20207
|
}
|
|
20208
|
+
const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
|
|
20167
20209
|
const skipped = auth.lastActivationSkippedSpaceIds;
|
|
20210
|
+
if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
|
|
20168
20211
|
if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
|
|
20169
|
-
return { action: "run", mode: "
|
|
20212
|
+
return { action: "run", mode: "repair" };
|
|
20170
20213
|
}
|
|
20171
20214
|
try {
|
|
20172
|
-
const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
|
|
20173
20215
|
const markerPermission = {
|
|
20174
20216
|
service: "tinycloud.kv",
|
|
20175
20217
|
space: accountSpaceId,
|
|
@@ -20181,7 +20223,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20181
20223
|
}
|
|
20182
20224
|
const marker = await this.readBootstrapCompletionMarker();
|
|
20183
20225
|
if (marker.ok) {
|
|
20184
|
-
if (this.isAcceptedBootstrapCompletionMarker(marker.data.data)) {
|
|
20226
|
+
if (this.isAcceptedBootstrapCompletionMarker(marker.data.data, steps.map((step) => step.id))) {
|
|
20185
20227
|
return { action: "skip" };
|
|
20186
20228
|
}
|
|
20187
20229
|
return { action: "run", mode: "repair" };
|
|
@@ -20225,15 +20267,22 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20225
20267
|
marker
|
|
20226
20268
|
);
|
|
20227
20269
|
if (!written.ok) {
|
|
20228
|
-
throw
|
|
20270
|
+
throw Object.assign(
|
|
20271
|
+
new Error(`Failed to write bootstrap completion marker: ${written.error.message}`),
|
|
20272
|
+
{ cause: written.error }
|
|
20273
|
+
);
|
|
20229
20274
|
}
|
|
20230
20275
|
}
|
|
20231
|
-
|
|
20276
|
+
/**
|
|
20277
|
+
* A marker written before a canonical space was added triggers one bounded repair.
|
|
20278
|
+
*/
|
|
20279
|
+
isAcceptedBootstrapCompletionMarker(value, canonicalStepIds) {
|
|
20232
20280
|
if (typeof value !== "object" || value === null) return false;
|
|
20233
20281
|
const entries = Object.entries(value);
|
|
20234
20282
|
const markerValue = (name) => entries.find(([key2]) => key2 === name)?.[1];
|
|
20235
20283
|
const version23 = markerValue("v");
|
|
20236
|
-
|
|
20284
|
+
const stepIds = markerValue("stepIds");
|
|
20285
|
+
return typeof version23 === "number" && Number.isInteger(version23) && ACCEPTED_MARKER_VERSIONS.some((acceptedVersion) => acceptedVersion === version23) && Array.isArray(stepIds) && canonicalStepIds.every((stepId) => stepIds.includes(stepId));
|
|
20237
20286
|
}
|
|
20238
20287
|
markerReadIsUnhostedSpace(meta) {
|
|
20239
20288
|
return meta?.status === 404;
|
|
@@ -20271,17 +20320,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20271
20320
|
rawAbilities
|
|
20272
20321
|
});
|
|
20273
20322
|
} catch (err) {
|
|
20274
|
-
throw
|
|
20275
|
-
|
|
20323
|
+
throw Object.assign(
|
|
20324
|
+
new Error(
|
|
20325
|
+
`Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
|
|
20326
|
+
),
|
|
20327
|
+
{ cause: err }
|
|
20276
20328
|
);
|
|
20277
20329
|
}
|
|
20278
20330
|
sessions.set(step.space, session);
|
|
20279
20331
|
}
|
|
20280
20332
|
for (const step of steps) {
|
|
20281
20333
|
if (step.kind !== "host") continue;
|
|
20282
|
-
const hosted = await auth.
|
|
20283
|
-
if (!hosted) {
|
|
20284
|
-
throw
|
|
20334
|
+
const hosted = await auth.hostOwnedSpaceResult(step.spaceId, "bootstrap-host");
|
|
20335
|
+
if (!hosted.success) {
|
|
20336
|
+
throw Object.assign(
|
|
20337
|
+
new Error(`Failed to host bootstrap space ${step.spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20338
|
+
{ cause: hosted }
|
|
20339
|
+
);
|
|
20285
20340
|
}
|
|
20286
20341
|
}
|
|
20287
20342
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -20293,8 +20348,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20293
20348
|
}
|
|
20294
20349
|
const activated = await activateSessionWithHost2(host, session.delegationHeader);
|
|
20295
20350
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
20296
|
-
throw
|
|
20297
|
-
|
|
20351
|
+
throw Object.assign(
|
|
20352
|
+
new Error(
|
|
20353
|
+
`Failed to activate bootstrap session for ${step.spaceId}: ${activated.success ? "space was skipped" : describeHostFailure2(activated)}`
|
|
20354
|
+
),
|
|
20355
|
+
{ cause: activated }
|
|
20298
20356
|
);
|
|
20299
20357
|
}
|
|
20300
20358
|
this.registerBootstrapRuntimeGrant(
|
|
@@ -20307,33 +20365,43 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20307
20365
|
if (step.kind === "account-index-schema") {
|
|
20308
20366
|
const ensured = await this.account.index.ensure();
|
|
20309
20367
|
if (!ensured.ok) {
|
|
20310
|
-
throw new Error(`Failed to create account index schema: ${ensured.error.message}`);
|
|
20368
|
+
throw Object.assign(new Error(`Failed to create account index schema: ${ensured.error.message}`), { cause: ensured.error });
|
|
20311
20369
|
}
|
|
20312
20370
|
}
|
|
20313
20371
|
if (step.kind === "seed-spaces") {
|
|
20314
|
-
const
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
|
|
20322
|
-
|
|
20323
|
-
|
|
20324
|
-
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20372
|
+
const inputs = step.spaces.map((space) => ({
|
|
20373
|
+
spaceId: space.spaceId,
|
|
20374
|
+
name: space.name,
|
|
20375
|
+
ownerDid: this.did,
|
|
20376
|
+
type: "owned",
|
|
20377
|
+
permissions: ["*"],
|
|
20378
|
+
status: "active"
|
|
20379
|
+
}));
|
|
20380
|
+
if (mode === "fresh") {
|
|
20381
|
+
const registered = await this.account.spaces.registerBatch(inputs);
|
|
20382
|
+
if (!registered.ok) {
|
|
20383
|
+
throw Object.assign(
|
|
20384
|
+
new Error(`Failed to seed account spaces: ${registered.error.message}`),
|
|
20385
|
+
{ cause: registered.error }
|
|
20386
|
+
);
|
|
20387
|
+
}
|
|
20388
|
+
const batchError = registered.data.recoveredFromBatchError;
|
|
20389
|
+
if (batchError) {
|
|
20390
|
+
warnings.push({
|
|
20391
|
+
stepId: step.id,
|
|
20392
|
+
kind: "batch-write-reconciled",
|
|
20393
|
+
code: batchError.code,
|
|
20394
|
+
message: batchError.message
|
|
20395
|
+
});
|
|
20396
|
+
}
|
|
20397
|
+
} else {
|
|
20398
|
+
const ensured = await this.account.spaces.registerMissing(inputs);
|
|
20399
|
+
if (!ensured.ok) {
|
|
20400
|
+
throw Object.assign(
|
|
20401
|
+
new Error(`Failed to seed account spaces: ${ensured.error.message}`),
|
|
20402
|
+
{ cause: ensured.error }
|
|
20403
|
+
);
|
|
20404
|
+
}
|
|
20337
20405
|
}
|
|
20338
20406
|
}
|
|
20339
20407
|
if (step.kind === "seed-applications") {
|
|
@@ -20344,7 +20412,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20344
20412
|
{ assumeUnregistered: true }
|
|
20345
20413
|
);
|
|
20346
20414
|
if (!registered.ok) {
|
|
20347
|
-
throw new Error(`Failed to seed bootstrap applications: ${registered.error.message}`);
|
|
20415
|
+
throw Object.assign(new Error(`Failed to seed bootstrap applications: ${registered.error.message}`), { cause: registered.error });
|
|
20348
20416
|
}
|
|
20349
20417
|
}
|
|
20350
20418
|
if (step.kind === "encryption-network-create") {
|
|
@@ -20362,8 +20430,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20362
20430
|
]
|
|
20363
20431
|
});
|
|
20364
20432
|
if (!migrated.ok) {
|
|
20365
|
-
throw
|
|
20366
|
-
`Failed to create secret_records schema: ${migrated.error.message}`
|
|
20433
|
+
throw Object.assign(
|
|
20434
|
+
new Error(`Failed to create secret_records schema: ${migrated.error.message}`),
|
|
20435
|
+
{ cause: migrated.error }
|
|
20367
20436
|
);
|
|
20368
20437
|
}
|
|
20369
20438
|
}
|
|
@@ -20630,6 +20699,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20630
20699
|
);
|
|
20631
20700
|
return;
|
|
20632
20701
|
}
|
|
20702
|
+
if (isStorageFullError(error) || isStorageFullError(error?.cause) || message.includes(STORAGE_FULL_MESSAGE) || message.includes(STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
|
|
20703
|
+
console.warn("TinyCloud account registry sync stopped: storage is full", error);
|
|
20704
|
+
return;
|
|
20705
|
+
}
|
|
20633
20706
|
lastError = error;
|
|
20634
20707
|
if (attempt < delays.length - 1) {
|
|
20635
20708
|
await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
|
|
@@ -20704,14 +20777,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20704
20777
|
}
|
|
20705
20778
|
if (!activation.success && activation.status !== 404) {
|
|
20706
20779
|
throw Object.assign(
|
|
20707
|
-
new Error(`Failed to check owned space ${spaceId}: ${
|
|
20780
|
+
new Error(`Failed to check owned space ${spaceId}: ${describeHostFailure2(activation)}`),
|
|
20708
20781
|
{ cause: activation }
|
|
20709
20782
|
);
|
|
20710
20783
|
}
|
|
20711
20784
|
const created = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20712
20785
|
if (!created.success) {
|
|
20713
20786
|
throw Object.assign(
|
|
20714
|
-
new Error(`Failed to create owned space ${spaceId}: ${
|
|
20787
|
+
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
20715
20788
|
{ cause: created }
|
|
20716
20789
|
);
|
|
20717
20790
|
}
|
|
@@ -20720,7 +20793,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20720
20793
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
20721
20794
|
throw Object.assign(
|
|
20722
20795
|
new Error(
|
|
20723
|
-
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" :
|
|
20796
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" : describeHostFailure2(retry)}`
|
|
20724
20797
|
),
|
|
20725
20798
|
{ cause: retry }
|
|
20726
20799
|
);
|
|
@@ -20757,19 +20830,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20757
20830
|
if (!host) {
|
|
20758
20831
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
20759
20832
|
}
|
|
20760
|
-
const hosted = await this.auth.
|
|
20761
|
-
|
|
20762
|
-
|
|
20763
|
-
|
|
20764
|
-
|
|
20833
|
+
const hosted = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
20834
|
+
if (!hosted.success) {
|
|
20835
|
+
throw Object.assign(
|
|
20836
|
+
new Error(`Failed to host owned space ${spaceId}: ${describeHostFailure2(hosted)}`),
|
|
20837
|
+
{ cause: hosted }
|
|
20838
|
+
);
|
|
20765
20839
|
}
|
|
20766
20840
|
const activation = await activateSessionWithHost2(
|
|
20767
20841
|
host,
|
|
20768
20842
|
session.delegationHeader
|
|
20769
20843
|
);
|
|
20770
20844
|
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
20771
|
-
throw
|
|
20772
|
-
|
|
20845
|
+
throw Object.assign(
|
|
20846
|
+
new Error(
|
|
20847
|
+
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
20848
|
+
),
|
|
20849
|
+
{ cause: activation }
|
|
20773
20850
|
);
|
|
20774
20851
|
}
|
|
20775
20852
|
try {
|
|
@@ -20965,23 +21042,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20965
21042
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
20966
21043
|
}
|
|
20967
21044
|
})();
|
|
20968
|
-
|
|
20969
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
20970
|
-
(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(
|
|
20971
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
20972
|
-
)
|
|
20973
|
-
)) {
|
|
20974
|
-
throw new UnsupportedSessionRestoreError(
|
|
20975
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
20976
|
-
);
|
|
20977
|
-
}
|
|
20978
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
20979
|
-
service: entry.service,
|
|
20980
|
-
space: entry.space,
|
|
20981
|
-
path: entry.path,
|
|
20982
|
-
actions: [...entry.actions],
|
|
20983
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
20984
|
-
}));
|
|
21045
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
20985
21046
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
20986
21047
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
20987
21048
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -21785,7 +21846,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21785
21846
|
if (cached) return cached;
|
|
21786
21847
|
const response = await fetch(`${this.config.host}/info`);
|
|
21787
21848
|
if (!response.ok) {
|
|
21788
|
-
throw
|
|
21849
|
+
throw await httpResponseError(response, "Failed to fetch node info");
|
|
21789
21850
|
}
|
|
21790
21851
|
const info = await response.json();
|
|
21791
21852
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -21835,9 +21896,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21835
21896
|
);
|
|
21836
21897
|
if (response.status === 404) return null;
|
|
21837
21898
|
if (!response.ok) {
|
|
21838
|
-
throw
|
|
21839
|
-
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
21840
|
-
);
|
|
21899
|
+
throw await httpResponseError(response, `Failed to fetch encryption network ${networkId}`);
|
|
21841
21900
|
}
|
|
21842
21901
|
const body = await response.json();
|
|
21843
21902
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -22338,7 +22397,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22338
22397
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
22339
22398
|
body: canonicalizeEncryptionJson(request)
|
|
22340
22399
|
});
|
|
22341
|
-
if (!response.ok) throw
|
|
22400
|
+
if (!response.ok) throw await httpResponseError(response, "V3 share delivery authorization failed");
|
|
22342
22401
|
const verified = validateShareDeliveryAuthorizationV3Bytes(new Uint8Array(await response.arrayBuffer()), {
|
|
22343
22402
|
request,
|
|
22344
22403
|
senderKeyDid: this.credentialHolderDid,
|
|
@@ -22560,9 +22619,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22560
22619
|
);
|
|
22561
22620
|
}
|
|
22562
22621
|
if (!response.ok) {
|
|
22563
|
-
throw
|
|
22564
|
-
`Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
22565
|
-
);
|
|
22622
|
+
throw await httpResponseError(response, `Failed to create encryption network ${networkId}`);
|
|
22566
22623
|
}
|
|
22567
22624
|
const created = await response.json();
|
|
22568
22625
|
return created.descriptor;
|
|
@@ -22846,6 +22903,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22846
22903
|
(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"))
|
|
22847
22904
|
);
|
|
22848
22905
|
}
|
|
22906
|
+
/**
|
|
22907
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22908
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22909
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22910
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22911
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22912
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22913
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22914
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22915
|
+
* which also refuses decrypt-only grants.
|
|
22916
|
+
*/
|
|
22917
|
+
verifySessionGrant(grant) {
|
|
22918
|
+
const bindings = this.wasmBindings;
|
|
22919
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22920
|
+
if (validate5 === void 0) {
|
|
22921
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22922
|
+
}
|
|
22923
|
+
const verified = validate5({
|
|
22924
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22925
|
+
delegationCid: grant.delegationCid,
|
|
22926
|
+
spaceId: grant.spaceId,
|
|
22927
|
+
jwk: this.sessionKeyJwk,
|
|
22928
|
+
address: canonicalizeAddress2(grant.address),
|
|
22929
|
+
chainId: grant.chainId,
|
|
22930
|
+
siwe: grant.siwe,
|
|
22931
|
+
signature: grant.signature
|
|
22932
|
+
});
|
|
22933
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22934
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22935
|
+
}
|
|
22936
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22937
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22938
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22939
|
+
}
|
|
22940
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22941
|
+
}
|
|
22849
22942
|
/**
|
|
22850
22943
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22851
22944
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -22870,8 +22963,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22870
22963
|
delegation.delegationHeader
|
|
22871
22964
|
);
|
|
22872
22965
|
if (!activateResult.success) {
|
|
22873
|
-
throw
|
|
22874
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
22966
|
+
throw Object.assign(
|
|
22967
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
22968
|
+
{ cause: activateResult }
|
|
22875
22969
|
);
|
|
22876
22970
|
}
|
|
22877
22971
|
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
@@ -22967,8 +23061,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22967
23061
|
delegatedSession.delegationHeader
|
|
22968
23062
|
);
|
|
22969
23063
|
if (!activateResult.success) {
|
|
22970
|
-
throw
|
|
22971
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
23064
|
+
throw Object.assign(
|
|
23065
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
23066
|
+
{ cause: activateResult }
|
|
22972
23067
|
);
|
|
22973
23068
|
}
|
|
22974
23069
|
const delegation = this.runtimeDelegationFromSession(
|
|
@@ -22976,7 +23071,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22976
23071
|
delegatedEntries,
|
|
22977
23072
|
spaceId,
|
|
22978
23073
|
session,
|
|
22979
|
-
expiresAt
|
|
23074
|
+
expiresAt,
|
|
23075
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
22980
23076
|
);
|
|
22981
23077
|
this.runtimePermissionGrants.push({
|
|
22982
23078
|
session: {
|
|
@@ -23153,7 +23249,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23153
23249
|
delegationSession.delegationHeader
|
|
23154
23250
|
);
|
|
23155
23251
|
if (!activateResult.success) {
|
|
23156
|
-
throw
|
|
23252
|
+
throw Object.assign(
|
|
23253
|
+
new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
|
|
23254
|
+
{ cause: activateResult }
|
|
23255
|
+
);
|
|
23157
23256
|
}
|
|
23158
23257
|
if (this._capabilityRegistry && this.session) {
|
|
23159
23258
|
const sessionKey = {
|
|
@@ -23506,8 +23605,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23506
23605
|
delegationHeader
|
|
23507
23606
|
);
|
|
23508
23607
|
if (!activateResult.success) {
|
|
23509
|
-
throw
|
|
23510
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23608
|
+
throw Object.assign(
|
|
23609
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23610
|
+
{ cause: activateResult }
|
|
23511
23611
|
);
|
|
23512
23612
|
}
|
|
23513
23613
|
return {
|
|
@@ -23543,8 +23643,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23543
23643
|
delegationHeader
|
|
23544
23644
|
);
|
|
23545
23645
|
if (!activateResult.success) {
|
|
23546
|
-
throw
|
|
23547
|
-
`Failed to activate delegation with host: ${activateResult
|
|
23646
|
+
throw Object.assign(
|
|
23647
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
23648
|
+
{ cause: activateResult }
|
|
23548
23649
|
);
|
|
23549
23650
|
}
|
|
23550
23651
|
return {
|
|
@@ -23757,7 +23858,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23757
23858
|
}
|
|
23758
23859
|
return grants;
|
|
23759
23860
|
}
|
|
23760
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23861
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23761
23862
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23762
23863
|
const primary = resources[0];
|
|
23763
23864
|
return {
|
|
@@ -23772,7 +23873,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23772
23873
|
delegateDID: session.verificationMethod,
|
|
23773
23874
|
ownerAddress: session.address,
|
|
23774
23875
|
chainId: session.chainId,
|
|
23775
|
-
host: this.config.host
|
|
23876
|
+
host: this.config.host,
|
|
23877
|
+
siweProof
|
|
23776
23878
|
};
|
|
23777
23879
|
}
|
|
23778
23880
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -23965,6 +24067,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23965
24067
|
if (grantedAction === requestedAction) {
|
|
23966
24068
|
return true;
|
|
23967
24069
|
}
|
|
24070
|
+
if (isExplicitOnlyAction(requestedAction)) {
|
|
24071
|
+
return false;
|
|
24072
|
+
}
|
|
23968
24073
|
if (grantedAction.endsWith("/*")) {
|
|
23969
24074
|
const prefix = grantedAction.slice(0, -2);
|
|
23970
24075
|
return requestedAction.startsWith(`${prefix}/`);
|
|
@@ -24151,7 +24256,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24151
24256
|
delegationSession.delegationHeader
|
|
24152
24257
|
);
|
|
24153
24258
|
if (!activateResult.success) {
|
|
24154
|
-
throw
|
|
24259
|
+
throw Object.assign(
|
|
24260
|
+
new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
|
|
24261
|
+
{ cause: activateResult }
|
|
24262
|
+
);
|
|
24155
24263
|
}
|
|
24156
24264
|
const result = {
|
|
24157
24265
|
cid: delegationSession.delegationCid,
|
|
@@ -24301,7 +24409,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24301
24409
|
invokerSession.delegationHeader
|
|
24302
24410
|
);
|
|
24303
24411
|
if (!activateResult.success) {
|
|
24304
|
-
throw
|
|
24412
|
+
throw Object.assign(
|
|
24413
|
+
new Error(`Failed to activate delegated session: ${describeHostFailure2(activateResult)}`),
|
|
24414
|
+
{ cause: activateResult }
|
|
24415
|
+
);
|
|
24305
24416
|
}
|
|
24306
24417
|
const session = {
|
|
24307
24418
|
address: mySession.address,
|
|
@@ -24418,7 +24529,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24418
24529
|
subDelegationSession.delegationHeader
|
|
24419
24530
|
);
|
|
24420
24531
|
if (!activateResult.success) {
|
|
24421
|
-
throw
|
|
24532
|
+
throw Object.assign(
|
|
24533
|
+
new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
|
|
24534
|
+
{ cause: activateResult }
|
|
24535
|
+
);
|
|
24422
24536
|
}
|
|
24423
24537
|
return {
|
|
24424
24538
|
cid: subDelegationSession.delegationCid,
|
|
@@ -24487,7 +24601,10 @@ import {
|
|
|
24487
24601
|
disableTinyCloudDebug,
|
|
24488
24602
|
getTinyCloudDebugLogs,
|
|
24489
24603
|
clearTinyCloudDebugLogs,
|
|
24490
|
-
installTinyCloudDebugGlobals
|
|
24604
|
+
installTinyCloudDebugGlobals,
|
|
24605
|
+
isStorageFullError as isStorageFullError2,
|
|
24606
|
+
STORAGE_FULL_MESSAGE as STORAGE_FULL_MESSAGE2,
|
|
24607
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE as STORAGE_WRITE_TOO_LARGE_MESSAGE2
|
|
24491
24608
|
} from "@tinycloud/sdk-core";
|
|
24492
24609
|
|
|
24493
24610
|
// src/storage/FileSessionStorage.ts
|
|
@@ -24683,6 +24800,29 @@ import {
|
|
|
24683
24800
|
decodeBase64Url,
|
|
24684
24801
|
principalDidEquals as principalDidEquals3
|
|
24685
24802
|
} from "@tinycloud/sdk-core";
|
|
24803
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24804
|
+
"host_mismatch",
|
|
24805
|
+
"expired",
|
|
24806
|
+
"cid_mismatch",
|
|
24807
|
+
"authority_invalid",
|
|
24808
|
+
"proof_missing",
|
|
24809
|
+
"proof_invalid",
|
|
24810
|
+
"owner_mismatch",
|
|
24811
|
+
"audience_mismatch",
|
|
24812
|
+
"resources_mismatch",
|
|
24813
|
+
"unsupported",
|
|
24814
|
+
"activation_rejected"
|
|
24815
|
+
];
|
|
24816
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24817
|
+
constructor(reason, message) {
|
|
24818
|
+
super(message);
|
|
24819
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24820
|
+
this.reason = reason;
|
|
24821
|
+
}
|
|
24822
|
+
};
|
|
24823
|
+
function reject(reason, message) {
|
|
24824
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24825
|
+
}
|
|
24686
24826
|
var SERVICE_BY_SHORT_NAME = {
|
|
24687
24827
|
kv: "tinycloud.kv",
|
|
24688
24828
|
sql: "tinycloud.sql",
|
|
@@ -24829,6 +24969,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24829
24969
|
abilities
|
|
24830
24970
|
));
|
|
24831
24971
|
}
|
|
24972
|
+
return canonicalSignedAuthority({
|
|
24973
|
+
issuer: payload.iss,
|
|
24974
|
+
audience: payload.aud,
|
|
24975
|
+
expiry,
|
|
24976
|
+
proofs: [...payload.prf],
|
|
24977
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24978
|
+
}, permissions);
|
|
24979
|
+
}
|
|
24980
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24832
24981
|
if (permissions.length === 0) {
|
|
24833
24982
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24834
24983
|
}
|
|
@@ -24840,15 +24989,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24840
24989
|
actions: [...permission.actions],
|
|
24841
24990
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24842
24991
|
}));
|
|
24843
|
-
return {
|
|
24844
|
-
|
|
24845
|
-
|
|
24846
|
-
|
|
24847
|
-
|
|
24848
|
-
|
|
24849
|
-
|
|
24850
|
-
|
|
24851
|
-
|
|
24992
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24993
|
+
}
|
|
24994
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24995
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24996
|
+
function comparableSpace(space) {
|
|
24997
|
+
const match = PKH_SPACE.exec(space);
|
|
24998
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24999
|
+
}
|
|
25000
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
25001
|
+
const proof = delegation.siweProof;
|
|
25002
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
25003
|
+
reject(
|
|
25004
|
+
"proof_missing",
|
|
25005
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
25006
|
+
);
|
|
25007
|
+
}
|
|
25008
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
25009
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
25010
|
+
}
|
|
25011
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
25012
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
25013
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
25014
|
+
}
|
|
25015
|
+
let verified;
|
|
25016
|
+
try {
|
|
25017
|
+
verified = node.verifySessionGrant({
|
|
25018
|
+
delegationHeader: { Authorization: authorization },
|
|
25019
|
+
delegationCid: cid,
|
|
25020
|
+
spaceId: delegation.spaceId,
|
|
25021
|
+
address: delegation.ownerAddress,
|
|
25022
|
+
chainId: delegation.chainId,
|
|
25023
|
+
siwe: proof.siwe,
|
|
25024
|
+
signature: proof.signature
|
|
25025
|
+
});
|
|
25026
|
+
} catch (error) {
|
|
25027
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
25028
|
+
}
|
|
25029
|
+
const space = comparableSpace(delegation.spaceId);
|
|
25030
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
25031
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
25032
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
25033
|
+
}
|
|
25034
|
+
const groups = /* @__PURE__ */ new Map();
|
|
25035
|
+
for (const entry of verified.recap) {
|
|
25036
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
25037
|
+
const raw = entry.space === "encryption";
|
|
25038
|
+
if (raw) {
|
|
25039
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
25040
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
25041
|
+
}
|
|
25042
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
25043
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
25044
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
25045
|
+
}
|
|
25046
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
25047
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
25048
|
+
}
|
|
25049
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
25050
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, canonicalizeRecapCaveats2(caveats)]);
|
|
25051
|
+
const group = groups.get(key2) ?? {
|
|
25052
|
+
service,
|
|
25053
|
+
...raw ? {} : { space: entry.space },
|
|
25054
|
+
path: entry.path,
|
|
25055
|
+
actions: [],
|
|
25056
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25057
|
+
};
|
|
25058
|
+
for (const action of entry.actions) {
|
|
25059
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25060
|
+
}
|
|
25061
|
+
groups.set(key2, group);
|
|
25062
|
+
}
|
|
25063
|
+
return canonicalSignedAuthority({
|
|
25064
|
+
issuer: owner,
|
|
25065
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25066
|
+
audience: node.sessionDid,
|
|
25067
|
+
expiry: verified.expiresAt,
|
|
25068
|
+
proofs: []
|
|
25069
|
+
}, [...groups.values()]);
|
|
24852
25070
|
}
|
|
24853
25071
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24854
25072
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24884,46 +25102,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24884
25102
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24885
25103
|
const host = normalizedHost(options.host);
|
|
24886
25104
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24887
|
-
|
|
25105
|
+
reject(
|
|
25106
|
+
"host_mismatch",
|
|
24888
25107
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24889
25108
|
);
|
|
24890
25109
|
}
|
|
24891
25110
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24892
|
-
|
|
25111
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24893
25112
|
}
|
|
24894
25113
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24895
|
-
|
|
25114
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24896
25115
|
}
|
|
24897
25116
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24898
25117
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24899
|
-
|
|
25118
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24900
25119
|
}
|
|
24901
25120
|
const cid = node.computeDelegationCid(authorization);
|
|
24902
25121
|
if (cid !== delegation.cid) {
|
|
24903
|
-
|
|
25122
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25123
|
+
}
|
|
25124
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25125
|
+
let signed2;
|
|
25126
|
+
try {
|
|
25127
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25128
|
+
} catch (error) {
|
|
25129
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25130
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24904
25131
|
}
|
|
24905
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24906
25132
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24907
|
-
|
|
25133
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24908
25134
|
}
|
|
24909
25135
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24910
|
-
|
|
25136
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24911
25137
|
}
|
|
24912
25138
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24913
|
-
|
|
25139
|
+
reject(
|
|
25140
|
+
"audience_mismatch",
|
|
24914
25141
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24915
25142
|
);
|
|
24916
25143
|
}
|
|
24917
25144
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24918
|
-
|
|
25145
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
24919
25146
|
}
|
|
24920
|
-
|
|
24921
|
-
|
|
24922
|
-
|
|
25147
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25148
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
25149
|
+
}
|
|
25150
|
+
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
25151
|
+
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24923
25152
|
}
|
|
24924
25153
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24925
25154
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24926
|
-
|
|
25155
|
+
reject(
|
|
25156
|
+
"cid_mismatch",
|
|
24927
25157
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24928
25158
|
);
|
|
24929
25159
|
}
|
|
@@ -24953,22 +25183,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
24953
25183
|
})),
|
|
24954
25184
|
expiry: new Date(signed2.expiry),
|
|
24955
25185
|
delegateDID: signed2.audience,
|
|
24956
|
-
host
|
|
25186
|
+
host,
|
|
25187
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
24957
25188
|
};
|
|
24958
|
-
|
|
24959
|
-
|
|
24960
|
-
|
|
24961
|
-
|
|
25189
|
+
try {
|
|
25190
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25191
|
+
await node.useDelegation(installedCandidate);
|
|
25192
|
+
} else {
|
|
25193
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25194
|
+
}
|
|
25195
|
+
} catch (error) {
|
|
25196
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
24962
25197
|
}
|
|
24963
25198
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24964
25199
|
if (!installed) {
|
|
24965
|
-
|
|
25200
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
24966
25201
|
}
|
|
24967
25202
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
24968
25203
|
canonicalResourcesFromPortableDelegation(installed),
|
|
24969
25204
|
signed2.resources
|
|
24970
25205
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
24971
|
-
|
|
25206
|
+
reject(
|
|
25207
|
+
"activation_rejected",
|
|
24972
25208
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
24973
25209
|
);
|
|
24974
25210
|
}
|
|
@@ -25199,9 +25435,13 @@ export {
|
|
|
25199
25435
|
PrefixedKVService,
|
|
25200
25436
|
PrivateKeySigner,
|
|
25201
25437
|
ProtocolMismatchError,
|
|
25438
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25439
|
+
RuntimeDelegationRejectedError,
|
|
25202
25440
|
SECRET_NAME_RE,
|
|
25203
25441
|
SQLAction,
|
|
25204
25442
|
SQLService3 as SQLService,
|
|
25443
|
+
STORAGE_FULL_MESSAGE2 as STORAGE_FULL_MESSAGE,
|
|
25444
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE2 as STORAGE_WRITE_TOO_LARGE_MESSAGE,
|
|
25205
25445
|
SecretsService2 as SecretsService,
|
|
25206
25446
|
ServiceContext3 as ServiceContext,
|
|
25207
25447
|
SessionExpiredError2 as SessionExpiredError,
|
|
@@ -25277,6 +25517,7 @@ export {
|
|
|
25277
25517
|
isCapabilitySubset2 as isCapabilitySubset,
|
|
25278
25518
|
isEvmAddress,
|
|
25279
25519
|
isNetworkId,
|
|
25520
|
+
isStorageFullError2 as isStorageFullError,
|
|
25280
25521
|
loadManifest,
|
|
25281
25522
|
makePkhSpaceId2 as makePkhSpaceId,
|
|
25282
25523
|
makePublicSpaceId2 as makePublicSpaceId,
|