@tinycloud/node-sdk 2.2.0-beta.1 → 2.2.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core-DcJ27GsA.d.cts +1538 -0
- package/dist/core-DcJ27GsA.d.ts +1538 -0
- package/dist/core.cjs +906 -183
- 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 +827 -93
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +909 -186
- 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 +822 -93
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -17159,6 +17159,7 @@ import {
|
|
|
17159
17159
|
DuckDbService as DuckDbService2,
|
|
17160
17160
|
HooksService as HooksService2,
|
|
17161
17161
|
DataVaultService,
|
|
17162
|
+
SecretsService,
|
|
17162
17163
|
createVaultCrypto,
|
|
17163
17164
|
ServiceContext as ServiceContext2,
|
|
17164
17165
|
SilentNotificationHandler,
|
|
@@ -17171,7 +17172,7 @@ import {
|
|
|
17171
17172
|
ACCOUNT_REGISTRY_SPACE,
|
|
17172
17173
|
PermissionNotInManifestError,
|
|
17173
17174
|
SessionExpiredError,
|
|
17174
|
-
|
|
17175
|
+
expandPermissionEntries as expandPermissionEntriesCore,
|
|
17175
17176
|
isCapabilitySubset,
|
|
17176
17177
|
parseRecapCapabilities,
|
|
17177
17178
|
SERVICE_LONG_TO_SHORT
|
|
@@ -17187,7 +17188,8 @@ import {
|
|
|
17187
17188
|
DEFAULT_MANIFEST_SPACE,
|
|
17188
17189
|
composeManifestRequest,
|
|
17189
17190
|
resourceCapabilitiesToAbilitiesMap,
|
|
17190
|
-
resourceCapabilitiesToSpaceAbilitiesMap
|
|
17191
|
+
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
17192
|
+
resolveTinyCloudHosts
|
|
17191
17193
|
} from "@tinycloud/sdk-core";
|
|
17192
17194
|
|
|
17193
17195
|
// src/authorization/strategies.ts
|
|
@@ -17321,9 +17323,9 @@ var NodeUserAuthorization = class {
|
|
|
17321
17323
|
this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1e3;
|
|
17322
17324
|
this.autoCreateSpace = config.autoCreateSpace ?? false;
|
|
17323
17325
|
this.spaceCreationHandler = config.spaceCreationHandler;
|
|
17324
|
-
this.tinycloudHosts = config.tinycloudHosts
|
|
17325
|
-
|
|
17326
|
-
|
|
17326
|
+
this.tinycloudHosts = config.tinycloudHosts;
|
|
17327
|
+
this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
|
|
17328
|
+
this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
|
|
17327
17329
|
this.enablePublicSpace = config.enablePublicSpace ?? true;
|
|
17328
17330
|
this.nonce = config.nonce;
|
|
17329
17331
|
this.siweConfig = config.siweConfig;
|
|
@@ -17344,6 +17346,9 @@ var NodeUserAuthorization = class {
|
|
|
17344
17346
|
get capabilityRequest() {
|
|
17345
17347
|
return this.getCapabilityRequest();
|
|
17346
17348
|
}
|
|
17349
|
+
get hosts() {
|
|
17350
|
+
return this.tinycloudHosts ? [...this.tinycloudHosts] : [];
|
|
17351
|
+
}
|
|
17347
17352
|
/**
|
|
17348
17353
|
* Install or replace the stored manifest. Takes effect on the next
|
|
17349
17354
|
* `signIn()` call — the current session (if any) is not touched.
|
|
@@ -17368,6 +17373,26 @@ var NodeUserAuthorization = class {
|
|
|
17368
17373
|
get tinyCloudSession() {
|
|
17369
17374
|
return this._tinyCloudSession;
|
|
17370
17375
|
}
|
|
17376
|
+
async resolveTinyCloudHostsForSignIn(address, chainId) {
|
|
17377
|
+
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
17378
|
+
return;
|
|
17379
|
+
}
|
|
17380
|
+
const subject = `did:pkh:eip155:${chainId}:${address}`;
|
|
17381
|
+
const resolved = await resolveTinyCloudHosts(subject, {
|
|
17382
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
17383
|
+
fallbackHosts: this.tinycloudFallbackHosts
|
|
17384
|
+
});
|
|
17385
|
+
this.tinycloudHosts = resolved.hosts;
|
|
17386
|
+
}
|
|
17387
|
+
requireTinyCloudHosts() {
|
|
17388
|
+
if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
|
|
17389
|
+
throw new Error("TinyCloud hosts have not been resolved. Call signIn() first.");
|
|
17390
|
+
}
|
|
17391
|
+
return this.tinycloudHosts;
|
|
17392
|
+
}
|
|
17393
|
+
get primaryTinyCloudHost() {
|
|
17394
|
+
return this.requireTinyCloudHosts()[0];
|
|
17395
|
+
}
|
|
17371
17396
|
get nodeFeatures() {
|
|
17372
17397
|
return this._nodeFeatures;
|
|
17373
17398
|
}
|
|
@@ -17499,7 +17524,7 @@ var NodeUserAuthorization = class {
|
|
|
17499
17524
|
if (!this._tinyCloudSession || !this._address || !this._chainId) {
|
|
17500
17525
|
throw new Error("Must be signed in to host space");
|
|
17501
17526
|
}
|
|
17502
|
-
const host = this.
|
|
17527
|
+
const host = this.primaryTinyCloudHost;
|
|
17503
17528
|
const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
|
|
17504
17529
|
const peerId = await fetchPeerId(host, spaceId);
|
|
17505
17530
|
const siwe = this.wasm.generateHostSIWEMessage({
|
|
@@ -17541,7 +17566,7 @@ var NodeUserAuthorization = class {
|
|
|
17541
17566
|
if (!this._tinyCloudSession) {
|
|
17542
17567
|
throw new Error("Must be signed in to ensure space exists");
|
|
17543
17568
|
}
|
|
17544
|
-
const host = this.
|
|
17569
|
+
const host = this.primaryTinyCloudHost;
|
|
17545
17570
|
const primarySpaceId = this._tinyCloudSession.spaceId;
|
|
17546
17571
|
const result = await activateSessionWithHost(
|
|
17547
17572
|
host,
|
|
@@ -17650,6 +17675,7 @@ var NodeUserAuthorization = class {
|
|
|
17650
17675
|
this._chainId = await this.signer.getChainId();
|
|
17651
17676
|
const address = this.wasm.ensureEip55(this._address);
|
|
17652
17677
|
const chainId = this._chainId;
|
|
17678
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
17653
17679
|
const keyId = `session-${Date.now()}`;
|
|
17654
17680
|
this.sessionManager.renameSessionKeyId("default", keyId);
|
|
17655
17681
|
const jwkString = this.sessionManager.jwk(keyId);
|
|
@@ -17728,7 +17754,7 @@ var NodeUserAuthorization = class {
|
|
|
17728
17754
|
this._address = address;
|
|
17729
17755
|
this._chainId = chainId;
|
|
17730
17756
|
const nodeInfo = await checkNodeInfo(
|
|
17731
|
-
this.
|
|
17757
|
+
this.primaryTinyCloudHost,
|
|
17732
17758
|
this.wasm.protocolVersion()
|
|
17733
17759
|
);
|
|
17734
17760
|
this._nodeFeatures = nodeInfo.features;
|
|
@@ -17844,6 +17870,7 @@ var NodeUserAuthorization = class {
|
|
|
17844
17870
|
});
|
|
17845
17871
|
const address = this.wasm.ensureEip55(await this.signer.getAddress());
|
|
17846
17872
|
const chainId = await this.signer.getChainId();
|
|
17873
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
17847
17874
|
const clientSession = {
|
|
17848
17875
|
address,
|
|
17849
17876
|
walletAddress: address,
|
|
@@ -17893,7 +17920,7 @@ var NodeUserAuthorization = class {
|
|
|
17893
17920
|
this._address = address;
|
|
17894
17921
|
this._chainId = chainId;
|
|
17895
17922
|
const nodeInfo = await checkNodeInfo(
|
|
17896
|
-
this.
|
|
17923
|
+
this.primaryTinyCloudHost,
|
|
17897
17924
|
this.wasm.protocolVersion()
|
|
17898
17925
|
);
|
|
17899
17926
|
this._nodeFeatures = nodeInfo.features;
|
|
@@ -18057,6 +18084,24 @@ var DelegatedAccess = class {
|
|
|
18057
18084
|
get hooks() {
|
|
18058
18085
|
return this._hooks;
|
|
18059
18086
|
}
|
|
18087
|
+
/**
|
|
18088
|
+
* Export the handles needed to rehydrate this activated delegation via
|
|
18089
|
+
* `TinyCloudNode.restoreSession(...)` in another process or after a
|
|
18090
|
+
* restart.
|
|
18091
|
+
*
|
|
18092
|
+
* See `RestorableSession` for lifetime caveats.
|
|
18093
|
+
*/
|
|
18094
|
+
get restorable() {
|
|
18095
|
+
return {
|
|
18096
|
+
delegationHeader: this.session.delegationHeader,
|
|
18097
|
+
delegationCid: this.session.delegationCid,
|
|
18098
|
+
spaceId: this.session.spaceId,
|
|
18099
|
+
jwk: this.session.jwk,
|
|
18100
|
+
verificationMethod: this.session.verificationMethod,
|
|
18101
|
+
address: this.session.address,
|
|
18102
|
+
chainId: this.session.chainId
|
|
18103
|
+
};
|
|
18104
|
+
}
|
|
18060
18105
|
};
|
|
18061
18106
|
|
|
18062
18107
|
// src/keys/WasmKeyProvider.ts
|
|
@@ -18197,6 +18242,152 @@ function extractSiweExpiration(siwe) {
|
|
|
18197
18242
|
return d;
|
|
18198
18243
|
}
|
|
18199
18244
|
|
|
18245
|
+
// src/NodeSecretsService.ts
|
|
18246
|
+
import {
|
|
18247
|
+
ErrorCodes,
|
|
18248
|
+
resolveSecretPath,
|
|
18249
|
+
resolveManifest
|
|
18250
|
+
} from "@tinycloud/sdk-core";
|
|
18251
|
+
var SECRETS_SPACE = "secrets";
|
|
18252
|
+
function ok() {
|
|
18253
|
+
return { ok: true, data: void 0 };
|
|
18254
|
+
}
|
|
18255
|
+
function secretsError(code, message, cause) {
|
|
18256
|
+
return {
|
|
18257
|
+
ok: false,
|
|
18258
|
+
error: {
|
|
18259
|
+
code,
|
|
18260
|
+
service: "secrets",
|
|
18261
|
+
message,
|
|
18262
|
+
...cause ? { cause } : {}
|
|
18263
|
+
}
|
|
18264
|
+
};
|
|
18265
|
+
}
|
|
18266
|
+
function displayActionUrn(action) {
|
|
18267
|
+
return action === "put" ? "tinycloud.vault/write" : "tinycloud.vault/delete";
|
|
18268
|
+
}
|
|
18269
|
+
function kvActionUrn(action) {
|
|
18270
|
+
return `tinycloud.kv/${action}`;
|
|
18271
|
+
}
|
|
18272
|
+
function vaultMutationAction(action) {
|
|
18273
|
+
return action === "put" ? "write" : "delete";
|
|
18274
|
+
}
|
|
18275
|
+
function secretPermissionEntries(name, options, action) {
|
|
18276
|
+
const secretPath = resolveSecretPath(name, options);
|
|
18277
|
+
return [
|
|
18278
|
+
{
|
|
18279
|
+
service: "tinycloud.vault",
|
|
18280
|
+
space: SECRETS_SPACE,
|
|
18281
|
+
path: secretPath.vaultKey,
|
|
18282
|
+
actions: [vaultMutationAction(action)],
|
|
18283
|
+
skipPrefix: true
|
|
18284
|
+
}
|
|
18285
|
+
];
|
|
18286
|
+
}
|
|
18287
|
+
function isSecretsSpace(space) {
|
|
18288
|
+
return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
|
|
18289
|
+
}
|
|
18290
|
+
var NodeSecretsService = class {
|
|
18291
|
+
constructor(config) {
|
|
18292
|
+
this.config = config;
|
|
18293
|
+
this.shouldRestoreUnlock = false;
|
|
18294
|
+
}
|
|
18295
|
+
get vault() {
|
|
18296
|
+
return this.service.vault;
|
|
18297
|
+
}
|
|
18298
|
+
get isUnlocked() {
|
|
18299
|
+
return this.service.isUnlocked;
|
|
18300
|
+
}
|
|
18301
|
+
async unlock(signer) {
|
|
18302
|
+
const effectiveSigner = signer ?? this.config.getUnlockSigner?.();
|
|
18303
|
+
if (effectiveSigner !== void 0) {
|
|
18304
|
+
this.unlockSigner = effectiveSigner;
|
|
18305
|
+
}
|
|
18306
|
+
const result = await this.service.unlock(effectiveSigner);
|
|
18307
|
+
if (result.ok) {
|
|
18308
|
+
this.shouldRestoreUnlock = true;
|
|
18309
|
+
}
|
|
18310
|
+
return result;
|
|
18311
|
+
}
|
|
18312
|
+
lock() {
|
|
18313
|
+
this.shouldRestoreUnlock = false;
|
|
18314
|
+
this.service.lock();
|
|
18315
|
+
}
|
|
18316
|
+
get(name, options) {
|
|
18317
|
+
return options === void 0 ? this.service.get(name) : this.service.get(name, options);
|
|
18318
|
+
}
|
|
18319
|
+
async put(name, value, options) {
|
|
18320
|
+
const permission = await this.ensureMutationPermission(name, options, "put");
|
|
18321
|
+
if (!permission.ok) return permission;
|
|
18322
|
+
return options === void 0 ? this.service.put(name, value) : this.service.put(name, value, options);
|
|
18323
|
+
}
|
|
18324
|
+
async delete(name, options) {
|
|
18325
|
+
const permission = await this.ensureMutationPermission(name, options, "del");
|
|
18326
|
+
if (!permission.ok) return permission;
|
|
18327
|
+
return options === void 0 ? this.service.delete(name) : this.service.delete(name, options);
|
|
18328
|
+
}
|
|
18329
|
+
list(options) {
|
|
18330
|
+
return options === void 0 ? this.service.list() : this.service.list(options);
|
|
18331
|
+
}
|
|
18332
|
+
get service() {
|
|
18333
|
+
return this.config.getService();
|
|
18334
|
+
}
|
|
18335
|
+
async ensureMutationPermission(name, options, action) {
|
|
18336
|
+
let permissionEntries;
|
|
18337
|
+
try {
|
|
18338
|
+
permissionEntries = secretPermissionEntries(name, options, action);
|
|
18339
|
+
} catch (error) {
|
|
18340
|
+
return secretsError(
|
|
18341
|
+
ErrorCodes.INVALID_INPUT,
|
|
18342
|
+
error instanceof Error ? error.message : String(error),
|
|
18343
|
+
error instanceof Error ? error : void 0
|
|
18344
|
+
);
|
|
18345
|
+
}
|
|
18346
|
+
if (this.hasMutationPermission(name, options, action)) {
|
|
18347
|
+
return ok();
|
|
18348
|
+
}
|
|
18349
|
+
if (!this.config.canEscalate()) {
|
|
18350
|
+
return secretsError(
|
|
18351
|
+
ErrorCodes.PERMISSION_DENIED,
|
|
18352
|
+
`Cannot autosign ${displayActionUrn(action)} for ${name}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
18353
|
+
);
|
|
18354
|
+
}
|
|
18355
|
+
try {
|
|
18356
|
+
await this.config.grantPermissions(permissionEntries);
|
|
18357
|
+
return this.restoreUnlockAfterEscalation();
|
|
18358
|
+
} catch (error) {
|
|
18359
|
+
return secretsError(
|
|
18360
|
+
ErrorCodes.PERMISSION_DENIED,
|
|
18361
|
+
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${name} failed.`,
|
|
18362
|
+
error instanceof Error ? error : void 0
|
|
18363
|
+
);
|
|
18364
|
+
}
|
|
18365
|
+
}
|
|
18366
|
+
async restoreUnlockAfterEscalation() {
|
|
18367
|
+
if (!this.shouldRestoreUnlock) {
|
|
18368
|
+
return ok();
|
|
18369
|
+
}
|
|
18370
|
+
return this.service.unlock(this.unlockSigner);
|
|
18371
|
+
}
|
|
18372
|
+
hasMutationPermission(name, options, action) {
|
|
18373
|
+
const manifest = this.config.getManifest();
|
|
18374
|
+
if (manifest === void 0) {
|
|
18375
|
+
return false;
|
|
18376
|
+
}
|
|
18377
|
+
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
18378
|
+
const requiredAction = kvActionUrn(action);
|
|
18379
|
+
const secretPath = resolveSecretPath(name, options);
|
|
18380
|
+
return manifests.some((entry) => {
|
|
18381
|
+
const resolved = resolveManifest(entry);
|
|
18382
|
+
return ["keys", "vault"].every(
|
|
18383
|
+
(base2) => resolved.resources.some(
|
|
18384
|
+
(resource) => resource.service === "tinycloud.kv" && isSecretsSpace(resource.space) && resource.path === secretPath.permissionPaths[base2] && resource.actions.includes(requiredAction)
|
|
18385
|
+
)
|
|
18386
|
+
);
|
|
18387
|
+
});
|
|
18388
|
+
}
|
|
18389
|
+
};
|
|
18390
|
+
|
|
18200
18391
|
// src/TinyCloudNode.ts
|
|
18201
18392
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
18202
18393
|
var _TinyCloudNode = class _TinyCloudNode {
|
|
@@ -18228,6 +18419,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18228
18419
|
this.auth = null;
|
|
18229
18420
|
this.tc = null;
|
|
18230
18421
|
this._chainId = 1;
|
|
18422
|
+
this.runtimePermissionGrants = [];
|
|
18423
|
+
this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
|
|
18424
|
+
return this.wasmBindings.invoke(
|
|
18425
|
+
this.selectInvocationSession(session, service, path, action),
|
|
18426
|
+
service,
|
|
18427
|
+
path,
|
|
18428
|
+
action,
|
|
18429
|
+
facts
|
|
18430
|
+
);
|
|
18431
|
+
};
|
|
18432
|
+
this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
|
|
18433
|
+
if (!this.wasmBindings.invokeAny) {
|
|
18434
|
+
throw new Error("WASM binding does not support invokeAny");
|
|
18435
|
+
}
|
|
18436
|
+
const grant = this.findGrantForOperations(
|
|
18437
|
+
entries.map((entry) => ({
|
|
18438
|
+
spaceId: entry.spaceId,
|
|
18439
|
+
service: this.invocationServiceName(entry.service),
|
|
18440
|
+
path: entry.path,
|
|
18441
|
+
action: entry.action
|
|
18442
|
+
}))
|
|
18443
|
+
);
|
|
18444
|
+
return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
|
|
18445
|
+
};
|
|
18446
|
+
this.explicitHost = config.host;
|
|
18231
18447
|
this.config = {
|
|
18232
18448
|
...config,
|
|
18233
18449
|
host: config.host ?? DEFAULT_HOST
|
|
@@ -18262,7 +18478,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18262
18478
|
this._sharingService = new SharingService({
|
|
18263
18479
|
hosts: [this.config.host],
|
|
18264
18480
|
// session: undefined - not needed for receive()
|
|
18265
|
-
invoke: this.
|
|
18481
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
18266
18482
|
fetch: globalThis.fetch.bind(globalThis),
|
|
18267
18483
|
keyProvider: this._keyProvider,
|
|
18268
18484
|
registry: this._capabilityRegistry,
|
|
@@ -18309,7 +18525,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18309
18525
|
* @internal
|
|
18310
18526
|
*/
|
|
18311
18527
|
setupAuth(config) {
|
|
18312
|
-
const host = this.config.host;
|
|
18313
18528
|
this.auth = new NodeUserAuthorization({
|
|
18314
18529
|
signer: this.signer,
|
|
18315
18530
|
signStrategy: { type: "auto-sign" },
|
|
@@ -18318,7 +18533,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18318
18533
|
domain: this.siweDomain,
|
|
18319
18534
|
spacePrefix: config.prefix,
|
|
18320
18535
|
sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1e3,
|
|
18321
|
-
tinycloudHosts: [
|
|
18536
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18537
|
+
tinycloudRegistryUrl: config.tinycloudRegistryUrl,
|
|
18538
|
+
tinycloudFallbackHosts: config.tinycloudFallbackHosts,
|
|
18322
18539
|
autoCreateSpace: config.autoCreateSpace,
|
|
18323
18540
|
enablePublicSpace: config.enablePublicSpace ?? true,
|
|
18324
18541
|
spaceCreationHandler: config.spaceCreationHandler,
|
|
@@ -18329,9 +18546,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18329
18546
|
includeAccountRegistryPermissions: config.includeAccountRegistryPermissions
|
|
18330
18547
|
});
|
|
18331
18548
|
this.tc = new TinyCloud(this.auth, {
|
|
18332
|
-
invokeAny: this.
|
|
18549
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
18333
18550
|
});
|
|
18334
18551
|
}
|
|
18552
|
+
syncResolvedHostFromAuth() {
|
|
18553
|
+
const host = this.auth?.hosts[0];
|
|
18554
|
+
if (host) {
|
|
18555
|
+
this.config.host = host;
|
|
18556
|
+
}
|
|
18557
|
+
}
|
|
18335
18558
|
/**
|
|
18336
18559
|
* Install or replace the manifest that drives the SIWE recap at
|
|
18337
18560
|
* sign-in. Takes effect on the next `signIn()` call — the current
|
|
@@ -18369,6 +18592,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18369
18592
|
get capabilityRequest() {
|
|
18370
18593
|
return this.auth?.capabilityRequest;
|
|
18371
18594
|
}
|
|
18595
|
+
get hosts() {
|
|
18596
|
+
const authHosts = this.auth?.hosts ?? [];
|
|
18597
|
+
return authHosts.length > 0 ? authHosts : [this.config.host];
|
|
18598
|
+
}
|
|
18372
18599
|
/**
|
|
18373
18600
|
* Get the primary identity DID for this user.
|
|
18374
18601
|
* - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})
|
|
@@ -18439,8 +18666,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18439
18666
|
this._sql = void 0;
|
|
18440
18667
|
this._duckdb = void 0;
|
|
18441
18668
|
this._hooks = void 0;
|
|
18669
|
+
this._vault = void 0;
|
|
18670
|
+
this._baseSecrets = void 0;
|
|
18671
|
+
this._secrets = void 0;
|
|
18672
|
+
this._spaceService = void 0;
|
|
18442
18673
|
this._serviceContext = void 0;
|
|
18674
|
+
this.runtimePermissionGrants = [];
|
|
18443
18675
|
await this.tc.signIn(options);
|
|
18676
|
+
this.syncResolvedHostFromAuth();
|
|
18444
18677
|
this.initializeServices();
|
|
18445
18678
|
await this.writeManifestRegistryRecords();
|
|
18446
18679
|
this.notificationHandler.success("Successfully signed in");
|
|
@@ -18460,7 +18693,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18460
18693
|
throw new Error("Manifest registry write requires wallet mode");
|
|
18461
18694
|
}
|
|
18462
18695
|
const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE);
|
|
18463
|
-
await this.
|
|
18696
|
+
await this.ensureOwnedSpaceHosted(accountSpaceId);
|
|
18464
18697
|
const accountKV = this.spaces.get(accountSpaceId).kv;
|
|
18465
18698
|
for (const record of request.registryRecords) {
|
|
18466
18699
|
const result = await accountKV.put(record.key, {
|
|
@@ -18475,6 +18708,39 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18475
18708
|
}
|
|
18476
18709
|
}
|
|
18477
18710
|
}
|
|
18711
|
+
async ensureOwnedSpaceHosted(spaceId) {
|
|
18712
|
+
if (!this.auth) {
|
|
18713
|
+
throw new Error("Owned space hosting requires wallet mode");
|
|
18714
|
+
}
|
|
18715
|
+
const session = this.auth.tinyCloudSession;
|
|
18716
|
+
if (!session) {
|
|
18717
|
+
throw new Error("Owned space hosting requires an active session");
|
|
18718
|
+
}
|
|
18719
|
+
const host = this.hosts[0] ?? this.config.host;
|
|
18720
|
+
if (!host) {
|
|
18721
|
+
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
18722
|
+
}
|
|
18723
|
+
const activation = await activateSessionWithHost2(host, session.delegationHeader);
|
|
18724
|
+
if (activation.success && !activation.skipped?.includes(spaceId)) {
|
|
18725
|
+
return;
|
|
18726
|
+
}
|
|
18727
|
+
if (!activation.success && activation.status !== 404) {
|
|
18728
|
+
throw new Error(
|
|
18729
|
+
`Failed to check owned space ${spaceId}: ${activation.error ?? activation.status}`
|
|
18730
|
+
);
|
|
18731
|
+
}
|
|
18732
|
+
const created = await this.auth.hostOwnedSpace(spaceId);
|
|
18733
|
+
if (!created) {
|
|
18734
|
+
throw new Error(`Failed to create owned space: ${spaceId}`);
|
|
18735
|
+
}
|
|
18736
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
18737
|
+
const retry = await activateSessionWithHost2(host, session.delegationHeader);
|
|
18738
|
+
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
18739
|
+
throw new Error(
|
|
18740
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.error ?? "space was skipped"}`
|
|
18741
|
+
);
|
|
18742
|
+
}
|
|
18743
|
+
}
|
|
18478
18744
|
/**
|
|
18479
18745
|
* Restore a previously established session from stored delegation data.
|
|
18480
18746
|
*
|
|
@@ -18490,7 +18756,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18490
18756
|
this._sql = void 0;
|
|
18491
18757
|
this._duckdb = void 0;
|
|
18492
18758
|
this._hooks = void 0;
|
|
18759
|
+
this._vault = void 0;
|
|
18760
|
+
this._baseSecrets = void 0;
|
|
18761
|
+
this._secrets = void 0;
|
|
18762
|
+
this._spaceService = void 0;
|
|
18493
18763
|
this._serviceContext = void 0;
|
|
18764
|
+
this.runtimePermissionGrants = [];
|
|
18494
18765
|
if (sessionData.address) {
|
|
18495
18766
|
this._address = sessionData.address;
|
|
18496
18767
|
}
|
|
@@ -18498,8 +18769,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18498
18769
|
this._chainId = sessionData.chainId;
|
|
18499
18770
|
}
|
|
18500
18771
|
this._serviceContext = new ServiceContext2({
|
|
18501
|
-
invoke: this.
|
|
18502
|
-
invokeAny: this.
|
|
18772
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
18773
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
18503
18774
|
fetch: globalThis.fetch.bind(globalThis),
|
|
18504
18775
|
hosts: [this.config.host]
|
|
18505
18776
|
});
|
|
@@ -18523,41 +18794,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18523
18794
|
jwk: sessionData.jwk
|
|
18524
18795
|
};
|
|
18525
18796
|
this._serviceContext.setSession(serviceSession);
|
|
18526
|
-
|
|
18527
|
-
const vaultCrypto = createVaultCrypto({
|
|
18528
|
-
vault_encrypt: wasm.vault_encrypt,
|
|
18529
|
-
vault_decrypt: wasm.vault_decrypt,
|
|
18530
|
-
vault_derive_key: wasm.vault_derive_key,
|
|
18531
|
-
vault_x25519_from_seed: wasm.vault_x25519_from_seed,
|
|
18532
|
-
vault_x25519_dh: wasm.vault_x25519_dh,
|
|
18533
|
-
vault_random_bytes: wasm.vault_random_bytes,
|
|
18534
|
-
vault_sha256: wasm.vault_sha256
|
|
18535
|
-
});
|
|
18536
|
-
const self2 = this;
|
|
18537
|
-
this._vault = new DataVaultService({
|
|
18538
|
-
spaceId: sessionData.spaceId,
|
|
18539
|
-
crypto: vaultCrypto,
|
|
18540
|
-
tc: {
|
|
18541
|
-
kv: this._kv,
|
|
18542
|
-
ensurePublicSpace: async () => {
|
|
18543
|
-
try {
|
|
18544
|
-
await self2.ensurePublicSpace();
|
|
18545
|
-
return { ok: true, data: void 0 };
|
|
18546
|
-
} catch (error) {
|
|
18547
|
-
return { ok: false, error: { code: "STORAGE_ERROR", message: error instanceof Error ? error.message : String(error), service: "vault" } };
|
|
18548
|
-
}
|
|
18549
|
-
},
|
|
18550
|
-
get publicKV() {
|
|
18551
|
-
return self2._publicKV ?? self2.tc.publicKV;
|
|
18552
|
-
},
|
|
18553
|
-
readPublicSpace: (host, spaceId, key2) => TinyCloud.readPublicSpace(host, spaceId, key2),
|
|
18554
|
-
makePublicSpaceId: TinyCloud.makePublicSpaceId,
|
|
18555
|
-
did: this.did,
|
|
18556
|
-
address: sessionData.address ?? this._address ?? "",
|
|
18557
|
-
chainId: sessionData.chainId ?? this._chainId,
|
|
18558
|
-
hosts: [this.config.host]
|
|
18559
|
-
}
|
|
18560
|
-
});
|
|
18797
|
+
this._vault = this.createVaultService(sessionData.spaceId, this._kv);
|
|
18561
18798
|
this._vault.initialize(this._serviceContext);
|
|
18562
18799
|
this._serviceContext.registerService("vault", this._vault);
|
|
18563
18800
|
this.initializeV2Services(serviceSession);
|
|
@@ -18592,7 +18829,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18592
18829
|
throw new Error("Wallet already connected. Cannot connect another wallet.");
|
|
18593
18830
|
}
|
|
18594
18831
|
const prefix = options?.prefix ?? "default";
|
|
18595
|
-
const host = this.config.host;
|
|
18596
18832
|
if (!_TinyCloudNode.nodeDefaults) {
|
|
18597
18833
|
throw new Error(
|
|
18598
18834
|
"connectWallet() requires PrivateKeySigner. Use connectSigner() instead, or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults."
|
|
@@ -18607,7 +18843,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18607
18843
|
domain: this.siweDomain,
|
|
18608
18844
|
spacePrefix: prefix,
|
|
18609
18845
|
sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
|
|
18610
|
-
tinycloudHosts: [
|
|
18846
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18847
|
+
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
18848
|
+
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
18611
18849
|
autoCreateSpace: this.config.autoCreateSpace,
|
|
18612
18850
|
enablePublicSpace: this.config.enablePublicSpace ?? true,
|
|
18613
18851
|
spaceCreationHandler: this.config.spaceCreationHandler,
|
|
@@ -18618,7 +18856,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18618
18856
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
18619
18857
|
});
|
|
18620
18858
|
this.tc = new TinyCloud(this.auth, {
|
|
18621
|
-
invokeAny: this.
|
|
18859
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
18622
18860
|
});
|
|
18623
18861
|
this.config.prefix = prefix;
|
|
18624
18862
|
}
|
|
@@ -18640,7 +18878,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18640
18878
|
throw new Error("Signer already connected. Cannot connect another signer.");
|
|
18641
18879
|
}
|
|
18642
18880
|
const prefix = options?.prefix ?? "default";
|
|
18643
|
-
const host = this.config.host;
|
|
18644
18881
|
this.signer = signer;
|
|
18645
18882
|
this.auth = new NodeUserAuthorization({
|
|
18646
18883
|
signer: this.signer,
|
|
@@ -18650,7 +18887,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18650
18887
|
domain: this.siweDomain,
|
|
18651
18888
|
spacePrefix: prefix,
|
|
18652
18889
|
sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1e3,
|
|
18653
|
-
tinycloudHosts: [
|
|
18890
|
+
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18891
|
+
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
18892
|
+
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
18654
18893
|
autoCreateSpace: this.config.autoCreateSpace,
|
|
18655
18894
|
enablePublicSpace: this.config.enablePublicSpace ?? true,
|
|
18656
18895
|
spaceCreationHandler: this.config.spaceCreationHandler,
|
|
@@ -18661,7 +18900,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18661
18900
|
includeAccountRegistryPermissions: this.config.includeAccountRegistryPermissions
|
|
18662
18901
|
});
|
|
18663
18902
|
this.tc = new TinyCloud(this.auth, {
|
|
18664
|
-
invokeAny: this.
|
|
18903
|
+
invokeAny: this.invokeAnyWithRuntimePermissions
|
|
18665
18904
|
});
|
|
18666
18905
|
this.config.prefix = prefix;
|
|
18667
18906
|
}
|
|
@@ -18674,10 +18913,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18674
18913
|
if (!session) {
|
|
18675
18914
|
return;
|
|
18676
18915
|
}
|
|
18677
|
-
this.tc.initializeServices(this.
|
|
18916
|
+
this.tc.initializeServices(this.invokeWithRuntimePermissions, [this.config.host]);
|
|
18678
18917
|
this._serviceContext = new ServiceContext2({
|
|
18679
|
-
invoke: this.
|
|
18680
|
-
invokeAny: this.
|
|
18918
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
18919
|
+
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
18681
18920
|
fetch: globalThis.fetch.bind(globalThis),
|
|
18682
18921
|
hosts: [this.config.host]
|
|
18683
18922
|
});
|
|
@@ -18707,6 +18946,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18707
18946
|
};
|
|
18708
18947
|
this._serviceContext.setSession(serviceSession);
|
|
18709
18948
|
this.tc.serviceContext.setSession(serviceSession);
|
|
18949
|
+
this._vault = this.createVaultService(session.spaceId, this._kv);
|
|
18950
|
+
this._vault.initialize(this._serviceContext);
|
|
18951
|
+
this._serviceContext.registerService("vault", this._vault);
|
|
18952
|
+
this.initializeV2Services(serviceSession);
|
|
18953
|
+
}
|
|
18954
|
+
createSpaceScopedKVService(spaceId) {
|
|
18955
|
+
const kvService = new KVService2({});
|
|
18956
|
+
if (this._serviceContext) {
|
|
18957
|
+
const spaceScopedContext = new ServiceContext2({
|
|
18958
|
+
invoke: this._serviceContext.invoke,
|
|
18959
|
+
fetch: this._serviceContext.fetch,
|
|
18960
|
+
hosts: this._serviceContext.hosts
|
|
18961
|
+
});
|
|
18962
|
+
const session = this._serviceContext.session;
|
|
18963
|
+
if (session) {
|
|
18964
|
+
spaceScopedContext.setSession({ ...session, spaceId });
|
|
18965
|
+
}
|
|
18966
|
+
kvService.initialize(spaceScopedContext);
|
|
18967
|
+
}
|
|
18968
|
+
return kvService;
|
|
18969
|
+
}
|
|
18970
|
+
createVaultService(spaceId, kv) {
|
|
18710
18971
|
const wasm = this.wasmBindings;
|
|
18711
18972
|
const vaultCrypto = createVaultCrypto({
|
|
18712
18973
|
vault_encrypt: wasm.vault_encrypt,
|
|
@@ -18718,11 +18979,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18718
18979
|
vault_sha256: wasm.vault_sha256
|
|
18719
18980
|
});
|
|
18720
18981
|
const self2 = this;
|
|
18721
|
-
|
|
18722
|
-
spaceId
|
|
18982
|
+
return new DataVaultService({
|
|
18983
|
+
spaceId,
|
|
18723
18984
|
crypto: vaultCrypto,
|
|
18724
18985
|
tc: {
|
|
18725
|
-
kv
|
|
18986
|
+
kv,
|
|
18726
18987
|
ensurePublicSpace: async () => {
|
|
18727
18988
|
try {
|
|
18728
18989
|
await self2.ensurePublicSpace();
|
|
@@ -18734,17 +18995,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18734
18995
|
get publicKV() {
|
|
18735
18996
|
return self2._publicKV ?? self2.tc.publicKV;
|
|
18736
18997
|
},
|
|
18737
|
-
readPublicSpace: (host,
|
|
18998
|
+
readPublicSpace: (host, targetSpaceId, key2) => TinyCloud.readPublicSpace(host, targetSpaceId, key2),
|
|
18738
18999
|
makePublicSpaceId: TinyCloud.makePublicSpaceId,
|
|
18739
19000
|
did: this.did,
|
|
18740
|
-
address: this._address,
|
|
19001
|
+
address: this._address ?? "",
|
|
18741
19002
|
chainId: this._chainId,
|
|
18742
19003
|
hosts: [this.config.host]
|
|
18743
19004
|
}
|
|
18744
19005
|
});
|
|
18745
|
-
this._vault.initialize(this._serviceContext);
|
|
18746
|
-
this._serviceContext.registerService("vault", this._vault);
|
|
18747
|
-
this.initializeV2Services(serviceSession);
|
|
18748
19006
|
}
|
|
18749
19007
|
/**
|
|
18750
19008
|
* Initialize the v2 delegation system services.
|
|
@@ -18828,7 +19086,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18828
19086
|
this._delegationManager = new DelegationManager({
|
|
18829
19087
|
hosts: [this.config.host],
|
|
18830
19088
|
session: serviceSession,
|
|
18831
|
-
invoke: this.
|
|
19089
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
18832
19090
|
fetch: globalThis.fetch.bind(globalThis)
|
|
18833
19091
|
});
|
|
18834
19092
|
this._spaceService = new SpaceService({
|
|
@@ -18839,20 +19097,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18839
19097
|
capabilityRegistry: this._capabilityRegistry,
|
|
18840
19098
|
userDid: this.did,
|
|
18841
19099
|
createKVService: (spaceId) => {
|
|
18842
|
-
|
|
19100
|
+
return this.createSpaceScopedKVService(spaceId);
|
|
19101
|
+
},
|
|
19102
|
+
createVaultService: (spaceId) => {
|
|
19103
|
+
const kvService = this.createSpaceScopedKVService(spaceId);
|
|
19104
|
+
const vaultService = this.createVaultService(spaceId, kvService);
|
|
18843
19105
|
if (this._serviceContext) {
|
|
18844
|
-
|
|
18845
|
-
invoke: this._serviceContext.invoke,
|
|
18846
|
-
fetch: this._serviceContext.fetch,
|
|
18847
|
-
hosts: this._serviceContext.hosts
|
|
18848
|
-
});
|
|
18849
|
-
const session = this._serviceContext.session;
|
|
18850
|
-
if (session) {
|
|
18851
|
-
spaceScopedContext.setSession({ ...session, spaceId });
|
|
18852
|
-
}
|
|
18853
|
-
kvService.initialize(spaceScopedContext);
|
|
19106
|
+
vaultService.initialize(this._serviceContext);
|
|
18854
19107
|
}
|
|
18855
|
-
return
|
|
19108
|
+
return vaultService;
|
|
18856
19109
|
},
|
|
18857
19110
|
// Enable space.delegations.create() via SIWE-based delegation
|
|
18858
19111
|
createDelegation: async (params) => {
|
|
@@ -19089,6 +19342,33 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19089
19342
|
}
|
|
19090
19343
|
return this._vault;
|
|
19091
19344
|
}
|
|
19345
|
+
/**
|
|
19346
|
+
* App-facing secrets API backed by the `secrets` space vault.
|
|
19347
|
+
*/
|
|
19348
|
+
get secrets() {
|
|
19349
|
+
if (!this._spaceService) {
|
|
19350
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19351
|
+
}
|
|
19352
|
+
if (!this._secrets) {
|
|
19353
|
+
this._secrets = new NodeSecretsService({
|
|
19354
|
+
getService: () => this.getBaseSecrets(),
|
|
19355
|
+
getManifest: () => this.manifest,
|
|
19356
|
+
grantPermissions: (additional) => this.grantRuntimePermissions(additional),
|
|
19357
|
+
canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
|
|
19358
|
+
getUnlockSigner: () => this.signer ?? void 0
|
|
19359
|
+
});
|
|
19360
|
+
}
|
|
19361
|
+
return this._secrets;
|
|
19362
|
+
}
|
|
19363
|
+
getBaseSecrets() {
|
|
19364
|
+
if (!this._spaceService) {
|
|
19365
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19366
|
+
}
|
|
19367
|
+
if (!this._baseSecrets) {
|
|
19368
|
+
this._baseSecrets = new SecretsService(() => this.space("secrets").vault);
|
|
19369
|
+
}
|
|
19370
|
+
return this._baseSecrets;
|
|
19371
|
+
}
|
|
19092
19372
|
/**
|
|
19093
19373
|
* Hooks write stream subscription API.
|
|
19094
19374
|
*/
|
|
@@ -19159,6 +19439,171 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19159
19439
|
}
|
|
19160
19440
|
};
|
|
19161
19441
|
}
|
|
19442
|
+
/**
|
|
19443
|
+
* Check whether the current session or an approved runtime delegation covers
|
|
19444
|
+
* every requested permission.
|
|
19445
|
+
*/
|
|
19446
|
+
hasRuntimePermissions(permissions) {
|
|
19447
|
+
const session = this.auth?.tinyCloudSession;
|
|
19448
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
19449
|
+
return false;
|
|
19450
|
+
}
|
|
19451
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
19452
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
19453
|
+
return true;
|
|
19454
|
+
}
|
|
19455
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).length > 0;
|
|
19456
|
+
}
|
|
19457
|
+
/**
|
|
19458
|
+
* Return installed runtime permission delegations. When `permissions` is
|
|
19459
|
+
* provided, only delegations currently covering those permissions are
|
|
19460
|
+
* returned. Base-session manifest permissions are not represented here.
|
|
19461
|
+
*/
|
|
19462
|
+
getRuntimePermissionDelegations(permissions) {
|
|
19463
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
19464
|
+
if (permissions === void 0) {
|
|
19465
|
+
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
19466
|
+
}
|
|
19467
|
+
const session = this.auth?.tinyCloudSession;
|
|
19468
|
+
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
19469
|
+
return [];
|
|
19470
|
+
}
|
|
19471
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
19472
|
+
return this.findRuntimeGrantsForPermissionEntries(expanded, session).map(
|
|
19473
|
+
(grant) => grant.delegation
|
|
19474
|
+
);
|
|
19475
|
+
}
|
|
19476
|
+
/**
|
|
19477
|
+
* Install a portable runtime permission delegation into this SDK instance so
|
|
19478
|
+
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
19479
|
+
*/
|
|
19480
|
+
async useRuntimeDelegation(delegation) {
|
|
19481
|
+
const session = this.auth?.tinyCloudSession;
|
|
19482
|
+
if (!session) {
|
|
19483
|
+
throw new SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19484
|
+
}
|
|
19485
|
+
if (delegation.expiry.getTime() <= Date.now()) {
|
|
19486
|
+
throw new SessionExpiredError(delegation.expiry);
|
|
19487
|
+
}
|
|
19488
|
+
const expectedDids = /* @__PURE__ */ new Set([session.verificationMethod, this.sessionDid]);
|
|
19489
|
+
if (!expectedDids.has(delegation.delegateDID)) {
|
|
19490
|
+
throw new Error(
|
|
19491
|
+
`Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
|
|
19492
|
+
);
|
|
19493
|
+
}
|
|
19494
|
+
const targetHost = delegation.host ?? this.config.host;
|
|
19495
|
+
const activateResult = await activateSessionWithHost2(
|
|
19496
|
+
targetHost,
|
|
19497
|
+
delegation.delegationHeader
|
|
19498
|
+
);
|
|
19499
|
+
if (!activateResult.success) {
|
|
19500
|
+
throw new Error(
|
|
19501
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
19502
|
+
);
|
|
19503
|
+
}
|
|
19504
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
19505
|
+
(grant) => grant.delegation.cid !== delegation.cid
|
|
19506
|
+
);
|
|
19507
|
+
this.runtimePermissionGrants.push(
|
|
19508
|
+
this.runtimeGrantFromDelegation(delegation, session)
|
|
19509
|
+
);
|
|
19510
|
+
}
|
|
19511
|
+
/**
|
|
19512
|
+
* Store additional permissions as narrow delegations to the current session
|
|
19513
|
+
* key. Future service invocations automatically use a stored delegation when
|
|
19514
|
+
* its `(space, service, path, action)` covers the request.
|
|
19515
|
+
*/
|
|
19516
|
+
async grantRuntimePermissions(permissions, options) {
|
|
19517
|
+
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
19518
|
+
throw new Error("grantRuntimePermissions requires a non-empty permissions array");
|
|
19519
|
+
}
|
|
19520
|
+
const session = this.auth?.tinyCloudSession;
|
|
19521
|
+
if (!session) {
|
|
19522
|
+
throw new SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19523
|
+
}
|
|
19524
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
19525
|
+
if (sessionExpiry !== void 0) {
|
|
19526
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
19527
|
+
if (sessionExpiry.getTime() <= Date.now() + marginMs) {
|
|
19528
|
+
throw new SessionExpiredError(sessionExpiry);
|
|
19529
|
+
}
|
|
19530
|
+
}
|
|
19531
|
+
const expanded = this.expandPermissionEntries(permissions);
|
|
19532
|
+
if (this.sessionCoversPermissionEntries(session, expanded)) {
|
|
19533
|
+
return [];
|
|
19534
|
+
}
|
|
19535
|
+
const existingGrants = this.findRuntimeGrantsForPermissionEntries(expanded, session);
|
|
19536
|
+
if (existingGrants.length > 0) {
|
|
19537
|
+
return existingGrants.map((grant) => grant.delegation);
|
|
19538
|
+
}
|
|
19539
|
+
if (!this.signer) {
|
|
19540
|
+
throw new Error(
|
|
19541
|
+
"grantRuntimePermissions requires wallet mode with a signer or privateKey."
|
|
19542
|
+
);
|
|
19543
|
+
}
|
|
19544
|
+
const bySpace = /* @__PURE__ */ new Map();
|
|
19545
|
+
for (const entry of expanded) {
|
|
19546
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
19547
|
+
const current = bySpace.get(spaceId) ?? [];
|
|
19548
|
+
current.push(entry);
|
|
19549
|
+
bySpace.set(spaceId, current);
|
|
19550
|
+
}
|
|
19551
|
+
const now = /* @__PURE__ */ new Date();
|
|
19552
|
+
const requestedExpiryMs = resolveExpiryMs(options?.expiry);
|
|
19553
|
+
let expiresAt = new Date(now.getTime() + requestedExpiryMs);
|
|
19554
|
+
if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
|
|
19555
|
+
expiresAt = sessionExpiry;
|
|
19556
|
+
}
|
|
19557
|
+
const delegations = [];
|
|
19558
|
+
for (const [spaceId, entries] of bySpace) {
|
|
19559
|
+
const abilities = this.permissionsToAbilities(entries);
|
|
19560
|
+
const prepared = this.wasmBindings.prepareSession({
|
|
19561
|
+
abilities,
|
|
19562
|
+
address: this.wasmBindings.ensureEip55(session.address),
|
|
19563
|
+
chainId: session.chainId,
|
|
19564
|
+
domain: this.siweDomain,
|
|
19565
|
+
issuedAt: now.toISOString(),
|
|
19566
|
+
expirationTime: expiresAt.toISOString(),
|
|
19567
|
+
spaceId,
|
|
19568
|
+
jwk: session.jwk
|
|
19569
|
+
});
|
|
19570
|
+
const signature2 = await this.signer.signMessage(prepared.siwe);
|
|
19571
|
+
const delegatedSession = this.wasmBindings.completeSessionSetup({
|
|
19572
|
+
...prepared,
|
|
19573
|
+
signature: signature2
|
|
19574
|
+
});
|
|
19575
|
+
const activateResult = await activateSessionWithHost2(
|
|
19576
|
+
this.config.host,
|
|
19577
|
+
delegatedSession.delegationHeader
|
|
19578
|
+
);
|
|
19579
|
+
if (!activateResult.success) {
|
|
19580
|
+
throw new Error(
|
|
19581
|
+
`Failed to activate runtime permission delegation: ${activateResult.error}`
|
|
19582
|
+
);
|
|
19583
|
+
}
|
|
19584
|
+
const delegation = this.runtimeDelegationFromSession(
|
|
19585
|
+
delegatedSession,
|
|
19586
|
+
entries,
|
|
19587
|
+
spaceId,
|
|
19588
|
+
session,
|
|
19589
|
+
expiresAt
|
|
19590
|
+
);
|
|
19591
|
+
this.runtimePermissionGrants.push({
|
|
19592
|
+
session: {
|
|
19593
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
19594
|
+
delegationCid: delegatedSession.delegationCid,
|
|
19595
|
+
spaceId,
|
|
19596
|
+
verificationMethod: session.verificationMethod,
|
|
19597
|
+
jwk: session.jwk
|
|
19598
|
+
},
|
|
19599
|
+
delegation,
|
|
19600
|
+
operations: this.permissionOperations(entries, spaceId),
|
|
19601
|
+
expiresAt
|
|
19602
|
+
});
|
|
19603
|
+
delegations.push(delegation);
|
|
19604
|
+
}
|
|
19605
|
+
return delegations;
|
|
19606
|
+
}
|
|
19162
19607
|
/**
|
|
19163
19608
|
* Get the DelegationManager for delegation CRUD operations.
|
|
19164
19609
|
*
|
|
@@ -19227,6 +19672,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19227
19672
|
get spaceService() {
|
|
19228
19673
|
return this.spaces;
|
|
19229
19674
|
}
|
|
19675
|
+
/**
|
|
19676
|
+
* Get a Space object by short name or full URI.
|
|
19677
|
+
*/
|
|
19678
|
+
space(nameOrUri) {
|
|
19679
|
+
return this.spaces.get(nameOrUri);
|
|
19680
|
+
}
|
|
19230
19681
|
/**
|
|
19231
19682
|
* Get the SharingService for creating and receiving v2 sharing links.
|
|
19232
19683
|
*
|
|
@@ -19341,7 +19792,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19341
19792
|
if (this._serviceContext) {
|
|
19342
19793
|
const publicKV = new KVService2({ prefix: "" });
|
|
19343
19794
|
const publicContext = new ServiceContext2({
|
|
19344
|
-
invoke: this.
|
|
19795
|
+
invoke: this.invokeWithRuntimePermissions,
|
|
19345
19796
|
fetch: this._serviceContext.fetch,
|
|
19346
19797
|
hosts: this._serviceContext.hosts
|
|
19347
19798
|
});
|
|
@@ -19429,8 +19880,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19429
19880
|
* Issue a delegation using the capability-chain flow.
|
|
19430
19881
|
*
|
|
19431
19882
|
* When every requested permission is a subset of the current
|
|
19432
|
-
* session's recap,
|
|
19433
|
-
*
|
|
19883
|
+
* session's recap, or of one installed runtime permission delegation,
|
|
19884
|
+
* the delegation is signed by the session key via WASM — no wallet
|
|
19885
|
+
* prompt. When at least one is NOT derivable, a
|
|
19434
19886
|
* {@link PermissionNotInManifestError} is raised (carrying the
|
|
19435
19887
|
* missing entries) so the caller can trigger an escalation flow
|
|
19436
19888
|
* (e.g. `TinyCloudWeb.requestPermissions`). Passing
|
|
@@ -19480,10 +19932,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19480
19932
|
"delegateTo requires a non-empty permissions array"
|
|
19481
19933
|
);
|
|
19482
19934
|
}
|
|
19483
|
-
const expandedEntries =
|
|
19484
|
-
...entry,
|
|
19485
|
-
actions: expandActionShortNames(entry.service, entry.actions)
|
|
19486
|
-
}));
|
|
19935
|
+
const expandedEntries = this.expandPermissionEntries(permissions);
|
|
19487
19936
|
const now = /* @__PURE__ */ new Date();
|
|
19488
19937
|
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
19489
19938
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
@@ -19510,6 +19959,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19510
19959
|
);
|
|
19511
19960
|
const { subset, missing } = isCapabilitySubset(expandedEntries, granted);
|
|
19512
19961
|
if (!subset) {
|
|
19962
|
+
const runtimeGrant = this.findGrantForOperations(
|
|
19963
|
+
this.permissionEntriesToOperations(expandedEntries, session)
|
|
19964
|
+
);
|
|
19965
|
+
if (runtimeGrant) {
|
|
19966
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
19967
|
+
if (runtimeGrant.expiresAt.getTime() <= Date.now() + marginMs) {
|
|
19968
|
+
throw new SessionExpiredError(runtimeGrant.expiresAt);
|
|
19969
|
+
}
|
|
19970
|
+
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
19971
|
+
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
19972
|
+
did,
|
|
19973
|
+
expandedEntries,
|
|
19974
|
+
runtimeExpiration,
|
|
19975
|
+
runtimeGrant
|
|
19976
|
+
);
|
|
19977
|
+
return { delegation: delegation2, prompted: false };
|
|
19978
|
+
}
|
|
19513
19979
|
throw new PermissionNotInManifestError(missing, granted);
|
|
19514
19980
|
}
|
|
19515
19981
|
const delegation = await this.createDelegationViaWasmPath(
|
|
@@ -19654,6 +20120,41 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19654
20120
|
host: this.config.host
|
|
19655
20121
|
};
|
|
19656
20122
|
}
|
|
20123
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
|
|
20124
|
+
const result = this.createDelegationWrapper({
|
|
20125
|
+
session: grant.session,
|
|
20126
|
+
delegateDID: did,
|
|
20127
|
+
spaceId: grant.session.spaceId,
|
|
20128
|
+
abilities: this.permissionsToAbilities(entries),
|
|
20129
|
+
expirationSecs: Math.floor(expirationTime.getTime() / 1e3)
|
|
20130
|
+
});
|
|
20131
|
+
const primary = result.resources[0];
|
|
20132
|
+
const delegationHeader = { Authorization: result.delegation };
|
|
20133
|
+
const targetHost = grant.delegation.host ?? this.config.host;
|
|
20134
|
+
const activateResult = await activateSessionWithHost2(
|
|
20135
|
+
targetHost,
|
|
20136
|
+
delegationHeader
|
|
20137
|
+
);
|
|
20138
|
+
if (!activateResult.success) {
|
|
20139
|
+
throw new Error(
|
|
20140
|
+
`Failed to activate delegation with host: ${activateResult.error}`
|
|
20141
|
+
);
|
|
20142
|
+
}
|
|
20143
|
+
return {
|
|
20144
|
+
cid: result.cid,
|
|
20145
|
+
delegationHeader,
|
|
20146
|
+
spaceId: grant.session.spaceId,
|
|
20147
|
+
path: primary.path,
|
|
20148
|
+
actions: primary.actions,
|
|
20149
|
+
resources: result.resources,
|
|
20150
|
+
disableSubDelegation: false,
|
|
20151
|
+
expiry: result.expiry,
|
|
20152
|
+
delegateDID: did,
|
|
20153
|
+
ownerAddress: grant.delegation.ownerAddress,
|
|
20154
|
+
chainId: grant.delegation.chainId,
|
|
20155
|
+
host: targetHost
|
|
20156
|
+
};
|
|
20157
|
+
}
|
|
19657
20158
|
resolvePermissionSpace(space, session) {
|
|
19658
20159
|
if (space === void 0) {
|
|
19659
20160
|
return this.wasmBindings.makeSpaceId(
|
|
@@ -19670,6 +20171,220 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19670
20171
|
}
|
|
19671
20172
|
return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
|
|
19672
20173
|
}
|
|
20174
|
+
expandPermissionEntries(permissions) {
|
|
20175
|
+
return expandPermissionEntriesCore(permissions);
|
|
20176
|
+
}
|
|
20177
|
+
shortServiceName(service) {
|
|
20178
|
+
const short = SERVICE_LONG_TO_SHORT[service];
|
|
20179
|
+
if (short === void 0) {
|
|
20180
|
+
throw new Error(
|
|
20181
|
+
`unknown service '${service}' \u2014 no short-form mapping`
|
|
20182
|
+
);
|
|
20183
|
+
}
|
|
20184
|
+
return short;
|
|
20185
|
+
}
|
|
20186
|
+
permissionsToAbilities(entries) {
|
|
20187
|
+
const abilities = {};
|
|
20188
|
+
for (const entry of entries) {
|
|
20189
|
+
const service = this.shortServiceName(entry.service);
|
|
20190
|
+
abilities[service] ?? (abilities[service] = {});
|
|
20191
|
+
const existing = abilities[service][entry.path] ?? [];
|
|
20192
|
+
const seen = new Set(existing);
|
|
20193
|
+
for (const action of entry.actions) {
|
|
20194
|
+
if (!seen.has(action)) {
|
|
20195
|
+
existing.push(action);
|
|
20196
|
+
seen.add(action);
|
|
20197
|
+
}
|
|
20198
|
+
}
|
|
20199
|
+
abilities[service][entry.path] = existing;
|
|
20200
|
+
}
|
|
20201
|
+
return abilities;
|
|
20202
|
+
}
|
|
20203
|
+
permissionOperations(entries, spaceId) {
|
|
20204
|
+
return entries.flatMap((entry) => {
|
|
20205
|
+
const service = this.shortServiceName(entry.service);
|
|
20206
|
+
return entry.actions.map((action) => ({
|
|
20207
|
+
spaceId,
|
|
20208
|
+
service,
|
|
20209
|
+
path: entry.path,
|
|
20210
|
+
action
|
|
20211
|
+
}));
|
|
20212
|
+
});
|
|
20213
|
+
}
|
|
20214
|
+
sessionCoversPermissionEntries(session, entries) {
|
|
20215
|
+
try {
|
|
20216
|
+
const granted = parseRecapCapabilities(
|
|
20217
|
+
(siwe) => this.wasmBindings.parseRecapFromSiwe(siwe),
|
|
20218
|
+
session.siwe
|
|
20219
|
+
);
|
|
20220
|
+
return isCapabilitySubset(entries, granted).subset;
|
|
20221
|
+
} catch {
|
|
20222
|
+
return false;
|
|
20223
|
+
}
|
|
20224
|
+
}
|
|
20225
|
+
permissionEntriesToOperations(entries, session) {
|
|
20226
|
+
return entries.flatMap((entry) => {
|
|
20227
|
+
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
20228
|
+
const service = this.shortServiceName(entry.service);
|
|
20229
|
+
return entry.actions.map((action) => ({
|
|
20230
|
+
spaceId,
|
|
20231
|
+
service,
|
|
20232
|
+
path: entry.path,
|
|
20233
|
+
action
|
|
20234
|
+
}));
|
|
20235
|
+
});
|
|
20236
|
+
}
|
|
20237
|
+
findRuntimeGrantsForPermissionEntries(entries, session) {
|
|
20238
|
+
const grants = [];
|
|
20239
|
+
const operations = this.permissionEntriesToOperations(entries, session);
|
|
20240
|
+
if (operations.length === 0) {
|
|
20241
|
+
return grants;
|
|
20242
|
+
}
|
|
20243
|
+
for (const operation of operations) {
|
|
20244
|
+
const grant = this.findGrantForOperation(operation);
|
|
20245
|
+
if (!grant) {
|
|
20246
|
+
return [];
|
|
20247
|
+
}
|
|
20248
|
+
if (!grants.includes(grant)) {
|
|
20249
|
+
grants.push(grant);
|
|
20250
|
+
}
|
|
20251
|
+
}
|
|
20252
|
+
return grants;
|
|
20253
|
+
}
|
|
20254
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
20255
|
+
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
20256
|
+
const primary = resources[0];
|
|
20257
|
+
return {
|
|
20258
|
+
cid: delegatedSession.delegationCid,
|
|
20259
|
+
delegationHeader: delegatedSession.delegationHeader,
|
|
20260
|
+
spaceId,
|
|
20261
|
+
path: primary.path,
|
|
20262
|
+
actions: primary.actions,
|
|
20263
|
+
resources,
|
|
20264
|
+
disableSubDelegation: false,
|
|
20265
|
+
expiry: expiresAt,
|
|
20266
|
+
delegateDID: session.verificationMethod,
|
|
20267
|
+
ownerAddress: session.address,
|
|
20268
|
+
chainId: session.chainId,
|
|
20269
|
+
host: this.config.host
|
|
20270
|
+
};
|
|
20271
|
+
}
|
|
20272
|
+
runtimeGrantFromDelegation(delegation, session) {
|
|
20273
|
+
const operations = this.operationsFromDelegation(delegation);
|
|
20274
|
+
return {
|
|
20275
|
+
session: {
|
|
20276
|
+
delegationHeader: delegation.delegationHeader,
|
|
20277
|
+
delegationCid: delegation.cid,
|
|
20278
|
+
spaceId: delegation.spaceId,
|
|
20279
|
+
verificationMethod: session.verificationMethod,
|
|
20280
|
+
jwk: session.jwk
|
|
20281
|
+
},
|
|
20282
|
+
delegation,
|
|
20283
|
+
operations,
|
|
20284
|
+
expiresAt: delegation.expiry
|
|
20285
|
+
};
|
|
20286
|
+
}
|
|
20287
|
+
delegatedResourcesForEntries(entries, spaceId) {
|
|
20288
|
+
return entries.map((entry) => ({
|
|
20289
|
+
service: this.shortServiceName(entry.service),
|
|
20290
|
+
space: spaceId,
|
|
20291
|
+
path: entry.path,
|
|
20292
|
+
actions: [...entry.actions]
|
|
20293
|
+
}));
|
|
20294
|
+
}
|
|
20295
|
+
operationsFromDelegation(delegation) {
|
|
20296
|
+
const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
|
|
20297
|
+
return resources.flatMap(
|
|
20298
|
+
(resource) => resource.actions.map((action) => ({
|
|
20299
|
+
spaceId: resource.space,
|
|
20300
|
+
service: this.invocationServiceName(resource.service),
|
|
20301
|
+
path: resource.path,
|
|
20302
|
+
action
|
|
20303
|
+
}))
|
|
20304
|
+
);
|
|
20305
|
+
}
|
|
20306
|
+
flatDelegationResources(delegation) {
|
|
20307
|
+
const byService = /* @__PURE__ */ new Map();
|
|
20308
|
+
for (const action of delegation.actions) {
|
|
20309
|
+
const service = this.shortServiceName(action.split("/")[0]);
|
|
20310
|
+
const actions = byService.get(service) ?? [];
|
|
20311
|
+
actions.push(action);
|
|
20312
|
+
byService.set(service, actions);
|
|
20313
|
+
}
|
|
20314
|
+
return [...byService.entries()].map(([service, actions]) => ({
|
|
20315
|
+
service,
|
|
20316
|
+
space: delegation.spaceId,
|
|
20317
|
+
path: delegation.path,
|
|
20318
|
+
actions
|
|
20319
|
+
}));
|
|
20320
|
+
}
|
|
20321
|
+
selectInvocationSession(fallback, service, path, action) {
|
|
20322
|
+
const grant = this.findGrantForOperation({
|
|
20323
|
+
spaceId: fallback.spaceId,
|
|
20324
|
+
service: this.invocationServiceName(service),
|
|
20325
|
+
path,
|
|
20326
|
+
action
|
|
20327
|
+
});
|
|
20328
|
+
return grant?.session ?? fallback;
|
|
20329
|
+
}
|
|
20330
|
+
findGrantForOperations(operations) {
|
|
20331
|
+
if (operations.length === 0) {
|
|
20332
|
+
return void 0;
|
|
20333
|
+
}
|
|
20334
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
20335
|
+
return this.runtimePermissionGrants.find((grant) => {
|
|
20336
|
+
return operations.every(
|
|
20337
|
+
(operation) => grant.operations.some(
|
|
20338
|
+
(granted) => this.operationCovers(granted, operation)
|
|
20339
|
+
)
|
|
20340
|
+
);
|
|
20341
|
+
});
|
|
20342
|
+
}
|
|
20343
|
+
findGrantForOperation(operation) {
|
|
20344
|
+
return this.findGrantForOperations([operation]);
|
|
20345
|
+
}
|
|
20346
|
+
pruneExpiredRuntimePermissionGrants() {
|
|
20347
|
+
const now = Date.now();
|
|
20348
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
20349
|
+
(grant) => grant.expiresAt.getTime() > now
|
|
20350
|
+
);
|
|
20351
|
+
}
|
|
20352
|
+
operationCovers(granted, requested) {
|
|
20353
|
+
return granted.spaceId === requested.spaceId && granted.service === requested.service && this.actionContains(granted.action, requested.action) && this.pathContains(granted.path, requested.path);
|
|
20354
|
+
}
|
|
20355
|
+
actionContains(grantedAction, requestedAction) {
|
|
20356
|
+
if (grantedAction === requestedAction) {
|
|
20357
|
+
return true;
|
|
20358
|
+
}
|
|
20359
|
+
if (grantedAction.endsWith("/*")) {
|
|
20360
|
+
const prefix = grantedAction.slice(0, -2);
|
|
20361
|
+
return requestedAction.startsWith(`${prefix}/`);
|
|
20362
|
+
}
|
|
20363
|
+
return false;
|
|
20364
|
+
}
|
|
20365
|
+
invocationServiceName(service) {
|
|
20366
|
+
return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
|
|
20367
|
+
}
|
|
20368
|
+
pathContains(grantedPath, requestedPath) {
|
|
20369
|
+
if (grantedPath === "" || grantedPath === "/") {
|
|
20370
|
+
return true;
|
|
20371
|
+
}
|
|
20372
|
+
if (grantedPath.endsWith("/**")) {
|
|
20373
|
+
return requestedPath.startsWith(grantedPath.slice(0, -3));
|
|
20374
|
+
}
|
|
20375
|
+
if (grantedPath.endsWith("/*")) {
|
|
20376
|
+
const prefix = grantedPath.slice(0, -2);
|
|
20377
|
+
if (!requestedPath.startsWith(prefix)) {
|
|
20378
|
+
return false;
|
|
20379
|
+
}
|
|
20380
|
+
const remainder = requestedPath.slice(prefix.length);
|
|
20381
|
+
return !remainder.includes("/") || remainder === "/";
|
|
20382
|
+
}
|
|
20383
|
+
if (grantedPath.endsWith("/")) {
|
|
20384
|
+
return requestedPath.startsWith(grantedPath);
|
|
20385
|
+
}
|
|
20386
|
+
return grantedPath === requestedPath;
|
|
20387
|
+
}
|
|
19673
20388
|
/**
|
|
19674
20389
|
* Issue a delegation via the legacy wallet-signed SIWE path for a single
|
|
19675
20390
|
* {@link PermissionEntry}. Shares the implementation with the public
|
|
@@ -20191,15 +20906,18 @@ import {
|
|
|
20191
20906
|
ACCOUNT_REGISTRY_SPACE as ACCOUNT_REGISTRY_SPACE2,
|
|
20192
20907
|
DEFAULT_MANIFEST_SPACE as DEFAULT_MANIFEST_SPACE2,
|
|
20193
20908
|
DEFAULT_MANIFEST_VERSION,
|
|
20909
|
+
VAULT_PERMISSION_SERVICE,
|
|
20194
20910
|
PermissionNotInManifestError as PermissionNotInManifestError2,
|
|
20195
20911
|
SessionExpiredError as SessionExpiredError2,
|
|
20196
20912
|
ManifestValidationError,
|
|
20197
20913
|
composeManifestRequest as composeManifestRequest2,
|
|
20198
|
-
resolveManifest,
|
|
20914
|
+
resolveManifest as resolveManifest2,
|
|
20199
20915
|
validateManifest,
|
|
20200
20916
|
loadManifest,
|
|
20201
20917
|
isCapabilitySubset as isCapabilitySubset2,
|
|
20202
|
-
expandActionShortNames
|
|
20918
|
+
expandActionShortNames,
|
|
20919
|
+
expandPermissionEntries,
|
|
20920
|
+
expandPermissionEntry,
|
|
20203
20921
|
parseExpiry as parseExpiry2,
|
|
20204
20922
|
resourceCapabilitiesToSpaceAbilitiesMap as resourceCapabilitiesToSpaceAbilitiesMap2
|
|
20205
20923
|
} from "@tinycloud/sdk-core";
|
|
@@ -20232,7 +20950,11 @@ import {
|
|
|
20232
20950
|
DataVaultService as DataVaultService2,
|
|
20233
20951
|
VaultHeaders,
|
|
20234
20952
|
VaultPublicSpaceKVActions,
|
|
20235
|
-
createVaultCrypto as createVaultCrypto2
|
|
20953
|
+
createVaultCrypto as createVaultCrypto2,
|
|
20954
|
+
SecretsService as SecretsService2,
|
|
20955
|
+
SECRET_NAME_RE,
|
|
20956
|
+
canonicalizeSecretScope,
|
|
20957
|
+
resolveSecretPath as resolveSecretPath2
|
|
20236
20958
|
} from "@tinycloud/sdk-core";
|
|
20237
20959
|
import { HooksService as HooksService3 } from "@tinycloud/sdk-core";
|
|
20238
20960
|
import {
|
|
@@ -20289,8 +21011,10 @@ export {
|
|
|
20289
21011
|
PrefixedKVService,
|
|
20290
21012
|
PrivateKeySigner,
|
|
20291
21013
|
ProtocolMismatchError,
|
|
21014
|
+
SECRET_NAME_RE,
|
|
20292
21015
|
SQLAction,
|
|
20293
21016
|
SQLService3 as SQLService,
|
|
21017
|
+
SecretsService2 as SecretsService,
|
|
20294
21018
|
ServiceContext3 as ServiceContext,
|
|
20295
21019
|
SessionExpiredError2 as SessionExpiredError,
|
|
20296
21020
|
SharingService2 as SharingService,
|
|
@@ -20301,11 +21025,13 @@ export {
|
|
|
20301
21025
|
TinyCloud2 as TinyCloud,
|
|
20302
21026
|
TinyCloudNode,
|
|
20303
21027
|
UnsupportedFeatureError2 as UnsupportedFeatureError,
|
|
21028
|
+
VAULT_PERMISSION_SERVICE,
|
|
20304
21029
|
VaultHeaders,
|
|
20305
21030
|
VaultPublicSpaceKVActions,
|
|
20306
21031
|
VersionCheckError,
|
|
20307
21032
|
WasmKeyProvider,
|
|
20308
21033
|
buildSpaceUri,
|
|
21034
|
+
canonicalizeSecretScope,
|
|
20309
21035
|
checkNodeInfo2 as checkNodeInfo,
|
|
20310
21036
|
composeManifestRequest2 as composeManifestRequest,
|
|
20311
21037
|
createCapabilityKeyRegistry,
|
|
@@ -20316,13 +21042,16 @@ export {
|
|
|
20316
21042
|
defaultSignStrategy,
|
|
20317
21043
|
defaultSpaceCreationHandler,
|
|
20318
21044
|
deserializeDelegation,
|
|
20319
|
-
|
|
21045
|
+
expandActionShortNames,
|
|
21046
|
+
expandPermissionEntries,
|
|
21047
|
+
expandPermissionEntry,
|
|
20320
21048
|
isCapabilitySubset2 as isCapabilitySubset,
|
|
20321
21049
|
loadManifest,
|
|
20322
21050
|
makePublicSpaceId2 as makePublicSpaceId,
|
|
20323
21051
|
parseExpiry2 as parseExpiry,
|
|
20324
21052
|
parseSpaceUri,
|
|
20325
|
-
resolveManifest,
|
|
21053
|
+
resolveManifest2 as resolveManifest,
|
|
21054
|
+
resolveSecretPath2 as resolveSecretPath,
|
|
20326
21055
|
resourceCapabilitiesToSpaceAbilitiesMap2 as resourceCapabilitiesToSpaceAbilitiesMap,
|
|
20327
21056
|
serializeDelegation,
|
|
20328
21057
|
validateManifest
|