@tinycloud/node-sdk 2.4.0-beta.3 → 2.4.0-beta.5

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.
@@ -976,6 +976,8 @@ declare class TinyCloudNode {
976
976
  signIn(options?: SignInOptions): Promise<void>;
977
977
  private ownedSpaceId;
978
978
  private writeManifestRegistryRecords;
979
+ private requestedEncryptionNetworkIds;
980
+ private ensureRequestedEncryptionNetworks;
979
981
  private ensureOwnedSpaceHosted;
980
982
  /**
981
983
  * Host one of this user's owned spaces by name (e.g. `"applications"`).
@@ -1192,7 +1194,7 @@ declare class TinyCloudNode {
1192
1194
  get encryption(): IEncryptionService;
1193
1195
  getEncryptionNetwork(nameOrNetworkId?: string): Promise<NetworkDescriptor | null>;
1194
1196
  createEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
1195
- ensureEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
1197
+ ensureEncryptionNetwork(nameOrNetworkId?: string): Promise<NetworkDescriptor>;
1196
1198
  /**
1197
1199
  * App-facing secrets API backed by the `secrets` space vault.
1198
1200
  */
@@ -976,6 +976,8 @@ declare class TinyCloudNode {
976
976
  signIn(options?: SignInOptions): Promise<void>;
977
977
  private ownedSpaceId;
978
978
  private writeManifestRegistryRecords;
979
+ private requestedEncryptionNetworkIds;
980
+ private ensureRequestedEncryptionNetworks;
979
981
  private ensureOwnedSpaceHosted;
980
982
  /**
981
983
  * Host one of this user's owned spaces by name (e.g. `"applications"`).
@@ -1192,7 +1194,7 @@ declare class TinyCloudNode {
1192
1194
  get encryption(): IEncryptionService;
1193
1195
  getEncryptionNetwork(nameOrNetworkId?: string): Promise<NetworkDescriptor | null>;
1194
1196
  createEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
1195
- ensureEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
1197
+ ensureEncryptionNetwork(nameOrNetworkId?: string): Promise<NetworkDescriptor>;
1196
1198
  /**
1197
1199
  * App-facing secrets API backed by the `secrets` space vault.
1198
1200
  */
package/dist/core.cjs CHANGED
@@ -317,6 +317,25 @@ var import_sdk_core2 = require("@tinycloud/sdk-core");
317
317
  var defaultSignStrategy = { type: "auto-sign" };
318
318
 
319
319
  // src/authorization/NodeUserAuthorization.ts
320
+ var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
321
+ var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
322
+ function didPrincipalMatches(actual, expected) {
323
+ try {
324
+ return (0, import_sdk_core2.principalDidEquals)(actual, expected);
325
+ } catch {
326
+ return actual === expected;
327
+ }
328
+ }
329
+ function addRawAbility(rawAbilities, resource, action) {
330
+ const actions = rawAbilities[resource];
331
+ if (actions === void 0) {
332
+ rawAbilities[resource] = [action];
333
+ return;
334
+ }
335
+ if (!actions.includes(action)) {
336
+ actions.push(action);
337
+ }
338
+ }
320
339
  var NodeUserAuthorization = class {
321
340
  constructor(config) {
322
341
  this.extensions = [];
@@ -546,20 +565,18 @@ var NodeUserAuthorization = class {
546
565
  };
547
566
  }
548
567
  const rawAbilities = {};
568
+ const currentDid = (0, import_sdk_core2.pkhDid)(address, chainId);
549
569
  const spaceResources = request.resources.filter((entry) => {
550
570
  if (entry.service !== import_sdk_core2.ENCRYPTION_PERMISSION_SERVICE) {
551
571
  return true;
552
572
  }
553
- const existing = rawAbilities[entry.path];
554
- if (existing === void 0) {
555
- rawAbilities[entry.path] = [...entry.actions];
556
- } else {
557
- const seen = new Set(existing);
558
- for (const action of entry.actions) {
559
- if (!seen.has(action)) {
560
- existing.push(action);
561
- seen.add(action);
562
- }
573
+ for (const action of entry.actions) {
574
+ addRawAbility(rawAbilities, entry.path, action);
575
+ }
576
+ if (entry.actions.includes(DECRYPT_ACTION)) {
577
+ const parsed = (0, import_sdk_core2.parseNetworkId)(entry.path);
578
+ if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
579
+ addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
563
580
  }
564
581
  }
565
582
  return false;
@@ -1522,11 +1539,11 @@ var NodeSecretsService = class {
1522
1539
  // src/TinyCloudNode.ts
1523
1540
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
1524
1541
  var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
1525
- var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
1526
- var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
1542
+ var NETWORK_CREATE_ACTION2 = "tinycloud.encryption/network.create";
1543
+ var DECRYPT_ACTION2 = "tinycloud.encryption/decrypt";
1527
1544
  var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
1528
1545
  var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core6.EXPIRY.SESSION_MS;
1529
- function didPrincipalMatches(actual, expected) {
1546
+ function didPrincipalMatches2(actual, expected) {
1530
1547
  try {
1531
1548
  return (0, import_sdk_core6.principalDidEquals)(actual, expected);
1532
1549
  } catch {
@@ -1902,6 +1919,7 @@ var _TinyCloudNode = class _TinyCloudNode {
1902
1919
  await this.tc.signIn(options);
1903
1920
  this.syncResolvedHostFromAuth();
1904
1921
  this.initializeServices();
1922
+ await this.ensureRequestedEncryptionNetworks();
1905
1923
  if (this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
1906
1924
  await this.ensureOwnedSpaceHosted(this.ownedSpaceId("secrets"));
1907
1925
  }
@@ -1938,6 +1956,31 @@ var _TinyCloudNode = class _TinyCloudNode {
1938
1956
  }
1939
1957
  }
1940
1958
  }
1959
+ requestedEncryptionNetworkIds() {
1960
+ const request = this.capabilityRequest;
1961
+ if (!request) {
1962
+ return [];
1963
+ }
1964
+ const networkIds = /* @__PURE__ */ new Set();
1965
+ for (const resource of request.resources) {
1966
+ if (resource.service === import_sdk_core6.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
1967
+ networkIds.add(resource.path);
1968
+ }
1969
+ }
1970
+ return [...networkIds];
1971
+ }
1972
+ async ensureRequestedEncryptionNetworks() {
1973
+ if (!this.signer || !this.auth) {
1974
+ return;
1975
+ }
1976
+ for (const networkId of this.requestedEncryptionNetworkIds()) {
1977
+ const parsed = (0, import_sdk_core6.parseNetworkId)(networkId);
1978
+ if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
1979
+ continue;
1980
+ }
1981
+ await this.ensureEncryptionNetwork(networkId);
1982
+ }
1983
+ }
1941
1984
  async ensureOwnedSpaceHosted(spaceId) {
1942
1985
  if (!this.auth) {
1943
1986
  throw new Error("Owned space hosting requires wallet mode");
@@ -2406,7 +2449,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2406
2449
  const signed = await this.signRawNetworkAuthorization({
2407
2450
  targetNode: input.targetNode,
2408
2451
  networkId: input.networkId,
2409
- action: DECRYPT_ACTION,
2452
+ action: DECRYPT_ACTION2,
2410
2453
  facts: input.facts
2411
2454
  });
2412
2455
  return {
@@ -2423,7 +2466,7 @@ var _TinyCloudNode = class _TinyCloudNode {
2423
2466
  },
2424
2467
  wellKnown: {
2425
2468
  fetchWellKnown: async (principal, discoveryKey) => {
2426
- if (!this._address || !didPrincipalMatches(principal, this.did)) {
2469
+ if (!this._address || !didPrincipalMatches2(principal, this.did)) {
2427
2470
  return null;
2428
2471
  }
2429
2472
  if (!this.config.host) {
@@ -2930,12 +2973,12 @@ var _TinyCloudNode = class _TinyCloudNode {
2930
2973
  crypto.sha256,
2931
2974
  body
2932
2975
  ),
2933
- action: NETWORK_CREATE_ACTION
2976
+ action: NETWORK_CREATE_ACTION2
2934
2977
  };
2935
2978
  const signed = await this.signRawNetworkAuthorization({
2936
2979
  targetNode,
2937
2980
  networkId,
2938
- action: NETWORK_CREATE_ACTION,
2981
+ action: NETWORK_CREATE_ACTION2,
2939
2982
  facts
2940
2983
  });
2941
2984
  const response = await fetch(`${this.config.host}/encryption/networks`, {
@@ -2956,12 +2999,19 @@ var _TinyCloudNode = class _TinyCloudNode {
2956
2999
  const created = await response.json();
2957
3000
  return created.descriptor;
2958
3001
  }
2959
- async ensureEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
2960
- const existing = await this.getEncryptionNetwork(name);
3002
+ async ensureEncryptionNetwork(nameOrNetworkId = DEFAULT_ENCRYPTION_NETWORK_NAME) {
3003
+ const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
3004
+ const existing = await this.getEncryptionNetwork(networkId);
2961
3005
  if (existing) {
2962
3006
  return existing;
2963
3007
  }
2964
- return this.createEncryptionNetwork(name);
3008
+ const parsed = (0, import_sdk_core6.parseNetworkId)(networkId);
3009
+ if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
3010
+ throw new Error(
3011
+ `Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
3012
+ );
3013
+ }
3014
+ return this.createEncryptionNetwork(parsed.name);
2965
3015
  }
2966
3016
  /**
2967
3017
  * App-facing secrets API backed by the `secrets` space vault.
@@ -3109,7 +3159,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3109
3159
  throw new import_sdk_core6.SessionExpiredError(delegation.expiry);
3110
3160
  }
3111
3161
  const expectedDids = [session.verificationMethod, this.sessionDid];
3112
- if (!expectedDids.some((did) => didPrincipalMatches(delegation.delegateDID, did))) {
3162
+ if (!expectedDids.some((did) => didPrincipalMatches2(delegation.delegateDID, did))) {
3113
3163
  throw new Error(
3114
3164
  `Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
3115
3165
  );
@@ -3638,7 +3688,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3638
3688
  );
3639
3689
  }
3640
3690
  const target = request.delegationTargets.find(
3641
- (entry) => didPrincipalMatches(entry.did, did)
3691
+ (entry) => didPrincipalMatches2(entry.did, did)
3642
3692
  );
3643
3693
  if (!target) {
3644
3694
  throw new Error(`No manifest delegation target found for DID ${did}`);
@@ -4368,7 +4418,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4368
4418
  const targetHost = delegation.host ?? this.config.host;
4369
4419
  if (this.isSessionOnly) {
4370
4420
  const myDid = this.did;
4371
- if (!didPrincipalMatches(delegation.delegateDID, myDid)) {
4421
+ if (!didPrincipalMatches2(delegation.delegateDID, myDid)) {
4372
4422
  throw new Error(
4373
4423
  `Delegation targets ${delegation.delegateDID} but this user's DID is ${myDid}. The delegation must target this user's DID.`
4374
4424
  );