@tinycloud/node-sdk 2.2.0-beta.1 → 2.2.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-BSqBtkg3.d.cts +1553 -0
- package/dist/core-BSqBtkg3.d.ts +1553 -0
- package/dist/core.cjs +943 -190
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +4 -1423
- package/dist/core.d.ts +4 -1423
- package/dist/core.js +869 -102
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +946 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +864 -102
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/core.cjs
CHANGED
|
@@ -20,70 +20,77 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/core.ts
|
|
21
21
|
var core_exports = {};
|
|
22
22
|
__export(core_exports, {
|
|
23
|
-
ACCOUNT_REGISTRY_PATH: () =>
|
|
24
|
-
ACCOUNT_REGISTRY_SPACE: () =>
|
|
25
|
-
AutoApproveSpaceCreationHandler: () =>
|
|
26
|
-
CapabilityKeyRegistry: () =>
|
|
27
|
-
CapabilityKeyRegistryErrorCodes: () =>
|
|
28
|
-
DEFAULT_MANIFEST_SPACE: () =>
|
|
29
|
-
DEFAULT_MANIFEST_VERSION: () =>
|
|
30
|
-
DataVaultService: () =>
|
|
31
|
-
DatabaseHandle: () =>
|
|
23
|
+
ACCOUNT_REGISTRY_PATH: () => import_sdk_core9.ACCOUNT_REGISTRY_PATH,
|
|
24
|
+
ACCOUNT_REGISTRY_SPACE: () => import_sdk_core9.ACCOUNT_REGISTRY_SPACE,
|
|
25
|
+
AutoApproveSpaceCreationHandler: () => import_sdk_core8.AutoApproveSpaceCreationHandler,
|
|
26
|
+
CapabilityKeyRegistry: () => import_sdk_core15.CapabilityKeyRegistry,
|
|
27
|
+
CapabilityKeyRegistryErrorCodes: () => import_sdk_core15.CapabilityKeyRegistryErrorCodes,
|
|
28
|
+
DEFAULT_MANIFEST_SPACE: () => import_sdk_core9.DEFAULT_MANIFEST_SPACE,
|
|
29
|
+
DEFAULT_MANIFEST_VERSION: () => import_sdk_core9.DEFAULT_MANIFEST_VERSION,
|
|
30
|
+
DataVaultService: () => import_sdk_core13.DataVaultService,
|
|
31
|
+
DatabaseHandle: () => import_sdk_core11.DatabaseHandle,
|
|
32
32
|
DelegatedAccess: () => DelegatedAccess,
|
|
33
|
-
DelegationErrorCodes: () =>
|
|
34
|
-
DelegationManager: () =>
|
|
35
|
-
DuckDbAction: () =>
|
|
36
|
-
DuckDbDatabaseHandle: () =>
|
|
37
|
-
DuckDbService: () =>
|
|
33
|
+
DelegationErrorCodes: () => import_sdk_core14.DelegationErrorCodes,
|
|
34
|
+
DelegationManager: () => import_sdk_core14.DelegationManager,
|
|
35
|
+
DuckDbAction: () => import_sdk_core12.DuckDbAction,
|
|
36
|
+
DuckDbDatabaseHandle: () => import_sdk_core12.DuckDbDatabaseHandle,
|
|
37
|
+
DuckDbService: () => import_sdk_core12.DuckDbService,
|
|
38
38
|
FileSessionStorage: () => FileSessionStorage,
|
|
39
|
-
KVService: () =>
|
|
40
|
-
ManifestValidationError: () =>
|
|
39
|
+
KVService: () => import_sdk_core10.KVService,
|
|
40
|
+
ManifestValidationError: () => import_sdk_core9.ManifestValidationError,
|
|
41
41
|
MemorySessionStorage: () => MemorySessionStorage,
|
|
42
42
|
NodeUserAuthorization: () => NodeUserAuthorization,
|
|
43
|
-
PermissionNotInManifestError: () =>
|
|
44
|
-
PrefixedKVService: () =>
|
|
45
|
-
ProtocolMismatchError: () =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
PermissionNotInManifestError: () => import_sdk_core9.PermissionNotInManifestError,
|
|
44
|
+
PrefixedKVService: () => import_sdk_core10.PrefixedKVService,
|
|
45
|
+
ProtocolMismatchError: () => import_sdk_core17.ProtocolMismatchError,
|
|
46
|
+
SECRET_NAME_RE: () => import_sdk_core13.SECRET_NAME_RE,
|
|
47
|
+
SQLAction: () => import_sdk_core11.SQLAction,
|
|
48
|
+
SQLService: () => import_sdk_core11.SQLService,
|
|
49
|
+
SecretsService: () => import_sdk_core13.SecretsService,
|
|
50
|
+
ServiceContext: () => import_sdk_core18.ServiceContext,
|
|
51
|
+
SessionExpiredError: () => import_sdk_core9.SessionExpiredError,
|
|
52
|
+
SharingService: () => import_sdk_core14.SharingService,
|
|
53
|
+
SilentNotificationHandler: () => import_sdk_core8.SilentNotificationHandler,
|
|
54
|
+
Space: () => import_sdk_core16.Space,
|
|
55
|
+
SpaceErrorCodes: () => import_sdk_core16.SpaceErrorCodes,
|
|
56
|
+
SpaceService: () => import_sdk_core16.SpaceService,
|
|
57
|
+
TinyCloud: () => import_sdk_core7.TinyCloud,
|
|
56
58
|
TinyCloudNode: () => TinyCloudNode,
|
|
57
|
-
UnsupportedFeatureError: () =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
UnsupportedFeatureError: () => import_sdk_core17.UnsupportedFeatureError,
|
|
60
|
+
VAULT_PERMISSION_SERVICE: () => import_sdk_core9.VAULT_PERMISSION_SERVICE,
|
|
61
|
+
VaultHeaders: () => import_sdk_core13.VaultHeaders,
|
|
62
|
+
VaultPublicSpaceKVActions: () => import_sdk_core13.VaultPublicSpaceKVActions,
|
|
63
|
+
VersionCheckError: () => import_sdk_core17.VersionCheckError,
|
|
61
64
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
62
|
-
buildSpaceUri: () =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
buildSpaceUri: () => import_sdk_core16.buildSpaceUri,
|
|
66
|
+
canonicalizeSecretScope: () => import_sdk_core13.canonicalizeSecretScope,
|
|
67
|
+
checkNodeInfo: () => import_sdk_core17.checkNodeInfo,
|
|
68
|
+
composeManifestRequest: () => import_sdk_core9.composeManifestRequest,
|
|
69
|
+
createCapabilityKeyRegistry: () => import_sdk_core15.createCapabilityKeyRegistry,
|
|
70
|
+
createSharingService: () => import_sdk_core14.createSharingService,
|
|
71
|
+
createSpaceService: () => import_sdk_core16.createSpaceService,
|
|
72
|
+
createVaultCrypto: () => import_sdk_core13.createVaultCrypto,
|
|
69
73
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
70
74
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
71
|
-
defaultSpaceCreationHandler: () =>
|
|
75
|
+
defaultSpaceCreationHandler: () => import_sdk_core8.defaultSpaceCreationHandler,
|
|
72
76
|
deserializeDelegation: () => deserializeDelegation,
|
|
73
|
-
expandActionShortNames: () =>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
expandActionShortNames: () => import_sdk_core9.expandActionShortNames,
|
|
78
|
+
expandPermissionEntries: () => import_sdk_core9.expandPermissionEntries,
|
|
79
|
+
expandPermissionEntry: () => import_sdk_core9.expandPermissionEntry,
|
|
80
|
+
isCapabilitySubset: () => import_sdk_core9.isCapabilitySubset,
|
|
81
|
+
loadManifest: () => import_sdk_core9.loadManifest,
|
|
82
|
+
makePublicSpaceId: () => import_sdk_core16.makePublicSpaceId,
|
|
83
|
+
parseExpiry: () => import_sdk_core9.parseExpiry,
|
|
84
|
+
parseSpaceUri: () => import_sdk_core16.parseSpaceUri,
|
|
85
|
+
resolveManifest: () => import_sdk_core9.resolveManifest,
|
|
86
|
+
resolveSecretPath: () => import_sdk_core13.resolveSecretPath,
|
|
87
|
+
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core9.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
81
88
|
serializeDelegation: () => serializeDelegation,
|
|
82
|
-
validateManifest: () =>
|
|
89
|
+
validateManifest: () => import_sdk_core9.validateManifest
|
|
83
90
|
});
|
|
84
91
|
module.exports = __toCommonJS(core_exports);
|
|
85
|
-
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
86
92
|
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
93
|
+
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
87
94
|
|
|
88
95
|
// src/storage/MemorySessionStorage.ts
|
|
89
96
|
var MemorySessionStorage = class {
|
|
@@ -336,12 +343,12 @@ var NodeUserAuthorization = class {
|
|
|
336
343
|
]
|
|
337
344
|
}
|
|
338
345
|
};
|
|
339
|
-
this.sessionExpirationMs = config.sessionExpirationMs ??
|
|
346
|
+
this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core2.EXPIRY.SESSION_MS;
|
|
340
347
|
this.autoCreateSpace = config.autoCreateSpace ?? false;
|
|
341
348
|
this.spaceCreationHandler = config.spaceCreationHandler;
|
|
342
|
-
this.tinycloudHosts = config.tinycloudHosts
|
|
343
|
-
|
|
344
|
-
|
|
349
|
+
this.tinycloudHosts = config.tinycloudHosts;
|
|
350
|
+
this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
|
|
351
|
+
this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
|
|
345
352
|
this.enablePublicSpace = config.enablePublicSpace ?? true;
|
|
346
353
|
this.nonce = config.nonce;
|
|
347
354
|
this.siweConfig = config.siweConfig;
|
|
@@ -362,6 +369,9 @@ var NodeUserAuthorization = class {
|
|
|
362
369
|
get capabilityRequest() {
|
|
363
370
|
return this.getCapabilityRequest();
|
|
364
371
|
}
|
|
372
|
+
get hosts() {
|
|
373
|
+
return this.tinycloudHosts ? [...this.tinycloudHosts] : [];
|
|
374
|
+
}
|
|
365
375
|
/**
|
|
366
376
|
* Install or replace the stored manifest. Takes effect on the next
|
|
367
377
|
* `signIn()` call — the current session (if any) is not touched.
|
|
@@ -386,6 +396,26 @@ var NodeUserAuthorization = class {
|
|
|
386
396
|
get tinyCloudSession() {
|
|
387
397
|
return this._tinyCloudSession;
|
|
388
398
|
}
|
|
399
|
+
async resolveTinyCloudHostsForSignIn(address, chainId) {
|
|
400
|
+
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const subject = `did:pkh:eip155:${chainId}:${address}`;
|
|
404
|
+
const resolved = await (0, import_sdk_core2.resolveTinyCloudHosts)(subject, {
|
|
405
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
406
|
+
fallbackHosts: this.tinycloudFallbackHosts
|
|
407
|
+
});
|
|
408
|
+
this.tinycloudHosts = resolved.hosts;
|
|
409
|
+
}
|
|
410
|
+
requireTinyCloudHosts() {
|
|
411
|
+
if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
|
|
412
|
+
throw new Error("TinyCloud hosts have not been resolved. Call signIn() first.");
|
|
413
|
+
}
|
|
414
|
+
return this.tinycloudHosts;
|
|
415
|
+
}
|
|
416
|
+
get primaryTinyCloudHost() {
|
|
417
|
+
return this.requireTinyCloudHosts()[0];
|
|
418
|
+
}
|
|
389
419
|
get nodeFeatures() {
|
|
390
420
|
return this._nodeFeatures;
|
|
391
421
|
}
|
|
@@ -517,7 +547,7 @@ var NodeUserAuthorization = class {
|
|
|
517
547
|
if (!this._tinyCloudSession || !this._address || !this._chainId) {
|
|
518
548
|
throw new Error("Must be signed in to host space");
|
|
519
549
|
}
|
|
520
|
-
const host = this.
|
|
550
|
+
const host = this.primaryTinyCloudHost;
|
|
521
551
|
const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
|
|
522
552
|
const peerId = await (0, import_sdk_core2.fetchPeerId)(host, spaceId);
|
|
523
553
|
const siwe = this.wasm.generateHostSIWEMessage({
|
|
@@ -559,7 +589,7 @@ var NodeUserAuthorization = class {
|
|
|
559
589
|
if (!this._tinyCloudSession) {
|
|
560
590
|
throw new Error("Must be signed in to ensure space exists");
|
|
561
591
|
}
|
|
562
|
-
const host = this.
|
|
592
|
+
const host = this.primaryTinyCloudHost;
|
|
563
593
|
const primarySpaceId = this._tinyCloudSession.spaceId;
|
|
564
594
|
const result = await (0, import_sdk_core2.activateSessionWithHost)(
|
|
565
595
|
host,
|
|
@@ -668,6 +698,7 @@ var NodeUserAuthorization = class {
|
|
|
668
698
|
this._chainId = await this.signer.getChainId();
|
|
669
699
|
const address = this.wasm.ensureEip55(this._address);
|
|
670
700
|
const chainId = this._chainId;
|
|
701
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
671
702
|
const keyId = `session-${Date.now()}`;
|
|
672
703
|
this.sessionManager.renameSessionKeyId("default", keyId);
|
|
673
704
|
const jwkString = this.sessionManager.jwk(keyId);
|
|
@@ -746,7 +777,7 @@ var NodeUserAuthorization = class {
|
|
|
746
777
|
this._address = address;
|
|
747
778
|
this._chainId = chainId;
|
|
748
779
|
const nodeInfo = await (0, import_sdk_core2.checkNodeInfo)(
|
|
749
|
-
this.
|
|
780
|
+
this.primaryTinyCloudHost,
|
|
750
781
|
this.wasm.protocolVersion()
|
|
751
782
|
);
|
|
752
783
|
this._nodeFeatures = nodeInfo.features;
|
|
@@ -862,6 +893,7 @@ var NodeUserAuthorization = class {
|
|
|
862
893
|
});
|
|
863
894
|
const address = this.wasm.ensureEip55(await this.signer.getAddress());
|
|
864
895
|
const chainId = await this.signer.getChainId();
|
|
896
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
865
897
|
const clientSession = {
|
|
866
898
|
address,
|
|
867
899
|
walletAddress: address,
|
|
@@ -911,7 +943,7 @@ var NodeUserAuthorization = class {
|
|
|
911
943
|
this._address = address;
|
|
912
944
|
this._chainId = chainId;
|
|
913
945
|
const nodeInfo = await (0, import_sdk_core2.checkNodeInfo)(
|
|
914
|
-
this.
|
|
946
|
+
this.primaryTinyCloudHost,
|
|
915
947
|
this.wasm.protocolVersion()
|
|
916
948
|
);
|
|
917
949
|
this._nodeFeatures = nodeInfo.features;
|
|
@@ -994,7 +1026,7 @@ var NodeUserAuthorization = class {
|
|
|
994
1026
|
};
|
|
995
1027
|
|
|
996
1028
|
// src/TinyCloudNode.ts
|
|
997
|
-
var
|
|
1029
|
+
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
998
1030
|
|
|
999
1031
|
// src/DelegatedAccess.ts
|
|
1000
1032
|
var import_sdk_core3 = require("@tinycloud/sdk-core");
|
|
@@ -1072,6 +1104,24 @@ var DelegatedAccess = class {
|
|
|
1072
1104
|
get hooks() {
|
|
1073
1105
|
return this._hooks;
|
|
1074
1106
|
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Export the handles needed to rehydrate this activated delegation via
|
|
1109
|
+
* `TinyCloudNode.restoreSession(...)` in another process or after a
|
|
1110
|
+
* restart.
|
|
1111
|
+
*
|
|
1112
|
+
* See `RestorableSession` for lifetime caveats.
|
|
1113
|
+
*/
|
|
1114
|
+
get restorable() {
|
|
1115
|
+
return {
|
|
1116
|
+
delegationHeader: this.session.delegationHeader,
|
|
1117
|
+
delegationCid: this.session.delegationCid,
|
|
1118
|
+
spaceId: this.session.spaceId,
|
|
1119
|
+
jwk: this.session.jwk,
|
|
1120
|
+
verificationMethod: this.session.verificationMethod,
|
|
1121
|
+
address: this.session.address,
|
|
1122
|
+
chainId: this.session.chainId
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1075
1125
|
};
|
|
1076
1126
|
|
|
1077
1127
|
// src/keys/WasmKeyProvider.ts
|
|
@@ -1181,9 +1231,10 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
|
1181
1231
|
}
|
|
1182
1232
|
return entries;
|
|
1183
1233
|
}
|
|
1234
|
+
var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core4.EXPIRY.SESSION_MS;
|
|
1184
1235
|
function resolveExpiryMs(expiry) {
|
|
1185
1236
|
if (expiry === void 0) {
|
|
1186
|
-
return
|
|
1237
|
+
return DEFAULT_DELEGATION_EXPIRY_MS;
|
|
1187
1238
|
}
|
|
1188
1239
|
if (typeof expiry === "number") {
|
|
1189
1240
|
if (!Number.isFinite(expiry) || expiry <= 0) {
|
|
@@ -1209,8 +1260,151 @@ function extractSiweExpiration(siwe) {
|
|
|
1209
1260
|
return d;
|
|
1210
1261
|
}
|
|
1211
1262
|
|
|
1263
|
+
// src/NodeSecretsService.ts
|
|
1264
|
+
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
1265
|
+
var SECRETS_SPACE = "secrets";
|
|
1266
|
+
function ok() {
|
|
1267
|
+
return { ok: true, data: void 0 };
|
|
1268
|
+
}
|
|
1269
|
+
function secretsError(code, message, cause) {
|
|
1270
|
+
return {
|
|
1271
|
+
ok: false,
|
|
1272
|
+
error: {
|
|
1273
|
+
code,
|
|
1274
|
+
service: "secrets",
|
|
1275
|
+
message,
|
|
1276
|
+
...cause ? { cause } : {}
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
function displayActionUrn(action) {
|
|
1281
|
+
return action === "put" ? "tinycloud.vault/write" : "tinycloud.vault/delete";
|
|
1282
|
+
}
|
|
1283
|
+
function kvActionUrn(action) {
|
|
1284
|
+
return `tinycloud.kv/${action}`;
|
|
1285
|
+
}
|
|
1286
|
+
function vaultMutationAction(action) {
|
|
1287
|
+
return action === "put" ? "write" : "delete";
|
|
1288
|
+
}
|
|
1289
|
+
function secretPermissionEntries(name, options, action) {
|
|
1290
|
+
const secretPath = (0, import_sdk_core5.resolveSecretPath)(name, options);
|
|
1291
|
+
return [
|
|
1292
|
+
{
|
|
1293
|
+
service: "tinycloud.vault",
|
|
1294
|
+
space: SECRETS_SPACE,
|
|
1295
|
+
path: secretPath.vaultKey,
|
|
1296
|
+
actions: [vaultMutationAction(action)],
|
|
1297
|
+
skipPrefix: true
|
|
1298
|
+
}
|
|
1299
|
+
];
|
|
1300
|
+
}
|
|
1301
|
+
function isSecretsSpace(space) {
|
|
1302
|
+
return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
|
|
1303
|
+
}
|
|
1304
|
+
var NodeSecretsService = class {
|
|
1305
|
+
constructor(config) {
|
|
1306
|
+
this.config = config;
|
|
1307
|
+
this.shouldRestoreUnlock = false;
|
|
1308
|
+
}
|
|
1309
|
+
get vault() {
|
|
1310
|
+
return this.service.vault;
|
|
1311
|
+
}
|
|
1312
|
+
get isUnlocked() {
|
|
1313
|
+
return this.service.isUnlocked;
|
|
1314
|
+
}
|
|
1315
|
+
async unlock(signer) {
|
|
1316
|
+
const effectiveSigner = signer ?? this.config.getUnlockSigner?.();
|
|
1317
|
+
if (effectiveSigner !== void 0) {
|
|
1318
|
+
this.unlockSigner = effectiveSigner;
|
|
1319
|
+
}
|
|
1320
|
+
const result = await this.service.unlock(effectiveSigner);
|
|
1321
|
+
if (result.ok) {
|
|
1322
|
+
this.shouldRestoreUnlock = true;
|
|
1323
|
+
}
|
|
1324
|
+
return result;
|
|
1325
|
+
}
|
|
1326
|
+
lock() {
|
|
1327
|
+
this.shouldRestoreUnlock = false;
|
|
1328
|
+
this.service.lock();
|
|
1329
|
+
}
|
|
1330
|
+
get(name, options) {
|
|
1331
|
+
return options === void 0 ? this.service.get(name) : this.service.get(name, options);
|
|
1332
|
+
}
|
|
1333
|
+
async put(name, value, options) {
|
|
1334
|
+
const permission = await this.ensureMutationPermission(name, options, "put");
|
|
1335
|
+
if (!permission.ok) return permission;
|
|
1336
|
+
return options === void 0 ? this.service.put(name, value) : this.service.put(name, value, options);
|
|
1337
|
+
}
|
|
1338
|
+
async delete(name, options) {
|
|
1339
|
+
const permission = await this.ensureMutationPermission(name, options, "del");
|
|
1340
|
+
if (!permission.ok) return permission;
|
|
1341
|
+
return options === void 0 ? this.service.delete(name) : this.service.delete(name, options);
|
|
1342
|
+
}
|
|
1343
|
+
list(options) {
|
|
1344
|
+
return options === void 0 ? this.service.list() : this.service.list(options);
|
|
1345
|
+
}
|
|
1346
|
+
get service() {
|
|
1347
|
+
return this.config.getService();
|
|
1348
|
+
}
|
|
1349
|
+
async ensureMutationPermission(name, options, action) {
|
|
1350
|
+
let permissionEntries;
|
|
1351
|
+
try {
|
|
1352
|
+
permissionEntries = secretPermissionEntries(name, options, action);
|
|
1353
|
+
} catch (error) {
|
|
1354
|
+
return secretsError(
|
|
1355
|
+
import_sdk_core5.ErrorCodes.INVALID_INPUT,
|
|
1356
|
+
error instanceof Error ? error.message : String(error),
|
|
1357
|
+
error instanceof Error ? error : void 0
|
|
1358
|
+
);
|
|
1359
|
+
}
|
|
1360
|
+
if (this.hasMutationPermission(name, options, action)) {
|
|
1361
|
+
return ok();
|
|
1362
|
+
}
|
|
1363
|
+
if (!this.config.canEscalate()) {
|
|
1364
|
+
return secretsError(
|
|
1365
|
+
import_sdk_core5.ErrorCodes.PERMISSION_DENIED,
|
|
1366
|
+
`Cannot autosign ${displayActionUrn(action)} for ${name}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
1367
|
+
);
|
|
1368
|
+
}
|
|
1369
|
+
try {
|
|
1370
|
+
await this.config.grantPermissions(permissionEntries);
|
|
1371
|
+
return this.restoreUnlockAfterEscalation();
|
|
1372
|
+
} catch (error) {
|
|
1373
|
+
return secretsError(
|
|
1374
|
+
import_sdk_core5.ErrorCodes.PERMISSION_DENIED,
|
|
1375
|
+
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${name} failed.`,
|
|
1376
|
+
error instanceof Error ? error : void 0
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
async restoreUnlockAfterEscalation() {
|
|
1381
|
+
if (!this.shouldRestoreUnlock) {
|
|
1382
|
+
return ok();
|
|
1383
|
+
}
|
|
1384
|
+
return this.service.unlock(this.unlockSigner);
|
|
1385
|
+
}
|
|
1386
|
+
hasMutationPermission(name, options, action) {
|
|
1387
|
+
const manifest = this.config.getManifest();
|
|
1388
|
+
if (manifest === void 0) {
|
|
1389
|
+
return false;
|
|
1390
|
+
}
|
|
1391
|
+
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
1392
|
+
const requiredAction = kvActionUrn(action);
|
|
1393
|
+
const secretPath = (0, import_sdk_core5.resolveSecretPath)(name, options);
|
|
1394
|
+
return manifests.some((entry) => {
|
|
1395
|
+
const resolved = (0, import_sdk_core5.resolveManifest)(entry);
|
|
1396
|
+
return ["keys", "vault"].every(
|
|
1397
|
+
(base) => resolved.resources.some(
|
|
1398
|
+
(resource) => resource.service === "tinycloud.kv" && isSecretsSpace(resource.space) && resource.path === secretPath.permissionPaths[base] && resource.actions.includes(requiredAction)
|
|
1399
|
+
)
|
|
1400
|
+
);
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1212
1405
|
// src/TinyCloudNode.ts
|
|
1213
1406
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
1407
|
+
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core6.EXPIRY.SESSION_MS;
|
|
1214
1408
|
var _TinyCloudNode = class _TinyCloudNode {
|
|
1215
1409
|
/**
|
|
1216
1410
|
* Create a new TinyCloudNode instance.
|
|
@@ -1240,6 +1434,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1240
1434
|
this.auth = null;
|
|
1241
1435
|
this.tc = null;
|
|
1242
1436
|
this._chainId = 1;
|
|
1437
|
+
this.runtimePermissionGrants = [];
|
|
1438
|
+
this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
|
|
1439
|
+
return this.wasmBindings.invoke(
|
|
1440
|
+
this.selectInvocationSession(session, service, path, action),
|
|
1441
|
+
service,
|
|
1442
|
+
path,
|
|
1443
|
+
action,
|
|
1444
|
+
facts
|
|
1445
|
+
);
|
|
1446
|
+
};
|
|
1447
|
+
this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
|
|
1448
|
+
if (!this.wasmBindings.invokeAny) {
|
|
1449
|
+
throw new Error("WASM binding does not support invokeAny");
|
|
1450
|
+
}
|
|
1451
|
+
const grant = this.findGrantForOperations(
|
|
1452
|
+
entries.map((entry) => ({
|
|
1453
|
+
spaceId: entry.spaceId,
|
|
1454
|
+
service: this.invocationServiceName(entry.service),
|
|
1455
|
+
path: entry.path,
|
|
1456
|
+
action: entry.action
|
|
1457
|
+
}))
|
|
1458
|
+
);
|
|
1459
|
+
return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
|
|
1460
|
+
};
|
|
1461
|
+
this.explicitHost = config.host;
|
|
1243
1462
|
this.config = {
|
|
1244
1463
|
...config,
|
|
1245
1464
|
host: config.host ?? DEFAULT_HOST
|
|
@@ -1266,23 +1485,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1266
1485
|
throw new Error("Failed to get session key JWK");
|
|
1267
1486
|
}
|
|
1268
1487
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
1269
|
-
this._capabilityRegistry = new
|
|
1488
|
+
this._capabilityRegistry = new import_sdk_core6.CapabilityKeyRegistry();
|
|
1270
1489
|
this._keyProvider = new WasmKeyProvider({
|
|
1271
1490
|
sessionManager: this.sessionManager
|
|
1272
1491
|
});
|
|
1273
|
-
this.notificationHandler = config.notificationHandler ?? new
|
|
1274
|
-
this._sharingService = new
|
|
1492
|
+
this.notificationHandler = config.notificationHandler ?? new import_sdk_core6.SilentNotificationHandler();
|
|
1493
|
+
this._sharingService = new import_sdk_core6.SharingService({
|
|
1275
1494
|
hosts: [this.config.host],
|
|
1276
1495
|
// session: undefined - not needed for receive()
|
|
1277
|
-
invoke: this.
|
|
1496
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1278
1497
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1279
1498
|
keyProvider: this._keyProvider,
|
|
1280
1499
|
registry: this._capabilityRegistry,
|
|
1281
1500
|
// delegationManager: undefined - not needed for receive()
|
|
1282
1501
|
createKVService: (config2) => {
|
|
1283
1502
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
1284
|
-
const kvService = new
|
|
1285
|
-
const kvContext = new
|
|
1503
|
+
const kvService = new import_sdk_core6.KVService({ prefix });
|
|
1504
|
+
const kvContext = new import_sdk_core6.ServiceContext({
|
|
1286
1505
|
invoke: config2.invoke,
|
|
1287
1506
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
1288
1507
|
hosts: config2.hosts
|
|
@@ -1321,7 +1540,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1321
1540
|
* @internal
|
|
1322
1541
|
*/
|
|
1323
1542
|
setupAuth(config) {
|
|
1324
|
-
const host = this.config.host;
|
|
1325
1543
|
this.auth = new NodeUserAuthorization({
|
|
1326
1544
|
signer: this.signer,
|
|
1327
1545
|
signStrategy: { type: "auto-sign" },
|
|
@@ -1329,8 +1547,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1329
1547
|
sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
|
|
1330
1548
|
domain: this.siweDomain,
|
|
1331
1549
|
spacePrefix: config.prefix,
|
|
1332
|
-
sessionExpirationMs: config.sessionExpirationMs ??
|
|
1333
|
-
tinycloudHosts: [
|
|
1550
|
+
sessionExpirationMs: config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
1551
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
1552
|
+
tinycloudRegistryUrl: config.tinycloudRegistryUrl,
|
|
1553
|
+
tinycloudFallbackHosts: config.tinycloudFallbackHosts,
|
|
1334
1554
|
autoCreateSpace: config.autoCreateSpace,
|
|
1335
1555
|
enablePublicSpace: config.enablePublicSpace ?? true,
|
|
1336
1556
|
spaceCreationHandler: config.spaceCreationHandler,
|
|
@@ -1340,10 +1560,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1340
1560
|
capabilityRequest: config.capabilityRequest,
|
|
1341
1561
|
includeAccountRegistryPermissions: config.includeAccountRegistryPermissions
|
|
1342
1562
|
});
|
|
1343
|
-
this.tc = new
|
|
1344
|
-
invokeAny: this.
|
|
1563
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1564
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1345
1565
|
});
|
|
1346
1566
|
}
|
|
1567
|
+
syncResolvedHostFromAuth() {
|
|
1568
|
+
const host = this.auth?.hosts[0];
|
|
1569
|
+
if (host) {
|
|
1570
|
+
this.config.host = host;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1347
1573
|
/**
|
|
1348
1574
|
* Install or replace the manifest that drives the SIWE recap at
|
|
1349
1575
|
* sign-in. Takes effect on the next `signIn()` call — the current
|
|
@@ -1381,6 +1607,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1381
1607
|
get capabilityRequest() {
|
|
1382
1608
|
return this.auth?.capabilityRequest;
|
|
1383
1609
|
}
|
|
1610
|
+
get hosts() {
|
|
1611
|
+
const authHosts = this.auth?.hosts ?? [];
|
|
1612
|
+
return authHosts.length > 0 ? authHosts : [this.config.host];
|
|
1613
|
+
}
|
|
1384
1614
|
/**
|
|
1385
1615
|
* Get the primary identity DID for this user.
|
|
1386
1616
|
* - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
|
|
@@ -1451,8 +1681,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1451
1681
|
this._sql = void 0;
|
|
1452
1682
|
this._duckdb = void 0;
|
|
1453
1683
|
this._hooks = void 0;
|
|
1684
|
+
this._vault = void 0;
|
|
1685
|
+
this._baseSecrets = void 0;
|
|
1686
|
+
this._secrets = void 0;
|
|
1687
|
+
this._spaceService = void 0;
|
|
1454
1688
|
this._serviceContext = void 0;
|
|
1689
|
+
this.runtimePermissionGrants = [];
|
|
1455
1690
|
await this.tc.signIn(options);
|
|
1691
|
+
this.syncResolvedHostFromAuth();
|
|
1456
1692
|
this.initializeServices();
|
|
1457
1693
|
await this.writeManifestRegistryRecords();
|
|
1458
1694
|
this.notificationHandler.success("Successfully signed in");
|
|
@@ -1471,8 +1707,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1471
1707
|
if (!this.auth || !this.signer) {
|
|
1472
1708
|
throw new Error("Manifest registry write requires wallet mode");
|
|
1473
1709
|
}
|
|
1474
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
1475
|
-
await this.
|
|
1710
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core6.ACCOUNT_REGISTRY_SPACE);
|
|
1711
|
+
await this.ensureOwnedSpaceHosted(accountSpaceId);
|
|
1476
1712
|
const accountKV = this.spaces.get(accountSpaceId).kv;
|
|
1477
1713
|
for (const record of request.registryRecords) {
|
|
1478
1714
|
const result = await accountKV.put(record.key, {
|
|
@@ -1487,6 +1723,39 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1487
1723
|
}
|
|
1488
1724
|
}
|
|
1489
1725
|
}
|
|
1726
|
+
async ensureOwnedSpaceHosted(spaceId) {
|
|
1727
|
+
if (!this.auth) {
|
|
1728
|
+
throw new Error("Owned space hosting requires wallet mode");
|
|
1729
|
+
}
|
|
1730
|
+
const session = this.auth.tinyCloudSession;
|
|
1731
|
+
if (!session) {
|
|
1732
|
+
throw new Error("Owned space hosting requires an active session");
|
|
1733
|
+
}
|
|
1734
|
+
const host = this.hosts[0] ?? this.config.host;
|
|
1735
|
+
if (!host) {
|
|
1736
|
+
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
1737
|
+
}
|
|
1738
|
+
const activation = await (0, import_sdk_core6.activateSessionWithHost)(host, session.delegationHeader);
|
|
1739
|
+
if (activation.success && !activation.skipped?.includes(spaceId)) {
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
if (!activation.success && activation.status !== 404) {
|
|
1743
|
+
throw new Error(
|
|
1744
|
+
`Failed to check owned space ${spaceId}: ${activation.error ?? activation.status}`
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
const created = await this.auth.hostOwnedSpace(spaceId);
|
|
1748
|
+
if (!created) {
|
|
1749
|
+
throw new Error(`Failed to create owned space: ${spaceId}`);
|
|
1750
|
+
}
|
|
1751
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1752
|
+
const retry = await (0, import_sdk_core6.activateSessionWithHost)(host, session.delegationHeader);
|
|
1753
|
+
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
1754
|
+
throw new Error(
|
|
1755
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.error ?? "space was skipped"}`
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1490
1759
|
/**
|
|
1491
1760
|
* Restore a previously established session from stored delegation data.
|
|
1492
1761
|
*
|
|
@@ -1502,29 +1771,34 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1502
1771
|
this._sql = void 0;
|
|
1503
1772
|
this._duckdb = void 0;
|
|
1504
1773
|
this._hooks = void 0;
|
|
1774
|
+
this._vault = void 0;
|
|
1775
|
+
this._baseSecrets = void 0;
|
|
1776
|
+
this._secrets = void 0;
|
|
1777
|
+
this._spaceService = void 0;
|
|
1505
1778
|
this._serviceContext = void 0;
|
|
1779
|
+
this.runtimePermissionGrants = [];
|
|
1506
1780
|
if (sessionData.address) {
|
|
1507
1781
|
this._address = sessionData.address;
|
|
1508
1782
|
}
|
|
1509
1783
|
if (sessionData.chainId) {
|
|
1510
1784
|
this._chainId = sessionData.chainId;
|
|
1511
1785
|
}
|
|
1512
|
-
this._serviceContext = new
|
|
1513
|
-
invoke: this.
|
|
1514
|
-
invokeAny: this.
|
|
1786
|
+
this._serviceContext = new import_sdk_core6.ServiceContext({
|
|
1787
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1788
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
1515
1789
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1516
1790
|
hosts: [this.config.host]
|
|
1517
1791
|
});
|
|
1518
|
-
this._kv = new
|
|
1792
|
+
this._kv = new import_sdk_core6.KVService({});
|
|
1519
1793
|
this._kv.initialize(this._serviceContext);
|
|
1520
1794
|
this._serviceContext.registerService("kv", this._kv);
|
|
1521
|
-
this._sql = new
|
|
1795
|
+
this._sql = new import_sdk_core6.SQLService({});
|
|
1522
1796
|
this._sql.initialize(this._serviceContext);
|
|
1523
1797
|
this._serviceContext.registerService("sql", this._sql);
|
|
1524
|
-
this._duckdb = new
|
|
1798
|
+
this._duckdb = new import_sdk_core6.DuckDbService({});
|
|
1525
1799
|
this._duckdb.initialize(this._serviceContext);
|
|
1526
1800
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1527
|
-
this._hooks = new
|
|
1801
|
+
this._hooks = new import_sdk_core6.HooksService({});
|
|
1528
1802
|
this._hooks.initialize(this._serviceContext);
|
|
1529
1803
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1530
1804
|
const serviceSession = {
|
|
@@ -1535,41 +1809,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1535
1809
|
jwk: sessionData.jwk
|
|
1536
1810
|
};
|
|
1537
1811
|
this._serviceContext.setSession(serviceSession);
|
|
1538
|
-
|
|
1539
|
-
const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
|
|
1540
|
-
vault_encrypt: wasm.vault_encrypt,
|
|
1541
|
-
vault_decrypt: wasm.vault_decrypt,
|
|
1542
|
-
vault_derive_key: wasm.vault_derive_key,
|
|
1543
|
-
vault_x25519_from_seed: wasm.vault_x25519_from_seed,
|
|
1544
|
-
vault_x25519_dh: wasm.vault_x25519_dh,
|
|
1545
|
-
vault_random_bytes: wasm.vault_random_bytes,
|
|
1546
|
-
vault_sha256: wasm.vault_sha256
|
|
1547
|
-
});
|
|
1548
|
-
const self = this;
|
|
1549
|
-
this._vault = new import_sdk_core5.DataVaultService({
|
|
1550
|
-
spaceId: sessionData.spaceId,
|
|
1551
|
-
crypto: vaultCrypto,
|
|
1552
|
-
tc: {
|
|
1553
|
-
kv: this._kv,
|
|
1554
|
-
ensurePublicSpace: async () => {
|
|
1555
|
-
try {
|
|
1556
|
-
await self.ensurePublicSpace();
|
|
1557
|
-
return { ok: true, data: void 0 };
|
|
1558
|
-
} catch (error) {
|
|
1559
|
-
return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
|
|
1560
|
-
}
|
|
1561
|
-
},
|
|
1562
|
-
get publicKV() {
|
|
1563
|
-
return self._publicKV ?? self.tc.publicKV;
|
|
1564
|
-
},
|
|
1565
|
-
readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
|
|
1566
|
-
makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
|
|
1567
|
-
did: this.did,
|
|
1568
|
-
address: sessionData.address ?? this._address ?? "",
|
|
1569
|
-
chainId: sessionData.chainId ?? this._chainId,
|
|
1570
|
-
hosts: [this.config.host]
|
|
1571
|
-
}
|
|
1572
|
-
});
|
|
1812
|
+
this._vault = this.createVaultService(sessionData.spaceId, this._kv);
|
|
1573
1813
|
this._vault.initialize(this._serviceContext);
|
|
1574
1814
|
this._serviceContext.registerService("vault", this._vault);
|
|
1575
1815
|
this.initializeV2Services(serviceSession);
|
|
@@ -1604,7 +1844,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1604
1844
|
throw new Error("Wallet already connected. Cannot connect another wallet.");
|
|
1605
1845
|
}
|
|
1606
1846
|
const prefix = options?.prefix ?? "default";
|
|
1607
|
-
const host = this.config.host;
|
|
1608
1847
|
if (!_TinyCloudNode.nodeDefaults) {
|
|
1609
1848
|
throw new Error(
|
|
1610
1849
|
"connectWallet() requires PrivateKeySigner. Use connectSigner() instead, or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
|
|
@@ -1618,8 +1857,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1618
1857
|
sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
|
|
1619
1858
|
domain: this.siweDomain,
|
|
1620
1859
|
spacePrefix: prefix,
|
|
1621
|
-
sessionExpirationMs: this.config.sessionExpirationMs ??
|
|
1622
|
-
tinycloudHosts: [
|
|
1860
|
+
sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
1861
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
1862
|
+
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
1863
|
+
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
1623
1864
|
autoCreateSpace: this.config.autoCreateSpace,
|
|
1624
1865
|
enablePublicSpace: this.config.enablePublicSpace ?? true,
|
|
1625
1866
|
spaceCreationHandler: this.config.spaceCreationHandler,
|
|
@@ -1629,8 +1870,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1629
1870
|
capabilityRequest: this.config.capabilityRequest,
|
|
1630
1871
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
1631
1872
|
});
|
|
1632
|
-
this.tc = new
|
|
1633
|
-
invokeAny: this.
|
|
1873
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1874
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1634
1875
|
});
|
|
1635
1876
|
this.config.prefix = prefix;
|
|
1636
1877
|
}
|
|
@@ -1652,7 +1893,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1652
1893
|
throw new Error("Signer already connected. Cannot connect another signer.");
|
|
1653
1894
|
}
|
|
1654
1895
|
const prefix = options?.prefix ?? "default";
|
|
1655
|
-
const host = this.config.host;
|
|
1656
1896
|
this.signer = signer;
|
|
1657
1897
|
this.auth = new NodeUserAuthorization({
|
|
1658
1898
|
signer: this.signer,
|
|
@@ -1661,8 +1901,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1661
1901
|
sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
|
|
1662
1902
|
domain: this.siweDomain,
|
|
1663
1903
|
spacePrefix: prefix,
|
|
1664
|
-
sessionExpirationMs: this.config.sessionExpirationMs ??
|
|
1665
|
-
tinycloudHosts: [
|
|
1904
|
+
sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
1905
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
1906
|
+
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
1907
|
+
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
1666
1908
|
autoCreateSpace: this.config.autoCreateSpace,
|
|
1667
1909
|
enablePublicSpace: this.config.enablePublicSpace ?? true,
|
|
1668
1910
|
spaceCreationHandler: this.config.spaceCreationHandler,
|
|
@@ -1672,8 +1914,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1672
1914
|
capabilityRequest: this.config.capabilityRequest,
|
|
1673
1915
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
1674
1916
|
});
|
|
1675
|
-
this.tc = new
|
|
1676
|
-
invokeAny: this.
|
|
1917
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1918
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1677
1919
|
});
|
|
1678
1920
|
this.config.prefix = prefix;
|
|
1679
1921
|
}
|
|
@@ -1686,28 +1928,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1686
1928
|
if (!session) {
|
|
1687
1929
|
return;
|
|
1688
1930
|
}
|
|
1689
|
-
this.tc.initializeServices(this.
|
|
1690
|
-
this._serviceContext = new
|
|
1691
|
-
invoke: this.
|
|
1692
|
-
invokeAny: this.
|
|
1931
|
+
this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
|
|
1932
|
+
this._serviceContext = new import_sdk_core6.ServiceContext({
|
|
1933
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1934
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
1693
1935
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1694
1936
|
hosts: [this.config.host]
|
|
1695
1937
|
});
|
|
1696
|
-
this._kv = new
|
|
1938
|
+
this._kv = new import_sdk_core6.KVService({});
|
|
1697
1939
|
this._kv.initialize(this._serviceContext);
|
|
1698
1940
|
this._serviceContext.registerService("kv", this._kv);
|
|
1699
1941
|
const features = this.nodeFeatures;
|
|
1700
1942
|
if (features.length === 0 || features.includes("sql")) {
|
|
1701
|
-
this._sql = new
|
|
1943
|
+
this._sql = new import_sdk_core6.SQLService({});
|
|
1702
1944
|
this._sql.initialize(this._serviceContext);
|
|
1703
1945
|
this._serviceContext.registerService("sql", this._sql);
|
|
1704
1946
|
}
|
|
1705
1947
|
if (features.length === 0 || features.includes("duckdb")) {
|
|
1706
|
-
this._duckdb = new
|
|
1948
|
+
this._duckdb = new import_sdk_core6.DuckDbService({});
|
|
1707
1949
|
this._duckdb.initialize(this._serviceContext);
|
|
1708
1950
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1709
1951
|
}
|
|
1710
|
-
this._hooks = new
|
|
1952
|
+
this._hooks = new import_sdk_core6.HooksService({});
|
|
1711
1953
|
this._hooks.initialize(this._serviceContext);
|
|
1712
1954
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1713
1955
|
const serviceSession = {
|
|
@@ -1719,8 +1961,30 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1719
1961
|
};
|
|
1720
1962
|
this._serviceContext.setSession(serviceSession);
|
|
1721
1963
|
this.tc.serviceContext.setSession(serviceSession);
|
|
1964
|
+
this._vault = this.createVaultService(session.spaceId, this._kv);
|
|
1965
|
+
this._vault.initialize(this._serviceContext);
|
|
1966
|
+
this._serviceContext.registerService("vault", this._vault);
|
|
1967
|
+
this.initializeV2Services(serviceSession);
|
|
1968
|
+
}
|
|
1969
|
+
createSpaceScopedKVService(spaceId) {
|
|
1970
|
+
const kvService = new import_sdk_core6.KVService({});
|
|
1971
|
+
if (this._serviceContext) {
|
|
1972
|
+
const spaceScopedContext = new import_sdk_core6.ServiceContext({
|
|
1973
|
+
invoke: this._serviceContext.invoke,
|
|
1974
|
+
fetch: this._serviceContext.fetch,
|
|
1975
|
+
hosts: this._serviceContext.hosts
|
|
1976
|
+
});
|
|
1977
|
+
const session = this._serviceContext.session;
|
|
1978
|
+
if (session) {
|
|
1979
|
+
spaceScopedContext.setSession({ ...session, spaceId });
|
|
1980
|
+
}
|
|
1981
|
+
kvService.initialize(spaceScopedContext);
|
|
1982
|
+
}
|
|
1983
|
+
return kvService;
|
|
1984
|
+
}
|
|
1985
|
+
createVaultService(spaceId, kv) {
|
|
1722
1986
|
const wasm = this.wasmBindings;
|
|
1723
|
-
const vaultCrypto = (0,
|
|
1987
|
+
const vaultCrypto = (0, import_sdk_core6.createVaultCrypto)({
|
|
1724
1988
|
vault_encrypt: wasm.vault_encrypt,
|
|
1725
1989
|
vault_decrypt: wasm.vault_decrypt,
|
|
1726
1990
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -1730,11 +1994,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1730
1994
|
vault_sha256: wasm.vault_sha256
|
|
1731
1995
|
});
|
|
1732
1996
|
const self = this;
|
|
1733
|
-
|
|
1734
|
-
spaceId
|
|
1997
|
+
return new import_sdk_core6.DataVaultService({
|
|
1998
|
+
spaceId,
|
|
1735
1999
|
crypto: vaultCrypto,
|
|
1736
2000
|
tc: {
|
|
1737
|
-
kv
|
|
2001
|
+
kv,
|
|
1738
2002
|
ensurePublicSpace: async () => {
|
|
1739
2003
|
try {
|
|
1740
2004
|
await self.ensurePublicSpace();
|
|
@@ -1746,24 +2010,21 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1746
2010
|
get publicKV() {
|
|
1747
2011
|
return self._publicKV ?? self.tc.publicKV;
|
|
1748
2012
|
},
|
|
1749
|
-
readPublicSpace: (host,
|
|
1750
|
-
makePublicSpaceId:
|
|
2013
|
+
readPublicSpace: (host, targetSpaceId, key) => import_sdk_core6.TinyCloud.readPublicSpace(host, targetSpaceId, key),
|
|
2014
|
+
makePublicSpaceId: import_sdk_core6.TinyCloud.makePublicSpaceId,
|
|
1751
2015
|
did: this.did,
|
|
1752
|
-
address: this._address,
|
|
2016
|
+
address: this._address ?? "",
|
|
1753
2017
|
chainId: this._chainId,
|
|
1754
2018
|
hosts: [this.config.host]
|
|
1755
2019
|
}
|
|
1756
2020
|
});
|
|
1757
|
-
this._vault.initialize(this._serviceContext);
|
|
1758
|
-
this._serviceContext.registerService("vault", this._vault);
|
|
1759
|
-
this.initializeV2Services(serviceSession);
|
|
1760
2021
|
}
|
|
1761
2022
|
/**
|
|
1762
2023
|
* Initialize the v2 delegation system services.
|
|
1763
2024
|
* @internal
|
|
1764
2025
|
*/
|
|
1765
2026
|
initializeV2Services(serviceSession) {
|
|
1766
|
-
this._capabilityRegistry = new
|
|
2027
|
+
this._capabilityRegistry = new import_sdk_core6.CapabilityKeyRegistry();
|
|
1767
2028
|
const tcSession = this.auth?.tinyCloudSession;
|
|
1768
2029
|
if (tcSession && this._address) {
|
|
1769
2030
|
const sessionKey = {
|
|
@@ -1837,13 +2098,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1837
2098
|
}
|
|
1838
2099
|
this._capabilityRegistry.registerKey(sessionKey, delegations);
|
|
1839
2100
|
}
|
|
1840
|
-
this._delegationManager = new
|
|
2101
|
+
this._delegationManager = new import_sdk_core6.DelegationManager({
|
|
1841
2102
|
hosts: [this.config.host],
|
|
1842
2103
|
session: serviceSession,
|
|
1843
|
-
invoke: this.
|
|
2104
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1844
2105
|
fetch: globalThis.fetch.bind(globalThis)
|
|
1845
2106
|
});
|
|
1846
|
-
this._spaceService = new
|
|
2107
|
+
this._spaceService = new import_sdk_core6.SpaceService({
|
|
1847
2108
|
hosts: [this.config.host],
|
|
1848
2109
|
session: serviceSession,
|
|
1849
2110
|
invoke: this.wasmBindings.invoke,
|
|
@@ -1851,20 +2112,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1851
2112
|
capabilityRegistry: this._capabilityRegistry,
|
|
1852
2113
|
userDid: this.did,
|
|
1853
2114
|
createKVService: (spaceId) => {
|
|
1854
|
-
|
|
2115
|
+
return this.createSpaceScopedKVService(spaceId);
|
|
2116
|
+
},
|
|
2117
|
+
createVaultService: (spaceId) => {
|
|
2118
|
+
const kvService = this.createSpaceScopedKVService(spaceId);
|
|
2119
|
+
const vaultService = this.createVaultService(spaceId, kvService);
|
|
1855
2120
|
if (this._serviceContext) {
|
|
1856
|
-
|
|
1857
|
-
invoke: this._serviceContext.invoke,
|
|
1858
|
-
fetch: this._serviceContext.fetch,
|
|
1859
|
-
hosts: this._serviceContext.hosts
|
|
1860
|
-
});
|
|
1861
|
-
const session = this._serviceContext.session;
|
|
1862
|
-
if (session) {
|
|
1863
|
-
spaceScopedContext.setSession({ ...session, spaceId });
|
|
1864
|
-
}
|
|
1865
|
-
kvService.initialize(spaceScopedContext);
|
|
2121
|
+
vaultService.initialize(this._serviceContext);
|
|
1866
2122
|
}
|
|
1867
|
-
return
|
|
2123
|
+
return vaultService;
|
|
1868
2124
|
},
|
|
1869
2125
|
// Enable space.delegations.create() via SIWE-based delegation
|
|
1870
2126
|
createDelegation: async (params) => {
|
|
@@ -1921,7 +2177,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1921
2177
|
* @internal
|
|
1922
2178
|
*/
|
|
1923
2179
|
getSessionExpiry() {
|
|
1924
|
-
const expirationMs = this.config.sessionExpirationMs ??
|
|
2180
|
+
const expirationMs = this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS;
|
|
1925
2181
|
return new Date(Date.now() + expirationMs);
|
|
1926
2182
|
}
|
|
1927
2183
|
/**
|
|
@@ -2005,7 +2261,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2005
2261
|
...prepared,
|
|
2006
2262
|
signature
|
|
2007
2263
|
});
|
|
2008
|
-
const activateResult = await (0,
|
|
2264
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2009
2265
|
host,
|
|
2010
2266
|
delegationSession.delegationHeader
|
|
2011
2267
|
);
|
|
@@ -2072,12 +2328,40 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2072
2328
|
if (!this._sql) {
|
|
2073
2329
|
const features = this.nodeFeatures;
|
|
2074
2330
|
if (features.length > 0 && !features.includes("sql")) {
|
|
2075
|
-
throw new
|
|
2331
|
+
throw new import_sdk_core6.UnsupportedFeatureError("sql", this.config.host, features);
|
|
2076
2332
|
}
|
|
2077
2333
|
throw new Error("Not signed in. Call signIn() first.");
|
|
2078
2334
|
}
|
|
2079
2335
|
return this._sql;
|
|
2080
2336
|
}
|
|
2337
|
+
/**
|
|
2338
|
+
* Get an SQL service scoped to a specific space.
|
|
2339
|
+
*
|
|
2340
|
+
* Mirrors {@link SpaceService}'s per-space KV factory: clones the active
|
|
2341
|
+
* service context and overrides its session's spaceId so that subsequent
|
|
2342
|
+
* `sql/<dbName>/<action>` invocations route to that space. Useful when
|
|
2343
|
+
* the caller already holds a delegation covering the target space (e.g.
|
|
2344
|
+
* via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
|
|
2345
|
+
* but the SDK's per-space SQL surface isn't otherwise exposed.
|
|
2346
|
+
*
|
|
2347
|
+
* Does NOT auto-create the space.
|
|
2348
|
+
*
|
|
2349
|
+
* @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
|
|
2350
|
+
*/
|
|
2351
|
+
sqlForSpace(spaceId) {
|
|
2352
|
+
if (!this._serviceContext || !this._serviceContext.session) {
|
|
2353
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2354
|
+
}
|
|
2355
|
+
const sql = new import_sdk_core6.SQLService({});
|
|
2356
|
+
const spaceScopedContext = new import_sdk_core6.ServiceContext({
|
|
2357
|
+
invoke: this._serviceContext.invoke,
|
|
2358
|
+
fetch: this._serviceContext.fetch,
|
|
2359
|
+
hosts: this._serviceContext.hosts
|
|
2360
|
+
});
|
|
2361
|
+
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
2362
|
+
sql.initialize(spaceScopedContext);
|
|
2363
|
+
return sql;
|
|
2364
|
+
}
|
|
2081
2365
|
/**
|
|
2082
2366
|
* DuckDB database operations on this user's space.
|
|
2083
2367
|
*/
|
|
@@ -2085,7 +2369,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2085
2369
|
if (!this._duckdb) {
|
|
2086
2370
|
const features = this.nodeFeatures;
|
|
2087
2371
|
if (features.length > 0 && !features.includes("duckdb")) {
|
|
2088
|
-
throw new
|
|
2372
|
+
throw new import_sdk_core6.UnsupportedFeatureError("duckdb", this.config.host, features);
|
|
2089
2373
|
}
|
|
2090
2374
|
throw new Error("Not signed in. Call signIn() first.");
|
|
2091
2375
|
}
|
|
@@ -2101,6 +2385,33 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2101
2385
|
}
|
|
2102
2386
|
return this._vault;
|
|
2103
2387
|
}
|
|
2388
|
+
/**
|
|
2389
|
+
* App-facing secrets API backed by the `secrets` space vault.
|
|
2390
|
+
*/
|
|
2391
|
+
get secrets() {
|
|
2392
|
+
if (!this._spaceService) {
|
|
2393
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2394
|
+
}
|
|
2395
|
+
if (!this._secrets) {
|
|
2396
|
+
this._secrets = new NodeSecretsService({
|
|
2397
|
+
getService: () => this.getBaseSecrets(),
|
|
2398
|
+
getManifest: () => this.manifest,
|
|
2399
|
+
grantPermissions: (additional) => this.grantRuntimePermissions(additional),
|
|
2400
|
+
canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
|
|
2401
|
+
getUnlockSigner: () => this.signer ?? void 0
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
return this._secrets;
|
|
2405
|
+
}
|
|
2406
|
+
getBaseSecrets() {
|
|
2407
|
+
if (!this._spaceService) {
|
|
2408
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2409
|
+
}
|
|
2410
|
+
if (!this._baseSecrets) {
|
|
2411
|
+
this._baseSecrets = new import_sdk_core6.SecretsService(() => this.space("secrets").vault);
|
|
2412
|
+
}
|
|
2413
|
+
return this._baseSecrets;
|
|
2414
|
+
}
|
|
2104
2415
|
/**
|
|
2105
2416
|
* Hooks write stream subscription API.
|
|
2106
2417
|
*/
|
|
@@ -2171,6 +2482,171 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2171
2482
|
}
|
|
2172
2483
|
};
|
|
2173
2484
|
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Check whether the current session or an approved runtime delegation covers
|
|
2487
|
+
* every requested permission.
|
|
2488
|
+
*/
|
|
2489
|
+
hasRuntimePermissions(permissions) {
|
|
2490
|
+
const session = this.auth?.tinyCloudSession;
|
|
2491
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
2492
|
+
return false;
|
|
2493
|
+
}
|
|
2494
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2495
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
2496
|
+
return true;
|
|
2497
|
+
}
|
|
2498
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).length > 0;
|
|
2499
|
+
}
|
|
2500
|
+
/**
|
|
2501
|
+
* Return installed runtime permission delegations. When `permissions` is
|
|
2502
|
+
* provided, only delegations currently covering those permissions are
|
|
2503
|
+
* returned. Base-session manifest permissions are not represented here.
|
|
2504
|
+
*/
|
|
2505
|
+
getRuntimePermissionDelegations(permissions) {
|
|
2506
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
2507
|
+
if (permissions === void 0) {
|
|
2508
|
+
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
2509
|
+
}
|
|
2510
|
+
const session = this.auth?.tinyCloudSession;
|
|
2511
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
2512
|
+
return [];
|
|
2513
|
+
}
|
|
2514
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2515
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).map(
|
|
2516
|
+
(grant) => grant.delegation
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Install a portable runtime permission delegation into this SDK instance so
|
|
2521
|
+
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
2522
|
+
*/
|
|
2523
|
+
async useRuntimeDelegation(delegation) {
|
|
2524
|
+
const session = this.auth?.tinyCloudSession;
|
|
2525
|
+
if (!session) {
|
|
2526
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2527
|
+
}
|
|
2528
|
+
if (delegation.expiry.getTime() <= Date.now()) {
|
|
2529
|
+
throw new import_sdk_core6.SessionExpiredError(delegation.expiry);
|
|
2530
|
+
}
|
|
2531
|
+
const expectedDids = /* @__PURE__ */ new Set([session.verificationMethod, this.sessionDid]);
|
|
2532
|
+
if (!expectedDids.has(delegation.delegateDID)) {
|
|
2533
|
+
throw new Error(
|
|
2534
|
+
`Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
const targetHost = delegation.host ?? this.config.host;
|
|
2538
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2539
|
+
targetHost,
|
|
2540
|
+
delegation.delegationHeader
|
|
2541
|
+
);
|
|
2542
|
+
if (!activateResult.success) {
|
|
2543
|
+
throw new Error(
|
|
2544
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
2545
|
+
);
|
|
2546
|
+
}
|
|
2547
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
2548
|
+
(grant) => grant.delegation.cid !== delegation.cid
|
|
2549
|
+
);
|
|
2550
|
+
this.runtimePermissionGrants.push(
|
|
2551
|
+
this.runtimeGrantFromDelegation(delegation, session)
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
/**
|
|
2555
|
+
* Store additional permissions as narrow delegations to the current session
|
|
2556
|
+
* key. Future service invocations automatically use a stored delegation when
|
|
2557
|
+
* its `(space, service, path, action)` covers the request.
|
|
2558
|
+
*/
|
|
2559
|
+
async grantRuntimePermissions(permissions, options) {
|
|
2560
|
+
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
2561
|
+
throw new Error("grantRuntimePermissions requires a non-empty permissions array");
|
|
2562
|
+
}
|
|
2563
|
+
const session = this.auth?.tinyCloudSession;
|
|
2564
|
+
if (!session) {
|
|
2565
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2566
|
+
}
|
|
2567
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
2568
|
+
if (sessionExpiry !== void 0) {
|
|
2569
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2570
|
+
if (sessionExpiry.getTime() <= Date.now() + marginMs) {
|
|
2571
|
+
throw new import_sdk_core6.SessionExpiredError(sessionExpiry);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2575
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
2576
|
+
return [];
|
|
2577
|
+
}
|
|
2578
|
+
const existingGrants = this.findRuntimeGrantsForPermissionEntries(expanded, session);
|
|
2579
|
+
if (existingGrants.length > 0) {
|
|
2580
|
+
return existingGrants.map((grant) => grant.delegation);
|
|
2581
|
+
}
|
|
2582
|
+
if (!this.signer) {
|
|
2583
|
+
throw new Error(
|
|
2584
|
+
"grantRuntimePermissions requires wallet mode with a signer or privateKey."
|
|
2585
|
+
);
|
|
2586
|
+
}
|
|
2587
|
+
const bySpace = /* @__PURE__ */ new Map();
|
|
2588
|
+
for (const entry of expanded) {
|
|
2589
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
2590
|
+
const current = bySpace.get(spaceId) ?? [];
|
|
2591
|
+
current.push(entry);
|
|
2592
|
+
bySpace.set(spaceId, current);
|
|
2593
|
+
}
|
|
2594
|
+
const now = /* @__PURE__ */ new Date();
|
|
2595
|
+
const requestedExpiryMs = resolveExpiryMs(options?.expiry);
|
|
2596
|
+
let expiresAt = new Date(now.getTime() + requestedExpiryMs);
|
|
2597
|
+
if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
|
|
2598
|
+
expiresAt = sessionExpiry;
|
|
2599
|
+
}
|
|
2600
|
+
const delegations = [];
|
|
2601
|
+
for (const [spaceId, entries] of bySpace) {
|
|
2602
|
+
const abilities = this.permissionsToAbilities(entries);
|
|
2603
|
+
const prepared = this.wasmBindings.prepareSession({
|
|
2604
|
+
abilities,
|
|
2605
|
+
address: this.wasmBindings.ensureEip55(session.address),
|
|
2606
|
+
chainId: session.chainId,
|
|
2607
|
+
domain: this.siweDomain,
|
|
2608
|
+
issuedAt: now.toISOString(),
|
|
2609
|
+
expirationTime: expiresAt.toISOString(),
|
|
2610
|
+
spaceId,
|
|
2611
|
+
jwk: session.jwk
|
|
2612
|
+
});
|
|
2613
|
+
const signature = await this.signer.signMessage(prepared.siwe);
|
|
2614
|
+
const delegatedSession = this.wasmBindings.completeSessionSetup({
|
|
2615
|
+
...prepared,
|
|
2616
|
+
signature
|
|
2617
|
+
});
|
|
2618
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2619
|
+
this.config.host,
|
|
2620
|
+
delegatedSession.delegationHeader
|
|
2621
|
+
);
|
|
2622
|
+
if (!activateResult.success) {
|
|
2623
|
+
throw new Error(
|
|
2624
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
2625
|
+
);
|
|
2626
|
+
}
|
|
2627
|
+
const delegation = this.runtimeDelegationFromSession(
|
|
2628
|
+
delegatedSession,
|
|
2629
|
+
entries,
|
|
2630
|
+
spaceId,
|
|
2631
|
+
session,
|
|
2632
|
+
expiresAt
|
|
2633
|
+
);
|
|
2634
|
+
this.runtimePermissionGrants.push({
|
|
2635
|
+
session: {
|
|
2636
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
2637
|
+
delegationCid: delegatedSession.delegationCid,
|
|
2638
|
+
spaceId,
|
|
2639
|
+
verificationMethod: session.verificationMethod,
|
|
2640
|
+
jwk: session.jwk
|
|
2641
|
+
},
|
|
2642
|
+
delegation,
|
|
2643
|
+
operations: this.permissionOperations(entries, spaceId),
|
|
2644
|
+
expiresAt
|
|
2645
|
+
});
|
|
2646
|
+
delegations.push(delegation);
|
|
2647
|
+
}
|
|
2648
|
+
return delegations;
|
|
2649
|
+
}
|
|
2174
2650
|
/**
|
|
2175
2651
|
* Get the DelegationManager for delegation CRUD operations.
|
|
2176
2652
|
*
|
|
@@ -2239,6 +2715,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2239
2715
|
get spaceService() {
|
|
2240
2716
|
return this.spaces;
|
|
2241
2717
|
}
|
|
2718
|
+
/**
|
|
2719
|
+
* Get a Space object by short name or full URI.
|
|
2720
|
+
*/
|
|
2721
|
+
space(nameOrUri) {
|
|
2722
|
+
return this.spaces.get(nameOrUri);
|
|
2723
|
+
}
|
|
2242
2724
|
/**
|
|
2243
2725
|
* Get the SharingService for creating and receiving v2 sharing links.
|
|
2244
2726
|
*
|
|
@@ -2306,7 +2788,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2306
2788
|
];
|
|
2307
2789
|
const abilities = { kv: { "": kvActions } };
|
|
2308
2790
|
const now = /* @__PURE__ */ new Date();
|
|
2309
|
-
const expiryMs =
|
|
2791
|
+
const expiryMs = import_sdk_core6.EXPIRY.EPHEMERAL_MS;
|
|
2310
2792
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
2311
2793
|
const prepared = this.wasmBindings.prepareSession({
|
|
2312
2794
|
abilities,
|
|
@@ -2324,7 +2806,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2324
2806
|
...prepared,
|
|
2325
2807
|
signature
|
|
2326
2808
|
});
|
|
2327
|
-
const activateResult = await (0,
|
|
2809
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2328
2810
|
this.config.host,
|
|
2329
2811
|
delegationSession.delegationHeader
|
|
2330
2812
|
);
|
|
@@ -2351,9 +2833,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2351
2833
|
}]);
|
|
2352
2834
|
}
|
|
2353
2835
|
if (this._serviceContext) {
|
|
2354
|
-
const publicKV = new
|
|
2355
|
-
const publicContext = new
|
|
2356
|
-
invoke: this.
|
|
2836
|
+
const publicKV = new import_sdk_core6.KVService({ prefix: "" });
|
|
2837
|
+
const publicContext = new import_sdk_core6.ServiceContext({
|
|
2838
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
2357
2839
|
fetch: this._serviceContext.fetch,
|
|
2358
2840
|
hosts: this._serviceContext.hosts
|
|
2359
2841
|
});
|
|
@@ -2441,8 +2923,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2441
2923
|
* Issue a delegation using the capability-chain flow.
|
|
2442
2924
|
*
|
|
2443
2925
|
* When every requested permission is a subset of the current
|
|
2444
|
-
* session's recap,
|
|
2445
|
-
*
|
|
2926
|
+
* session's recap, or of one installed runtime permission delegation,
|
|
2927
|
+
* the delegation is signed by the session key via WASM — no wallet
|
|
2928
|
+
* prompt. When at least one is NOT derivable, a
|
|
2446
2929
|
* {@link PermissionNotInManifestError} is raised (carrying the
|
|
2447
2930
|
* missing entries) so the caller can trigger an escalation flow
|
|
2448
2931
|
* (e.g. `TinyCloudWeb.requestPermissions`). Passing
|
|
@@ -2477,14 +2960,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2477
2960
|
async delegateTo(did, permissions, options) {
|
|
2478
2961
|
const session = this.auth?.tinyCloudSession;
|
|
2479
2962
|
if (!session) {
|
|
2480
|
-
throw new
|
|
2963
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2481
2964
|
}
|
|
2482
2965
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
2483
2966
|
if (sessionExpiry !== void 0) {
|
|
2484
2967
|
const now2 = Date.now();
|
|
2485
2968
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2486
2969
|
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
2487
|
-
throw new
|
|
2970
|
+
throw new import_sdk_core6.SessionExpiredError(sessionExpiry);
|
|
2488
2971
|
}
|
|
2489
2972
|
}
|
|
2490
2973
|
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -2492,10 +2975,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2492
2975
|
"delegateTo requires a non-empty permissions array"
|
|
2493
2976
|
);
|
|
2494
2977
|
}
|
|
2495
|
-
const expandedEntries =
|
|
2496
|
-
...entry,
|
|
2497
|
-
actions: (0, import_sdk_core5.expandActionShortNames)(entry.service, entry.actions)
|
|
2498
|
-
}));
|
|
2978
|
+
const expandedEntries = this.expandPermissionEntries(permissions);
|
|
2499
2979
|
const now = /* @__PURE__ */ new Date();
|
|
2500
2980
|
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
2501
2981
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
@@ -2516,13 +2996,30 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2516
2996
|
);
|
|
2517
2997
|
return { delegation: delegation2, prompted: true };
|
|
2518
2998
|
}
|
|
2519
|
-
const granted = (0,
|
|
2999
|
+
const granted = (0, import_sdk_core6.parseRecapCapabilities)(
|
|
2520
3000
|
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
2521
3001
|
session.siwe
|
|
2522
3002
|
);
|
|
2523
|
-
const { subset, missing } = (0,
|
|
3003
|
+
const { subset, missing } = (0, import_sdk_core6.isCapabilitySubset)(expandedEntries, granted);
|
|
2524
3004
|
if (!subset) {
|
|
2525
|
-
|
|
3005
|
+
const runtimeGrant = this.findGrantForOperations(
|
|
3006
|
+
this.permissionEntriesToOperations(expandedEntries, session)
|
|
3007
|
+
);
|
|
3008
|
+
if (runtimeGrant) {
|
|
3009
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
3010
|
+
if (runtimeGrant.expiresAt.getTime() <= Date.now() + marginMs) {
|
|
3011
|
+
throw new import_sdk_core6.SessionExpiredError(runtimeGrant.expiresAt);
|
|
3012
|
+
}
|
|
3013
|
+
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
3014
|
+
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
3015
|
+
did,
|
|
3016
|
+
expandedEntries,
|
|
3017
|
+
runtimeExpiration,
|
|
3018
|
+
runtimeGrant
|
|
3019
|
+
);
|
|
3020
|
+
return { delegation: delegation2, prompted: false };
|
|
3021
|
+
}
|
|
3022
|
+
throw new import_sdk_core6.PermissionNotInManifestError(missing, granted);
|
|
2526
3023
|
}
|
|
2527
3024
|
const delegation = await this.createDelegationViaWasmPath(
|
|
2528
3025
|
did,
|
|
@@ -2602,7 +3099,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2602
3099
|
const spaceId = [...resolvedSpaces][0];
|
|
2603
3100
|
const abilities = {};
|
|
2604
3101
|
for (const entry of entries) {
|
|
2605
|
-
const shortService =
|
|
3102
|
+
const shortService = import_sdk_core6.SERVICE_LONG_TO_SHORT[entry.service];
|
|
2606
3103
|
if (shortService === void 0) {
|
|
2607
3104
|
throw new Error(
|
|
2608
3105
|
`delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
|
|
@@ -2642,7 +3139,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2642
3139
|
});
|
|
2643
3140
|
const primary = result.resources[0];
|
|
2644
3141
|
const delegationHeader = { Authorization: result.delegation };
|
|
2645
|
-
const activateResult = await (0,
|
|
3142
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2646
3143
|
this.config.host,
|
|
2647
3144
|
delegationHeader
|
|
2648
3145
|
);
|
|
@@ -2666,6 +3163,41 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2666
3163
|
host: this.config.host
|
|
2667
3164
|
};
|
|
2668
3165
|
}
|
|
3166
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
|
|
3167
|
+
const result = this.createDelegationWrapper({
|
|
3168
|
+
session: grant.session,
|
|
3169
|
+
delegateDID: did,
|
|
3170
|
+
spaceId: grant.session.spaceId,
|
|
3171
|
+
abilities: this.permissionsToAbilities(entries),
|
|
3172
|
+
expirationSecs: Math.floor(expirationTime.getTime() / 1e3)
|
|
3173
|
+
});
|
|
3174
|
+
const primary = result.resources[0];
|
|
3175
|
+
const delegationHeader = { Authorization: result.delegation };
|
|
3176
|
+
const targetHost = grant.delegation.host ?? this.config.host;
|
|
3177
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
3178
|
+
targetHost,
|
|
3179
|
+
delegationHeader
|
|
3180
|
+
);
|
|
3181
|
+
if (!activateResult.success) {
|
|
3182
|
+
throw new Error(
|
|
3183
|
+
`Failed to activate delegation with host: ${activateResult.error}`
|
|
3184
|
+
);
|
|
3185
|
+
}
|
|
3186
|
+
return {
|
|
3187
|
+
cid: result.cid,
|
|
3188
|
+
delegationHeader,
|
|
3189
|
+
spaceId: grant.session.spaceId,
|
|
3190
|
+
path: primary.path,
|
|
3191
|
+
actions: primary.actions,
|
|
3192
|
+
resources: result.resources,
|
|
3193
|
+
disableSubDelegation: false,
|
|
3194
|
+
expiry: result.expiry,
|
|
3195
|
+
delegateDID: did,
|
|
3196
|
+
ownerAddress: grant.delegation.ownerAddress,
|
|
3197
|
+
chainId: grant.delegation.chainId,
|
|
3198
|
+
host: targetHost
|
|
3199
|
+
};
|
|
3200
|
+
}
|
|
2669
3201
|
resolvePermissionSpace(space, session) {
|
|
2670
3202
|
if (space === void 0) {
|
|
2671
3203
|
return this.wasmBindings.makeSpaceId(
|
|
@@ -2682,6 +3214,220 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2682
3214
|
}
|
|
2683
3215
|
return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
|
|
2684
3216
|
}
|
|
3217
|
+
expandPermissionEntries(permissions) {
|
|
3218
|
+
return (0, import_sdk_core6.expandPermissionEntries)(permissions);
|
|
3219
|
+
}
|
|
3220
|
+
shortServiceName(service) {
|
|
3221
|
+
const short = import_sdk_core6.SERVICE_LONG_TO_SHORT[service];
|
|
3222
|
+
if (short === void 0) {
|
|
3223
|
+
throw new Error(
|
|
3224
|
+
`unknown service '${service}' \u2014 no short-form mapping`
|
|
3225
|
+
);
|
|
3226
|
+
}
|
|
3227
|
+
return short;
|
|
3228
|
+
}
|
|
3229
|
+
permissionsToAbilities(entries) {
|
|
3230
|
+
const abilities = {};
|
|
3231
|
+
for (const entry of entries) {
|
|
3232
|
+
const service = this.shortServiceName(entry.service);
|
|
3233
|
+
abilities[service] ?? (abilities[service] = {});
|
|
3234
|
+
const existing = abilities[service][entry.path] ?? [];
|
|
3235
|
+
const seen = new Set(existing);
|
|
3236
|
+
for (const action of entry.actions) {
|
|
3237
|
+
if (!seen.has(action)) {
|
|
3238
|
+
existing.push(action);
|
|
3239
|
+
seen.add(action);
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3242
|
+
abilities[service][entry.path] = existing;
|
|
3243
|
+
}
|
|
3244
|
+
return abilities;
|
|
3245
|
+
}
|
|
3246
|
+
permissionOperations(entries, spaceId) {
|
|
3247
|
+
return entries.flatMap((entry) => {
|
|
3248
|
+
const service = this.shortServiceName(entry.service);
|
|
3249
|
+
return entry.actions.map((action) => ({
|
|
3250
|
+
spaceId,
|
|
3251
|
+
service,
|
|
3252
|
+
path: entry.path,
|
|
3253
|
+
action
|
|
3254
|
+
}));
|
|
3255
|
+
});
|
|
3256
|
+
}
|
|
3257
|
+
sessionCoversPermissionEntries(session, entries) {
|
|
3258
|
+
try {
|
|
3259
|
+
const granted = (0, import_sdk_core6.parseRecapCapabilities)(
|
|
3260
|
+
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
3261
|
+
session.siwe
|
|
3262
|
+
);
|
|
3263
|
+
return (0, import_sdk_core6.isCapabilitySubset)(entries, granted).subset;
|
|
3264
|
+
} catch {
|
|
3265
|
+
return false;
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
permissionEntriesToOperations(entries, session) {
|
|
3269
|
+
return entries.flatMap((entry) => {
|
|
3270
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
3271
|
+
const service = this.shortServiceName(entry.service);
|
|
3272
|
+
return entry.actions.map((action) => ({
|
|
3273
|
+
spaceId,
|
|
3274
|
+
service,
|
|
3275
|
+
path: entry.path,
|
|
3276
|
+
action
|
|
3277
|
+
}));
|
|
3278
|
+
});
|
|
3279
|
+
}
|
|
3280
|
+
findRuntimeGrantsForPermissionEntries(entries, session) {
|
|
3281
|
+
const grants = [];
|
|
3282
|
+
const operations = this.permissionEntriesToOperations(entries, session);
|
|
3283
|
+
if (operations.length === 0) {
|
|
3284
|
+
return grants;
|
|
3285
|
+
}
|
|
3286
|
+
for (const operation of operations) {
|
|
3287
|
+
const grant = this.findGrantForOperation(operation);
|
|
3288
|
+
if (!grant) {
|
|
3289
|
+
return [];
|
|
3290
|
+
}
|
|
3291
|
+
if (!grants.includes(grant)) {
|
|
3292
|
+
grants.push(grant);
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
return grants;
|
|
3296
|
+
}
|
|
3297
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
3298
|
+
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
3299
|
+
const primary = resources[0];
|
|
3300
|
+
return {
|
|
3301
|
+
cid: delegatedSession.delegationCid,
|
|
3302
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
3303
|
+
spaceId,
|
|
3304
|
+
path: primary.path,
|
|
3305
|
+
actions: primary.actions,
|
|
3306
|
+
resources,
|
|
3307
|
+
disableSubDelegation: false,
|
|
3308
|
+
expiry: expiresAt,
|
|
3309
|
+
delegateDID: session.verificationMethod,
|
|
3310
|
+
ownerAddress: session.address,
|
|
3311
|
+
chainId: session.chainId,
|
|
3312
|
+
host: this.config.host
|
|
3313
|
+
};
|
|
3314
|
+
}
|
|
3315
|
+
runtimeGrantFromDelegation(delegation, session) {
|
|
3316
|
+
const operations = this.operationsFromDelegation(delegation);
|
|
3317
|
+
return {
|
|
3318
|
+
session: {
|
|
3319
|
+
delegationHeader: delegation.delegationHeader,
|
|
3320
|
+
delegationCid: delegation.cid,
|
|
3321
|
+
spaceId: delegation.spaceId,
|
|
3322
|
+
verificationMethod: session.verificationMethod,
|
|
3323
|
+
jwk: session.jwk
|
|
3324
|
+
},
|
|
3325
|
+
delegation,
|
|
3326
|
+
operations,
|
|
3327
|
+
expiresAt: delegation.expiry
|
|
3328
|
+
};
|
|
3329
|
+
}
|
|
3330
|
+
delegatedResourcesForEntries(entries, spaceId) {
|
|
3331
|
+
return entries.map((entry) => ({
|
|
3332
|
+
service: this.shortServiceName(entry.service),
|
|
3333
|
+
space: spaceId,
|
|
3334
|
+
path: entry.path,
|
|
3335
|
+
actions: [...entry.actions]
|
|
3336
|
+
}));
|
|
3337
|
+
}
|
|
3338
|
+
operationsFromDelegation(delegation) {
|
|
3339
|
+
const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
|
|
3340
|
+
return resources.flatMap(
|
|
3341
|
+
(resource) => resource.actions.map((action) => ({
|
|
3342
|
+
spaceId: resource.space,
|
|
3343
|
+
service: this.invocationServiceName(resource.service),
|
|
3344
|
+
path: resource.path,
|
|
3345
|
+
action
|
|
3346
|
+
}))
|
|
3347
|
+
);
|
|
3348
|
+
}
|
|
3349
|
+
flatDelegationResources(delegation) {
|
|
3350
|
+
const byService = /* @__PURE__ */ new Map();
|
|
3351
|
+
for (const action of delegation.actions) {
|
|
3352
|
+
const service = this.shortServiceName(action.split("/")[0]);
|
|
3353
|
+
const actions = byService.get(service) ?? [];
|
|
3354
|
+
actions.push(action);
|
|
3355
|
+
byService.set(service, actions);
|
|
3356
|
+
}
|
|
3357
|
+
return [...byService.entries()].map(([service, actions]) => ({
|
|
3358
|
+
service,
|
|
3359
|
+
space: delegation.spaceId,
|
|
3360
|
+
path: delegation.path,
|
|
3361
|
+
actions
|
|
3362
|
+
}));
|
|
3363
|
+
}
|
|
3364
|
+
selectInvocationSession(fallback, service, path, action) {
|
|
3365
|
+
const grant = this.findGrantForOperation({
|
|
3366
|
+
spaceId: fallback.spaceId,
|
|
3367
|
+
service: this.invocationServiceName(service),
|
|
3368
|
+
path,
|
|
3369
|
+
action
|
|
3370
|
+
});
|
|
3371
|
+
return grant?.session ?? fallback;
|
|
3372
|
+
}
|
|
3373
|
+
findGrantForOperations(operations) {
|
|
3374
|
+
if (operations.length === 0) {
|
|
3375
|
+
return void 0;
|
|
3376
|
+
}
|
|
3377
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
3378
|
+
return this.runtimePermissionGrants.find((grant) => {
|
|
3379
|
+
return operations.every(
|
|
3380
|
+
(operation) => grant.operations.some(
|
|
3381
|
+
(granted) => this.operationCovers(granted, operation)
|
|
3382
|
+
)
|
|
3383
|
+
);
|
|
3384
|
+
});
|
|
3385
|
+
}
|
|
3386
|
+
findGrantForOperation(operation) {
|
|
3387
|
+
return this.findGrantForOperations([operation]);
|
|
3388
|
+
}
|
|
3389
|
+
pruneExpiredRuntimePermissionGrants() {
|
|
3390
|
+
const now = Date.now();
|
|
3391
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
3392
|
+
(grant) => grant.expiresAt.getTime() > now
|
|
3393
|
+
);
|
|
3394
|
+
}
|
|
3395
|
+
operationCovers(granted, requested) {
|
|
3396
|
+
return granted.spaceId === requested.spaceId && granted.service === requested.service && this.actionContains(granted.action, requested.action) && this.pathContains(granted.path, requested.path);
|
|
3397
|
+
}
|
|
3398
|
+
actionContains(grantedAction, requestedAction) {
|
|
3399
|
+
if (grantedAction === requestedAction) {
|
|
3400
|
+
return true;
|
|
3401
|
+
}
|
|
3402
|
+
if (grantedAction.endsWith("/*")) {
|
|
3403
|
+
const prefix = grantedAction.slice(0, -2);
|
|
3404
|
+
return requestedAction.startsWith(`${prefix}/`);
|
|
3405
|
+
}
|
|
3406
|
+
return false;
|
|
3407
|
+
}
|
|
3408
|
+
invocationServiceName(service) {
|
|
3409
|
+
return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
|
|
3410
|
+
}
|
|
3411
|
+
pathContains(grantedPath, requestedPath) {
|
|
3412
|
+
if (grantedPath === "" || grantedPath === "/") {
|
|
3413
|
+
return true;
|
|
3414
|
+
}
|
|
3415
|
+
if (grantedPath.endsWith("/**")) {
|
|
3416
|
+
return requestedPath.startsWith(grantedPath.slice(0, -3));
|
|
3417
|
+
}
|
|
3418
|
+
if (grantedPath.endsWith("/*")) {
|
|
3419
|
+
const prefix = grantedPath.slice(0, -2);
|
|
3420
|
+
if (!requestedPath.startsWith(prefix)) {
|
|
3421
|
+
return false;
|
|
3422
|
+
}
|
|
3423
|
+
const remainder = requestedPath.slice(prefix.length);
|
|
3424
|
+
return !remainder.includes("/") || remainder === "/";
|
|
3425
|
+
}
|
|
3426
|
+
if (grantedPath.endsWith("/")) {
|
|
3427
|
+
return requestedPath.startsWith(grantedPath);
|
|
3428
|
+
}
|
|
3429
|
+
return grantedPath === requestedPath;
|
|
3430
|
+
}
|
|
2685
3431
|
/**
|
|
2686
3432
|
* Issue a delegation via the legacy wallet-signed SIWE path for a single
|
|
2687
3433
|
* {@link PermissionEntry}. Shares the implementation with the public
|
|
@@ -2738,7 +3484,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2738
3484
|
);
|
|
2739
3485
|
return result.delegation;
|
|
2740
3486
|
} catch (err) {
|
|
2741
|
-
if (err instanceof
|
|
3487
|
+
if (err instanceof import_sdk_core6.PermissionNotInManifestError) {
|
|
2742
3488
|
} else {
|
|
2743
3489
|
throw err;
|
|
2744
3490
|
}
|
|
@@ -2795,7 +3541,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2795
3541
|
...prepared,
|
|
2796
3542
|
signature
|
|
2797
3543
|
});
|
|
2798
|
-
const activateResult = await (0,
|
|
3544
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2799
3545
|
this.config.host,
|
|
2800
3546
|
delegationSession.delegationHeader
|
|
2801
3547
|
);
|
|
@@ -2817,7 +3563,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2817
3563
|
};
|
|
2818
3564
|
const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
|
|
2819
3565
|
if (hasKvActions && params.includePublicSpace !== false) {
|
|
2820
|
-
const publicSpaceId = (0,
|
|
3566
|
+
const publicSpaceId = (0, import_sdk_core6.makePublicSpaceId)(
|
|
2821
3567
|
this.wasmBindings.ensureEip55(session.address),
|
|
2822
3568
|
session.chainId
|
|
2823
3569
|
);
|
|
@@ -2840,7 +3586,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2840
3586
|
...publicPrepared,
|
|
2841
3587
|
signature: publicSignature
|
|
2842
3588
|
});
|
|
2843
|
-
const publicActivateResult = await (0,
|
|
3589
|
+
const publicActivateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2844
3590
|
this.config.host,
|
|
2845
3591
|
publicSession.delegationHeader
|
|
2846
3592
|
);
|
|
@@ -2939,7 +3685,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2939
3685
|
...prepared,
|
|
2940
3686
|
signature
|
|
2941
3687
|
});
|
|
2942
|
-
const activateResult = await (0,
|
|
3688
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2943
3689
|
targetHost,
|
|
2944
3690
|
invokerSession.delegationHeader
|
|
2945
3691
|
);
|
|
@@ -3028,7 +3774,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3028
3774
|
...prepared,
|
|
3029
3775
|
signature
|
|
3030
3776
|
});
|
|
3031
|
-
const activateResult = await (0,
|
|
3777
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
3032
3778
|
targetHost,
|
|
3033
3779
|
subDelegationSession.delegationHeader
|
|
3034
3780
|
);
|
|
@@ -3064,7 +3810,7 @@ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
|
3064
3810
|
var TinyCloudNode = _TinyCloudNode;
|
|
3065
3811
|
|
|
3066
3812
|
// src/core.ts
|
|
3067
|
-
var
|
|
3813
|
+
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
3068
3814
|
|
|
3069
3815
|
// src/delegation.ts
|
|
3070
3816
|
function serializeDelegation(delegation) {
|
|
@@ -3083,7 +3829,6 @@ function deserializeDelegation(data) {
|
|
|
3083
3829
|
}
|
|
3084
3830
|
|
|
3085
3831
|
// src/core.ts
|
|
3086
|
-
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
3087
3832
|
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
3088
3833
|
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
3089
3834
|
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
@@ -3092,6 +3837,7 @@ var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
|
3092
3837
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
3093
3838
|
var import_sdk_core16 = require("@tinycloud/sdk-core");
|
|
3094
3839
|
var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
3840
|
+
var import_sdk_core18 = require("@tinycloud/sdk-core");
|
|
3095
3841
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3096
3842
|
0 && (module.exports = {
|
|
3097
3843
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -3117,8 +3863,10 @@ var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
|
3117
3863
|
PermissionNotInManifestError,
|
|
3118
3864
|
PrefixedKVService,
|
|
3119
3865
|
ProtocolMismatchError,
|
|
3866
|
+
SECRET_NAME_RE,
|
|
3120
3867
|
SQLAction,
|
|
3121
3868
|
SQLService,
|
|
3869
|
+
SecretsService,
|
|
3122
3870
|
ServiceContext,
|
|
3123
3871
|
SessionExpiredError,
|
|
3124
3872
|
SharingService,
|
|
@@ -3129,11 +3877,13 @@ var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
|
3129
3877
|
TinyCloud,
|
|
3130
3878
|
TinyCloudNode,
|
|
3131
3879
|
UnsupportedFeatureError,
|
|
3880
|
+
VAULT_PERMISSION_SERVICE,
|
|
3132
3881
|
VaultHeaders,
|
|
3133
3882
|
VaultPublicSpaceKVActions,
|
|
3134
3883
|
VersionCheckError,
|
|
3135
3884
|
WasmKeyProvider,
|
|
3136
3885
|
buildSpaceUri,
|
|
3886
|
+
canonicalizeSecretScope,
|
|
3137
3887
|
checkNodeInfo,
|
|
3138
3888
|
composeManifestRequest,
|
|
3139
3889
|
createCapabilityKeyRegistry,
|
|
@@ -3145,12 +3895,15 @@ var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
|
3145
3895
|
defaultSpaceCreationHandler,
|
|
3146
3896
|
deserializeDelegation,
|
|
3147
3897
|
expandActionShortNames,
|
|
3898
|
+
expandPermissionEntries,
|
|
3899
|
+
expandPermissionEntry,
|
|
3148
3900
|
isCapabilitySubset,
|
|
3149
3901
|
loadManifest,
|
|
3150
3902
|
makePublicSpaceId,
|
|
3151
3903
|
parseExpiry,
|
|
3152
3904
|
parseSpaceUri,
|
|
3153
3905
|
resolveManifest,
|
|
3906
|
+
resolveSecretPath,
|
|
3154
3907
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
3155
3908
|
serializeDelegation,
|
|
3156
3909
|
validateManifest
|