@tinycloud/share-sdk 1.4.0 → 1.4.1-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.
@@ -20,6 +20,9 @@ interface TargetPublishInput {
20
20
  readonly resourceKind?: "exact" | "prefix";
21
21
  readonly actions?: readonly ("read" | "list" | "edit")[];
22
22
  readonly notify?: boolean;
23
+ readonly credentialDescriptor?: unknown;
24
+ readonly issuerDid?: string;
25
+ readonly issuerKid?: string;
23
26
  /** Publish as the next write-once version of this artifact and pin the share to it (TC-1428). */
24
27
  readonly artifact?: {
25
28
  readonly id: string;
@@ -44,6 +47,9 @@ declare function publishTargetShare(input: SharePublishOptions & {
44
47
  }[];
45
48
  readonly resourceKind?: "exact" | "prefix";
46
49
  readonly actions?: readonly ("read" | "list" | "edit")[];
50
+ readonly credentialDescriptor?: unknown;
51
+ readonly issuerDid?: string;
52
+ readonly issuerKid?: string;
47
53
  }): Promise<TargetPublishOutcome>;
48
54
 
49
55
  interface AddressedOwnerRootInput {
@@ -203,6 +209,7 @@ interface AddressedShareBoundInput extends AddressedShareRequest {
203
209
  };
204
210
  /** The owner's encryption network for the space. */
205
211
  readonly encryptionNetwork: string;
212
+ readonly encryptionKeyPath?: string;
206
213
  readonly mediaType: string;
207
214
  readonly byteLength: number;
208
215
  readonly artifact?: "html";
@@ -20,6 +20,9 @@ interface TargetPublishInput {
20
20
  readonly resourceKind?: "exact" | "prefix";
21
21
  readonly actions?: readonly ("read" | "list" | "edit")[];
22
22
  readonly notify?: boolean;
23
+ readonly credentialDescriptor?: unknown;
24
+ readonly issuerDid?: string;
25
+ readonly issuerKid?: string;
23
26
  /** Publish as the next write-once version of this artifact and pin the share to it (TC-1428). */
24
27
  readonly artifact?: {
25
28
  readonly id: string;
@@ -44,6 +47,9 @@ declare function publishTargetShare(input: SharePublishOptions & {
44
47
  }[];
45
48
  readonly resourceKind?: "exact" | "prefix";
46
49
  readonly actions?: readonly ("read" | "list" | "edit")[];
50
+ readonly credentialDescriptor?: unknown;
51
+ readonly issuerDid?: string;
52
+ readonly issuerKid?: string;
47
53
  }): Promise<TargetPublishOutcome>;
48
54
 
49
55
  interface AddressedOwnerRootInput {
@@ -203,6 +209,7 @@ interface AddressedShareBoundInput extends AddressedShareRequest {
203
209
  };
204
210
  /** The owner's encryption network for the space. */
205
211
  readonly encryptionNetwork: string;
212
+ readonly encryptionKeyPath?: string;
206
213
  readonly mediaType: string;
207
214
  readonly byteLength: number;
208
215
  readonly artifact?: "html";
package/dist/artifact.cjs CHANGED
@@ -5244,6 +5244,23 @@ var unifiedEncryptionNetworkSchema = external_exports.string().refine((value) =>
5244
5244
  const network = separator < 0 ? "" : rest.slice(separator + 1);
5245
5245
  return owner.startsWith("did:") && owner.length > 4 && network.length > 0 && !/[:/%?#\s]/.test(network);
5246
5246
  }, { message: "expected canonical TinyCloud encryption network" });
5247
+ var unifiedEncryptionResourceSchema = external_exports.string().refine((value) => {
5248
+ const prefix = "urn:tinycloud:encryption:";
5249
+ if (!value.startsWith(prefix)) return false;
5250
+ const match = /^(did:.+):([^/:?#\s]+)(?:\/(.+))?$/.exec(value.slice(prefix.length));
5251
+ if (match === null) return false;
5252
+ const path = match[3];
5253
+ return path === void 0 || path.split("/").every(
5254
+ (segment) => segment.length > 0 && segment !== "." && segment !== ".." && !/[\\:%?#\s]/.test(segment)
5255
+ );
5256
+ }, { message: "expected a canonical TinyCloud encryption resource" });
5257
+ var unifiedEncryptionKeyPathSchema = external_exports.string().regex(/^share\/[^/]+$/).refine(
5258
+ (value) => {
5259
+ const segment = value.slice("share/".length);
5260
+ return segment !== "." && segment !== ".." && !/[\\:%?#\s]/.test(segment);
5261
+ },
5262
+ { message: "expected an exact share key path" }
5263
+ );
5247
5264
  var unifiedKvCapabilitySchema = external_exports.object({
5248
5265
  kind: external_exports.literal("kv"),
5249
5266
  resource: unifiedResourceSchema,
@@ -5257,7 +5274,7 @@ var unifiedKvCapabilitySchema = external_exports.object({
5257
5274
  }).strict();
5258
5275
  var unifiedEncryptionCapabilitySchema = external_exports.object({
5259
5276
  kind: external_exports.literal("encryption"),
5260
- resource: unifiedEncryptionNetworkSchema,
5277
+ resource: unifiedEncryptionResourceSchema,
5261
5278
  action: external_exports.literal("tinycloud.encryption/decrypt")
5262
5279
  }).strict();
5263
5280
  var unifiedCapabilitySchema = external_exports.union([unifiedKvCapabilitySchema, unifiedEncryptionCapabilitySchema]);
@@ -5266,6 +5283,7 @@ var unifiedContentSourceSchema = external_exports.object({
5266
5283
  kvResource: unifiedResourceSchema,
5267
5284
  selector: external_exports.union([external_exports.literal("exact"), external_exports.literal("prefix")]),
5268
5285
  encryptionNetwork: unifiedEncryptionNetworkSchema,
5286
+ encryptionKeyPath: unifiedEncryptionKeyPathSchema.optional(),
5269
5287
  encryptedSymmetricKeyDigestHex: external_exports.string().regex(/^[0-9a-f]{64}$/),
5270
5288
  keyVersion: external_exports.number().int().positive(),
5271
5289
  mode: external_exports.union([external_exports.literal("mutable"), external_exports.literal("immutable")]),
@@ -5383,16 +5401,21 @@ function validateV3Invariants(value, ctx) {
5383
5401
  if (value.attestedEnforcerBinding.nodeAudience !== value.target.nodeAudience || value.attestedEnforcerBinding.signature.signerDid !== value.attestedEnforcerBinding.nodeAudience || Date.parse(value.attestedEnforcerBinding.expiresAt) < Date.parse(value.expiry)) {
5384
5402
  ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["attestedEnforcerBinding"], message: "enforcer binding does not cover the target and share lifetime" });
5385
5403
  }
5386
- if (value.policy.contentSource.shareId !== value.contentSource.shareId || value.policy.contentSource.kvResource !== value.contentSource.kvResource || value.policy.contentSource.selector !== value.contentSource.selector || value.policy.contentSource.encryptionNetwork !== value.encryptionNetwork || value.policy.contentSource.encryptedSymmetricKeyDigestHex !== value.contentSource.encryptedSymmetricKeyDigestHex || value.policy.contentSource.keyVersion !== value.contentSource.keyVersion || value.policy.contentSource.mode !== value.contentSource.mode || value.policy.contentSource.initialCiphertextDigestHex !== value.contentSource.initialCiphertextDigestHex) {
5404
+ const encryptionKeyPath = value.contentSource.encryptionKeyPath;
5405
+ if (encryptionKeyPath !== void 0 && encryptionKeyPath !== `share/${value.contentSource.shareId}`) {
5406
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["contentSource", "encryptionKeyPath"], message: "share key path must name this share" });
5407
+ }
5408
+ if (value.policy.contentSource.shareId !== value.contentSource.shareId || value.policy.contentSource.kvResource !== value.contentSource.kvResource || value.policy.contentSource.selector !== value.contentSource.selector || value.policy.contentSource.encryptionNetwork !== value.encryptionNetwork || value.policy.contentSource.encryptionKeyPath !== encryptionKeyPath || value.policy.contentSource.encryptedSymmetricKeyDigestHex !== value.contentSource.encryptedSymmetricKeyDigestHex || value.policy.contentSource.keyVersion !== value.contentSource.keyVersion || value.policy.contentSource.mode !== value.contentSource.mode || value.policy.contentSource.initialCiphertextDigestHex !== value.contentSource.initialCiphertextDigestHex) {
5387
5409
  ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["contentSource"], message: "content source is not bound to policy" });
5388
5410
  }
5389
5411
  if (value.policy.signature.suite !== "Ed25519" || value.policy.signature.signerDid !== value.policy.ownerDid) {
5390
5412
  ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policy", "signature"], message: "policy must be signed by its owner" });
5391
5413
  }
5392
5414
  const kvCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "kv");
5393
- const decryptCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "encryption" && capability.resource === value.encryptionNetwork && capability.action === "tinycloud.encryption/decrypt");
5415
+ const expectedEncryptionResource = encryptionKeyPath === void 0 ? value.encryptionNetwork : `${value.encryptionNetwork}/${encryptionKeyPath}`;
5416
+ const decryptCapabilities = value.policy.capabilityCeiling.filter((capability) => capability.kind === "encryption" && capability.resource === expectedEncryptionResource && capability.action === "tinycloud.encryption/decrypt");
5394
5417
  if (value.policy.capabilityCeiling.length !== 2 || kvCapabilities.length !== 1 || decryptCapabilities.length !== 1 || kvCapabilities[0]?.resource !== value.contentSource.kvResource || kvCapabilities[0]?.selector !== value.contentSource.selector) {
5395
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policy", "capabilityCeiling"], message: "policy ceiling must contain exact decrypt network" });
5418
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["policy", "capabilityCeiling"], message: "policy ceiling must contain the exact decrypt resource" });
5396
5419
  }
5397
5420
  }
5398
5421
  var unsignedShareEnvelopeV3Schema = unsignedShareEnvelopeV3BaseSchema.superRefine(validateV3Invariants);