@tinycloud/node-sdk 2.2.0-beta.6 → 2.2.0-beta.8
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-DdMPUB5s.d.cts → core-DcJ27GsA.d.cts} +71 -4
- package/dist/{core-DdMPUB5s.d.ts → core-DcJ27GsA.d.ts} +71 -4
- package/dist/core.cjs +794 -168
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +700 -71
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +797 -171
- 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 +701 -71
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/core.cjs
CHANGED
|
@@ -20,70 +20,71 @@ 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
|
-
SQLAction: () =>
|
|
47
|
-
SQLService: () =>
|
|
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
|
+
SQLAction: () => import_sdk_core11.SQLAction,
|
|
47
|
+
SQLService: () => import_sdk_core11.SQLService,
|
|
48
|
+
SecretsService: () => import_sdk_core13.SecretsService,
|
|
49
|
+
ServiceContext: () => import_sdk_core18.ServiceContext,
|
|
50
|
+
SessionExpiredError: () => import_sdk_core9.SessionExpiredError,
|
|
51
|
+
SharingService: () => import_sdk_core14.SharingService,
|
|
52
|
+
SilentNotificationHandler: () => import_sdk_core8.SilentNotificationHandler,
|
|
53
|
+
Space: () => import_sdk_core16.Space,
|
|
54
|
+
SpaceErrorCodes: () => import_sdk_core16.SpaceErrorCodes,
|
|
55
|
+
SpaceService: () => import_sdk_core16.SpaceService,
|
|
56
|
+
TinyCloud: () => import_sdk_core7.TinyCloud,
|
|
56
57
|
TinyCloudNode: () => TinyCloudNode,
|
|
57
|
-
UnsupportedFeatureError: () =>
|
|
58
|
-
VaultHeaders: () =>
|
|
59
|
-
VaultPublicSpaceKVActions: () =>
|
|
60
|
-
VersionCheckError: () =>
|
|
58
|
+
UnsupportedFeatureError: () => import_sdk_core17.UnsupportedFeatureError,
|
|
59
|
+
VaultHeaders: () => import_sdk_core13.VaultHeaders,
|
|
60
|
+
VaultPublicSpaceKVActions: () => import_sdk_core13.VaultPublicSpaceKVActions,
|
|
61
|
+
VersionCheckError: () => import_sdk_core17.VersionCheckError,
|
|
61
62
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
62
|
-
buildSpaceUri: () =>
|
|
63
|
-
checkNodeInfo: () =>
|
|
64
|
-
composeManifestRequest: () =>
|
|
65
|
-
createCapabilityKeyRegistry: () =>
|
|
66
|
-
createSharingService: () =>
|
|
67
|
-
createSpaceService: () =>
|
|
68
|
-
createVaultCrypto: () =>
|
|
63
|
+
buildSpaceUri: () => import_sdk_core16.buildSpaceUri,
|
|
64
|
+
checkNodeInfo: () => import_sdk_core17.checkNodeInfo,
|
|
65
|
+
composeManifestRequest: () => import_sdk_core9.composeManifestRequest,
|
|
66
|
+
createCapabilityKeyRegistry: () => import_sdk_core15.createCapabilityKeyRegistry,
|
|
67
|
+
createSharingService: () => import_sdk_core14.createSharingService,
|
|
68
|
+
createSpaceService: () => import_sdk_core16.createSpaceService,
|
|
69
|
+
createVaultCrypto: () => import_sdk_core13.createVaultCrypto,
|
|
69
70
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
70
71
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
71
|
-
defaultSpaceCreationHandler: () =>
|
|
72
|
+
defaultSpaceCreationHandler: () => import_sdk_core8.defaultSpaceCreationHandler,
|
|
72
73
|
deserializeDelegation: () => deserializeDelegation,
|
|
73
|
-
expandActionShortNames: () =>
|
|
74
|
-
isCapabilitySubset: () =>
|
|
75
|
-
loadManifest: () =>
|
|
76
|
-
makePublicSpaceId: () =>
|
|
77
|
-
parseExpiry: () =>
|
|
78
|
-
parseSpaceUri: () =>
|
|
79
|
-
resolveManifest: () =>
|
|
80
|
-
resourceCapabilitiesToSpaceAbilitiesMap: () =>
|
|
74
|
+
expandActionShortNames: () => import_sdk_core9.expandActionShortNames,
|
|
75
|
+
isCapabilitySubset: () => import_sdk_core9.isCapabilitySubset,
|
|
76
|
+
loadManifest: () => import_sdk_core9.loadManifest,
|
|
77
|
+
makePublicSpaceId: () => import_sdk_core16.makePublicSpaceId,
|
|
78
|
+
parseExpiry: () => import_sdk_core9.parseExpiry,
|
|
79
|
+
parseSpaceUri: () => import_sdk_core16.parseSpaceUri,
|
|
80
|
+
resolveManifest: () => import_sdk_core9.resolveManifest,
|
|
81
|
+
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core9.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
81
82
|
serializeDelegation: () => serializeDelegation,
|
|
82
|
-
validateManifest: () =>
|
|
83
|
+
validateManifest: () => import_sdk_core9.validateManifest
|
|
83
84
|
});
|
|
84
85
|
module.exports = __toCommonJS(core_exports);
|
|
85
|
-
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
86
86
|
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
87
|
+
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
87
88
|
|
|
88
89
|
// src/storage/MemorySessionStorage.ts
|
|
89
90
|
var MemorySessionStorage = class {
|
|
@@ -1019,7 +1020,7 @@ var NodeUserAuthorization = class {
|
|
|
1019
1020
|
};
|
|
1020
1021
|
|
|
1021
1022
|
// src/TinyCloudNode.ts
|
|
1022
|
-
var
|
|
1023
|
+
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
1023
1024
|
|
|
1024
1025
|
// src/DelegatedAccess.ts
|
|
1025
1026
|
var import_sdk_core3 = require("@tinycloud/sdk-core");
|
|
@@ -1252,6 +1253,148 @@ function extractSiweExpiration(siwe) {
|
|
|
1252
1253
|
return d;
|
|
1253
1254
|
}
|
|
1254
1255
|
|
|
1256
|
+
// src/NodeSecretsService.ts
|
|
1257
|
+
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
1258
|
+
var SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
1259
|
+
var SECRET_PREFIX = "secrets/";
|
|
1260
|
+
var SECRETS_SPACE = "secrets";
|
|
1261
|
+
function ok() {
|
|
1262
|
+
return { ok: true, data: void 0 };
|
|
1263
|
+
}
|
|
1264
|
+
function secretsError(code, message, cause) {
|
|
1265
|
+
return {
|
|
1266
|
+
ok: false,
|
|
1267
|
+
error: {
|
|
1268
|
+
code,
|
|
1269
|
+
service: "secrets",
|
|
1270
|
+
message,
|
|
1271
|
+
...cause ? { cause } : {}
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
function actionUrn(action) {
|
|
1276
|
+
return `tinycloud.kv/${action}`;
|
|
1277
|
+
}
|
|
1278
|
+
function secretResourcePath(base, name) {
|
|
1279
|
+
return `${base}/${SECRET_PREFIX}${name}`;
|
|
1280
|
+
}
|
|
1281
|
+
function secretPermissionEntries(name, action) {
|
|
1282
|
+
return [
|
|
1283
|
+
{
|
|
1284
|
+
service: "tinycloud.kv",
|
|
1285
|
+
space: SECRETS_SPACE,
|
|
1286
|
+
path: secretResourcePath("keys", name),
|
|
1287
|
+
actions: [action],
|
|
1288
|
+
skipPrefix: true
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
service: "tinycloud.kv",
|
|
1292
|
+
space: SECRETS_SPACE,
|
|
1293
|
+
path: secretResourcePath("vault", name),
|
|
1294
|
+
actions: [action],
|
|
1295
|
+
skipPrefix: true
|
|
1296
|
+
}
|
|
1297
|
+
];
|
|
1298
|
+
}
|
|
1299
|
+
function isSecretsSpace(space) {
|
|
1300
|
+
return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
|
|
1301
|
+
}
|
|
1302
|
+
var NodeSecretsService = class {
|
|
1303
|
+
constructor(config) {
|
|
1304
|
+
this.config = config;
|
|
1305
|
+
this.shouldRestoreUnlock = false;
|
|
1306
|
+
}
|
|
1307
|
+
get vault() {
|
|
1308
|
+
return this.service.vault;
|
|
1309
|
+
}
|
|
1310
|
+
get isUnlocked() {
|
|
1311
|
+
return this.service.isUnlocked;
|
|
1312
|
+
}
|
|
1313
|
+
async unlock(signer) {
|
|
1314
|
+
const effectiveSigner = signer ?? this.config.getUnlockSigner?.();
|
|
1315
|
+
if (effectiveSigner !== void 0) {
|
|
1316
|
+
this.unlockSigner = effectiveSigner;
|
|
1317
|
+
}
|
|
1318
|
+
const result = await this.service.unlock(effectiveSigner);
|
|
1319
|
+
if (result.ok) {
|
|
1320
|
+
this.shouldRestoreUnlock = true;
|
|
1321
|
+
}
|
|
1322
|
+
return result;
|
|
1323
|
+
}
|
|
1324
|
+
lock() {
|
|
1325
|
+
this.shouldRestoreUnlock = false;
|
|
1326
|
+
this.service.lock();
|
|
1327
|
+
}
|
|
1328
|
+
get(name) {
|
|
1329
|
+
return this.service.get(name);
|
|
1330
|
+
}
|
|
1331
|
+
async put(name, value) {
|
|
1332
|
+
const permission = await this.ensureMutationPermission(name, "put");
|
|
1333
|
+
if (!permission.ok) return permission;
|
|
1334
|
+
return this.service.put(name, value);
|
|
1335
|
+
}
|
|
1336
|
+
async delete(name) {
|
|
1337
|
+
const permission = await this.ensureMutationPermission(name, "del");
|
|
1338
|
+
if (!permission.ok) return permission;
|
|
1339
|
+
return this.service.delete(name);
|
|
1340
|
+
}
|
|
1341
|
+
list() {
|
|
1342
|
+
return this.service.list();
|
|
1343
|
+
}
|
|
1344
|
+
get service() {
|
|
1345
|
+
return this.config.getService();
|
|
1346
|
+
}
|
|
1347
|
+
async ensureMutationPermission(name, action) {
|
|
1348
|
+
if (!SECRET_NAME_RE.test(name)) {
|
|
1349
|
+
return secretsError(
|
|
1350
|
+
import_sdk_core5.ErrorCodes.INVALID_INPUT,
|
|
1351
|
+
`Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1354
|
+
if (this.hasMutationPermission(name, action)) {
|
|
1355
|
+
return ok();
|
|
1356
|
+
}
|
|
1357
|
+
if (!this.config.canEscalate()) {
|
|
1358
|
+
return secretsError(
|
|
1359
|
+
import_sdk_core5.ErrorCodes.PERMISSION_DENIED,
|
|
1360
|
+
`Cannot autosign ${actionUrn(action)} for ${name}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
try {
|
|
1364
|
+
await this.config.grantPermissions(secretPermissionEntries(name, action));
|
|
1365
|
+
return this.restoreUnlockAfterEscalation();
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
return secretsError(
|
|
1368
|
+
import_sdk_core5.ErrorCodes.PERMISSION_DENIED,
|
|
1369
|
+
error instanceof Error ? error.message : `Autosign escalation for ${actionUrn(action)} on ${name} failed.`,
|
|
1370
|
+
error instanceof Error ? error : void 0
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
async restoreUnlockAfterEscalation() {
|
|
1375
|
+
if (!this.shouldRestoreUnlock) {
|
|
1376
|
+
return ok();
|
|
1377
|
+
}
|
|
1378
|
+
return this.service.unlock(this.unlockSigner);
|
|
1379
|
+
}
|
|
1380
|
+
hasMutationPermission(name, action) {
|
|
1381
|
+
const manifest = this.config.getManifest();
|
|
1382
|
+
if (manifest === void 0) {
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
1386
|
+
const requiredAction = actionUrn(action);
|
|
1387
|
+
return manifests.some((entry) => {
|
|
1388
|
+
const resolved = (0, import_sdk_core5.resolveManifest)(entry);
|
|
1389
|
+
return ["keys", "vault"].every(
|
|
1390
|
+
(base) => resolved.resources.some(
|
|
1391
|
+
(resource) => resource.service === "tinycloud.kv" && isSecretsSpace(resource.space) && resource.path === secretResourcePath(base, name) && resource.actions.includes(requiredAction)
|
|
1392
|
+
)
|
|
1393
|
+
);
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1255
1398
|
// src/TinyCloudNode.ts
|
|
1256
1399
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
1257
1400
|
var _TinyCloudNode = class _TinyCloudNode {
|
|
@@ -1283,6 +1426,30 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1283
1426
|
this.auth = null;
|
|
1284
1427
|
this.tc = null;
|
|
1285
1428
|
this._chainId = 1;
|
|
1429
|
+
this.runtimePermissionGrants = [];
|
|
1430
|
+
this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
|
|
1431
|
+
return this.wasmBindings.invoke(
|
|
1432
|
+
this.selectInvocationSession(session, service, path, action),
|
|
1433
|
+
service,
|
|
1434
|
+
path,
|
|
1435
|
+
action,
|
|
1436
|
+
facts
|
|
1437
|
+
);
|
|
1438
|
+
};
|
|
1439
|
+
this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
|
|
1440
|
+
if (!this.wasmBindings.invokeAny) {
|
|
1441
|
+
throw new Error("WASM binding does not support invokeAny");
|
|
1442
|
+
}
|
|
1443
|
+
const grant = this.findGrantForOperations(
|
|
1444
|
+
entries.map((entry) => ({
|
|
1445
|
+
spaceId: entry.spaceId,
|
|
1446
|
+
service: this.invocationServiceName(entry.service),
|
|
1447
|
+
path: entry.path,
|
|
1448
|
+
action: entry.action
|
|
1449
|
+
}))
|
|
1450
|
+
);
|
|
1451
|
+
return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
|
|
1452
|
+
};
|
|
1286
1453
|
this.explicitHost = config.host;
|
|
1287
1454
|
this.config = {
|
|
1288
1455
|
...config,
|
|
@@ -1310,23 +1477,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1310
1477
|
throw new Error("Failed to get session key JWK");
|
|
1311
1478
|
}
|
|
1312
1479
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
1313
|
-
this._capabilityRegistry = new
|
|
1480
|
+
this._capabilityRegistry = new import_sdk_core6.CapabilityKeyRegistry();
|
|
1314
1481
|
this._keyProvider = new WasmKeyProvider({
|
|
1315
1482
|
sessionManager: this.sessionManager
|
|
1316
1483
|
});
|
|
1317
|
-
this.notificationHandler = config.notificationHandler ?? new
|
|
1318
|
-
this._sharingService = new
|
|
1484
|
+
this.notificationHandler = config.notificationHandler ?? new import_sdk_core6.SilentNotificationHandler();
|
|
1485
|
+
this._sharingService = new import_sdk_core6.SharingService({
|
|
1319
1486
|
hosts: [this.config.host],
|
|
1320
1487
|
// session: undefined - not needed for receive()
|
|
1321
|
-
invoke: this.
|
|
1488
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1322
1489
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1323
1490
|
keyProvider: this._keyProvider,
|
|
1324
1491
|
registry: this._capabilityRegistry,
|
|
1325
1492
|
// delegationManager: undefined - not needed for receive()
|
|
1326
1493
|
createKVService: (config2) => {
|
|
1327
1494
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
1328
|
-
const kvService = new
|
|
1329
|
-
const kvContext = new
|
|
1495
|
+
const kvService = new import_sdk_core6.KVService({ prefix });
|
|
1496
|
+
const kvContext = new import_sdk_core6.ServiceContext({
|
|
1330
1497
|
invoke: config2.invoke,
|
|
1331
1498
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
1332
1499
|
hosts: config2.hosts
|
|
@@ -1385,8 +1552,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1385
1552
|
capabilityRequest: config.capabilityRequest,
|
|
1386
1553
|
includeAccountRegistryPermissions: config.includeAccountRegistryPermissions
|
|
1387
1554
|
});
|
|
1388
|
-
this.tc = new
|
|
1389
|
-
invokeAny: this.
|
|
1555
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1556
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1390
1557
|
});
|
|
1391
1558
|
}
|
|
1392
1559
|
syncResolvedHostFromAuth() {
|
|
@@ -1506,7 +1673,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1506
1673
|
this._sql = void 0;
|
|
1507
1674
|
this._duckdb = void 0;
|
|
1508
1675
|
this._hooks = void 0;
|
|
1676
|
+
this._vault = void 0;
|
|
1677
|
+
this._baseSecrets = void 0;
|
|
1678
|
+
this._secrets = void 0;
|
|
1679
|
+
this._spaceService = void 0;
|
|
1509
1680
|
this._serviceContext = void 0;
|
|
1681
|
+
this.runtimePermissionGrants = [];
|
|
1510
1682
|
await this.tc.signIn(options);
|
|
1511
1683
|
this.syncResolvedHostFromAuth();
|
|
1512
1684
|
this.initializeServices();
|
|
@@ -1527,7 +1699,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1527
1699
|
if (!this.auth || !this.signer) {
|
|
1528
1700
|
throw new Error("Manifest registry write requires wallet mode");
|
|
1529
1701
|
}
|
|
1530
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
1702
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core6.ACCOUNT_REGISTRY_SPACE);
|
|
1531
1703
|
await this.ensureOwnedSpaceHosted(accountSpaceId);
|
|
1532
1704
|
const accountKV = this.spaces.get(accountSpaceId).kv;
|
|
1533
1705
|
for (const record of request.registryRecords) {
|
|
@@ -1555,7 +1727,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1555
1727
|
if (!host) {
|
|
1556
1728
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
1557
1729
|
}
|
|
1558
|
-
const activation = await (0,
|
|
1730
|
+
const activation = await (0, import_sdk_core6.activateSessionWithHost)(host, session.delegationHeader);
|
|
1559
1731
|
if (activation.success && !activation.skipped?.includes(spaceId)) {
|
|
1560
1732
|
return;
|
|
1561
1733
|
}
|
|
@@ -1569,7 +1741,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1569
1741
|
throw new Error(`Failed to create owned space: ${spaceId}`);
|
|
1570
1742
|
}
|
|
1571
1743
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1572
|
-
const retry = await (0,
|
|
1744
|
+
const retry = await (0, import_sdk_core6.activateSessionWithHost)(host, session.delegationHeader);
|
|
1573
1745
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
1574
1746
|
throw new Error(
|
|
1575
1747
|
`Failed to activate session after creating owned space ${spaceId}: ${retry.error ?? "space was skipped"}`
|
|
@@ -1591,29 +1763,34 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1591
1763
|
this._sql = void 0;
|
|
1592
1764
|
this._duckdb = void 0;
|
|
1593
1765
|
this._hooks = void 0;
|
|
1766
|
+
this._vault = void 0;
|
|
1767
|
+
this._baseSecrets = void 0;
|
|
1768
|
+
this._secrets = void 0;
|
|
1769
|
+
this._spaceService = void 0;
|
|
1594
1770
|
this._serviceContext = void 0;
|
|
1771
|
+
this.runtimePermissionGrants = [];
|
|
1595
1772
|
if (sessionData.address) {
|
|
1596
1773
|
this._address = sessionData.address;
|
|
1597
1774
|
}
|
|
1598
1775
|
if (sessionData.chainId) {
|
|
1599
1776
|
this._chainId = sessionData.chainId;
|
|
1600
1777
|
}
|
|
1601
|
-
this._serviceContext = new
|
|
1602
|
-
invoke: this.
|
|
1603
|
-
invokeAny: this.
|
|
1778
|
+
this._serviceContext = new import_sdk_core6.ServiceContext({
|
|
1779
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1780
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
1604
1781
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1605
1782
|
hosts: [this.config.host]
|
|
1606
1783
|
});
|
|
1607
|
-
this._kv = new
|
|
1784
|
+
this._kv = new import_sdk_core6.KVService({});
|
|
1608
1785
|
this._kv.initialize(this._serviceContext);
|
|
1609
1786
|
this._serviceContext.registerService("kv", this._kv);
|
|
1610
|
-
this._sql = new
|
|
1787
|
+
this._sql = new import_sdk_core6.SQLService({});
|
|
1611
1788
|
this._sql.initialize(this._serviceContext);
|
|
1612
1789
|
this._serviceContext.registerService("sql", this._sql);
|
|
1613
|
-
this._duckdb = new
|
|
1790
|
+
this._duckdb = new import_sdk_core6.DuckDbService({});
|
|
1614
1791
|
this._duckdb.initialize(this._serviceContext);
|
|
1615
1792
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1616
|
-
this._hooks = new
|
|
1793
|
+
this._hooks = new import_sdk_core6.HooksService({});
|
|
1617
1794
|
this._hooks.initialize(this._serviceContext);
|
|
1618
1795
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1619
1796
|
const serviceSession = {
|
|
@@ -1624,41 +1801,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1624
1801
|
jwk: sessionData.jwk
|
|
1625
1802
|
};
|
|
1626
1803
|
this._serviceContext.setSession(serviceSession);
|
|
1627
|
-
|
|
1628
|
-
const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
|
|
1629
|
-
vault_encrypt: wasm.vault_encrypt,
|
|
1630
|
-
vault_decrypt: wasm.vault_decrypt,
|
|
1631
|
-
vault_derive_key: wasm.vault_derive_key,
|
|
1632
|
-
vault_x25519_from_seed: wasm.vault_x25519_from_seed,
|
|
1633
|
-
vault_x25519_dh: wasm.vault_x25519_dh,
|
|
1634
|
-
vault_random_bytes: wasm.vault_random_bytes,
|
|
1635
|
-
vault_sha256: wasm.vault_sha256
|
|
1636
|
-
});
|
|
1637
|
-
const self = this;
|
|
1638
|
-
this._vault = new import_sdk_core5.DataVaultService({
|
|
1639
|
-
spaceId: sessionData.spaceId,
|
|
1640
|
-
crypto: vaultCrypto,
|
|
1641
|
-
tc: {
|
|
1642
|
-
kv: this._kv,
|
|
1643
|
-
ensurePublicSpace: async () => {
|
|
1644
|
-
try {
|
|
1645
|
-
await self.ensurePublicSpace();
|
|
1646
|
-
return { ok: true, data: void 0 };
|
|
1647
|
-
} catch (error) {
|
|
1648
|
-
return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
|
|
1649
|
-
}
|
|
1650
|
-
},
|
|
1651
|
-
get publicKV() {
|
|
1652
|
-
return self._publicKV ?? self.tc.publicKV;
|
|
1653
|
-
},
|
|
1654
|
-
readPublicSpace: (host, spaceId, key) => import_sdk_core5.TinyCloud.readPublicSpace(host, spaceId, key),
|
|
1655
|
-
makePublicSpaceId: import_sdk_core5.TinyCloud.makePublicSpaceId,
|
|
1656
|
-
did: this.did,
|
|
1657
|
-
address: sessionData.address ?? this._address ?? "",
|
|
1658
|
-
chainId: sessionData.chainId ?? this._chainId,
|
|
1659
|
-
hosts: [this.config.host]
|
|
1660
|
-
}
|
|
1661
|
-
});
|
|
1804
|
+
this._vault = this.createVaultService(sessionData.spaceId, this._kv);
|
|
1662
1805
|
this._vault.initialize(this._serviceContext);
|
|
1663
1806
|
this._serviceContext.registerService("vault", this._vault);
|
|
1664
1807
|
this.initializeV2Services(serviceSession);
|
|
@@ -1719,8 +1862,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1719
1862
|
capabilityRequest: this.config.capabilityRequest,
|
|
1720
1863
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
1721
1864
|
});
|
|
1722
|
-
this.tc = new
|
|
1723
|
-
invokeAny: this.
|
|
1865
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1866
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1724
1867
|
});
|
|
1725
1868
|
this.config.prefix = prefix;
|
|
1726
1869
|
}
|
|
@@ -1763,8 +1906,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1763
1906
|
capabilityRequest: this.config.capabilityRequest,
|
|
1764
1907
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
1765
1908
|
});
|
|
1766
|
-
this.tc = new
|
|
1767
|
-
invokeAny: this.
|
|
1909
|
+
this.tc = new import_sdk_core6.TinyCloud(this.auth, {
|
|
1910
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
1768
1911
|
});
|
|
1769
1912
|
this.config.prefix = prefix;
|
|
1770
1913
|
}
|
|
@@ -1777,28 +1920,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1777
1920
|
if (!session) {
|
|
1778
1921
|
return;
|
|
1779
1922
|
}
|
|
1780
|
-
this.tc.initializeServices(this.
|
|
1781
|
-
this._serviceContext = new
|
|
1782
|
-
invoke: this.
|
|
1783
|
-
invokeAny: this.
|
|
1923
|
+
this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
|
|
1924
|
+
this._serviceContext = new import_sdk_core6.ServiceContext({
|
|
1925
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1926
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
1784
1927
|
fetch: globalThis.fetch.bind(globalThis),
|
|
1785
1928
|
hosts: [this.config.host]
|
|
1786
1929
|
});
|
|
1787
|
-
this._kv = new
|
|
1930
|
+
this._kv = new import_sdk_core6.KVService({});
|
|
1788
1931
|
this._kv.initialize(this._serviceContext);
|
|
1789
1932
|
this._serviceContext.registerService("kv", this._kv);
|
|
1790
1933
|
const features = this.nodeFeatures;
|
|
1791
1934
|
if (features.length === 0 || features.includes("sql")) {
|
|
1792
|
-
this._sql = new
|
|
1935
|
+
this._sql = new import_sdk_core6.SQLService({});
|
|
1793
1936
|
this._sql.initialize(this._serviceContext);
|
|
1794
1937
|
this._serviceContext.registerService("sql", this._sql);
|
|
1795
1938
|
}
|
|
1796
1939
|
if (features.length === 0 || features.includes("duckdb")) {
|
|
1797
|
-
this._duckdb = new
|
|
1940
|
+
this._duckdb = new import_sdk_core6.DuckDbService({});
|
|
1798
1941
|
this._duckdb.initialize(this._serviceContext);
|
|
1799
1942
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
1800
1943
|
}
|
|
1801
|
-
this._hooks = new
|
|
1944
|
+
this._hooks = new import_sdk_core6.HooksService({});
|
|
1802
1945
|
this._hooks.initialize(this._serviceContext);
|
|
1803
1946
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
1804
1947
|
const serviceSession = {
|
|
@@ -1810,8 +1953,30 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1810
1953
|
};
|
|
1811
1954
|
this._serviceContext.setSession(serviceSession);
|
|
1812
1955
|
this.tc.serviceContext.setSession(serviceSession);
|
|
1956
|
+
this._vault = this.createVaultService(session.spaceId, this._kv);
|
|
1957
|
+
this._vault.initialize(this._serviceContext);
|
|
1958
|
+
this._serviceContext.registerService("vault", this._vault);
|
|
1959
|
+
this.initializeV2Services(serviceSession);
|
|
1960
|
+
}
|
|
1961
|
+
createSpaceScopedKVService(spaceId) {
|
|
1962
|
+
const kvService = new import_sdk_core6.KVService({});
|
|
1963
|
+
if (this._serviceContext) {
|
|
1964
|
+
const spaceScopedContext = new import_sdk_core6.ServiceContext({
|
|
1965
|
+
invoke: this._serviceContext.invoke,
|
|
1966
|
+
fetch: this._serviceContext.fetch,
|
|
1967
|
+
hosts: this._serviceContext.hosts
|
|
1968
|
+
});
|
|
1969
|
+
const session = this._serviceContext.session;
|
|
1970
|
+
if (session) {
|
|
1971
|
+
spaceScopedContext.setSession({ ...session, spaceId });
|
|
1972
|
+
}
|
|
1973
|
+
kvService.initialize(spaceScopedContext);
|
|
1974
|
+
}
|
|
1975
|
+
return kvService;
|
|
1976
|
+
}
|
|
1977
|
+
createVaultService(spaceId, kv) {
|
|
1813
1978
|
const wasm = this.wasmBindings;
|
|
1814
|
-
const vaultCrypto = (0,
|
|
1979
|
+
const vaultCrypto = (0, import_sdk_core6.createVaultCrypto)({
|
|
1815
1980
|
vault_encrypt: wasm.vault_encrypt,
|
|
1816
1981
|
vault_decrypt: wasm.vault_decrypt,
|
|
1817
1982
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -1821,11 +1986,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1821
1986
|
vault_sha256: wasm.vault_sha256
|
|
1822
1987
|
});
|
|
1823
1988
|
const self = this;
|
|
1824
|
-
|
|
1825
|
-
spaceId
|
|
1989
|
+
return new import_sdk_core6.DataVaultService({
|
|
1990
|
+
spaceId,
|
|
1826
1991
|
crypto: vaultCrypto,
|
|
1827
1992
|
tc: {
|
|
1828
|
-
kv
|
|
1993
|
+
kv,
|
|
1829
1994
|
ensurePublicSpace: async () => {
|
|
1830
1995
|
try {
|
|
1831
1996
|
await self.ensurePublicSpace();
|
|
@@ -1837,24 +2002,21 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1837
2002
|
get publicKV() {
|
|
1838
2003
|
return self._publicKV ?? self.tc.publicKV;
|
|
1839
2004
|
},
|
|
1840
|
-
readPublicSpace: (host,
|
|
1841
|
-
makePublicSpaceId:
|
|
2005
|
+
readPublicSpace: (host, targetSpaceId, key) => import_sdk_core6.TinyCloud.readPublicSpace(host, targetSpaceId, key),
|
|
2006
|
+
makePublicSpaceId: import_sdk_core6.TinyCloud.makePublicSpaceId,
|
|
1842
2007
|
did: this.did,
|
|
1843
|
-
address: this._address,
|
|
2008
|
+
address: this._address ?? "",
|
|
1844
2009
|
chainId: this._chainId,
|
|
1845
2010
|
hosts: [this.config.host]
|
|
1846
2011
|
}
|
|
1847
2012
|
});
|
|
1848
|
-
this._vault.initialize(this._serviceContext);
|
|
1849
|
-
this._serviceContext.registerService("vault", this._vault);
|
|
1850
|
-
this.initializeV2Services(serviceSession);
|
|
1851
2013
|
}
|
|
1852
2014
|
/**
|
|
1853
2015
|
* Initialize the v2 delegation system services.
|
|
1854
2016
|
* @internal
|
|
1855
2017
|
*/
|
|
1856
2018
|
initializeV2Services(serviceSession) {
|
|
1857
|
-
this._capabilityRegistry = new
|
|
2019
|
+
this._capabilityRegistry = new import_sdk_core6.CapabilityKeyRegistry();
|
|
1858
2020
|
const tcSession = this.auth?.tinyCloudSession;
|
|
1859
2021
|
if (tcSession && this._address) {
|
|
1860
2022
|
const sessionKey = {
|
|
@@ -1928,13 +2090,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1928
2090
|
}
|
|
1929
2091
|
this._capabilityRegistry.registerKey(sessionKey, delegations);
|
|
1930
2092
|
}
|
|
1931
|
-
this._delegationManager = new
|
|
2093
|
+
this._delegationManager = new import_sdk_core6.DelegationManager({
|
|
1932
2094
|
hosts: [this.config.host],
|
|
1933
2095
|
session: serviceSession,
|
|
1934
|
-
invoke: this.
|
|
2096
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
1935
2097
|
fetch: globalThis.fetch.bind(globalThis)
|
|
1936
2098
|
});
|
|
1937
|
-
this._spaceService = new
|
|
2099
|
+
this._spaceService = new import_sdk_core6.SpaceService({
|
|
1938
2100
|
hosts: [this.config.host],
|
|
1939
2101
|
session: serviceSession,
|
|
1940
2102
|
invoke: this.wasmBindings.invoke,
|
|
@@ -1942,20 +2104,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
1942
2104
|
capabilityRegistry: this._capabilityRegistry,
|
|
1943
2105
|
userDid: this.did,
|
|
1944
2106
|
createKVService: (spaceId) => {
|
|
1945
|
-
|
|
2107
|
+
return this.createSpaceScopedKVService(spaceId);
|
|
2108
|
+
},
|
|
2109
|
+
createVaultService: (spaceId) => {
|
|
2110
|
+
const kvService = this.createSpaceScopedKVService(spaceId);
|
|
2111
|
+
const vaultService = this.createVaultService(spaceId, kvService);
|
|
1946
2112
|
if (this._serviceContext) {
|
|
1947
|
-
|
|
1948
|
-
invoke: this._serviceContext.invoke,
|
|
1949
|
-
fetch: this._serviceContext.fetch,
|
|
1950
|
-
hosts: this._serviceContext.hosts
|
|
1951
|
-
});
|
|
1952
|
-
const session = this._serviceContext.session;
|
|
1953
|
-
if (session) {
|
|
1954
|
-
spaceScopedContext.setSession({ ...session, spaceId });
|
|
1955
|
-
}
|
|
1956
|
-
kvService.initialize(spaceScopedContext);
|
|
2113
|
+
vaultService.initialize(this._serviceContext);
|
|
1957
2114
|
}
|
|
1958
|
-
return
|
|
2115
|
+
return vaultService;
|
|
1959
2116
|
},
|
|
1960
2117
|
// Enable space.delegations.create() via SIWE-based delegation
|
|
1961
2118
|
createDelegation: async (params) => {
|
|
@@ -2096,7 +2253,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2096
2253
|
...prepared,
|
|
2097
2254
|
signature
|
|
2098
2255
|
});
|
|
2099
|
-
const activateResult = await (0,
|
|
2256
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2100
2257
|
host,
|
|
2101
2258
|
delegationSession.delegationHeader
|
|
2102
2259
|
);
|
|
@@ -2163,7 +2320,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2163
2320
|
if (!this._sql) {
|
|
2164
2321
|
const features = this.nodeFeatures;
|
|
2165
2322
|
if (features.length > 0 && !features.includes("sql")) {
|
|
2166
|
-
throw new
|
|
2323
|
+
throw new import_sdk_core6.UnsupportedFeatureError("sql", this.config.host, features);
|
|
2167
2324
|
}
|
|
2168
2325
|
throw new Error("Not signed in. Call signIn() first.");
|
|
2169
2326
|
}
|
|
@@ -2176,7 +2333,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2176
2333
|
if (!this._duckdb) {
|
|
2177
2334
|
const features = this.nodeFeatures;
|
|
2178
2335
|
if (features.length > 0 && !features.includes("duckdb")) {
|
|
2179
|
-
throw new
|
|
2336
|
+
throw new import_sdk_core6.UnsupportedFeatureError("duckdb", this.config.host, features);
|
|
2180
2337
|
}
|
|
2181
2338
|
throw new Error("Not signed in. Call signIn() first.");
|
|
2182
2339
|
}
|
|
@@ -2192,6 +2349,33 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2192
2349
|
}
|
|
2193
2350
|
return this._vault;
|
|
2194
2351
|
}
|
|
2352
|
+
/**
|
|
2353
|
+
* App-facing secrets API backed by the `secrets` space vault.
|
|
2354
|
+
*/
|
|
2355
|
+
get secrets() {
|
|
2356
|
+
if (!this._spaceService) {
|
|
2357
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2358
|
+
}
|
|
2359
|
+
if (!this._secrets) {
|
|
2360
|
+
this._secrets = new NodeSecretsService({
|
|
2361
|
+
getService: () => this.getBaseSecrets(),
|
|
2362
|
+
getManifest: () => this.manifest,
|
|
2363
|
+
grantPermissions: (additional) => this.grantRuntimePermissions(additional),
|
|
2364
|
+
canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
|
|
2365
|
+
getUnlockSigner: () => this.signer ?? void 0
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
return this._secrets;
|
|
2369
|
+
}
|
|
2370
|
+
getBaseSecrets() {
|
|
2371
|
+
if (!this._spaceService) {
|
|
2372
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
2373
|
+
}
|
|
2374
|
+
if (!this._baseSecrets) {
|
|
2375
|
+
this._baseSecrets = new import_sdk_core6.SecretsService(() => this.space("secrets").vault);
|
|
2376
|
+
}
|
|
2377
|
+
return this._baseSecrets;
|
|
2378
|
+
}
|
|
2195
2379
|
/**
|
|
2196
2380
|
* Hooks write stream subscription API.
|
|
2197
2381
|
*/
|
|
@@ -2262,6 +2446,171 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2262
2446
|
}
|
|
2263
2447
|
};
|
|
2264
2448
|
}
|
|
2449
|
+
/**
|
|
2450
|
+
* Check whether the current session or an approved runtime delegation covers
|
|
2451
|
+
* every requested permission.
|
|
2452
|
+
*/
|
|
2453
|
+
hasRuntimePermissions(permissions) {
|
|
2454
|
+
const session = this.auth?.tinyCloudSession;
|
|
2455
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
2456
|
+
return false;
|
|
2457
|
+
}
|
|
2458
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2459
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
2460
|
+
return true;
|
|
2461
|
+
}
|
|
2462
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).length > 0;
|
|
2463
|
+
}
|
|
2464
|
+
/**
|
|
2465
|
+
* Return installed runtime permission delegations. When `permissions` is
|
|
2466
|
+
* provided, only delegations currently covering those permissions are
|
|
2467
|
+
* returned. Base-session manifest permissions are not represented here.
|
|
2468
|
+
*/
|
|
2469
|
+
getRuntimePermissionDelegations(permissions) {
|
|
2470
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
2471
|
+
if (permissions === void 0) {
|
|
2472
|
+
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
2473
|
+
}
|
|
2474
|
+
const session = this.auth?.tinyCloudSession;
|
|
2475
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
2476
|
+
return [];
|
|
2477
|
+
}
|
|
2478
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2479
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).map(
|
|
2480
|
+
(grant) => grant.delegation
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
/**
|
|
2484
|
+
* Install a portable runtime permission delegation into this SDK instance so
|
|
2485
|
+
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
2486
|
+
*/
|
|
2487
|
+
async useRuntimeDelegation(delegation) {
|
|
2488
|
+
const session = this.auth?.tinyCloudSession;
|
|
2489
|
+
if (!session) {
|
|
2490
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2491
|
+
}
|
|
2492
|
+
if (delegation.expiry.getTime() <= Date.now()) {
|
|
2493
|
+
throw new import_sdk_core6.SessionExpiredError(delegation.expiry);
|
|
2494
|
+
}
|
|
2495
|
+
const expectedDids = /* @__PURE__ */ new Set([session.verificationMethod, this.sessionDid]);
|
|
2496
|
+
if (!expectedDids.has(delegation.delegateDID)) {
|
|
2497
|
+
throw new Error(
|
|
2498
|
+
`Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
|
|
2499
|
+
);
|
|
2500
|
+
}
|
|
2501
|
+
const targetHost = delegation.host ?? this.config.host;
|
|
2502
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2503
|
+
targetHost,
|
|
2504
|
+
delegation.delegationHeader
|
|
2505
|
+
);
|
|
2506
|
+
if (!activateResult.success) {
|
|
2507
|
+
throw new Error(
|
|
2508
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
2509
|
+
);
|
|
2510
|
+
}
|
|
2511
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
2512
|
+
(grant) => grant.delegation.cid !== delegation.cid
|
|
2513
|
+
);
|
|
2514
|
+
this.runtimePermissionGrants.push(
|
|
2515
|
+
this.runtimeGrantFromDelegation(delegation, session)
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Store additional permissions as narrow delegations to the current session
|
|
2520
|
+
* key. Future service invocations automatically use a stored delegation when
|
|
2521
|
+
* its `(space, service, path, action)` covers the request.
|
|
2522
|
+
*/
|
|
2523
|
+
async grantRuntimePermissions(permissions, options) {
|
|
2524
|
+
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
2525
|
+
throw new Error("grantRuntimePermissions requires a non-empty permissions array");
|
|
2526
|
+
}
|
|
2527
|
+
const session = this.auth?.tinyCloudSession;
|
|
2528
|
+
if (!session) {
|
|
2529
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2530
|
+
}
|
|
2531
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
2532
|
+
if (sessionExpiry !== void 0) {
|
|
2533
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2534
|
+
if (sessionExpiry.getTime() <= Date.now() + marginMs) {
|
|
2535
|
+
throw new import_sdk_core6.SessionExpiredError(sessionExpiry);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
2539
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
2540
|
+
return [];
|
|
2541
|
+
}
|
|
2542
|
+
const existingGrants = this.findRuntimeGrantsForPermissionEntries(expanded, session);
|
|
2543
|
+
if (existingGrants.length > 0) {
|
|
2544
|
+
return existingGrants.map((grant) => grant.delegation);
|
|
2545
|
+
}
|
|
2546
|
+
if (!this.signer) {
|
|
2547
|
+
throw new Error(
|
|
2548
|
+
"grantRuntimePermissions requires wallet mode with a signer or privateKey."
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
const bySpace = /* @__PURE__ */ new Map();
|
|
2552
|
+
for (const entry of expanded) {
|
|
2553
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
2554
|
+
const current = bySpace.get(spaceId) ?? [];
|
|
2555
|
+
current.push(entry);
|
|
2556
|
+
bySpace.set(spaceId, current);
|
|
2557
|
+
}
|
|
2558
|
+
const now = /* @__PURE__ */ new Date();
|
|
2559
|
+
const requestedExpiryMs = resolveExpiryMs(options?.expiry);
|
|
2560
|
+
let expiresAt = new Date(now.getTime() + requestedExpiryMs);
|
|
2561
|
+
if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
|
|
2562
|
+
expiresAt = sessionExpiry;
|
|
2563
|
+
}
|
|
2564
|
+
const delegations = [];
|
|
2565
|
+
for (const [spaceId, entries] of bySpace) {
|
|
2566
|
+
const abilities = this.permissionsToAbilities(entries);
|
|
2567
|
+
const prepared = this.wasmBindings.prepareSession({
|
|
2568
|
+
abilities,
|
|
2569
|
+
address: this.wasmBindings.ensureEip55(session.address),
|
|
2570
|
+
chainId: session.chainId,
|
|
2571
|
+
domain: this.siweDomain,
|
|
2572
|
+
issuedAt: now.toISOString(),
|
|
2573
|
+
expirationTime: expiresAt.toISOString(),
|
|
2574
|
+
spaceId,
|
|
2575
|
+
jwk: session.jwk
|
|
2576
|
+
});
|
|
2577
|
+
const signature = await this.signer.signMessage(prepared.siwe);
|
|
2578
|
+
const delegatedSession = this.wasmBindings.completeSessionSetup({
|
|
2579
|
+
...prepared,
|
|
2580
|
+
signature
|
|
2581
|
+
});
|
|
2582
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2583
|
+
this.config.host,
|
|
2584
|
+
delegatedSession.delegationHeader
|
|
2585
|
+
);
|
|
2586
|
+
if (!activateResult.success) {
|
|
2587
|
+
throw new Error(
|
|
2588
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
2589
|
+
);
|
|
2590
|
+
}
|
|
2591
|
+
const delegation = this.runtimeDelegationFromSession(
|
|
2592
|
+
delegatedSession,
|
|
2593
|
+
entries,
|
|
2594
|
+
spaceId,
|
|
2595
|
+
session,
|
|
2596
|
+
expiresAt
|
|
2597
|
+
);
|
|
2598
|
+
this.runtimePermissionGrants.push({
|
|
2599
|
+
session: {
|
|
2600
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
2601
|
+
delegationCid: delegatedSession.delegationCid,
|
|
2602
|
+
spaceId,
|
|
2603
|
+
verificationMethod: session.verificationMethod,
|
|
2604
|
+
jwk: session.jwk
|
|
2605
|
+
},
|
|
2606
|
+
delegation,
|
|
2607
|
+
operations: this.permissionOperations(entries, spaceId),
|
|
2608
|
+
expiresAt
|
|
2609
|
+
});
|
|
2610
|
+
delegations.push(delegation);
|
|
2611
|
+
}
|
|
2612
|
+
return delegations;
|
|
2613
|
+
}
|
|
2265
2614
|
/**
|
|
2266
2615
|
* Get the DelegationManager for delegation CRUD operations.
|
|
2267
2616
|
*
|
|
@@ -2330,6 +2679,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2330
2679
|
get spaceService() {
|
|
2331
2680
|
return this.spaces;
|
|
2332
2681
|
}
|
|
2682
|
+
/**
|
|
2683
|
+
* Get a Space object by short name or full URI.
|
|
2684
|
+
*/
|
|
2685
|
+
space(nameOrUri) {
|
|
2686
|
+
return this.spaces.get(nameOrUri);
|
|
2687
|
+
}
|
|
2333
2688
|
/**
|
|
2334
2689
|
* Get the SharingService for creating and receiving v2 sharing links.
|
|
2335
2690
|
*
|
|
@@ -2415,7 +2770,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2415
2770
|
...prepared,
|
|
2416
2771
|
signature
|
|
2417
2772
|
});
|
|
2418
|
-
const activateResult = await (0,
|
|
2773
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2419
2774
|
this.config.host,
|
|
2420
2775
|
delegationSession.delegationHeader
|
|
2421
2776
|
);
|
|
@@ -2442,9 +2797,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2442
2797
|
}]);
|
|
2443
2798
|
}
|
|
2444
2799
|
if (this._serviceContext) {
|
|
2445
|
-
const publicKV = new
|
|
2446
|
-
const publicContext = new
|
|
2447
|
-
invoke: this.
|
|
2800
|
+
const publicKV = new import_sdk_core6.KVService({ prefix: "" });
|
|
2801
|
+
const publicContext = new import_sdk_core6.ServiceContext({
|
|
2802
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
2448
2803
|
fetch: this._serviceContext.fetch,
|
|
2449
2804
|
hosts: this._serviceContext.hosts
|
|
2450
2805
|
});
|
|
@@ -2532,8 +2887,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2532
2887
|
* Issue a delegation using the capability-chain flow.
|
|
2533
2888
|
*
|
|
2534
2889
|
* When every requested permission is a subset of the current
|
|
2535
|
-
* session's recap,
|
|
2536
|
-
*
|
|
2890
|
+
* session's recap, or of one installed runtime permission delegation,
|
|
2891
|
+
* the delegation is signed by the session key via WASM — no wallet
|
|
2892
|
+
* prompt. When at least one is NOT derivable, a
|
|
2537
2893
|
* {@link PermissionNotInManifestError} is raised (carrying the
|
|
2538
2894
|
* missing entries) so the caller can trigger an escalation flow
|
|
2539
2895
|
* (e.g. `TinyCloudWeb.requestPermissions`). Passing
|
|
@@ -2568,14 +2924,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2568
2924
|
async delegateTo(did, permissions, options) {
|
|
2569
2925
|
const session = this.auth?.tinyCloudSession;
|
|
2570
2926
|
if (!session) {
|
|
2571
|
-
throw new
|
|
2927
|
+
throw new import_sdk_core6.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
2572
2928
|
}
|
|
2573
2929
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
2574
2930
|
if (sessionExpiry !== void 0) {
|
|
2575
2931
|
const now2 = Date.now();
|
|
2576
2932
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2577
2933
|
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
2578
|
-
throw new
|
|
2934
|
+
throw new import_sdk_core6.SessionExpiredError(sessionExpiry);
|
|
2579
2935
|
}
|
|
2580
2936
|
}
|
|
2581
2937
|
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -2585,7 +2941,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2585
2941
|
}
|
|
2586
2942
|
const expandedEntries = permissions.map((entry) => ({
|
|
2587
2943
|
...entry,
|
|
2588
|
-
actions: (0,
|
|
2944
|
+
actions: (0, import_sdk_core6.expandActionShortNames)(entry.service, entry.actions)
|
|
2589
2945
|
}));
|
|
2590
2946
|
const now = /* @__PURE__ */ new Date();
|
|
2591
2947
|
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
@@ -2607,13 +2963,30 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2607
2963
|
);
|
|
2608
2964
|
return { delegation: delegation2, prompted: true };
|
|
2609
2965
|
}
|
|
2610
|
-
const granted = (0,
|
|
2966
|
+
const granted = (0, import_sdk_core6.parseRecapCapabilities)(
|
|
2611
2967
|
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
2612
2968
|
session.siwe
|
|
2613
2969
|
);
|
|
2614
|
-
const { subset, missing } = (0,
|
|
2970
|
+
const { subset, missing } = (0, import_sdk_core6.isCapabilitySubset)(expandedEntries, granted);
|
|
2615
2971
|
if (!subset) {
|
|
2616
|
-
|
|
2972
|
+
const runtimeGrant = this.findGrantForOperations(
|
|
2973
|
+
this.permissionEntriesToOperations(expandedEntries, session)
|
|
2974
|
+
);
|
|
2975
|
+
if (runtimeGrant) {
|
|
2976
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
2977
|
+
if (runtimeGrant.expiresAt.getTime() <= Date.now() + marginMs) {
|
|
2978
|
+
throw new import_sdk_core6.SessionExpiredError(runtimeGrant.expiresAt);
|
|
2979
|
+
}
|
|
2980
|
+
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
2981
|
+
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
2982
|
+
did,
|
|
2983
|
+
expandedEntries,
|
|
2984
|
+
runtimeExpiration,
|
|
2985
|
+
runtimeGrant
|
|
2986
|
+
);
|
|
2987
|
+
return { delegation: delegation2, prompted: false };
|
|
2988
|
+
}
|
|
2989
|
+
throw new import_sdk_core6.PermissionNotInManifestError(missing, granted);
|
|
2617
2990
|
}
|
|
2618
2991
|
const delegation = await this.createDelegationViaWasmPath(
|
|
2619
2992
|
did,
|
|
@@ -2693,7 +3066,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2693
3066
|
const spaceId = [...resolvedSpaces][0];
|
|
2694
3067
|
const abilities = {};
|
|
2695
3068
|
for (const entry of entries) {
|
|
2696
|
-
const shortService =
|
|
3069
|
+
const shortService = import_sdk_core6.SERVICE_LONG_TO_SHORT[entry.service];
|
|
2697
3070
|
if (shortService === void 0) {
|
|
2698
3071
|
throw new Error(
|
|
2699
3072
|
`delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
|
|
@@ -2733,7 +3106,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2733
3106
|
});
|
|
2734
3107
|
const primary = result.resources[0];
|
|
2735
3108
|
const delegationHeader = { Authorization: result.delegation };
|
|
2736
|
-
const activateResult = await (0,
|
|
3109
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2737
3110
|
this.config.host,
|
|
2738
3111
|
delegationHeader
|
|
2739
3112
|
);
|
|
@@ -2757,6 +3130,41 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2757
3130
|
host: this.config.host
|
|
2758
3131
|
};
|
|
2759
3132
|
}
|
|
3133
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
|
|
3134
|
+
const result = this.createDelegationWrapper({
|
|
3135
|
+
session: grant.session,
|
|
3136
|
+
delegateDID: did,
|
|
3137
|
+
spaceId: grant.session.spaceId,
|
|
3138
|
+
abilities: this.permissionsToAbilities(entries),
|
|
3139
|
+
expirationSecs: Math.floor(expirationTime.getTime() / 1e3)
|
|
3140
|
+
});
|
|
3141
|
+
const primary = result.resources[0];
|
|
3142
|
+
const delegationHeader = { Authorization: result.delegation };
|
|
3143
|
+
const targetHost = grant.delegation.host ?? this.config.host;
|
|
3144
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
3145
|
+
targetHost,
|
|
3146
|
+
delegationHeader
|
|
3147
|
+
);
|
|
3148
|
+
if (!activateResult.success) {
|
|
3149
|
+
throw new Error(
|
|
3150
|
+
`Failed to activate delegation with host: ${activateResult.error}`
|
|
3151
|
+
);
|
|
3152
|
+
}
|
|
3153
|
+
return {
|
|
3154
|
+
cid: result.cid,
|
|
3155
|
+
delegationHeader,
|
|
3156
|
+
spaceId: grant.session.spaceId,
|
|
3157
|
+
path: primary.path,
|
|
3158
|
+
actions: primary.actions,
|
|
3159
|
+
resources: result.resources,
|
|
3160
|
+
disableSubDelegation: false,
|
|
3161
|
+
expiry: result.expiry,
|
|
3162
|
+
delegateDID: did,
|
|
3163
|
+
ownerAddress: grant.delegation.ownerAddress,
|
|
3164
|
+
chainId: grant.delegation.chainId,
|
|
3165
|
+
host: targetHost
|
|
3166
|
+
};
|
|
3167
|
+
}
|
|
2760
3168
|
resolvePermissionSpace(space, session) {
|
|
2761
3169
|
if (space === void 0) {
|
|
2762
3170
|
return this.wasmBindings.makeSpaceId(
|
|
@@ -2773,6 +3181,223 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2773
3181
|
}
|
|
2774
3182
|
return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
|
|
2775
3183
|
}
|
|
3184
|
+
expandPermissionEntries(permissions) {
|
|
3185
|
+
return permissions.map((entry) => ({
|
|
3186
|
+
...entry,
|
|
3187
|
+
actions: (0, import_sdk_core6.expandActionShortNames)(entry.service, entry.actions)
|
|
3188
|
+
}));
|
|
3189
|
+
}
|
|
3190
|
+
shortServiceName(service) {
|
|
3191
|
+
const short = import_sdk_core6.SERVICE_LONG_TO_SHORT[service];
|
|
3192
|
+
if (short === void 0) {
|
|
3193
|
+
throw new Error(
|
|
3194
|
+
`unknown service '${service}' \u2014 no short-form mapping`
|
|
3195
|
+
);
|
|
3196
|
+
}
|
|
3197
|
+
return short;
|
|
3198
|
+
}
|
|
3199
|
+
permissionsToAbilities(entries) {
|
|
3200
|
+
const abilities = {};
|
|
3201
|
+
for (const entry of entries) {
|
|
3202
|
+
const service = this.shortServiceName(entry.service);
|
|
3203
|
+
abilities[service] ?? (abilities[service] = {});
|
|
3204
|
+
const existing = abilities[service][entry.path] ?? [];
|
|
3205
|
+
const seen = new Set(existing);
|
|
3206
|
+
for (const action of entry.actions) {
|
|
3207
|
+
if (!seen.has(action)) {
|
|
3208
|
+
existing.push(action);
|
|
3209
|
+
seen.add(action);
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
abilities[service][entry.path] = existing;
|
|
3213
|
+
}
|
|
3214
|
+
return abilities;
|
|
3215
|
+
}
|
|
3216
|
+
permissionOperations(entries, spaceId) {
|
|
3217
|
+
return entries.flatMap((entry) => {
|
|
3218
|
+
const service = this.shortServiceName(entry.service);
|
|
3219
|
+
return entry.actions.map((action) => ({
|
|
3220
|
+
spaceId,
|
|
3221
|
+
service,
|
|
3222
|
+
path: entry.path,
|
|
3223
|
+
action
|
|
3224
|
+
}));
|
|
3225
|
+
});
|
|
3226
|
+
}
|
|
3227
|
+
sessionCoversPermissionEntries(session, entries) {
|
|
3228
|
+
try {
|
|
3229
|
+
const granted = (0, import_sdk_core6.parseRecapCapabilities)(
|
|
3230
|
+
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
3231
|
+
session.siwe
|
|
3232
|
+
);
|
|
3233
|
+
return (0, import_sdk_core6.isCapabilitySubset)(entries, granted).subset;
|
|
3234
|
+
} catch {
|
|
3235
|
+
return false;
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
permissionEntriesToOperations(entries, session) {
|
|
3239
|
+
return entries.flatMap((entry) => {
|
|
3240
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
3241
|
+
const service = this.shortServiceName(entry.service);
|
|
3242
|
+
return entry.actions.map((action) => ({
|
|
3243
|
+
spaceId,
|
|
3244
|
+
service,
|
|
3245
|
+
path: entry.path,
|
|
3246
|
+
action
|
|
3247
|
+
}));
|
|
3248
|
+
});
|
|
3249
|
+
}
|
|
3250
|
+
findRuntimeGrantsForPermissionEntries(entries, session) {
|
|
3251
|
+
const grants = [];
|
|
3252
|
+
const operations = this.permissionEntriesToOperations(entries, session);
|
|
3253
|
+
if (operations.length === 0) {
|
|
3254
|
+
return grants;
|
|
3255
|
+
}
|
|
3256
|
+
for (const operation of operations) {
|
|
3257
|
+
const grant = this.findGrantForOperation(operation);
|
|
3258
|
+
if (!grant) {
|
|
3259
|
+
return [];
|
|
3260
|
+
}
|
|
3261
|
+
if (!grants.includes(grant)) {
|
|
3262
|
+
grants.push(grant);
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
return grants;
|
|
3266
|
+
}
|
|
3267
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
3268
|
+
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
3269
|
+
const primary = resources[0];
|
|
3270
|
+
return {
|
|
3271
|
+
cid: delegatedSession.delegationCid,
|
|
3272
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
3273
|
+
spaceId,
|
|
3274
|
+
path: primary.path,
|
|
3275
|
+
actions: primary.actions,
|
|
3276
|
+
resources,
|
|
3277
|
+
disableSubDelegation: false,
|
|
3278
|
+
expiry: expiresAt,
|
|
3279
|
+
delegateDID: session.verificationMethod,
|
|
3280
|
+
ownerAddress: session.address,
|
|
3281
|
+
chainId: session.chainId,
|
|
3282
|
+
host: this.config.host
|
|
3283
|
+
};
|
|
3284
|
+
}
|
|
3285
|
+
runtimeGrantFromDelegation(delegation, session) {
|
|
3286
|
+
const operations = this.operationsFromDelegation(delegation);
|
|
3287
|
+
return {
|
|
3288
|
+
session: {
|
|
3289
|
+
delegationHeader: delegation.delegationHeader,
|
|
3290
|
+
delegationCid: delegation.cid,
|
|
3291
|
+
spaceId: delegation.spaceId,
|
|
3292
|
+
verificationMethod: session.verificationMethod,
|
|
3293
|
+
jwk: session.jwk
|
|
3294
|
+
},
|
|
3295
|
+
delegation,
|
|
3296
|
+
operations,
|
|
3297
|
+
expiresAt: delegation.expiry
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
delegatedResourcesForEntries(entries, spaceId) {
|
|
3301
|
+
return entries.map((entry) => ({
|
|
3302
|
+
service: this.shortServiceName(entry.service),
|
|
3303
|
+
space: spaceId,
|
|
3304
|
+
path: entry.path,
|
|
3305
|
+
actions: [...entry.actions]
|
|
3306
|
+
}));
|
|
3307
|
+
}
|
|
3308
|
+
operationsFromDelegation(delegation) {
|
|
3309
|
+
const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
|
|
3310
|
+
return resources.flatMap(
|
|
3311
|
+
(resource) => resource.actions.map((action) => ({
|
|
3312
|
+
spaceId: resource.space,
|
|
3313
|
+
service: this.invocationServiceName(resource.service),
|
|
3314
|
+
path: resource.path,
|
|
3315
|
+
action
|
|
3316
|
+
}))
|
|
3317
|
+
);
|
|
3318
|
+
}
|
|
3319
|
+
flatDelegationResources(delegation) {
|
|
3320
|
+
const byService = /* @__PURE__ */ new Map();
|
|
3321
|
+
for (const action of delegation.actions) {
|
|
3322
|
+
const service = this.shortServiceName(action.split("/")[0]);
|
|
3323
|
+
const actions = byService.get(service) ?? [];
|
|
3324
|
+
actions.push(action);
|
|
3325
|
+
byService.set(service, actions);
|
|
3326
|
+
}
|
|
3327
|
+
return [...byService.entries()].map(([service, actions]) => ({
|
|
3328
|
+
service,
|
|
3329
|
+
space: delegation.spaceId,
|
|
3330
|
+
path: delegation.path,
|
|
3331
|
+
actions
|
|
3332
|
+
}));
|
|
3333
|
+
}
|
|
3334
|
+
selectInvocationSession(fallback, service, path, action) {
|
|
3335
|
+
const grant = this.findGrantForOperation({
|
|
3336
|
+
spaceId: fallback.spaceId,
|
|
3337
|
+
service: this.invocationServiceName(service),
|
|
3338
|
+
path,
|
|
3339
|
+
action
|
|
3340
|
+
});
|
|
3341
|
+
return grant?.session ?? fallback;
|
|
3342
|
+
}
|
|
3343
|
+
findGrantForOperations(operations) {
|
|
3344
|
+
if (operations.length === 0) {
|
|
3345
|
+
return void 0;
|
|
3346
|
+
}
|
|
3347
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
3348
|
+
return this.runtimePermissionGrants.find((grant) => {
|
|
3349
|
+
return operations.every(
|
|
3350
|
+
(operation) => grant.operations.some(
|
|
3351
|
+
(granted) => this.operationCovers(granted, operation)
|
|
3352
|
+
)
|
|
3353
|
+
);
|
|
3354
|
+
});
|
|
3355
|
+
}
|
|
3356
|
+
findGrantForOperation(operation) {
|
|
3357
|
+
return this.findGrantForOperations([operation]);
|
|
3358
|
+
}
|
|
3359
|
+
pruneExpiredRuntimePermissionGrants() {
|
|
3360
|
+
const now = Date.now();
|
|
3361
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
3362
|
+
(grant) => grant.expiresAt.getTime() > now
|
|
3363
|
+
);
|
|
3364
|
+
}
|
|
3365
|
+
operationCovers(granted, requested) {
|
|
3366
|
+
return granted.spaceId === requested.spaceId && granted.service === requested.service && this.actionContains(granted.action, requested.action) && this.pathContains(granted.path, requested.path);
|
|
3367
|
+
}
|
|
3368
|
+
actionContains(grantedAction, requestedAction) {
|
|
3369
|
+
if (grantedAction === requestedAction) {
|
|
3370
|
+
return true;
|
|
3371
|
+
}
|
|
3372
|
+
if (grantedAction.endsWith("/*")) {
|
|
3373
|
+
const prefix = grantedAction.slice(0, -2);
|
|
3374
|
+
return requestedAction.startsWith(`${prefix}/`);
|
|
3375
|
+
}
|
|
3376
|
+
return false;
|
|
3377
|
+
}
|
|
3378
|
+
invocationServiceName(service) {
|
|
3379
|
+
return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
|
|
3380
|
+
}
|
|
3381
|
+
pathContains(grantedPath, requestedPath) {
|
|
3382
|
+
if (grantedPath === "" || grantedPath === "/") {
|
|
3383
|
+
return true;
|
|
3384
|
+
}
|
|
3385
|
+
if (grantedPath.endsWith("/**")) {
|
|
3386
|
+
return requestedPath.startsWith(grantedPath.slice(0, -3));
|
|
3387
|
+
}
|
|
3388
|
+
if (grantedPath.endsWith("/*")) {
|
|
3389
|
+
const prefix = grantedPath.slice(0, -2);
|
|
3390
|
+
if (!requestedPath.startsWith(prefix)) {
|
|
3391
|
+
return false;
|
|
3392
|
+
}
|
|
3393
|
+
const remainder = requestedPath.slice(prefix.length);
|
|
3394
|
+
return !remainder.includes("/") || remainder === "/";
|
|
3395
|
+
}
|
|
3396
|
+
if (grantedPath.endsWith("/")) {
|
|
3397
|
+
return requestedPath.startsWith(grantedPath);
|
|
3398
|
+
}
|
|
3399
|
+
return grantedPath === requestedPath;
|
|
3400
|
+
}
|
|
2776
3401
|
/**
|
|
2777
3402
|
* Issue a delegation via the legacy wallet-signed SIWE path for a single
|
|
2778
3403
|
* {@link PermissionEntry}. Shares the implementation with the public
|
|
@@ -2829,7 +3454,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2829
3454
|
);
|
|
2830
3455
|
return result.delegation;
|
|
2831
3456
|
} catch (err) {
|
|
2832
|
-
if (err instanceof
|
|
3457
|
+
if (err instanceof import_sdk_core6.PermissionNotInManifestError) {
|
|
2833
3458
|
} else {
|
|
2834
3459
|
throw err;
|
|
2835
3460
|
}
|
|
@@ -2886,7 +3511,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2886
3511
|
...prepared,
|
|
2887
3512
|
signature
|
|
2888
3513
|
});
|
|
2889
|
-
const activateResult = await (0,
|
|
3514
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2890
3515
|
this.config.host,
|
|
2891
3516
|
delegationSession.delegationHeader
|
|
2892
3517
|
);
|
|
@@ -2908,7 +3533,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2908
3533
|
};
|
|
2909
3534
|
const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
|
|
2910
3535
|
if (hasKvActions && params.includePublicSpace !== false) {
|
|
2911
|
-
const publicSpaceId = (0,
|
|
3536
|
+
const publicSpaceId = (0, import_sdk_core6.makePublicSpaceId)(
|
|
2912
3537
|
this.wasmBindings.ensureEip55(session.address),
|
|
2913
3538
|
session.chainId
|
|
2914
3539
|
);
|
|
@@ -2931,7 +3556,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2931
3556
|
...publicPrepared,
|
|
2932
3557
|
signature: publicSignature
|
|
2933
3558
|
});
|
|
2934
|
-
const publicActivateResult = await (0,
|
|
3559
|
+
const publicActivateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
2935
3560
|
this.config.host,
|
|
2936
3561
|
publicSession.delegationHeader
|
|
2937
3562
|
);
|
|
@@ -3030,7 +3655,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3030
3655
|
...prepared,
|
|
3031
3656
|
signature
|
|
3032
3657
|
});
|
|
3033
|
-
const activateResult = await (0,
|
|
3658
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
3034
3659
|
targetHost,
|
|
3035
3660
|
invokerSession.delegationHeader
|
|
3036
3661
|
);
|
|
@@ -3119,7 +3744,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3119
3744
|
...prepared,
|
|
3120
3745
|
signature
|
|
3121
3746
|
});
|
|
3122
|
-
const activateResult = await (0,
|
|
3747
|
+
const activateResult = await (0, import_sdk_core6.activateSessionWithHost)(
|
|
3123
3748
|
targetHost,
|
|
3124
3749
|
subDelegationSession.delegationHeader
|
|
3125
3750
|
);
|
|
@@ -3155,7 +3780,7 @@ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
|
3155
3780
|
var TinyCloudNode = _TinyCloudNode;
|
|
3156
3781
|
|
|
3157
3782
|
// src/core.ts
|
|
3158
|
-
var
|
|
3783
|
+
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
3159
3784
|
|
|
3160
3785
|
// src/delegation.ts
|
|
3161
3786
|
function serializeDelegation(delegation) {
|
|
@@ -3174,7 +3799,6 @@ function deserializeDelegation(data) {
|
|
|
3174
3799
|
}
|
|
3175
3800
|
|
|
3176
3801
|
// src/core.ts
|
|
3177
|
-
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
3178
3802
|
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
3179
3803
|
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
3180
3804
|
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
@@ -3183,6 +3807,7 @@ var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
|
3183
3807
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
3184
3808
|
var import_sdk_core16 = require("@tinycloud/sdk-core");
|
|
3185
3809
|
var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
3810
|
+
var import_sdk_core18 = require("@tinycloud/sdk-core");
|
|
3186
3811
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3187
3812
|
0 && (module.exports = {
|
|
3188
3813
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -3210,6 +3835,7 @@ var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
|
3210
3835
|
ProtocolMismatchError,
|
|
3211
3836
|
SQLAction,
|
|
3212
3837
|
SQLService,
|
|
3838
|
+
SecretsService,
|
|
3213
3839
|
ServiceContext,
|
|
3214
3840
|
SessionExpiredError,
|
|
3215
3841
|
SharingService,
|