@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/index.cjs CHANGED
@@ -17347,8 +17347,8 @@ var MemorySessionStorage = class {
17347
17347
  };
17348
17348
 
17349
17349
  // src/authorization/NodeUserAuthorization.ts
17350
- var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
17351
- var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
17350
+ var DECRYPT_ACTION = import_sdk_core2.ENCRYPTION.DECRYPT;
17351
+ var NETWORK_CREATE_ACTION = import_sdk_core2.ENCRYPTION.NETWORK_CREATE;
17352
17352
  function didPrincipalMatches(actual, expected) {
17353
17353
  try {
17354
17354
  return (0, import_sdk_core2.principalDidEquals)(actual, expected);
@@ -17381,44 +17381,27 @@ var NodeUserAuthorization = class {
17381
17381
  this.spacePrefix = config.spacePrefix ?? "default";
17382
17382
  this.defaultActions = config.defaultActions ?? {
17383
17383
  kv: {
17384
- "": [
17385
- "tinycloud.kv/put",
17386
- "tinycloud.kv/get",
17387
- "tinycloud.kv/del",
17388
- "tinycloud.kv/list",
17389
- "tinycloud.kv/metadata"
17390
- ]
17384
+ "": [import_sdk_core2.KV.PUT, import_sdk_core2.KV.GET, import_sdk_core2.KV.DEL, import_sdk_core2.KV.LIST, import_sdk_core2.KV.METADATA]
17391
17385
  },
17392
17386
  sql: {
17393
- "": [
17394
- "tinycloud.sql/read",
17395
- "tinycloud.sql/write",
17396
- "tinycloud.sql/schema",
17397
- "tinycloud.sql/admin",
17398
- "tinycloud.sql/export"
17399
- ]
17387
+ "": [import_sdk_core2.SQL.READ, import_sdk_core2.SQL.WRITE, import_sdk_core2.SQL.SCHEMA, import_sdk_core2.SQL.ADMIN, import_sdk_core2.SQL.EXPORT]
17400
17388
  },
17401
17389
  duckdb: {
17402
17390
  "": [
17403
- "tinycloud.duckdb/read",
17404
- "tinycloud.duckdb/write",
17405
- "tinycloud.duckdb/admin",
17406
- "tinycloud.duckdb/describe",
17407
- "tinycloud.duckdb/export",
17408
- "tinycloud.duckdb/import",
17409
- "tinycloud.duckdb/execute"
17391
+ import_sdk_core2.DUCKDB.READ,
17392
+ import_sdk_core2.DUCKDB.WRITE,
17393
+ import_sdk_core2.DUCKDB.ADMIN,
17394
+ import_sdk_core2.DUCKDB.DESCRIBE,
17395
+ import_sdk_core2.DUCKDB.EXPORT,
17396
+ import_sdk_core2.DUCKDB.IMPORT,
17397
+ import_sdk_core2.DUCKDB.EXECUTE
17410
17398
  ]
17411
17399
  },
17412
17400
  capabilities: {
17413
- "": ["tinycloud.capabilities/read"]
17401
+ "": [import_sdk_core2.CAPABILITIES.READ]
17414
17402
  },
17415
17403
  hooks: {
17416
- "": [
17417
- "tinycloud.hooks/subscribe",
17418
- "tinycloud.hooks/register",
17419
- "tinycloud.hooks/list",
17420
- "tinycloud.hooks/unregister"
17421
- ]
17404
+ "": [import_sdk_core2.HOOKS.SUBSCRIBE, import_sdk_core2.HOOKS.REGISTER, import_sdk_core2.HOOKS.LIST, import_sdk_core2.HOOKS.UNREGISTER]
17422
17405
  }
17423
17406
  };
17424
17407
  this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core2.EXPIRY.SESSION_MS;
@@ -17618,20 +17601,17 @@ var NodeUserAuthorization = class {
17618
17601
  [secretsSpaceId]: {
17619
17602
  kv: {
17620
17603
  "vault/secrets/": [
17621
- "tinycloud.kv/get",
17622
- "tinycloud.kv/put",
17623
- "tinycloud.kv/del",
17624
- "tinycloud.kv/list",
17625
- "tinycloud.kv/metadata"
17604
+ import_sdk_core2.KV.GET,
17605
+ import_sdk_core2.KV.PUT,
17606
+ import_sdk_core2.KV.DEL,
17607
+ import_sdk_core2.KV.LIST,
17608
+ import_sdk_core2.KV.METADATA
17626
17609
  ]
17627
17610
  }
17628
17611
  }
17629
17612
  },
17630
17613
  rawAbilities: {
17631
- [defaultNetworkId]: [
17632
- "tinycloud.encryption/decrypt",
17633
- "tinycloud.encryption/network.create"
17634
- ]
17614
+ [defaultNetworkId]: [DECRYPT_ACTION, NETWORK_CREATE_ACTION]
17635
17615
  }
17636
17616
  };
17637
17617
  }
@@ -18692,9 +18672,27 @@ var NodeSecretsService = class {
18692
18672
  // src/TinyCloudNode.ts
18693
18673
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
18694
18674
  var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
18695
- var NETWORK_CREATE_ACTION2 = "tinycloud.encryption/network.create";
18696
- var DECRYPT_ACTION2 = "tinycloud.encryption/decrypt";
18675
+ var NETWORK_CREATE_ACTION2 = import_sdk_core7.ENCRYPTION.NETWORK_CREATE;
18676
+ var DECRYPT_ACTION2 = import_sdk_core7.ENCRYPTION.DECRYPT;
18697
18677
  var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
18678
+ var ROOT_DELEGATION_ACTIONS = [
18679
+ import_sdk_core7.KV.PUT,
18680
+ import_sdk_core7.KV.GET,
18681
+ import_sdk_core7.KV.DEL,
18682
+ import_sdk_core7.KV.LIST,
18683
+ import_sdk_core7.KV.METADATA,
18684
+ import_sdk_core7.SQL.READ,
18685
+ import_sdk_core7.SQL.WRITE,
18686
+ import_sdk_core7.SQL.ADMIN,
18687
+ import_sdk_core7.SQL.ALL,
18688
+ import_sdk_core7.DUCKDB.READ,
18689
+ import_sdk_core7.DUCKDB.WRITE,
18690
+ import_sdk_core7.DUCKDB.ADMIN,
18691
+ import_sdk_core7.DUCKDB.DESCRIBE,
18692
+ import_sdk_core7.DUCKDB.EXPORT,
18693
+ import_sdk_core7.DUCKDB.IMPORT,
18694
+ import_sdk_core7.DUCKDB.ALL
18695
+ ];
18698
18696
  var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core7.EXPIRY.SESSION_MS;
18699
18697
  function isOpenKeyAutoSignStrategy(strategy) {
18700
18698
  return strategy?.openKeyAutoSign === true;
@@ -19166,6 +19164,10 @@ var _TinyCloudNode = class _TinyCloudNode {
19166
19164
  await this.tc.signIn(options);
19167
19165
  this.syncResolvedHostFromAuth();
19168
19166
  this.initializeServices();
19167
+ const primarySession = this.currentTinyCloudSession();
19168
+ if (primarySession) {
19169
+ this.registerPrimarySessionGrant(primarySession);
19170
+ }
19169
19171
  const bootstrapped = await this.bootstrapAccountIfNeeded();
19170
19172
  await this.ensureRequestedEncryptionNetworks();
19171
19173
  if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
@@ -19409,7 +19411,107 @@ var _TinyCloudNode = class _TinyCloudNode {
19409
19411
  host: this.config.host
19410
19412
  },
19411
19413
  operations,
19412
- expiresAt
19414
+ expiresAt,
19415
+ provenance: "bootstrap"
19416
+ });
19417
+ }
19418
+ /**
19419
+ * Map the base session's OWN recap into runtime permission operations.
19420
+ *
19421
+ * Uses the RAW `parseRecapFromSiwe` binding — NOT `parseRecapCapabilities`,
19422
+ * whose `normalizeSpace` collapses `tinycloud:pkh:...:<owner>:<space>` to a
19423
+ * bare short name and would conflate two owners' identically-named spaces.
19424
+ * We must keep the full owner-scoped URI so a synthetic primary grant can
19425
+ * never cover an operation on a different owner's space.
19426
+ *
19427
+ * Mirrors {@link operationsFromDelegation}'s op shape: encryption network
19428
+ * entries (`urn:tinycloud:encryption:` paths) become `resource` ops; every
19429
+ * other entry becomes a `spaceId` op carrying the raw recap `space` URI.
19430
+ * One op per action.
19431
+ *
19432
+ * Returns `[]` for session-only / restored-without-siwe modes and for any
19433
+ * unparseable SIWE — the primary grant is simply not registered in that case.
19434
+ */
19435
+ recapOperationsFromSession(session) {
19436
+ const siwe = session.siwe;
19437
+ if (!siwe) {
19438
+ return [];
19439
+ }
19440
+ if (this._recapOperationsCache?.siwe === siwe) {
19441
+ return this._recapOperationsCache.operations;
19442
+ }
19443
+ let operations = [];
19444
+ try {
19445
+ const entries = this.wasmBindings.parseRecapFromSiwe(siwe);
19446
+ if (Array.isArray(entries)) {
19447
+ operations = entries.flatMap((entry) => {
19448
+ const service = this.invocationServiceName(entry.service);
19449
+ return entry.actions.map((action) => ({
19450
+ ...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
19451
+ service,
19452
+ path: entry.path,
19453
+ action
19454
+ }));
19455
+ });
19456
+ }
19457
+ } catch {
19458
+ operations = [];
19459
+ }
19460
+ this._recapOperationsCache = { siwe, operations };
19461
+ return operations;
19462
+ }
19463
+ /**
19464
+ * Register the base (primary) session's own recap as a synthetic runtime
19465
+ * grant tagged `provenance: "primary"` so it always out-ranks other covering
19466
+ * grants in {@link findGrantForOperations}. This closes the selection-design
19467
+ * hazard where a broad — possibly broken — bootstrap/delegated grant could
19468
+ * hijack an operation the primary session itself already authorized (TC-111).
19469
+ *
19470
+ * Two safety exclusions:
19471
+ * - Ops whose space is in `lastActivationSkippedSpaceIds` are dropped: the
19472
+ * node refused to activate those spaces this sign-in even though the recap
19473
+ * claims them. Including them would let the synthetic primary out-rank a
19474
+ * working grant and 401 (the "skipped-activation inverted hijack").
19475
+ * - Encryption `resource` ops are kept as-is (space-independent).
19476
+ *
19477
+ * No-ops when nothing remains after exclusion. Callers (`signIn`,
19478
+ * `restoreSession`) clear `runtimePermissionGrants` first, so no dupes.
19479
+ */
19480
+ registerPrimarySessionGrant(session) {
19481
+ const skipped = this.auth ? this.auth.lastActivationSkippedSpaceIds ?? [] : [];
19482
+ const operations = this.recapOperationsFromSession(session).filter(
19483
+ (operation) => operation.spaceId === void 0 || !skipped.some((spaceId) => this.spaceIdsEqual(spaceId, operation.spaceId))
19484
+ );
19485
+ if (operations.length === 0) {
19486
+ return;
19487
+ }
19488
+ const expiresAt = extractSiweExpiration(session.siwe) ?? this.getSessionExpiry();
19489
+ const actions = [...new Set(operations.map((operation) => operation.action))];
19490
+ this.runtimePermissionGrants.push({
19491
+ session: {
19492
+ delegationHeader: session.delegationHeader,
19493
+ delegationCid: session.delegationCid,
19494
+ spaceId: session.spaceId,
19495
+ verificationMethod: session.verificationMethod,
19496
+ jwk: session.jwk
19497
+ },
19498
+ delegation: {
19499
+ cid: session.delegationCid,
19500
+ delegationHeader: session.delegationHeader,
19501
+ delegateDID: session.verificationMethod,
19502
+ delegatorDID: this.did,
19503
+ spaceId: session.spaceId,
19504
+ path: "",
19505
+ actions,
19506
+ expiry: expiresAt,
19507
+ allowSubDelegation: true,
19508
+ ownerAddress: session.address,
19509
+ chainId: session.chainId,
19510
+ host: this.config.host
19511
+ },
19512
+ operations,
19513
+ expiresAt,
19514
+ provenance: "primary"
19413
19515
  });
19414
19516
  }
19415
19517
  async writeManifestRegistryRecords() {
@@ -19745,6 +19847,7 @@ var _TinyCloudNode = class _TinyCloudNode {
19745
19847
  } else {
19746
19848
  this._restoredTcSession = tcSession;
19747
19849
  }
19850
+ this.registerPrimarySessionGrant(tcSession);
19748
19851
  }
19749
19852
  }
