@tinycloud/node-sdk 3.5.0-beta.0 → 3.5.0

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.cjs CHANGED
@@ -2983,6 +2983,16 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
2983
2983
  return entries;
2984
2984
  }
2985
2985
  var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core8.EXPIRY.SESSION_MS;
2986
+ var SHARE_NETWORK_NAME_RE = /^share-[a-z0-9][a-z0-9-]{15,35}$/;
2987
+ function grantsCappedDecrypt(path, actions) {
2988
+ if (!actions.some((action) => (0, import_sdk_core8.actionContains)(action, import_sdk_core8.ENCRYPTION.DECRYPT))) {
2989
+ return false;
2990
+ }
2991
+ return !((0, import_sdk_core8.isNetworkId)(path) && SHARE_NETWORK_NAME_RE.test((0, import_sdk_core8.parseNetworkId)(path).name));
2992
+ }
2993
+ function includesDecrypt(entries) {
2994
+ return entries.some((entry) => grantsCappedDecrypt(entry.path, entry.actions));
2995
+ }
2986
2996
  function resolveExpiryMs(expiry) {
2987
2997
  if (expiry === void 0) {
2988
2998
  return DEFAULT_DELEGATION_EXPIRY_MS;
@@ -3150,6 +3160,15 @@ var NodeSecretsService = class {
3150
3160
  if (this.hasPermission(permissionEntries)) {
3151
3161
  return ok();
3152
3162
  }
3163
+ let escalation;
3164
+ try {
3165
+ escalation = this.config.uncoveredEntries?.(permissionEntries) ?? permissionEntries;
3166
+ } catch (error) {
3167
+ return this.escalationError(action, target, error);
3168
+ }
3169
+ if (this.config.uncoveredEntries !== void 0 && escalation.length === 0) {
3170
+ return ok();
3171
+ }
3153
3172
  if (!this.config.canEscalate()) {
3154
3173
  return secretsError(
3155
3174
  import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
@@ -3157,16 +3176,20 @@ var NodeSecretsService = class {
3157
3176
  );
3158
3177
  }
3159
3178
  try {
3160
- await this.config.grantPermissions(permissionEntries);
3179
+ const grant = action === "get" && this.config.grantGetPermissions !== void 0 ? this.config.grantGetPermissions : this.config.grantPermissions;
3180
+ await grant(escalation);
3161
3181
  return this.restoreUnlockAfterEscalation();
3162
3182
  } catch (error) {
3163
- return secretsError(
3164
- import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
3165
- error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
3166
- error instanceof Error ? error : void 0
3167
- );
3183
+ return this.escalationError(action, target, error);
3168
3184
  }
3169
3185
  }
3186
+ escalationError(action, target, error) {
3187
+ return secretsError(
3188
+ import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
3189
+ error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
3190
+ error instanceof Error ? error : void 0
3191
+ );
3192
+ }
3170
3193
  async restoreUnlockAfterEscalation() {
3171
3194
  if (!this.shouldRestoreUnlock) {
3172
3195
  return ok();
@@ -3572,6 +3595,8 @@ function ownerPermissionsToAbilities(permissions) {
3572
3595
  return { abilities, rawAbilities };
3573
3596
  }
3574
3597
  var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation to a did:key (not did:pkh); use the session-key DID or drop the flag";
3598
+ var DECRYPT_GRANT_MAX_EXPIRY_MS = 60 * 60 * 1e3;
3599
+ var SECRET_GET_GRANT_EXPIRY_MS = 59 * 60 * 1e3;
3575
3600
  function base64UrlEncode(bytes) {
3576
3601
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
3577
3602
  let output = "";
@@ -7694,6 +7719,8 @@ var _TinyCloudNode = class _TinyCloudNode {
7694
7719
  getManifest: () => this.manifest,
7695
7720
  hasPermissions: (permissions) => this.hasRuntimePermissions(permissions),
7696
7721
  grantPermissions: (additional) => this.grantRuntimePermissions(additional),
7722
+ grantGetPermissions: (additional) => this.grantRuntimePermissions(additional, { expiry: SECRET_GET_GRANT_EXPIRY_MS }),
7723
+ uncoveredEntries: (permissions) => permissions.filter((entry) => !this.hasRuntimePermissions([entry])),
7697
7724
  canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
7698
7725
  getEncryptionNetworkId: () => this.getEncryptionNetworkIdForSpace(resolvedSpace),
7699
7726
  resolveSpace: (space) => space.startsWith("tinycloud:") ? space : this.ownedSpaceId(space),
@@ -8041,6 +8068,13 @@ var _TinyCloudNode = class _TinyCloudNode {
8041
8068
  }
8042
8069
  }
8043
8070
  const expanded = this.expandPermissionEntries(permissions);
8071
+ const requestsDecrypt = includesDecrypt(expanded);
8072
+ const requestedExpiryMs = requestsDecrypt && options?.expiry === void 0 ? DECRYPT_GRANT_MAX_EXPIRY_MS : resolveExpiryMs(options?.expiry);
8073
+ if (requestsDecrypt && requestedExpiryMs > DECRYPT_GRANT_MAX_EXPIRY_MS) {
8074
+ throw Object.assign(new Error("decrypt grants last at most one hour"), {
8075
+ code: "DECRYPT_EXPIRY_TOO_LONG"
8076
+ });
8077
+ }
8044
8078
  if (this.sessionCoversPermissionEntries(session, expanded)) {
8045
8079
  return [];
8046
8080
  }
@@ -8071,7 +8105,6 @@ var _TinyCloudNode = class _TinyCloudNode {
8071
8105
  bySpace.set(session.spaceId, []);
8072
8106
  }
8073
8107
  const now = /* @__PURE__ */ new Date();
8074
- const requestedExpiryMs = resolveExpiryMs(options?.expiry);
8075
8108
  let expiresAt = new Date(now.getTime() + requestedExpiryMs);
8076
8109
  if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
8077
8110
  expiresAt = sessionExpiry;