@tinycloud/node-sdk 2.5.1 → 2.6.0-beta.1
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-ojeY-wet.d.cts → core-Cr-zD1lk.d.cts} +42 -0
- package/dist/{core-ojeY-wet.d.ts → core-Cr-zD1lk.d.ts} +42 -0
- package/dist/core.cjs +169 -96
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +180 -97
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +169 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +180 -97
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -910,6 +910,12 @@ declare class TinyCloudNode {
|
|
|
910
910
|
private _delegationManager?;
|
|
911
911
|
private _spaceService?;
|
|
912
912
|
private runtimePermissionGrants;
|
|
913
|
+
/**
|
|
914
|
+
* Memoized `recapOperationsFromSession` result, keyed by the exact SIWE it
|
|
915
|
+
* was parsed from. The primary session is stable for the life of a sign-in,
|
|
916
|
+
* so this avoids re-parsing the recap on every registration.
|
|
917
|
+
*/
|
|
918
|
+
private _recapOperationsCache?;
|
|
913
919
|
/**
|
|
914
920
|
* TinyCloudSession captured by {@link restoreSession} when there's no
|
|
915
921
|
* auth-layer signer available (session-only mode used by OpenKey-backed
|
|
@@ -1052,6 +1058,42 @@ declare class TinyCloudNode {
|
|
|
1052
1058
|
private isFreshBootstrapAccount;
|
|
1053
1059
|
private runAccountBootstrap;
|
|
1054
1060
|
private registerBootstrapRuntimeGrant;
|
|
1061
|
+
/**
|
|
1062
|
+
* Map the base session's OWN recap into runtime permission operations.
|
|
1063
|
+
*
|
|
1064
|
+
* Uses the RAW `parseRecapFromSiwe` binding — NOT `parseRecapCapabilities`,
|
|
1065
|
+
* whose `normalizeSpace` collapses `tinycloud:pkh:...:<owner>:<space>` to a
|
|
1066
|
+
* bare short name and would conflate two owners' identically-named spaces.
|
|
1067
|
+
* We must keep the full owner-scoped URI so a synthetic primary grant can
|
|
1068
|
+
* never cover an operation on a different owner's space.
|
|
1069
|
+
*
|
|
1070
|
+
* Mirrors {@link operationsFromDelegation}'s op shape: encryption network
|
|
1071
|
+
* entries (`urn:tinycloud:encryption:` paths) become `resource` ops; every
|
|
1072
|
+
* other entry becomes a `spaceId` op carrying the raw recap `space` URI.
|
|
1073
|
+
* One op per action.
|
|
1074
|
+
*
|
|
1075
|
+
* Returns `[]` for session-only / restored-without-siwe modes and for any
|
|
1076
|
+
* unparseable SIWE — the primary grant is simply not registered in that case.
|
|
1077
|
+
*/
|
|
1078
|
+
private recapOperationsFromSession;
|
|
1079
|
+
/**
|
|
1080
|
+
* Register the base (primary) session's own recap as a synthetic runtime
|
|
1081
|
+
* grant tagged `provenance: "primary"` so it always out-ranks other covering
|
|
1082
|
+
* grants in {@link findGrantForOperations}. This closes the selection-design
|
|
1083
|
+
* hazard where a broad — possibly broken — bootstrap/delegated grant could
|
|
1084
|
+
* hijack an operation the primary session itself already authorized (TC-111).
|
|
1085
|
+
*
|
|
1086
|
+
* Two safety exclusions:
|
|
1087
|
+
* - Ops whose space is in `lastActivationSkippedSpaceIds` are dropped: the
|
|
1088
|
+
* node refused to activate those spaces this sign-in even though the recap
|
|
1089
|
+
* claims them. Including them would let the synthetic primary out-rank a
|
|
1090
|
+
* working grant and 401 (the "skipped-activation inverted hijack").
|
|
1091
|
+
* - Encryption `resource` ops are kept as-is (space-independent).
|
|
1092
|
+
*
|
|
1093
|
+
* No-ops when nothing remains after exclusion. Callers (`signIn`,
|
|
1094
|
+
* `restoreSession`) clear `runtimePermissionGrants` first, so no dupes.
|
|
1095
|
+
*/
|
|
1096
|
+
private registerPrimarySessionGrant;
|
|
1055
1097
|
private writeManifestRegistryRecords;
|
|
1056
1098
|
private scheduleAccountRegistrySync;
|
|
1057
1099
|
private withAccountRegistryRetry;
|
|
@@ -910,6 +910,12 @@ declare class TinyCloudNode {
|
|
|
910
910
|
private _delegationManager?;
|
|
911
911
|
private _spaceService?;
|
|
912
912
|
private runtimePermissionGrants;
|
|
913
|
+
/**
|
|
914
|
+
* Memoized `recapOperationsFromSession` result, keyed by the exact SIWE it
|
|
915
|
+
* was parsed from. The primary session is stable for the life of a sign-in,
|
|
916
|
+
* so this avoids re-parsing the recap on every registration.
|
|
917
|
+
*/
|
|
918
|
+
private _recapOperationsCache?;
|
|
913
919
|
/**
|
|
914
920
|
* TinyCloudSession captured by {@link restoreSession} when there's no
|
|
915
921
|
* auth-layer signer available (session-only mode used by OpenKey-backed
|
|
@@ -1052,6 +1058,42 @@ declare class TinyCloudNode {
|
|
|
1052
1058
|
private isFreshBootstrapAccount;
|
|
1053
1059
|
private runAccountBootstrap;
|
|
1054
1060
|
private registerBootstrapRuntimeGrant;
|
|
1061
|
+
/**
|
|
1062
|
+
* Map the base session's OWN recap into runtime permission operations.
|
|
1063
|
+
*
|
|
1064
|
+
* Uses the RAW `parseRecapFromSiwe` binding — NOT `parseRecapCapabilities`,
|
|
1065
|
+
* whose `normalizeSpace` collapses `tinycloud:pkh:...:<owner>:<space>` to a
|
|
1066
|
+
* bare short name and would conflate two owners' identically-named spaces.
|
|
1067
|
+
* We must keep the full owner-scoped URI so a synthetic primary grant can
|
|
1068
|
+
* never cover an operation on a different owner's space.
|
|
1069
|
+
*
|
|
1070
|
+
* Mirrors {@link operationsFromDelegation}'s op shape: encryption network
|
|
1071
|
+
* entries (`urn:tinycloud:encryption:` paths) become `resource` ops; every
|
|
1072
|
+
* other entry becomes a `spaceId` op carrying the raw recap `space` URI.
|
|
1073
|
+
* One op per action.
|
|
1074
|
+
*
|
|
1075
|
+
* Returns `[]` for session-only / restored-without-siwe modes and for any
|
|
1076
|
+
* unparseable SIWE — the primary grant is simply not registered in that case.
|
|
1077
|
+
*/
|
|
1078
|
+
private recapOperationsFromSession;
|
|
1079
|
+
/**
|
|
1080
|
+
* Register the base (primary) session's own recap as a synthetic runtime
|
|
1081
|
+
* grant tagged `provenance: "primary"` so it always out-ranks other covering
|
|
1082
|
+
* grants in {@link findGrantForOperations}. This closes the selection-design
|
|
1083
|
+
* hazard where a broad — possibly broken — bootstrap/delegated grant could
|
|
1084
|
+
* hijack an operation the primary session itself already authorized (TC-111).
|
|
1085
|
+
*
|
|
1086
|
+
* Two safety exclusions:
|
|
1087
|
+
* - Ops whose space is in `lastActivationSkippedSpaceIds` are dropped: the
|
|
1088
|
+
* node refused to activate those spaces this sign-in even though the recap
|
|
1089
|
+
* claims them. Including them would let the synthetic primary out-rank a
|
|
1090
|
+
* working grant and 401 (the "skipped-activation inverted hijack").
|
|
1091
|
+
* - Encryption `resource` ops are kept as-is (space-independent).
|
|
1092
|
+
*
|
|
1093
|
+
* No-ops when nothing remains after exclusion. Callers (`signIn`,
|
|
1094
|
+
* `restoreSession`) clear `runtimePermissionGrants` first, so no dupes.
|
|
1095
|
+
*/
|
|
1096
|
+
private registerPrimarySessionGrant;
|
|
1055
1097
|
private writeManifestRegistryRecords;
|
|
1056
1098
|
private scheduleAccountRegistrySync;
|
|
1057
1099
|
private withAccountRegistryRetry;
|
package/dist/core.cjs
CHANGED
|
@@ -327,8 +327,8 @@ var import_sdk_core2 = require("@tinycloud/sdk-core");
|
|
|
327
327
|
var defaultSignStrategy = { type: "auto-sign" };
|
|
328
328
|
|
|
329
329
|
// src/authorization/NodeUserAuthorization.ts
|
|
330
|
-
var DECRYPT_ACTION =
|
|
331
|
-
var NETWORK_CREATE_ACTION =
|
|
330
|
+
var DECRYPT_ACTION = import_sdk_core3.ENCRYPTION.DECRYPT;
|
|
331
|
+
var NETWORK_CREATE_ACTION = import_sdk_core3.ENCRYPTION.NETWORK_CREATE;
|
|
332
332
|
function didPrincipalMatches(actual, expected) {
|
|
333
333
|
try {
|
|
334
334
|
return (0, import_sdk_core3.principalDidEquals)(actual, expected);
|
|
@@ -361,44 +361,27 @@ var NodeUserAuthorization = class {
|
|
|
361
361
|
this.spacePrefix = config.spacePrefix ?? "default";
|
|
362
362
|
this.defaultActions = config.defaultActions ?? {
|
|
363
363
|
kv: {
|
|
364
|
-
"": [
|
|
365
|
-
"tinycloud.kv/put",
|
|
366
|
-
"tinycloud.kv/get",
|
|
367
|
-
"tinycloud.kv/del",
|
|
368
|
-
"tinycloud.kv/list",
|
|
369
|
-
"tinycloud.kv/metadata"
|
|
370
|
-
]
|
|
364
|
+
"": [import_sdk_core3.KV.PUT, import_sdk_core3.KV.GET, import_sdk_core3.KV.DEL, import_sdk_core3.KV.LIST, import_sdk_core3.KV.METADATA]
|
|
371
365
|
},
|
|
372
366
|
sql: {
|
|
373
|
-
"": [
|
|
374
|
-
"tinycloud.sql/read",
|
|
375
|
-
"tinycloud.sql/write",
|
|
376
|
-
"tinycloud.sql/schema",
|
|
377
|
-
"tinycloud.sql/admin",
|
|
378
|
-
"tinycloud.sql/export"
|
|
379
|
-
]
|
|
367
|
+
"": [import_sdk_core3.SQL.READ, import_sdk_core3.SQL.WRITE, import_sdk_core3.SQL.SCHEMA, import_sdk_core3.SQL.ADMIN, import_sdk_core3.SQL.EXPORT]
|
|
380
368
|
},
|
|
381
369
|
duckdb: {
|
|
382
370
|
"": [
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
371
|
+
import_sdk_core3.DUCKDB.READ,
|
|
372
|
+
import_sdk_core3.DUCKDB.WRITE,
|
|
373
|
+
import_sdk_core3.DUCKDB.ADMIN,
|
|
374
|
+
import_sdk_core3.DUCKDB.DESCRIBE,
|
|
375
|
+
import_sdk_core3.DUCKDB.EXPORT,
|
|
376
|
+
import_sdk_core3.DUCKDB.IMPORT,
|
|
377
|
+
import_sdk_core3.DUCKDB.EXECUTE
|
|
390
378
|
]
|
|
391
379
|
},
|
|
392
380
|
capabilities: {
|
|
393
|
-
"": [
|
|
381
|
+
"": [import_sdk_core3.CAPABILITIES.READ]
|
|
394
382
|
},
|
|
395
383
|
hooks: {
|
|
396
|
-
"": [
|
|
397
|
-
"tinycloud.hooks/subscribe",
|
|
398
|
-
"tinycloud.hooks/register",
|
|
399
|
-
"tinycloud.hooks/list",
|
|
400
|
-
"tinycloud.hooks/unregister"
|
|
401
|
-
]
|
|
384
|
+
"": [import_sdk_core3.HOOKS.SUBSCRIBE, import_sdk_core3.HOOKS.REGISTER, import_sdk_core3.HOOKS.LIST, import_sdk_core3.HOOKS.UNREGISTER]
|
|
402
385
|
}
|
|
403
386
|
};
|
|
404
387
|
this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core3.EXPIRY.SESSION_MS;
|
|
@@ -598,20 +581,17 @@ var NodeUserAuthorization = class {
|
|
|
598
581
|
[secretsSpaceId]: {
|
|
599
582
|
kv: {
|
|
600
583
|
"vault/secrets/": [
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
584
|
+
import_sdk_core3.KV.GET,
|
|
585
|
+
import_sdk_core3.KV.PUT,
|
|
586
|
+
import_sdk_core3.KV.DEL,
|
|
587
|
+
import_sdk_core3.KV.LIST,
|
|
588
|
+
import_sdk_core3.KV.METADATA
|
|
606
589
|
]
|
|
607
590
|
}
|
|
608
591
|
}
|
|
609
592
|
},
|
|
610
593
|
rawAbilities: {
|
|
611
|
-
[defaultNetworkId]: [
|
|
612
|
-
"tinycloud.encryption/decrypt",
|
|
613
|
-
"tinycloud.encryption/network.create"
|
|
614
|
-
]
|
|
594
|
+
[defaultNetworkId]: [DECRYPT_ACTION, NETWORK_CREATE_ACTION]
|
|
615
595
|
}
|
|
616
596
|
};
|
|
617
597
|
}
|
|
@@ -1675,9 +1655,27 @@ var NodeSecretsService = class {
|
|
|
1675
1655
|
// src/TinyCloudNode.ts
|
|
1676
1656
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
1677
1657
|
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
1678
|
-
var NETWORK_CREATE_ACTION2 =
|
|
1679
|
-
var DECRYPT_ACTION2 =
|
|
1658
|
+
var NETWORK_CREATE_ACTION2 = import_sdk_core8.ENCRYPTION.NETWORK_CREATE;
|
|
1659
|
+
var DECRYPT_ACTION2 = import_sdk_core8.ENCRYPTION.DECRYPT;
|
|
1680
1660
|
var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
|
|
1661
|
+
var ROOT_DELEGATION_ACTIONS = [
|
|
1662
|
+
import_sdk_core8.KV.PUT,
|
|
1663
|
+
import_sdk_core8.KV.GET,
|
|
1664
|
+
import_sdk_core8.KV.DEL,
|
|
1665
|
+
import_sdk_core8.KV.LIST,
|
|
1666
|
+
import_sdk_core8.KV.METADATA,
|
|
1667
|
+
import_sdk_core8.SQL.READ,
|
|
1668
|
+
import_sdk_core8.SQL.WRITE,
|
|
1669
|
+
import_sdk_core8.SQL.ADMIN,
|
|
1670
|
+
import_sdk_core8.SQL.ALL,
|
|
1671
|
+
import_sdk_core8.DUCKDB.READ,
|
|
1672
|
+
import_sdk_core8.DUCKDB.WRITE,
|
|
1673
|
+
import_sdk_core8.DUCKDB.ADMIN,
|
|
1674
|
+
import_sdk_core8.DUCKDB.DESCRIBE,
|
|
1675
|
+
import_sdk_core8.DUCKDB.EXPORT,
|
|
1676
|
+
import_sdk_core8.DUCKDB.IMPORT,
|
|
1677
|
+
import_sdk_core8.DUCKDB.ALL
|
|
1678
|
+
];
|
|
1681
1679
|
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core8.EXPIRY.SESSION_MS;
|
|
1682
1680
|
function isOpenKeyAutoSignStrategy(strategy) {
|
|
1683
1681
|
return strategy?.openKeyAutoSign === true;
|
|
@@ -2149,6 +2147,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2149
2147
|
await this.tc.signIn(options);
|
|
2150
2148
|
this.syncResolvedHostFromAuth();
|
|
2151
2149
|
this.initializeServices();
|
|
2150
|
+
const primarySession = this.currentTinyCloudSession();
|
|
2151
|
+
if (primarySession) {
|
|
2152
|
+
this.registerPrimarySessionGrant(primarySession);
|
|
2153
|
+
}
|
|
2152
2154
|
const bootstrapped = await this.bootstrapAccountIfNeeded();
|
|
2153
2155
|
await this.ensureRequestedEncryptionNetworks();
|
|
2154
2156
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
@@ -2392,7 +2394,107 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2392
2394
|
host: this.config.host
|
|
2393
2395
|
},
|
|
2394
2396
|
operations,
|
|
2395
|
-
expiresAt
|
|
2397
|
+
expiresAt,
|
|
2398
|
+
provenance: "bootstrap"
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
/**
|
|
2402
|
+
* Map the base session's OWN recap into runtime permission operations.
|
|
2403
|
+
*
|
|
2404
|
+
* Uses the RAW `parseRecapFromSiwe` binding — NOT `parseRecapCapabilities`,
|
|
2405
|
+
* whose `normalizeSpace` collapses `tinycloud:pkh:...:<owner>:<space>` to a
|
|
2406
|
+
* bare short name and would conflate two owners' identically-named spaces.
|
|
2407
|
+
* We must keep the full owner-scoped URI so a synthetic primary grant can
|
|
2408
|
+
* never cover an operation on a different owner's space.
|
|
2409
|
+
*
|
|
2410
|
+
* Mirrors {@link operationsFromDelegation}'s op shape: encryption network
|
|
2411
|
+
* entries (`urn:tinycloud:encryption:` paths) become `resource` ops; every
|
|
2412
|
+
* other entry becomes a `spaceId` op carrying the raw recap `space` URI.
|
|
2413
|
+
* One op per action.
|
|
2414
|
+
*
|
|
2415
|
+
* Returns `[]` for session-only / restored-without-siwe modes and for any
|
|
2416
|
+
* unparseable SIWE — the primary grant is simply not registered in that case.
|
|
2417
|
+
*/
|
|
2418
|
+
recapOperationsFromSession(session) {
|
|
2419
|
+
const siwe = session.siwe;
|
|
2420
|
+
if (!siwe) {
|
|
2421
|
+
return [];
|
|
2422
|
+
}
|
|
2423
|
+
if (this._recapOperationsCache?.siwe === siwe) {
|
|
2424
|
+
return this._recapOperationsCache.operations;
|
|
2425
|
+
}
|
|
2426
|
+
let operations = [];
|
|
2427
|
+
try {
|
|
2428
|
+
const entries = this.wasmBindings.parseRecapFromSiwe(siwe);
|
|
2429
|
+
if (Array.isArray(entries)) {
|
|
2430
|
+
operations = entries.flatMap((entry) => {
|
|
2431
|
+
const service = this.invocationServiceName(entry.service);
|
|
2432
|
+
return entry.actions.map((action) => ({
|
|
2433
|
+
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
|
|
2434
|
+
service,
|
|
2435
|
+
path: entry.path,
|
|
2436
|
+
action
|
|
2437
|
+
}));
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
} catch {
|
|
2441
|
+
operations = [];
|
|
2442
|
+
}
|
|
2443
|
+
this._recapOperationsCache = { siwe, operations };
|
|
2444
|
+
return operations;
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* Register the base (primary) session's own recap as a synthetic runtime
|
|
2448
|
+
* grant tagged `provenance: "primary"` so it always out-ranks other covering
|
|
2449
|
+
* grants in {@link findGrantForOperations}. This closes the selection-design
|
|
2450
|
+
* hazard where a broad — possibly broken — bootstrap/delegated grant could
|
|
2451
|
+
* hijack an operation the primary session itself already authorized (TC-111).
|
|
2452
|
+
*
|
|
2453
|
+
* Two safety exclusions:
|
|
2454
|
+
* - Ops whose space is in `lastActivationSkippedSpaceIds` are dropped: the
|
|
2455
|
+
* node refused to activate those spaces this sign-in even though the recap
|
|
2456
|
+
* claims them. Including them would let the synthetic primary out-rank a
|
|
2457
|
+
* working grant and 401 (the "skipped-activation inverted hijack").
|
|
2458
|
+
* - Encryption `resource` ops are kept as-is (space-independent).
|
|
2459
|
+
*
|
|
2460
|
+
* No-ops when nothing remains after exclusion. Callers (`signIn`,
|
|
2461
|
+
* `restoreSession`) clear `runtimePermissionGrants` first, so no dupes.
|
|
2462
|
+
*/
|
|
2463
|
+
registerPrimarySessionGrant(session) {
|
|
2464
|
+
const skipped = this.auth ? this.auth.lastActivationSkippedSpaceIds ?? [] : [];
|
|
2465
|
+
const operations = this.recapOperationsFromSession(session).filter(
|
|
2466
|
+
(operation) => operation.spaceId === void 0 || !skipped.some((spaceId) => this.spaceIdsEqual(spaceId, operation.spaceId))
|
|
2467
|
+
);
|
|
2468
|
+
if (operations.length === 0) {
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
const expiresAt = extractSiweExpiration(session.siwe) ?? this.getSessionExpiry();
|
|
2472
|
+
const actions = [...new Set(operations.map((operation) => operation.action))];
|
|
2473
|
+
this.runtimePermissionGrants.push({
|
|
2474
|
+
session: {
|
|
2475
|
+
delegationHeader: session.delegationHeader,
|
|
2476
|
+
delegationCid: session.delegationCid,
|
|
2477
|
+
spaceId: session.spaceId,
|
|
2478
|
+
verificationMethod: session.verificationMethod,
|
|
2479
|
+
jwk: session.jwk
|
|
2480
|
+
},
|
|
2481
|
+
delegation: {
|
|
2482
|
+
cid: session.delegationCid,
|
|
2483
|
+
delegationHeader: session.delegationHeader,
|
|
2484
|
+
delegateDID: session.verificationMethod,
|
|
2485
|
+
delegatorDID: this.did,
|
|
2486
|
+
spaceId: session.spaceId,
|
|
2487
|
+
path: "",
|
|
2488
|
+
actions,
|
|
2489
|
+
expiry: expiresAt,
|
|
2490
|
+
allowSubDelegation: true,
|
|
2491
|
+
ownerAddress: session.address,
|
|
2492
|
+
chainId: session.chainId,
|
|
2493
|
+
host: this.config.host
|
|
2494
|
+
},
|
|
2495
|
+
operations,
|
|
2496
|
+
expiresAt,
|
|
2497
|
+
provenance: "primary"
|
|
2396
2498
|
});
|
|
2397
2499
|
}
|
|
2398
2500
|
async writeManifestRegistryRecords() {
|
|
@@ -2728,6 +2830,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
2728
2830
|
} else {
|
|
2729
2831
|
this._restoredTcSession = tcSession;
|
|
2730
2832
|
}
|
|
2833
|
+
this.registerPrimarySessionGrant(tcSession);
|
|
2731
2834
|
}
|
|
2732
2835
|
}
|
|
2733
2836
|
/**
|
|
@@ -3199,24 +3302,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3199
3302
|
spaceId: tcSession.spaceId,
|
|
3200
3303
|
path: "",
|
|
3201
3304
|
// Root access
|
|
3202
|
-
actions: [
|
|
3203
|
-
"tinycloud.kv/put",
|
|
3204
|
-
"tinycloud.kv/get",
|
|
3205
|
-
"tinycloud.kv/del",
|
|
3206
|
-
"tinycloud.kv/list",
|
|
3207
|
-
"tinycloud.kv/metadata",
|
|
3208
|
-
"tinycloud.sql/read",
|
|
3209
|
-
"tinycloud.sql/write",
|
|
3210
|
-
"tinycloud.sql/admin",
|
|
3211
|
-
"tinycloud.sql/*",
|
|
3212
|
-
"tinycloud.duckdb/read",
|
|
3213
|
-
"tinycloud.duckdb/write",
|
|
3214
|
-
"tinycloud.duckdb/admin",
|
|
3215
|
-
"tinycloud.duckdb/describe",
|
|
3216
|
-
"tinycloud.duckdb/export",
|
|
3217
|
-
"tinycloud.duckdb/import",
|
|
3218
|
-
"tinycloud.duckdb/*"
|
|
3219
|
-
],
|
|
3305
|
+
actions: [...ROOT_DELEGATION_ACTIONS],
|
|
3220
3306
|
expiry: this.getSessionExpiry(),
|
|
3221
3307
|
isRevoked: false,
|
|
3222
3308
|
allowSubDelegation: true
|
|
@@ -3229,24 +3315,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3229
3315
|
delegateDID: tcSession.verificationMethod,
|
|
3230
3316
|
spaceId,
|
|
3231
3317
|
path: "",
|
|
3232
|
-
actions: [
|
|
3233
|
-
"tinycloud.kv/put",
|
|
3234
|
-
"tinycloud.kv/get",
|
|
3235
|
-
"tinycloud.kv/del",
|
|
3236
|
-
"tinycloud.kv/list",
|
|
3237
|
-
"tinycloud.kv/metadata",
|
|
3238
|
-
"tinycloud.sql/read",
|
|
3239
|
-
"tinycloud.sql/write",
|
|
3240
|
-
"tinycloud.sql/admin",
|
|
3241
|
-
"tinycloud.sql/*",
|
|
3242
|
-
"tinycloud.duckdb/read",
|
|
3243
|
-
"tinycloud.duckdb/write",
|
|
3244
|
-
"tinycloud.duckdb/admin",
|
|
3245
|
-
"tinycloud.duckdb/describe",
|
|
3246
|
-
"tinycloud.duckdb/export",
|
|
3247
|
-
"tinycloud.duckdb/import",
|
|
3248
|
-
"tinycloud.duckdb/*"
|
|
3249
|
-
],
|
|
3318
|
+
actions: [...ROOT_DELEGATION_ACTIONS],
|
|
3250
3319
|
expiry: this.getSessionExpiry(),
|
|
3251
3320
|
isRevoked: false,
|
|
3252
3321
|
allowSubDelegation: true
|
|
@@ -3800,7 +3869,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3800
3869
|
getRuntimePermissionDelegations(permissions) {
|
|
3801
3870
|
this.pruneExpiredRuntimePermissionGrants();
|
|
3802
3871
|
if (permissions === void 0) {
|
|
3803
|
-
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
3872
|
+
return this.runtimePermissionGrants.filter((grant) => grant.provenance !== "primary").map((grant) => grant.delegation);
|
|
3804
3873
|
}
|
|
3805
3874
|
const session = this.currentTinyCloudSession();
|
|
3806
3875
|
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -3952,7 +4021,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3952
4021
|
},
|
|
3953
4022
|
delegation,
|
|
3954
4023
|
operations: this.permissionOperations(delegatedEntries, spaceId),
|
|
3955
|
-
expiresAt
|
|
4024
|
+
expiresAt,
|
|
4025
|
+
provenance: "runtime"
|
|
3956
4026
|
});
|
|
3957
4027
|
delegations.push(delegation);
|
|
3958
4028
|
}
|
|
@@ -4090,13 +4160,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4090
4160
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
4091
4161
|
}
|
|
4092
4162
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
4093
|
-
const kvActions = [
|
|
4094
|
-
"tinycloud.kv/put",
|
|
4095
|
-
"tinycloud.kv/get",
|
|
4096
|
-
"tinycloud.kv/del",
|
|
4097
|
-
"tinycloud.kv/list",
|
|
4098
|
-
"tinycloud.kv/metadata"
|
|
4099
|
-
];
|
|
4163
|
+
const kvActions = [import_sdk_core8.KV.PUT, import_sdk_core8.KV.GET, import_sdk_core8.KV.DEL, import_sdk_core8.KV.LIST, import_sdk_core8.KV.METADATA];
|
|
4100
4164
|
const abilities = { kv: { "": kvActions } };
|
|
4101
4165
|
const now = /* @__PURE__ */ new Date();
|
|
4102
4166
|
const expiryMs = import_sdk_core8.EXPIRY.EPHEMERAL_MS;
|
|
@@ -4619,7 +4683,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4619
4683
|
return grants;
|
|
4620
4684
|
}
|
|
4621
4685
|
for (const operation of operations) {
|
|
4622
|
-
const grant = this.findGrantForOperation(operation);
|
|
4686
|
+
const grant = this.findGrantForOperation(operation, { excludePrimary: true });
|
|
4623
4687
|
if (!grant) {
|
|
4624
4688
|
return [];
|
|
4625
4689
|
}
|
|
@@ -4659,7 +4723,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4659
4723
|
},
|
|
4660
4724
|
delegation,
|
|
4661
4725
|
operations,
|
|
4662
|
-
expiresAt: delegation.expiry
|
|
4726
|
+
expiresAt: delegation.expiry,
|
|
4727
|
+
provenance: "delegated"
|
|
4663
4728
|
};
|
|
4664
4729
|
}
|
|
4665
4730
|
installRuntimeGrantFromServiceSession(delegation, session, expiresAt) {
|
|
@@ -4674,7 +4739,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4674
4739
|
session,
|
|
4675
4740
|
delegation,
|
|
4676
4741
|
operations,
|
|
4677
|
-
expiresAt
|
|
4742
|
+
expiresAt,
|
|
4743
|
+
provenance: "delegated"
|
|
4678
4744
|
});
|
|
4679
4745
|
}
|
|
4680
4746
|
delegatedResourcesForEntries(entries, spaceId) {
|
|
@@ -4774,21 +4840,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4774
4840
|
});
|
|
4775
4841
|
return grant?.session ?? fallback;
|
|
4776
4842
|
}
|
|
4777
|
-
findGrantForOperations(operations) {
|
|
4843
|
+
findGrantForOperations(operations, options) {
|
|
4778
4844
|
if (operations.length === 0) {
|
|
4779
4845
|
return void 0;
|
|
4780
4846
|
}
|
|
4781
4847
|
this.pruneExpiredRuntimePermissionGrants();
|
|
4782
|
-
|
|
4848
|
+
const covering = this.runtimePermissionGrants.filter((grant) => {
|
|
4849
|
+
if (options?.excludePrimary && grant.provenance === "primary") {
|
|
4850
|
+
return false;
|
|
4851
|
+
}
|
|
4783
4852
|
return operations.every(
|
|
4784
4853
|
(operation) => grant.operations.some(
|
|
4785
4854
|
(granted) => this.operationCovers(granted, operation)
|
|
4786
4855
|
)
|
|
4787
4856
|
);
|
|
4788
4857
|
});
|
|
4858
|
+
if (covering.length === 0) {
|
|
4859
|
+
return void 0;
|
|
4860
|
+
}
|
|
4861
|
+
return covering.find((grant) => grant.provenance === "primary") ?? covering[0];
|
|
4789
4862
|
}
|
|
4790
|
-
findGrantForOperation(operation) {
|
|
4791
|
-
return this.findGrantForOperations([operation]);
|
|
4863
|
+
findGrantForOperation(operation, options) {
|
|
4864
|
+
return this.findGrantForOperations([operation], options);
|
|
4792
4865
|
}
|
|
4793
4866
|
pruneExpiredRuntimePermissionGrants() {
|
|
4794
4867
|
const now = Date.now();
|
|
@@ -5025,7 +5098,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5025
5098
|
session.chainId
|
|
5026
5099
|
);
|
|
5027
5100
|
const publicAbilities = {
|
|
5028
|
-
kv: { "": [
|
|
5101
|
+
kv: { "": [import_sdk_core8.KV.GET, import_sdk_core8.KV.PUT, import_sdk_core8.KV.METADATA] }
|
|
5029
5102
|
};
|
|
5030
5103
|
const publicPrepared = this.wasmBindings.prepareSession({
|
|
5031
5104
|
abilities: publicAbilities,
|
|
@@ -5053,7 +5126,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5053
5126
|
delegationHeader: publicSession.delegationHeader,
|
|
5054
5127
|
spaceId: publicSpaceId,
|
|
5055
5128
|
path: "",
|
|
5056
|
-
actions: [
|
|
5129
|
+
actions: [import_sdk_core8.KV.GET, import_sdk_core8.KV.PUT, import_sdk_core8.KV.METADATA],
|
|
5057
5130
|
disableSubDelegation: params.disableSubDelegation ?? false,
|
|
5058
5131
|
expiry: expirationTime,
|
|
5059
5132
|
delegateDID: params.delegateDID,
|