19750
19853
  /**
@@ -20216,24 +20319,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20216
20319
  spaceId: tcSession.spaceId,
20217
20320
  path: "",
20218
20321
  // Root access
20219
- actions: [
20220
- "tinycloud.kv/put",
20221
- "tinycloud.kv/get",
20222
- "tinycloud.kv/del",
20223
- "tinycloud.kv/list",
20224
- "tinycloud.kv/metadata",
20225
- "tinycloud.sql/read",
20226
- "tinycloud.sql/write",
20227
- "tinycloud.sql/admin",
20228
- "tinycloud.sql/*",
20229
- "tinycloud.duckdb/read",
20230
- "tinycloud.duckdb/write",
20231
- "tinycloud.duckdb/admin",
20232
- "tinycloud.duckdb/describe",
20233
- "tinycloud.duckdb/export",
20234
- "tinycloud.duckdb/import",
20235
- "tinycloud.duckdb/*"
20236
- ],
20322
+ actions: [...ROOT_DELEGATION_ACTIONS],
20237
20323
  expiry: this.getSessionExpiry(),
20238
20324
  isRevoked: false,
20239
20325
  allowSubDelegation: true
@@ -20246,24 +20332,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20246
20332
  delegateDID: tcSession.verificationMethod,
20247
20333
  spaceId,
20248
20334
  path: "",
20249
- actions: [
20250
- "tinycloud.kv/put",
20251
- "tinycloud.kv/get",
20252
- "tinycloud.kv/del",
20253
- "tinycloud.kv/list",
20254
- "tinycloud.kv/metadata",
20255
- "tinycloud.sql/read",
20256
- "tinycloud.sql/write",
20257
- "tinycloud.sql/admin",
20258
- "tinycloud.sql/*",
20259
- "tinycloud.duckdb/read",
20260
- "tinycloud.duckdb/write",
20261
- "tinycloud.duckdb/admin",
20262
- "tinycloud.duckdb/describe",
20263
- "tinycloud.duckdb/export",
20264
- "tinycloud.duckdb/import",
20265
- "tinycloud.duckdb/*"
20266
- ],
20335
+ actions: [...ROOT_DELEGATION_ACTIONS],
20267
20336
  expiry: this.getSessionExpiry(),
20268
20337
  isRevoked: false,
20269
20338
  allowSubDelegation: true
@@ -20817,7 +20886,7 @@ var _TinyCloudNode = class _TinyCloudNode {
20817
20886
  getRuntimePermissionDelegations(permissions) {
20818
20887
  this.pruneExpiredRuntimePermissionGrants();
20819
20888
  if (permissions === void 0) {
20820
- return this.runtimePermissionGrants.map((grant) => grant.delegation);
20889
+ return this.runtimePermissionGrants.filter((grant) => grant.provenance !== "primary").map((grant) => grant.delegation);
20821
20890
  }
20822
20891
  const session = this.currentTinyCloudSession();
20823
20892
  if (!session || !Array.isArray(permissions) || permissions.length === 0) {
@@ -20969,7 +21038,8 @@ var _TinyCloudNode = class _TinyCloudNode {
20969
21038
  },
20970
21039
  delegation,
20971
21040
  operations: this.permissionOperations(delegatedEntries, spaceId),
20972
- expiresAt
21041
+ expiresAt,
21042
+ provenance: "runtime"
20973
21043
  });
20974
21044
  delegations.push(delegation);
20975
21045
  }
@@ -21107,13 +21177,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21107
21177
  throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
21108
21178
  }
21109
21179
  await this.auth.hostPublicSpace(publicSpaceId);
21110
- const kvActions = [
21111
- "tinycloud.kv/put",
21112
- "tinycloud.kv/get",
21113
- "tinycloud.kv/del",
21114
- "tinycloud.kv/list",
21115
- "tinycloud.kv/metadata"
21116
- ];
21180
+ const kvActions = [import_sdk_core7.KV.PUT, import_sdk_core7.KV.GET, import_sdk_core7.KV.DEL, import_sdk_core7.KV.LIST, import_sdk_core7.KV.METADATA];
21117
21181
  const abilities = { kv: { "": kvActions } };
21118
21182
  const now = /* @__PURE__ */ new Date();
