@tinycloud/cli 0.9.1-beta.1 → 0.9.1-beta.3
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 +149 -45
- package/dist/index.js.map +1 -1
- package/dist/legacy-entry.js +24 -18
- package/dist/legacy-entry.js.map +1 -1
- package/package.json +5 -5
package/dist/legacy-entry.js
CHANGED
|
@@ -17687,7 +17687,7 @@ function validateV3Invariants(value, ctx) {
|
|
|
17687
17687
|
if (value.contentSource.encryptionNetwork !== value.encryptionNetwork) {
|
|
17688
17688
|
ctx.addIssue({ code: external_exports2.ZodIssueCode.custom, path: ["encryptionNetwork"], message: "encryption network is not bound to the source" });
|
|
17689
17689
|
}
|
|
17690
|
-
if (value.attestedEnforcerBinding.enforcerDid !== value.target.nodeAudience || value.attestedEnforcerBinding.
|
|
17690
|
+
if (value.attestedEnforcerBinding.enforcerDid !== value.target.nodeAudience || value.attestedEnforcerBinding.signature.signerDid !== value.attestedEnforcerBinding.nodeAudience || Date.parse(value.attestedEnforcerBinding.expiresAt) < Date.parse(value.expiry)) {
|
|
17691
17691
|
ctx.addIssue({ code: external_exports2.ZodIssueCode.custom, path: ["attestedEnforcerBinding"], message: "enforcer binding does not cover the target and share lifetime" });
|
|
17692
17692
|
}
|
|
17693
17693
|
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) {
|
|
@@ -18036,9 +18036,9 @@ function verifyCompactUcanAuthorization(authorization, expectedCid) {
|
|
|
18036
18036
|
const segments = authorization.split(".");
|
|
18037
18037
|
if (segments.length !== 3 || segments.some((segment) => segment.length === 0)) throw new TypeError("compact Authorization must contain three segments");
|
|
18038
18038
|
const [headerSegment, payloadSegment, signatureSegment] = segments;
|
|
18039
|
-
const headerBytes =
|
|
18040
|
-
const payloadBytes =
|
|
18041
|
-
const signature =
|
|
18039
|
+
const headerBytes = fromBase64Url(headerSegment);
|
|
18040
|
+
const payloadBytes = fromBase64Url(payloadSegment);
|
|
18041
|
+
const signature = fromBase64Url(signatureSegment);
|
|
18042
18042
|
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
18043
18043
|
const header = JSON.parse(decoder.decode(headerBytes));
|
|
18044
18044
|
const payload = JSON.parse(decoder.decode(payloadBytes));
|
|
@@ -18051,7 +18051,7 @@ function verifyCompactUcanAuthorization(authorization, expectedCid) {
|
|
|
18051
18051
|
if (typeof payload.iss !== "string" || typeof payload.aud !== "string" || typeof payload.nnc !== "string" || !Number.isInteger(payload.nbf) || !Number.isInteger(payload.exp) || payload.nbf >= payload.exp || !Array.isArray(payload.prf) || payload.prf.some((proof) => typeof proof !== "string") || !Array.isArray(payload.fct) || payload.fct.length !== 1) throw new TypeError("compact Authorization payload is invalid");
|
|
18052
18052
|
const principal = payload.iss.split("#", 1)[0];
|
|
18053
18053
|
const publicKey = ed25519PublicKeyFromDidKey(principal);
|
|
18054
|
-
if (!equal(publicKey,
|
|
18054
|
+
if (!equal(publicKey, fromBase64Url(jwk.x))) throw new TypeError("compact Authorization JWK does not bind issuer");
|
|
18055
18055
|
if (!ed25519.verify(signature, new TextEncoder().encode(`${headerSegment}.${payloadSegment}`), publicKey, { zip215: false })) throw new TypeError("compact Authorization signature is invalid");
|
|
18056
18056
|
const cid2 = CID.createV1(85, create(30, blake3(new TextEncoder().encode(authorization)))).toString();
|
|
18057
18057
|
if (expectedCid !== void 0 && cid2 !== expectedCid) throw new TypeError("compact Authorization CID mismatch");
|
|
@@ -18064,13 +18064,6 @@ function object(value, label) {
|
|
|
18064
18064
|
function assertExactKeys(value, keys, label) {
|
|
18065
18065
|
if (Object.keys(value).length !== keys.length || Object.keys(value).some((key) => !keys.includes(key))) throw new TypeError(`${label} has unknown or missing fields`);
|
|
18066
18066
|
}
|
|
18067
|
-
function decodeBase64Url(value) {
|
|
18068
|
-
if (!/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1) throw new TypeError("compact Authorization segment is not base64url");
|
|
18069
|
-
const bytes3 = typeof Buffer !== "undefined" ? new Uint8Array(Buffer.from(value, "base64url")) : Uint8Array.from(atob(value.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(value.length / 4) * 4, "=")), (character) => character.charCodeAt(0));
|
|
18070
|
-
const encoded = typeof Buffer !== "undefined" ? Buffer.from(bytes3).toString("base64url") : btoa(String.fromCharCode(...bytes3)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
18071
|
-
if (encoded !== value) throw new TypeError("compact Authorization segment is not canonical");
|
|
18072
|
-
return bytes3;
|
|
18073
|
-
}
|
|
18074
18067
|
function equal(left, right) {
|
|
18075
18068
|
return left.length === right.length && left.every((byte, index) => byte === right[index]);
|
|
18076
18069
|
}
|
|
@@ -18190,10 +18183,10 @@ async function verifyEnvelopeV3(envelope, options) {
|
|
|
18190
18183
|
const binding = parsed.attestedEnforcerBinding;
|
|
18191
18184
|
const { signature: bindingSignature, ...unsignedBinding } = binding;
|
|
18192
18185
|
const expectedBindingDigestHex = hex(sha2562(new TextEncoder().encode(canonicalize2({ enforcerDid: binding.enforcerDid, nodeAudience: binding.nodeAudience }))));
|
|
18193
|
-
if (binding.enforcerDid !== parsed.target.nodeAudience || binding.
|
|
18186
|
+
if (binding.enforcerDid !== parsed.target.nodeAudience || binding.attestationBindingDigestHex !== expectedBindingDigestHex || bindingSignature.signerDid !== binding.nodeAudience || bindingSignature.suite !== "Ed25519" || Date.parse(binding.issuedAt) > Date.now() || Date.parse(binding.expiresAt) <= Date.now() || Date.parse(binding.expiresAt) < Date.parse(parsed.expiry)) return false;
|
|
18194
18187
|
try {
|
|
18195
18188
|
const digest4 = sha2562(new TextEncoder().encode(`${ATTESTED_ENFORCER_V2_DOMAIN}${canonicalize2(unsignedBinding)}`));
|
|
18196
|
-
if (!ed25519.verify(fromBase64Url(bindingSignature.value), digest4, ed25519PublicKeyFromDidKey(binding.
|
|
18189
|
+
if (!ed25519.verify(fromBase64Url(bindingSignature.value), digest4, ed25519PublicKeyFromDidKey(binding.nodeAudience), ED25519_VERIFY_OPTS2)) return false;
|
|
18197
18190
|
} catch {
|
|
18198
18191
|
return false;
|
|
18199
18192
|
}
|
|
@@ -18206,7 +18199,7 @@ async function verifyEnvelopeV3(envelope, options) {
|
|
|
18206
18199
|
const common = ["ownerDid", "policyId", "policyDigestHex", "policyCid", "contentSourceDigestHex", "capabilityCeilingHashHex", "nativeProjectionHashHex", "nodeAudience"];
|
|
18207
18200
|
const policyKeys = [...common, "role", "mode"];
|
|
18208
18201
|
const enforcementKeys = [...policyKeys, "enforcerDid"];
|
|
18209
|
-
if (Object.keys(policyFact).length !== policyKeys.length || policyKeys.some((key) => !(key in policyFact)) || Object.keys(enforcementFact).length !== enforcementKeys.length || enforcementKeys.some((key) => !(key in enforcementFact)) || policyRoot.payload.prf.length !== 0 || enforcementRoot.payload.prf.length !== 0 || policyRoot.payload.iss.split("#", 1)[0] !== policy.ownerDid || enforcementRoot.payload.iss.split("#", 1)[0] !== policy.ownerDid || policyRoot.payload.nbf !== enforcementRoot.payload.nbf || policyRoot.payload.exp !== enforcementRoot.payload.exp || canonicalize2(policyRoot.payload.att) !== canonicalize2(expectedAttenuation) || canonicalize2(enforcementRoot.payload.att) !== canonicalize2(expectedAttenuation) || policyFact.role !== "policy-authority" || policyFact.mode !== "policy-source" || "enforcerDid" in policyFact || enforcementFact.role !== "policy-enforcement" || enforcementFact.mode !== "conditional-mint" || policyRoot.payload.aud !== `did:tinycloud:policy:${hex(policyIdDigest)}` || enforcementRoot.payload.aud !==
|
|
18202
|
+
if (Object.keys(policyFact).length !== policyKeys.length || policyKeys.some((key) => !(key in policyFact)) || Object.keys(enforcementFact).length !== enforcementKeys.length || enforcementKeys.some((key) => !(key in enforcementFact)) || policyRoot.payload.prf.length !== 0 || enforcementRoot.payload.prf.length !== 0 || policyRoot.payload.iss.split("#", 1)[0] !== policy.ownerDid || enforcementRoot.payload.iss.split("#", 1)[0] !== policy.ownerDid || policyRoot.payload.nbf !== enforcementRoot.payload.nbf || policyRoot.payload.exp !== enforcementRoot.payload.exp || canonicalize2(policyRoot.payload.att) !== canonicalize2(expectedAttenuation) || canonicalize2(enforcementRoot.payload.att) !== canonicalize2(expectedAttenuation) || policyFact.role !== "policy-authority" || policyFact.mode !== "policy-source" || "enforcerDid" in policyFact || enforcementFact.role !== "policy-enforcement" || enforcementFact.mode !== "conditional-mint" || policyRoot.payload.aud !== `did:tinycloud:policy:${hex(policyIdDigest)}` || enforcementRoot.payload.aud !== binding.enforcerDid || enforcementFact.enforcerDid !== binding.enforcerDid || common.some((key) => policyFact[key] !== enforcementFact[key]) || policyFact.ownerDid !== policy.ownerDid || policyFact.policyId !== policy.policyId || policyFact.policyDigestHex !== hex(policyIdDigest) || policyFact.policyCid !== parsed.policyCid || policyFact.contentSourceDigestHex !== parsed.contentSourceDigestHex || policyFact.capabilityCeilingHashHex !== capabilityCeilingHashHex || policyFact.nativeProjectionHashHex !== nativeProjectionHashHex || policyFact.nodeAudience !== binding.nodeAudience || policyRoot.payload.exp * 1e3 < Date.parse(parsed.expiry)) return false;
|
|
18210
18203
|
} catch {
|
|
18211
18204
|
return false;
|
|
18212
18205
|
}
|
|
@@ -18388,8 +18381,12 @@ async function readResponseBytes(response, limit, tooLargeCode) {
|
|
|
18388
18381
|
function registryFetcher(options, limit, tooLargeCode = "max-bytes-exceeded", stage = "envelope") {
|
|
18389
18382
|
if (options.fetchBlob !== void 0) return async (input) => {
|
|
18390
18383
|
try {
|
|
18391
|
-
|
|
18384
|
+
options.signal?.throwIfAborted();
|
|
18385
|
+
const bytes3 = await options.fetchBlob({ ...input, ...options.signal === void 0 ? {} : { signal: options.signal } });
|
|
18386
|
+
options.signal?.throwIfAborted();
|
|
18387
|
+
return boundedBytes(bytes3, limit, tooLargeCode);
|
|
18392
18388
|
} catch (error) {
|
|
18389
|
+
if (options.signal?.aborted) throw options.signal.reason ?? error;
|
|
18393
18390
|
if (error instanceof ShareReceiveError) throw error;
|
|
18394
18391
|
throw new ShareReceiveError("fetch-failed", "registry unavailable", { stage });
|
|
18395
18392
|
}
|
|
@@ -18399,10 +18396,19 @@ function registryFetcher(options, limit, tooLargeCode = "max-bytes-exceeded", st
|
|
|
18399
18396
|
const base33 = options.registryBaseUrl.replace(/\/+$/, "");
|
|
18400
18397
|
return async ({ cid: cid2 }) => {
|
|
18401
18398
|
try {
|
|
18402
|
-
|
|
18399
|
+
options.signal?.throwIfAborted();
|
|
18400
|
+
const response = await fetchFn(`${base33}/ipfs/${cid2}?format=raw`, {
|
|
18401
|
+
headers: { accept: "application/vnd.ipld.raw" },
|
|
18402
|
+
redirect: "error",
|
|
18403
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
18404
|
+
});
|
|
18405
|
+
options.signal?.throwIfAborted();
|
|
18403
18406
|
if (!response.ok) throw new ShareReceiveError("fetch-failed", `registry returned ${response.status}`, { stage });
|
|
18404
|
-
|
|
18407
|
+
const bytes3 = await readResponseBytes(response, limit, tooLargeCode);
|
|
18408
|
+
options.signal?.throwIfAborted();
|
|
18409
|
+
return bytes3;
|
|
18405
18410
|
} catch (error) {
|
|
18411
|
+
if (options.signal?.aborted) throw options.signal.reason ?? error;
|
|
18406
18412
|
if (error instanceof ShareReceiveError) throw error;
|
|
18407
18413
|
throw new ShareReceiveError("fetch-failed", "registry unavailable", { stage });
|
|
18408
18414
|
}
|