@tinycloud/share-sdk 1.1.0-beta.1 → 1.1.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/index.cjs CHANGED
@@ -7993,7 +7993,6 @@ async function notifyShare(input) {
7993
7993
  };
7994
7994
  }
7995
7995
  let attempts = 0;
7996
- let lastError;
7997
7996
  while (attempts < attemptsLimit) {
7998
7997
  if (input.signal?.aborted) throw new ShareNotifyError("share delivery was cancelled");
7999
7998
  attempts += 1;
@@ -8020,10 +8019,19 @@ async function notifyShare(input) {
8020
8019
  reason: "delivery-window-expired"
8021
8020
  };
8022
8021
  }
8023
- lastError = error;
8022
+ if (error !== null && typeof error === "object" && "status" in error && (error.status === 401 || error.status === 403)) {
8023
+ return {
8024
+ protocol: "tinycloud-share",
8025
+ version: 1,
8026
+ shareId: input.shareId,
8027
+ state: "partial-failure",
8028
+ idempotencyKey,
8029
+ attempts,
8030
+ retryable: false
8031
+ };
8032
+ }
8024
8033
  }
8025
8034
  }
8026
- void lastError;
8027
8035
  return { protocol: "tinycloud-share", version: 1, shareId: input.shareId, state: "partial-failure", idempotencyKey, attempts, retryable: true };
8028
8036
  }
8029
8037
  async function defaultIdempotencyKey(shareId, recipient) {
@@ -8449,6 +8457,10 @@ function parseV3InlineEncryptedEnvelope(bytes3, expected) {
8449
8457
  }
8450
8458
  return record;
8451
8459
  }
8460
+ async function recipientHttpError(response, context) {
8461
+ const body = (await response.text().catch(() => "")).trim().slice(0, 512);
8462
+ return Object.assign(new Error(`${context} (${response.status})${body ? `: ${body}` : ""}`), { status: response.status });
8463
+ }
8452
8464
  var ShareRecipientClient = class {
8453
8465
  constructor(options) {
8454
8466
  this.options = options;
@@ -8522,7 +8534,7 @@ var ShareRecipientClient = class {
8522
8534
  body: JSON.stringify({ policyCid: envelope.policyCid, recipientDid: this.options.holderDid, requestedCapabilities: envelope.policy.capabilityCeiling }),
8523
8535
  ...this.options.signal === void 0 ? {} : { signal: this.options.signal }
8524
8536
  });
8525
- if (!challengeResponse.ok) throw new Error(`v3 policy challenge rejected (${challengeResponse.status})`);
8537
+ if (!challengeResponse.ok) throw await recipientHttpError(challengeResponse, "v3 policy challenge rejected");
8526
8538
  const challenge = object3(await challengeResponse.json(), "v3 policy challenge");
8527
8539
  if (typeof challenge.challengeId !== "string" || typeof challenge.nonce !== "string" || challenge.policyCid !== envelope.policyCid || challenge.recipientDid !== this.options.holderDid || challenge.nodeAudience !== attestedEnforcer.nodeAudience || challenge.enforcerDid !== void 0 && challenge.enforcerDid !== attestedEnforcer.enforcerDid || typeof challenge.expiresAt !== "string" || !Number.isFinite(Date.parse(challenge.expiresAt)) || Date.parse(challenge.expiresAt) <= Date.now()) throw new Error("v3 policy challenge binding mismatch");
8528
8540
  const material = await this.options.buildPresentation({
@@ -8547,14 +8559,14 @@ var ShareRecipientClient = class {
8547
8559
  const requestedExpiresAt = requestedSessionExpiry(envelope.expiry);
8548
8560
  let delegationResponse = await mint(requestedExpiresAt === void 0 ? mintBody : { ...mintBody, requestedExpiresAt });
8549
8561
  if (requestedExpiresAt !== void 0 && delegationResponse.status === 422) delegationResponse = await mint(mintBody);
8550
- if (!delegationResponse.ok) throw new Error(`v3 policy delegation rejected (${delegationResponse.status})`);
8562
+ if (!delegationResponse.ok) throw await recipientHttpError(delegationResponse, "v3 policy delegation rejected");
8551
8563
  const delegation = object3(await delegationResponse.json(), "v3 policy delegation");
8552
8564
  if (delegation.admitted !== true || typeof delegation.sessionCid !== "string" || typeof delegation.authorization !== "string") throw new Error("v3 policy delegation response is not admitted");
8553
8565
  const compact = verifyV3PolicyAuthorization({ authorization: delegation.authorization, cid: delegation.sessionCid, envelope, holderDid: this.options.holderDid });
8554
8566
  const fact = compact.payload.fct[0];
8555
8567
  this.options.onStage?.("delegation-import");
8556
8568
  const imported = await this.fetchFn(new URL("/delegate", this.options.nodeOrigin), { method: "POST", redirect: "error", headers: { Authorization: delegation.authorization }, ...this.options.signal === void 0 ? {} : { signal: this.options.signal } });
8557
- if (!imported.ok) throw new Error(`ordinary delegation import rejected (${imported.status})`);
8569
+ if (!imported.ok) throw await recipientHttpError(imported, "ordinary delegation import rejected");
8558
8570
  this.signer = material.sign;
8559
8571
  this.v3Authorization = delegation.authorization;
8560
8572
  this.v3NodeAudience = fact.nodeAudience;
@@ -8589,7 +8601,7 @@ var ShareRecipientClient = class {
8589
8601
  try {
8590
8602
  this.options.onStage?.("decryption");
8591
8603
  const response = await this.fetchFn(new URL("/invoke", this.options.nodeOrigin), { method: "POST", redirect: "error", headers: { accept: "application/json", "content-type": "application/json", Authorization: invocation.authorization }, body: JSON.stringify(body), ...this.options.signal === void 0 ? {} : { signal: this.options.signal } });
8592
- if (!response.ok) throw new Error(`v3 decrypt invocation rejected (${response.status})`);
8604
+ if (!response.ok) throw await recipientHttpError(response, "v3 decrypt invocation rejected");
8593
8605
  const value = object3(await response.json(), "v3 decrypt response");
8594
8606
  const allowed = ["type", "targetNode", "networkId", "invocationCid", "encryptedSymmetricKeyHash", "receiverPublicKeyHash", "wrappedKey", "alg", "keyVersion", "requestHash", "nodeId", "nodeSignature"];
8595
8607
  if (Object.keys(value).length !== allowed.length || Object.keys(value).some((key) => !allowed.includes(key)) || value.type !== "tinycloud.encryption.decrypt-result/v1" || value.targetNode !== body.targetNode || value.nodeId !== body.targetNode || value.networkId !== body.networkId || value.invocationCid !== invocation.cid || value.encryptedSymmetricKeyHash !== body.encryptedSymmetricKeyHash || value.receiverPublicKeyHash !== receiverPublicKeyHash || value.alg !== body.alg || value.keyVersion !== body.keyVersion || value.requestHash !== hex3((0, import_sha2565.sha256)(new TextEncoder().encode(`${invocation.cid}${bodyHash}`))) || typeof value.wrappedKey !== "string" || typeof value.nodeSignature !== "string") throw new Error("v3 decrypt response binding is invalid");