@tinycloud/sdk-core 3.8.0-beta.3 → 3.8.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.
package/dist/index.cjs CHANGED
@@ -7311,8 +7311,14 @@ var DelegationManager = class {
7311
7311
  };
7312
7312
  }
7313
7313
  }
7314
- /** Query lifecycle-complete delegation history for the authenticated account. */
7315
- async query(options2 = {}) {
7314
+ /**
7315
+ * Query lifecycle-complete delegation history for the authenticated account.
7316
+ *
7317
+ * `scope.spaces` lists the spaces to sign `tinycloud.delegation/list` for, in order. Omitted, the
7318
+ * account space is tried, then the session's own space. A caller that knows which of them the session
7319
+ * holds passes only those; an empty list sends nothing and answers PERMISSION_DENIED.
7320
+ */
7321
+ async query(options2 = {}, scope = {}) {
7316
7322
  const validated = AccountDelegationQueryOptionsSchema.safeParse(options2);
7317
7323
  if (!validated.success) {
7318
7324
  return {
@@ -7346,7 +7352,7 @@ var DelegationManager = class {
7346
7352
  }
7347
7353
  try {
7348
7354
  let response;
7349
- for (const spaceId of /* @__PURE__ */ new Set([accountSpaceId, this.session.spaceId])) {
7355
+ for (const spaceId of new Set(scope.spaces ?? [accountSpaceId, this.session.spaceId])) {
7350
7356
  const headers = Object.fromEntries(new Headers(this.invokeAny(this.session, [{
7351
7357
  spaceId,
7352
7358
  service: "delegation",
@@ -7835,6 +7841,14 @@ function expandEncryptionPermissionEntry(entry) {
7835
7841
  `tinycloud.encryption entries require path to be a networkId URN (got ${JSON.stringify(entry.path)})`
7836
7842
  );
7837
7843
  }
7844
+ if (entry.path.includes("/")) {
7845
+ throw new ManifestValidationError("named keys go in manifest.keys");
7846
+ }
7847
+ try {
7848
+ (0, import_sdk_services2.parseNetworkId)(entry.path);
7849
+ } catch {
7850
+ throw new ManifestValidationError("tinycloud.encryption entries require a valid networkId URN");
7851
+ }
7838
7852
  const normalizedActions = [];
7839
7853
  for (const action of entry.actions) {
7840
7854
  if (action === "decrypt" || action === "tinycloud.encryption/decrypt") {
@@ -7959,8 +7973,56 @@ function validateManifest(input) {
7959
7973
  if (m.secrets !== void 0) {
7960
7974
  validateManifestSecrets(m.secrets);
7961
7975
  }
7976
+ if (Object.prototype.hasOwnProperty.call(m, "keys_app_id") && (typeof m.keys_app_id !== "string" || !KEY_APP_ID.test(m.keys_app_id))) {
7977
+ throw new ManifestValidationError("manifest.keys_app_id is invalid");
7978
+ }
7979
+ validateManifestKeys(m.keys_app_id ?? m.app_id, m.keys);
7962
7980
  return m;
7963
7981
  }
7982
+ var KEY_SEGMENT = "[a-z0-9][a-z0-9._-]{0,63}";
7983
+ var KEY_APP_ID = new RegExp(`^${KEY_SEGMENT}$`);
7984
+ var KEY_PATH = new RegExp(`^${KEY_SEGMENT}(?:/${KEY_SEGMENT}){2,7}$`);
7985
+ var KEY_ABILITIES = ["key.create", "decrypt", "key.block", "key.unblock"];
7986
+ function validateManifestKeys(appId, keys) {
7987
+ if (keys === void 0) return;
7988
+ if (!Array.isArray(keys) || keys.length > 32) {
7989
+ throw new ManifestValidationError("manifest.keys must contain at most 32 entries");
7990
+ }
7991
+ if (keys.length === 0) return;
7992
+ if (!KEY_APP_ID.test(appId)) {
7993
+ throw new ManifestValidationError("manifest.keys requires a valid app_id");
7994
+ }
7995
+ const paths = /* @__PURE__ */ new Set();
7996
+ let prefixSeen = false;
7997
+ for (const [index, value] of keys.entries()) {
7998
+ const label = `manifest.keys[${index}]`;
7999
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
8000
+ throw new ManifestValidationError(`${label} must be an object`);
8001
+ }
8002
+ const entry = value;
8003
+ const fields = Object.keys(entry);
8004
+ const hasPath = Object.prototype.hasOwnProperty.call(entry, "path");
8005
+ const hasPrefix = Object.prototype.hasOwnProperty.call(entry, "prefix");
8006
+ if (hasPath === hasPrefix || fields.some((field) => !["path", "prefix", "abilities"].includes(field))) {
8007
+ throw new ManifestValidationError(`${label} must have one path or prefix and abilities`);
8008
+ }
8009
+ if (!Array.isArray(entry.abilities) || entry.abilities.length === 0 || new Set(entry.abilities).size !== entry.abilities.length || entry.abilities.some((ability) => typeof ability !== "string" || !KEY_ABILITIES.includes(ability))) {
8010
+ throw new ManifestValidationError(`${label}.abilities is invalid`);
8011
+ }
8012
+ if (hasPath) {
8013
+ const path = entry.path;
8014
+ if (typeof path !== "string" || path.length > 255 || !KEY_PATH.test(path) || !path.startsWith(`apps/${appId}/`) || paths.has(path)) {
8015
+ throw new ManifestValidationError(`${label}.path is invalid`);
8016
+ }
8017
+ paths.add(path);
8018
+ } else {
8019
+ if (entry.prefix !== `apps/${appId}/` || prefixSeen) {
8020
+ throw new ManifestValidationError(`${label}.prefix is invalid`);
8021
+ }
8022
+ prefixSeen = true;
8023
+ }
8024
+ }
8025
+ }
7964
8026
  function resolveManifestKnowledgeRoot(knowledge) {
7965
8027
  if (knowledge === void 0) {
7966
8028
  return void 0;