@haex-space/vault-sdk 2.5.106 → 2.5.108
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/{client-CbYg_Bl8.d.mts → client-CBCjziWo.d.mts} +1 -1
- package/dist/{client-0DvgO2Jf.d.ts → client-_FhZZse3.d.ts} +1 -1
- package/dist/index.d.mts +101 -7
- package/dist/index.d.ts +101 -7
- package/dist/index.js +195 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +179 -1
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js.map +1 -1
- package/dist/react.mjs.map +1 -1
- package/dist/runtime/nuxt.plugin.client.d.mts +2 -2
- package/dist/runtime/nuxt.plugin.client.d.ts +2 -2
- package/dist/runtime/nuxt.plugin.client.js.map +1 -1
- package/dist/runtime/nuxt.plugin.client.mjs.map +1 -1
- package/dist/svelte.d.mts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/{types-CORIMooS.d.mts → types-NWYbdRXr.d.mts} +44 -1
- package/dist/{types-CORIMooS.d.ts → types-NWYbdRXr.d.ts} +44 -1
- package/dist/vue.d.mts +2 -2
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2742,6 +2742,184 @@ async function verifyExtensionSignature(files, manifest) {
|
|
|
2742
2742
|
}
|
|
2743
2743
|
}
|
|
2744
2744
|
|
|
2745
|
+
// src/crypto/userKeypair.ts
|
|
2746
|
+
var SIGNING_ALGO = { name: "ECDSA", namedCurve: "P-256" };
|
|
2747
|
+
var KEY_AGREEMENT_ALGO = { name: "ECDH", namedCurve: "P-256" };
|
|
2748
|
+
async function generateUserKeypairAsync() {
|
|
2749
|
+
const keypair = await crypto.subtle.generateKey(SIGNING_ALGO, true, ["sign", "verify"]);
|
|
2750
|
+
return { publicKey: keypair.publicKey, privateKey: keypair.privateKey };
|
|
2751
|
+
}
|
|
2752
|
+
async function exportUserKeypairAsync(keypair) {
|
|
2753
|
+
const pub = await crypto.subtle.exportKey("spki", keypair.publicKey);
|
|
2754
|
+
const priv = await crypto.subtle.exportKey("pkcs8", keypair.privateKey);
|
|
2755
|
+
return { publicKey: arrayBufferToBase64(pub), privateKey: arrayBufferToBase64(priv) };
|
|
2756
|
+
}
|
|
2757
|
+
async function importUserPublicKeyAsync(base64) {
|
|
2758
|
+
return crypto.subtle.importKey("spki", base64ToArrayBuffer(base64), SIGNING_ALGO, true, ["verify"]);
|
|
2759
|
+
}
|
|
2760
|
+
async function importUserPrivateKeyAsync(base64) {
|
|
2761
|
+
return crypto.subtle.importKey("pkcs8", base64ToArrayBuffer(base64), SIGNING_ALGO, true, ["sign"]);
|
|
2762
|
+
}
|
|
2763
|
+
async function importPublicKeyForKeyAgreementAsync(base64) {
|
|
2764
|
+
return crypto.subtle.importKey("spki", base64ToArrayBuffer(base64), KEY_AGREEMENT_ALGO, true, []);
|
|
2765
|
+
}
|
|
2766
|
+
async function importPrivateKeyForKeyAgreementAsync(base64) {
|
|
2767
|
+
return crypto.subtle.importKey("pkcs8", base64ToArrayBuffer(base64), KEY_AGREEMENT_ALGO, true, ["deriveBits"]);
|
|
2768
|
+
}
|
|
2769
|
+
async function encryptPrivateKeyAsync(privateKeyBase64, password) {
|
|
2770
|
+
const salt = crypto.getRandomValues(new Uint8Array(32));
|
|
2771
|
+
const derivedKey = await deriveKeyFromPassword(password, salt);
|
|
2772
|
+
const nonce = crypto.getRandomValues(new Uint8Array(12));
|
|
2773
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
2774
|
+
{ name: "AES-GCM", iv: nonce },
|
|
2775
|
+
derivedKey,
|
|
2776
|
+
new TextEncoder().encode(privateKeyBase64)
|
|
2777
|
+
);
|
|
2778
|
+
return {
|
|
2779
|
+
encryptedPrivateKey: arrayBufferToBase64(encrypted),
|
|
2780
|
+
nonce: arrayBufferToBase64(nonce),
|
|
2781
|
+
salt: arrayBufferToBase64(salt)
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
async function decryptPrivateKeyAsync(encryptedPrivateKey, nonce, salt, password) {
|
|
2785
|
+
const derivedKey = await deriveKeyFromPassword(password, base64ToArrayBuffer(salt));
|
|
2786
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
2787
|
+
{ name: "AES-GCM", iv: base64ToArrayBuffer(nonce) },
|
|
2788
|
+
derivedKey,
|
|
2789
|
+
base64ToArrayBuffer(encryptedPrivateKey)
|
|
2790
|
+
);
|
|
2791
|
+
return new TextDecoder().decode(decrypted);
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
// src/crypto/spaceKey.ts
|
|
2795
|
+
function generateSpaceKey() {
|
|
2796
|
+
return generateVaultKey();
|
|
2797
|
+
}
|
|
2798
|
+
async function encryptSpaceKeyForRecipientAsync(spaceKey, recipientPublicKeyBase64) {
|
|
2799
|
+
const ephemeral = await crypto.subtle.generateKey(KEY_AGREEMENT_ALGO, true, ["deriveBits"]);
|
|
2800
|
+
const recipientKey = await importPublicKeyForKeyAgreementAsync(recipientPublicKeyBase64);
|
|
2801
|
+
const sharedBits = await crypto.subtle.deriveBits(
|
|
2802
|
+
{ name: "ECDH", public: recipientKey },
|
|
2803
|
+
ephemeral.privateKey,
|
|
2804
|
+
256
|
|
2805
|
+
);
|
|
2806
|
+
const aesKey = await crypto.subtle.deriveKey(
|
|
2807
|
+
{
|
|
2808
|
+
name: "HKDF",
|
|
2809
|
+
hash: "SHA-256",
|
|
2810
|
+
salt: new Uint8Array(0),
|
|
2811
|
+
info: new TextEncoder().encode("haex-space-key")
|
|
2812
|
+
},
|
|
2813
|
+
await crypto.subtle.importKey("raw", sharedBits, "HKDF", false, ["deriveKey"]),
|
|
2814
|
+
{ name: "AES-GCM", length: 256 },
|
|
2815
|
+
false,
|
|
2816
|
+
["encrypt"]
|
|
2817
|
+
);
|
|
2818
|
+
const nonce = crypto.getRandomValues(new Uint8Array(12));
|
|
2819
|
+
const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, aesKey, spaceKey);
|
|
2820
|
+
const ephPub = await crypto.subtle.exportKey("spki", ephemeral.publicKey);
|
|
2821
|
+
return {
|
|
2822
|
+
encryptedSpaceKey: arrayBufferToBase64(encrypted),
|
|
2823
|
+
keyNonce: arrayBufferToBase64(nonce),
|
|
2824
|
+
ephemeralPublicKey: arrayBufferToBase64(ephPub)
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
async function decryptSpaceKeyAsync(encrypted, ownPrivateKeyBase64) {
|
|
2828
|
+
const ephPubKey = await crypto.subtle.importKey(
|
|
2829
|
+
"spki",
|
|
2830
|
+
base64ToArrayBuffer(encrypted.ephemeralPublicKey),
|
|
2831
|
+
KEY_AGREEMENT_ALGO,
|
|
2832
|
+
true,
|
|
2833
|
+
[]
|
|
2834
|
+
);
|
|
2835
|
+
const ownPrivKey = await importPrivateKeyForKeyAgreementAsync(ownPrivateKeyBase64);
|
|
2836
|
+
const sharedBits = await crypto.subtle.deriveBits(
|
|
2837
|
+
{ name: "ECDH", public: ephPubKey },
|
|
2838
|
+
ownPrivKey,
|
|
2839
|
+
256
|
|
2840
|
+
);
|
|
2841
|
+
const aesKey = await crypto.subtle.deriveKey(
|
|
2842
|
+
{
|
|
2843
|
+
name: "HKDF",
|
|
2844
|
+
hash: "SHA-256",
|
|
2845
|
+
salt: new Uint8Array(0),
|
|
2846
|
+
info: new TextEncoder().encode("haex-space-key")
|
|
2847
|
+
},
|
|
2848
|
+
await crypto.subtle.importKey("raw", sharedBits, "HKDF", false, ["deriveKey"]),
|
|
2849
|
+
{ name: "AES-GCM", length: 256 },
|
|
2850
|
+
false,
|
|
2851
|
+
["decrypt"]
|
|
2852
|
+
);
|
|
2853
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
2854
|
+
{ name: "AES-GCM", iv: base64ToArrayBuffer(encrypted.keyNonce) },
|
|
2855
|
+
aesKey,
|
|
2856
|
+
base64ToArrayBuffer(encrypted.encryptedSpaceKey)
|
|
2857
|
+
);
|
|
2858
|
+
return new Uint8Array(decrypted);
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
// src/crypto/recordSigning.ts
|
|
2862
|
+
function canonicalize(record) {
|
|
2863
|
+
const parts = [
|
|
2864
|
+
record.tableName,
|
|
2865
|
+
record.rowPks,
|
|
2866
|
+
record.columnName === null ? "NULL" : record.columnName,
|
|
2867
|
+
record.encryptedValue === null ? "NULL" : record.encryptedValue,
|
|
2868
|
+
record.hlcTimestamp
|
|
2869
|
+
].join("\0");
|
|
2870
|
+
return new TextEncoder().encode(parts);
|
|
2871
|
+
}
|
|
2872
|
+
async function signRecordAsync(record, privateKeyBase64) {
|
|
2873
|
+
const key = await importUserPrivateKeyAsync(privateKeyBase64);
|
|
2874
|
+
const sig = await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, key, canonicalize(record));
|
|
2875
|
+
return arrayBufferToBase64(sig);
|
|
2876
|
+
}
|
|
2877
|
+
async function verifyRecordSignatureAsync(record, signatureBase64, publicKeyBase64) {
|
|
2878
|
+
const key = await importUserPublicKeyAsync(publicKeyBase64);
|
|
2879
|
+
return crypto.subtle.verify(
|
|
2880
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
2881
|
+
key,
|
|
2882
|
+
base64ToArrayBuffer(signatureBase64),
|
|
2883
|
+
canonicalize(record)
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
var CHALLENGE_MAX_AGE_MS = 3e4;
|
|
2887
|
+
function canonicalizeChallenge(spaceId, timestamp) {
|
|
2888
|
+
return new TextEncoder().encode(`${spaceId}\0${timestamp}`).buffer;
|
|
2889
|
+
}
|
|
2890
|
+
async function signSpaceChallengeAsync(spaceId, privateKeyBase64) {
|
|
2891
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2892
|
+
const key = await importUserPrivateKeyAsync(privateKeyBase64);
|
|
2893
|
+
const sig = await crypto.subtle.sign(
|
|
2894
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
2895
|
+
key,
|
|
2896
|
+
canonicalizeChallenge(spaceId, timestamp)
|
|
2897
|
+
);
|
|
2898
|
+
return { signature: arrayBufferToBase64(sig), timestamp };
|
|
2899
|
+
}
|
|
2900
|
+
async function verifySpaceChallengeAsync(spaceId, timestamp, signatureBase64, publicKeyBase64) {
|
|
2901
|
+
const tsMs = new Date(timestamp).getTime();
|
|
2902
|
+
if (Number.isNaN(tsMs)) {
|
|
2903
|
+
return { valid: false, error: "Invalid timestamp format" };
|
|
2904
|
+
}
|
|
2905
|
+
const age = Date.now() - tsMs;
|
|
2906
|
+
if (age < 0 || age > CHALLENGE_MAX_AGE_MS) {
|
|
2907
|
+
return { valid: false, error: "Challenge timestamp expired or in the future" };
|
|
2908
|
+
}
|
|
2909
|
+
try {
|
|
2910
|
+
const key = await importUserPublicKeyAsync(publicKeyBase64);
|
|
2911
|
+
const isValid = await crypto.subtle.verify(
|
|
2912
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
2913
|
+
key,
|
|
2914
|
+
base64ToArrayBuffer(signatureBase64),
|
|
2915
|
+
canonicalizeChallenge(spaceId, timestamp)
|
|
2916
|
+
);
|
|
2917
|
+
return isValid ? { valid: true } : { valid: false, error: "Invalid challenge signature" };
|
|
2918
|
+
} catch {
|
|
2919
|
+
return { valid: false, error: "Challenge verification failed" };
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2745
2923
|
// src/crypto/passkey.ts
|
|
2746
2924
|
function toArrayBuffer(data) {
|
|
2747
2925
|
if (data instanceof ArrayBuffer) {
|
|
@@ -2912,6 +3090,6 @@ function createHaexVaultSdk(config = {}) {
|
|
|
2912
3090
|
return new HaexVaultSdk(config);
|
|
2913
3091
|
}
|
|
2914
3092
|
|
|
2915
|
-
export { COSE_ALGORITHM, DEFAULT_TIMEOUT, DatabaseAPI, EXTERNAL_EVENTS, ErrorCode, ExternalConnectionErrorCode, ExternalConnectionState, FilesystemAPI, HAEXSPACE_MESSAGE_TYPES, HAEXTENSION_EVENTS, HaexVaultSdk, HaexVaultSdkError, LOCALSEND_EVENTS, LocalSendAPI, PermissionErrorCode, PermissionStatus, PermissionsAPI, RemoteStorageAPI, TABLE_SEPARATOR, TAURI_COMMANDS, WebAPI, arrayBufferToBase64, base64ToArrayBuffer, canExternalClientSendRequests, createHaexVaultSdk, decryptCrdtData, decryptString, decryptVaultKey, decryptVaultName, deriveKeyFromPassword, encryptCrdtData, encryptString, encryptVaultKey, exportKeyPairAsync, exportPrivateKeyAsync, exportPublicKeyAsync, exportPublicKeyCoseAsync, generateCredentialId, generatePasskeyPairAsync, generateVaultKey, getTableName, hexToBytes, importPrivateKeyAsync, importPublicKeyAsync, installBaseTag, installCookiePolyfill, installHistoryPolyfill, installLocalStoragePolyfill, installPolyfills, installSessionStoragePolyfill, isExternalClientConnected, isPermissionDeniedError, isPermissionError, isPermissionPromptError, signWithPasskeyAsync, sortObjectKeysRecursively, unwrapKey, verifyExtensionSignature, verifyWithPasskeyAsync, wrapKey };
|
|
3093
|
+
export { COSE_ALGORITHM, DEFAULT_TIMEOUT, DatabaseAPI, EXTERNAL_EVENTS, ErrorCode, ExternalConnectionErrorCode, ExternalConnectionState, FilesystemAPI, HAEXSPACE_MESSAGE_TYPES, HAEXTENSION_EVENTS, HaexVaultSdk, HaexVaultSdkError, KEY_AGREEMENT_ALGO, LOCALSEND_EVENTS, LocalSendAPI, PermissionErrorCode, PermissionStatus, PermissionsAPI, RemoteStorageAPI, SIGNING_ALGO, TABLE_SEPARATOR, TAURI_COMMANDS, WebAPI, arrayBufferToBase64, base64ToArrayBuffer, canExternalClientSendRequests, createHaexVaultSdk, decryptCrdtData, decryptPrivateKeyAsync, decryptSpaceKeyAsync, decryptString, decryptVaultKey, decryptVaultName, deriveKeyFromPassword, encryptCrdtData, encryptPrivateKeyAsync, encryptSpaceKeyForRecipientAsync, encryptString, encryptVaultKey, exportKeyPairAsync, exportPrivateKeyAsync, exportPublicKeyAsync, exportPublicKeyCoseAsync, exportUserKeypairAsync, generateCredentialId, generatePasskeyPairAsync, generateSpaceKey, generateUserKeypairAsync, generateVaultKey, getTableName, hexToBytes, importPrivateKeyAsync, importPrivateKeyForKeyAgreementAsync, importPublicKeyAsync, importPublicKeyForKeyAgreementAsync, importUserPrivateKeyAsync, importUserPublicKeyAsync, installBaseTag, installCookiePolyfill, installHistoryPolyfill, installLocalStoragePolyfill, installPolyfills, installSessionStoragePolyfill, isExternalClientConnected, isPermissionDeniedError, isPermissionError, isPermissionPromptError, signRecordAsync, signSpaceChallengeAsync, signWithPasskeyAsync, sortObjectKeysRecursively, unwrapKey, verifyExtensionSignature, verifyRecordSignatureAsync, verifySpaceChallengeAsync, verifyWithPasskeyAsync, wrapKey };
|
|
2916
3094
|
//# sourceMappingURL=index.mjs.map
|
|
2917
3095
|
//# sourceMappingURL=index.mjs.map
|