21119
21183
  const expiryMs = import_sdk_core7.EXPIRY.EPHEMERAL_MS;
@@ -21636,7 +21700,7 @@ var _TinyCloudNode = class _TinyCloudNode {
21636
21700
  return grants;
21637
21701
  }
21638
21702
  for (const operation of operations) {
21639
- const grant = this.findGrantForOperation(operation);
21703
+ const grant = this.findGrantForOperation(operation, { excludePrimary: true });
21640
21704
  if (!grant) {
21641
21705
  return [];
21642
21706
  }
@@ -21676,7 +21740,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21676
21740
  },
21677
21741
  delegation,
21678
21742
  operations,
21679
- expiresAt: delegation.expiry
21743
+ expiresAt: delegation.expiry,
21744
+ provenance: "delegated"
21680
21745
  };
21681
21746
  }
21682
21747
  installRuntimeGrantFromServiceSession(delegation, session, expiresAt) {
@@ -21691,7 +21756,8 @@ var _TinyCloudNode = class _TinyCloudNode {
21691
21756
  session,
21692
21757
  delegation,
21693
21758
  operations,
21694
- expiresAt
21759
+ expiresAt,
21760
+ provenance: "delegated"
21695
21761
  });
21696
21762
  }
21697
21763
  delegatedResourcesForEntries(entries, spaceId) {
@@ -21791,21 +21857,28 @@ var _TinyCloudNode = class _TinyCloudNode {
21791
21857
  });
