@tinycloud/share-sdk 1.4.1-beta.1 → 1.4.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.cjs +21 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +21 -38
- package/dist/index.js.map +1 -1
- package/dist/{web-recipient-entry-Cy1fXl_5.d.cts → web-recipient-entry-Bn3yRB7g.d.cts} +1 -1
- package/dist/{web-recipient-entry-CPntAP0H.d.ts → web-recipient-entry-CTFoIH8l.d.ts} +1 -1
- package/dist/web-recipient.cjs +21 -38
- package/dist/web-recipient.cjs.map +1 -1
- package/dist/web-recipient.d.cts +1 -1
- package/dist/web-recipient.d.ts +1 -1
- package/dist/web-recipient.js +21 -38
- package/dist/web-recipient.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -8812,41 +8812,18 @@ function bytes2(value, label) {
|
|
|
8812
8812
|
if (decoded.length !== 64 || toBase64Url(decoded) !== value) throw new Error(`${label} is invalid`);
|
|
8813
8813
|
return decoded;
|
|
8814
8814
|
}
|
|
8815
|
-
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8816
8815
|
function toBase64(bytes3) {
|
|
8817
|
-
|
|
8818
|
-
for (let i = 0; i < bytes3.length; i += 3) {
|
|
8819
|
-
const b0 = bytes3[i];
|
|
8820
|
-
const b1 = i + 1 < bytes3.length ? bytes3[i + 1] : 0;
|
|
8821
|
-
const b2 = i + 2 < bytes3.length ? bytes3[i + 2] : 0;
|
|
8822
|
-
out += BASE64_ALPHABET[b0 >> 2 & 63];
|
|
8823
|
-
out += BASE64_ALPHABET[(b0 << 4 | b1 >> 4) & 63];
|
|
8824
|
-
out += i + 1 < bytes3.length ? BASE64_ALPHABET[(b1 << 2 | b2 >> 6) & 63] : "=";
|
|
8825
|
-
out += i + 2 < bytes3.length ? BASE64_ALPHABET[b2 & 63] : "=";
|
|
8826
|
-
}
|
|
8827
|
-
return out;
|
|
8816
|
+
return toBase64Url(bytes3).replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(bytes3.length / 3) * 4, "=");
|
|
8828
8817
|
}
|
|
8829
8818
|
function fromBase64(value, label) {
|
|
8830
8819
|
if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) {
|
|
8831
8820
|
throw new Error(`${label} is invalid`);
|
|
8832
8821
|
}
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
const v1 = BASE64_ALPHABET.indexOf(value[i + 1]);
|
|
8839
|
-
const v2 = value[i + 2] === "=" ? 0 : BASE64_ALPHABET.indexOf(value[i + 2]);
|
|
8840
|
-
const v3 = value[i + 3] === "=" ? 0 : BASE64_ALPHABET.indexOf(value[i + 3]);
|
|
8841
|
-
const b0 = v0 << 2 | v1 >> 4;
|
|
8842
|
-
const b1 = (v1 & 15) << 4 | v2 >> 2;
|
|
8843
|
-
const b2 = (v2 & 3) << 6 | v3;
|
|
8844
|
-
if (outIdx < out.length) out[outIdx++] = b0;
|
|
8845
|
-
if (outIdx < out.length) out[outIdx++] = b1;
|
|
8846
|
-
if (outIdx < out.length) out[outIdx++] = b2;
|
|
8847
|
-
}
|
|
8848
|
-
if (toBase64(out) !== value) throw new Error(`${label} is invalid`);
|
|
8849
|
-
return out;
|
|
8822
|
+
try {
|
|
8823
|
+
return fromBase64Url(value.replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_"));
|
|
8824
|
+
} catch {
|
|
8825
|
+
throw new Error(`${label} is invalid`);
|
|
8826
|
+
}
|
|
8850
8827
|
}
|
|
8851
8828
|
async function digestBytes2(value) {
|
|
8852
8829
|
return toBase64Url(new Uint8Array(await crypto.subtle.digest("SHA-256", value)));
|
|
@@ -8963,16 +8940,16 @@ function matchesInitialCiphertextDigest(bytes3, expected) {
|
|
|
8963
8940
|
function canonicalHashHex(value) {
|
|
8964
8941
|
return hex3((0, import_sha2565.sha256)(new TextEncoder().encode(canonicalize(value))));
|
|
8965
8942
|
}
|
|
8966
|
-
async function aesGcmDecrypt(key, blob) {
|
|
8943
|
+
async function aesGcmDecrypt(key, blob, aad) {
|
|
8967
8944
|
if (key.length !== 32 || blob.length < 28) throw new Error("encrypted content is malformed");
|
|
8968
8945
|
const cryptoKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["decrypt"]);
|
|
8969
|
-
return new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv: blob.slice(0, 12) }, cryptoKey, blob.slice(12)));
|
|
8946
|
+
return new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv: blob.slice(0, 12), ...aad && { additionalData: aad } }, cryptoKey, blob.slice(12)));
|
|
8970
8947
|
}
|
|
8971
|
-
async function aesGcmEncrypt(key, plaintext) {
|
|
8948
|
+
async function aesGcmEncrypt(key, plaintext, aad) {
|
|
8972
8949
|
if (key.length !== 32) throw new Error("encrypted content key is malformed");
|
|
8973
8950
|
const nonce = crypto.getRandomValues(new Uint8Array(12));
|
|
8974
8951
|
const cryptoKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt"]);
|
|
8975
|
-
const ciphertext = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, cryptoKey, plaintext));
|
|
8952
|
+
const ciphertext = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce, ...aad && { additionalData: aad } }, cryptoKey, plaintext));
|
|
8976
8953
|
const output = new Uint8Array(nonce.length + ciphertext.length);
|
|
8977
8954
|
output.set(nonce);
|
|
8978
8955
|
output.set(ciphertext, nonce.length);
|
|
@@ -8987,8 +8964,9 @@ function parseV3InlineEncryptedEnvelope(bytes3, expected) {
|
|
|
8987
8964
|
}
|
|
8988
8965
|
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("encrypted content envelope is malformed");
|
|
8989
8966
|
const record = value;
|
|
8990
|
-
const allowed = ["v", "networkId", "keyPath", "alg", "keyVersion", "encryptedSymmetricKey", "encryptedSymmetricKeyHash", "ciphertext", "metadata"];
|
|
8991
|
-
|
|
8967
|
+
const allowed = ["v", "networkId", "keyPath", "alg", "keyVersion", "encryptedSymmetricKey", "encryptedSymmetricKeyHash", "ciphertext", "aad", "metadata"];
|
|
8968
|
+
const source = expected.contentSource;
|
|
8969
|
+
if (Object.keys(record).some((key) => !allowed.includes(key)) || record.v !== (source.encryptionKeyPath === void 0 ? 1 : 2) || record.networkId !== source.encryptionNetwork || record.networkId !== expected.encryptionNetwork || record.keyPath !== source.encryptionKeyPath || record.keyPath !== void 0 && record.keyPath !== `share/${expected.shareId}` || record.alg !== "x25519-aes256gcm/v1" || record.keyVersion !== source.keyVersion || typeof record.encryptedSymmetricKey !== "string" || typeof record.encryptedSymmetricKeyHash !== "string" || hex3((0, import_sha2565.sha256)(fromBase64(record.encryptedSymmetricKey, "v3 encrypted symmetric key"))) !== source.encryptedSymmetricKeyDigestHex || record.encryptedSymmetricKeyHash !== canonicalHashHex(record.encryptedSymmetricKey) || typeof record.ciphertext !== "string" || record.aad !== void 0 && typeof record.aad !== "string" || record.metadata !== void 0 && (record.metadata === null || typeof record.metadata !== "object" || Array.isArray(record.metadata) || Object.values(record.metadata).some((entry) => typeof entry !== "string"))) {
|
|
8992
8970
|
throw new Error("encrypted content envelope binding is invalid");
|
|
8993
8971
|
}
|
|
8994
8972
|
return record;
|
|
@@ -9109,7 +9087,7 @@ var ShareRecipientClient = class {
|
|
|
9109
9087
|
this.session = { sessionId: delegation.sessionCid, expiresAt: new Date(compact.payload.exp * 1e3).toISOString(), actions: envelope.actions, resource: envelope.resource };
|
|
9110
9088
|
return this.session;
|
|
9111
9089
|
}
|
|
9112
|
-
/** Decrypt
|
|
9090
|
+
/** Decrypt unscoped v1 or path-bound v2 content, independently checking canonical and registered raw-key digests. */
|
|
9113
9091
|
async decryptV3Content(bytes3) {
|
|
9114
9092
|
const envelope = this.options.envelope;
|
|
9115
9093
|
const signer = this.nativeSigner ?? this.signer;
|
|
@@ -9117,6 +9095,9 @@ var ShareRecipientClient = class {
|
|
|
9117
9095
|
assertArtifactBinding(artifactBindingView(envelope));
|
|
9118
9096
|
if (!matchesInitialCiphertextDigest(bytes3, envelope.contentSource.initialCiphertextDigestHex)) throw new Error("v3 owner KV ciphertext digest mismatch");
|
|
9119
9097
|
const encrypted = parseV3InlineEncryptedEnvelope(bytes3, envelope);
|
|
9098
|
+
const ciphertext = fromBase64(encrypted.ciphertext, "v3 encrypted content");
|
|
9099
|
+
if (ciphertext.length < 28) throw new Error("encrypted content is malformed");
|
|
9100
|
+
const aad = encrypted.aad === void 0 ? void 0 : fromBase64(encrypted.aad, "v3 encrypted content AAD");
|
|
9120
9101
|
const receiverPrivateKey = crypto.getRandomValues(new Uint8Array(32));
|
|
9121
9102
|
const receiverPublicKey = toBase64(import_ed255195.x25519.getPublicKey(receiverPrivateKey));
|
|
9122
9103
|
const receiverPublicKeyHash = canonicalHashHex(receiverPublicKey);
|
|
@@ -9153,7 +9134,7 @@ var ShareRecipientClient = class {
|
|
|
9153
9134
|
const symmetricKey = await aesGcmDecrypt(shared, wrapped.slice(33));
|
|
9154
9135
|
shared.fill(0);
|
|
9155
9136
|
if (symmetricKey.length !== 32) throw new Error("v3 content key is malformed");
|
|
9156
|
-
const plaintext = await aesGcmDecrypt(symmetricKey,
|
|
9137
|
+
const plaintext = await aesGcmDecrypt(symmetricKey, ciphertext, aad);
|
|
9157
9138
|
this.v3ContentKey?.fill(0);
|
|
9158
9139
|
this.v3ContentKey = symmetricKey;
|
|
9159
9140
|
this.v3ContentEnvelope = encrypted;
|
|
@@ -9165,7 +9146,9 @@ var ShareRecipientClient = class {
|
|
|
9165
9146
|
/** Re-encrypt edited v3 content with the admitted content key. */
|
|
9166
9147
|
async encryptV3Content(bytes3, mediaType) {
|
|
9167
9148
|
if (this.options.envelope.version !== 3 || this.v3ContentKey === void 0 || this.v3ContentEnvelope === void 0) throw new Error("v3 content must be decrypted before it can be saved");
|
|
9168
|
-
|
|
9149
|
+
const envelope = this.v3ContentEnvelope;
|
|
9150
|
+
const aad = envelope.aad === void 0 ? void 0 : fromBase64(envelope.aad, "v3 encrypted content AAD");
|
|
9151
|
+
return new TextEncoder().encode(canonicalize({ ...envelope, ciphertext: toBase64(await aesGcmEncrypt(this.v3ContentKey, bytes3, aad)), metadata: { ...envelope.metadata ?? {}, contentType: mediaType } }));
|
|
9169
9152
|
}
|
|
9170
9153
|
async resumeWithProof(envelope, resumeToken, proof) {
|
|
9171
9154
|
void envelope;
|