@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.js CHANGED
@@ -7909,7 +7909,6 @@ async function notifyShare(input) {
7909
7909
  };
7910
7910
  }
7911
7911
  let attempts = 0;
7912
- let lastError;
7913
7912
  while (attempts < attemptsLimit) {
7914
7913
  if (input.signal?.aborted) throw new ShareNotifyError("share delivery was cancelled");
7915
7914
  attempts += 1;
@@ -7936,10 +7935,19 @@ async function notifyShare(input) {
7936
7935
  reason: "delivery-window-expired"
7937
7936
  };
7938
7937
  }
7939
- lastError = error;
7938
+ if (error !== null && typeof error === "object" && "status" in error && (error.status === 401 || error.status === 403)) {
7939
+ return {
7940
+ protocol: "tinycloud-share",
7941
+ version: 1,
7942
+ shareId: input.shareId,
7943
+ state: "partial-failure",
7944
+ idempotencyKey,
7945
+ attempts,
7946
+ retryable: false
7947
+ };
7948
+ }
7940
7949
  }
7941
7950
  }
7942
- void lastError;
7943
7951
  return { protocol: "tinycloud-share", version: 1, shareId: input.shareId, state: "partial-failure", idempotencyKey, attempts, retryable: true };
7944
7952
  }
7945
7953
  async function defaultIdempotencyKey(shareId, recipient) {
@@ -8365,6 +8373,10 @@ function parseV3InlineEncryptedEnvelope(bytes3, expected) {
8365
8373
  }
8366
8374
  return record;
8367
8375
  }
8376
+ async function recipientHttpError(response, context) {
8377
+ const body = (await response.text().catch(() => "")).trim().slice(0, 512);
8378
+ return Object.assign(new Error(`${context} (${response.status})${body ? `: ${body}` : ""}`), { status: response.status });
8379
+ }
8368
8380
  var ShareRecipientClient = class {
8369
8381
  constructor(options) {
8370
8382
  this.options = options;
@@ -8438,7 +8450,7 @@ var ShareRecipientClient = class {
8438
8450
  body: JSON.stringify({ policyCid: envelope.policyCid, recipientDid: this.options.holderDid, requestedCapabilities: envelope.policy.capabilityCeiling }),
8439
8451
  ...this.options.signal === void 0 ? {} : { signal: this.options.signal }
8440
8452
  });
8441
- if (!challengeResponse.ok) throw new Error(`v3 policy challenge rejected (${challengeResponse.status})`);
8453
+ if (!challengeResponse.ok) throw await recipientHttpError(challengeResponse, "v3 policy challenge rejected");
8442
8454
  const challenge = object3(await challengeResponse.json(), "v3 policy challenge");
8443
8455
  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");
8444
8456
  const material = await this.options.buildPresentation({
@@ -8463,14 +8475,14 @@ var ShareRecipientClient = class {
8463
8475
  const requestedExpiresAt = requestedSessionExpiry(envelope.expiry);
8464
8476
  let delegationResponse = await mint(requestedExpiresAt === void 0 ? mintBody : { ...mintBody, requestedExpiresAt });
8465
8477
  if (requestedExpiresAt !== void 0 && delegationResponse.status === 422) delegationResponse = await mint(mintBody);
8466
- if (!delegationResponse.ok) throw new Error(`v3 policy delegation rejected (${delegationResponse.status})`);
8478
+ if (!delegationResponse.ok) throw await recipientHttpError(delegationResponse, "v3 policy delegation rejected");
8467
8479
  const delegation = object3(await delegationResponse.json(), "v3 policy delegation");
8468
8480
  if (delegation.admitted !== true || typeof delegation.sessionCid !== "string" || typeof delegation.authorization !== "string") throw new Error("v3 policy delegation response is not admitted");
8469
8481
  const compact = verifyV3PolicyAuthorization({ authorization: delegation.authorization, cid: delegation.sessionCid, envelope, holderDid: this.options.holderDid });
8470
8482
  const fact = compact.payload.fct[0];
8471
8483
  this.options.onStage?.("delegation-import");
8472
8484
  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 } });
8473
- if (!imported.ok) throw new Error(`ordinary delegation import rejected (${imported.status})`);
8485
+ if (!imported.ok) throw await recipientHttpError(imported, "ordinary delegation import rejected");
8474
8486
  this.signer = material.sign;
8475
8487
  this.v3Authorization = delegation.authorization;
8476
8488
  this.v3NodeAudience = fact.nodeAudience;
@@ -8505,7 +8517,7 @@ var ShareRecipientClient = class {
8505
8517
  try {
8506
8518
  this.options.onStage?.("decryption");
8507
8519
  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 } });
8508
- if (!response.ok) throw new Error(`v3 decrypt invocation rejected (${response.status})`);
8520
+ if (!response.ok) throw await recipientHttpError(response, "v3 decrypt invocation rejected");
8509
8521
  const value = object3(await response.json(), "v3 decrypt response");
8510
8522
  const allowed = ["type", "targetNode", "networkId", "invocationCid", "encryptedSymmetricKeyHash", "receiverPublicKeyHash", "wrappedKey", "alg", "keyVersion", "requestHash", "nodeId", "nodeSignature"];
8511
8523
  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(sha2566(new TextEncoder().encode(`${invocation.cid}${bodyHash}`))) || typeof value.wrappedKey !== "string" || typeof value.nodeSignature !== "string") throw new Error("v3 decrypt response binding is invalid");