21792
21858
  return grant?.session ?? fallback;
21793
21859
  }
21794
- findGrantForOperations(operations) {
21860
+ findGrantForOperations(operations, options) {
21795
21861
  if (operations.length === 0) {
21796
21862
  return void 0;
21797
21863
  }
21798
21864
  this.pruneExpiredRuntimePermissionGrants();
21799
- return this.runtimePermissionGrants.find((grant) => {
21865
+ const covering = this.runtimePermissionGrants.filter((grant) => {
21866
+ if (options?.excludePrimary && grant.provenance === "primary") {
21867
+ return false;
21868
+ }
21800
21869
  return operations.every(
21801
21870
  (operation) => grant.operations.some(
21802
21871
  (granted) => this.operationCovers(granted, operation)
21803
21872
  )
21804
21873
  );
21805
21874
  });
21875
+ if (covering.length === 0) {
21876
+ return void 0;
21877
+ }
21878
+ return covering.find((grant) => grant.provenance === "primary") ?? covering[0];
21806
21879
  }
21807
- findGrantForOperation(operation) {
21808
- return this.findGrantForOperations([operation]);
21880
+ findGrantForOperation(operation, options) {
21881
+ return this.findGrantForOperations([operation], options);
21809
21882
  }
21810
21883
  pruneExpiredRuntimePermissionGrants() {
21811
21884
  const now = Date.now();
@@ -22042,7 +22115,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22042
22115
  session.chainId
22043
22116
  );
22044
22117
  const publicAbilities = {
22045
- kv: { "": ["tinycloud.kv/get", "tinycloud.kv/put", "tinycloud.kv/metadata"] }
22118
+ kv: { "": [import_sdk_core7.KV.GET, import_sdk_core7.KV.PUT, import_sdk_core7.KV.METADATA] }
22046
22119
  };
22047
22120
  const publicPrepared = this.wasmBindings.prepareSession({
22048
22121
  abilities: publicAbilities,
@@ -22070,7 +22143,7 @@ var _TinyCloudNode = class _TinyCloudNode {
22070
22143
  delegationHeader: publicSession.delegationHeader,
22071
22144
  spaceId: publicSpaceId,
22072
22145
  path: "",
22073
- actions: ["tinycloud.kv/get", "tinycloud.kv/put", "tinycloud.kv/metadata"],
22146
+ actions: [import_sdk_core7.KV.GET, import_sdk_core7.KV.PUT, import_sdk_core7.KV.METADATA],
22074
22147
  disableSubDelegation: params.disableSubDelegation ?? false,
22075
22148
  expiry: expirationTime,
22076
22149
  delegateDID: params.delegateDID,