@functionland/fula-client 0.2.24 → 0.2.25
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/fula_js.d.ts +65 -5
- package/fula_js.js +167 -13
- package/fula_js_bg.wasm +0 -0
- package/package.json +1 -1
package/fula_js.d.ts
CHANGED
|
@@ -189,6 +189,61 @@ export function putEncrypted(client: EncryptedClient, bucket: string, key: strin
|
|
|
189
189
|
*/
|
|
190
190
|
export function putEncryptedWithType(client: EncryptedClient, bucket: string, key: string, data: Uint8Array, content_type: string): Promise<any>;
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* AES-256-GCM decrypt data with a DEK
|
|
194
|
+
*
|
|
195
|
+
* @param dekBytes - 32-byte DEK
|
|
196
|
+
* @param nonceBase64 - Base64 encoded 12-byte nonce
|
|
197
|
+
* @param ciphertextBase64 - Base64 encoded ciphertext
|
|
198
|
+
* @returns Decrypted plaintext
|
|
199
|
+
*/
|
|
200
|
+
export function testAesGcmDecrypt(dek_bytes: Uint8Array, nonce_base64: string, ciphertext_base64: string): Uint8Array;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* AES-256-GCM encrypt data with a DEK
|
|
204
|
+
*
|
|
205
|
+
* @param dekBytes - 32-byte DEK
|
|
206
|
+
* @param plaintext - Data to encrypt
|
|
207
|
+
* @returns JSON string with {nonce, ciphertext} (both base64 encoded)
|
|
208
|
+
*/
|
|
209
|
+
export function testAesGcmEncrypt(dek_bytes: Uint8Array, plaintext: Uint8Array): string;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Full encryption round-trip test
|
|
213
|
+
*
|
|
214
|
+
* This tests the EXACT flow: derive key -> encrypt DEK with HPKE -> encrypt data with AES-GCM
|
|
215
|
+
* then decrypt in reverse order. If this works, the WASM crypto is correct.
|
|
216
|
+
*
|
|
217
|
+
* @param context - Key derivation context (e.g., "fula-files-v1")
|
|
218
|
+
* @param input - Key derivation input (e.g., credentials)
|
|
219
|
+
* @param plaintext - Data to encrypt and decrypt
|
|
220
|
+
* @returns Original plaintext if successful (proves round-trip works)
|
|
221
|
+
*/
|
|
222
|
+
export function testFullEncryptionRoundtrip(context: string, input: Uint8Array, plaintext: Uint8Array): Uint8Array;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Decrypt a wrapped DEK using HPKE with the given secret key
|
|
226
|
+
*
|
|
227
|
+
* This simulates what WebUI WASM should do when decrypting a file.
|
|
228
|
+
*
|
|
229
|
+
* @param secretKeyBytes - 32-byte X25519 secret key
|
|
230
|
+
* @param wrappedDekJson - JSON string from testHpkeEncryptDek
|
|
231
|
+
* @returns 32-byte decrypted DEK
|
|
232
|
+
*/
|
|
233
|
+
export function testHpkeDecryptDek(secret_key_bytes: Uint8Array, wrapped_dek_json: string): Uint8Array;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Encrypt a DEK using HPKE with the given public key
|
|
237
|
+
*
|
|
238
|
+
* This simulates what FxFiles does when encrypting a file.
|
|
239
|
+
* Returns JSON string containing the EncryptedData (wrapped DEK).
|
|
240
|
+
*
|
|
241
|
+
* @param publicKeyBytes - 32-byte X25519 public key
|
|
242
|
+
* @param dekBytes - 32-byte DEK to encrypt
|
|
243
|
+
* @returns JSON string with {version, encapsulated_key, ciphertext}
|
|
244
|
+
*/
|
|
245
|
+
export function testHpkeEncryptDek(public_key_bytes: Uint8Array, dek_bytes: Uint8Array): string;
|
|
246
|
+
|
|
192
247
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
193
248
|
|
|
194
249
|
export interface InitOutput {
|
|
@@ -217,12 +272,17 @@ export interface InitOutput {
|
|
|
217
272
|
readonly listDirectory: (a: number, b: number, c: number, d: number, e: number) => any;
|
|
218
273
|
readonly putEncrypted: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => any;
|
|
219
274
|
readonly putEncryptedWithType: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => any;
|
|
275
|
+
readonly testAesGcmDecrypt: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
|
|
276
|
+
readonly testAesGcmEncrypt: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
277
|
+
readonly testFullEncryptionRoundtrip: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number, number];
|
|
278
|
+
readonly testHpkeDecryptDek: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
279
|
+
readonly testHpkeEncryptDek: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
|
220
280
|
readonly init: () => void;
|
|
221
|
-
readonly
|
|
222
|
-
readonly
|
|
223
|
-
readonly
|
|
224
|
-
readonly
|
|
225
|
-
readonly
|
|
281
|
+
readonly wasm_bindgen__convert__closures_____invoke__hb49647253b2911c5: (a: number, b: number) => void;
|
|
282
|
+
readonly wasm_bindgen__closure__destroy__hde34fe38f5ae6975: (a: number, b: number) => void;
|
|
283
|
+
readonly wasm_bindgen__convert__closures_____invoke__h7e10992c477d6050: (a: number, b: number, c: any) => void;
|
|
284
|
+
readonly wasm_bindgen__closure__destroy__h40a33609ceb56b6e: (a: number, b: number) => void;
|
|
285
|
+
readonly wasm_bindgen__convert__closures_____invoke__h4b8cebda0a70f497: (a: number, b: number, c: any, d: any) => void;
|
|
226
286
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
227
287
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
228
288
|
readonly __wbindgen_exn_store: (a: number) => void;
|
package/fula_js.js
CHANGED
|
@@ -227,16 +227,16 @@ if (!('encodeInto' in cachedTextEncoder)) {
|
|
|
227
227
|
|
|
228
228
|
let WASM_VECTOR_LEN = 0;
|
|
229
229
|
|
|
230
|
-
function
|
|
231
|
-
wasm.
|
|
230
|
+
function wasm_bindgen__convert__closures_____invoke__hb49647253b2911c5(arg0, arg1) {
|
|
231
|
+
wasm.wasm_bindgen__convert__closures_____invoke__hb49647253b2911c5(arg0, arg1);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
function
|
|
235
|
-
wasm.
|
|
234
|
+
function wasm_bindgen__convert__closures_____invoke__h7e10992c477d6050(arg0, arg1, arg2) {
|
|
235
|
+
wasm.wasm_bindgen__convert__closures_____invoke__h7e10992c477d6050(arg0, arg1, arg2);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
function
|
|
239
|
-
wasm.
|
|
238
|
+
function wasm_bindgen__convert__closures_____invoke__h4b8cebda0a70f497(arg0, arg1, arg2, arg3) {
|
|
239
|
+
wasm.wasm_bindgen__convert__closures_____invoke__h4b8cebda0a70f497(arg0, arg1, arg2, arg3);
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
const __wbindgen_enum_RequestCache = ["default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached"];
|
|
@@ -707,6 +707,160 @@ export function putEncryptedWithType(client, bucket, key, data, content_type) {
|
|
|
707
707
|
return ret;
|
|
708
708
|
}
|
|
709
709
|
|
|
710
|
+
/**
|
|
711
|
+
* AES-256-GCM decrypt data with a DEK
|
|
712
|
+
*
|
|
713
|
+
* @param dekBytes - 32-byte DEK
|
|
714
|
+
* @param nonceBase64 - Base64 encoded 12-byte nonce
|
|
715
|
+
* @param ciphertextBase64 - Base64 encoded ciphertext
|
|
716
|
+
* @returns Decrypted plaintext
|
|
717
|
+
* @param {Uint8Array} dek_bytes
|
|
718
|
+
* @param {string} nonce_base64
|
|
719
|
+
* @param {string} ciphertext_base64
|
|
720
|
+
* @returns {Uint8Array}
|
|
721
|
+
*/
|
|
722
|
+
export function testAesGcmDecrypt(dek_bytes, nonce_base64, ciphertext_base64) {
|
|
723
|
+
const ptr0 = passArray8ToWasm0(dek_bytes, wasm.__wbindgen_malloc);
|
|
724
|
+
const len0 = WASM_VECTOR_LEN;
|
|
725
|
+
const ptr1 = passStringToWasm0(nonce_base64, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
726
|
+
const len1 = WASM_VECTOR_LEN;
|
|
727
|
+
const ptr2 = passStringToWasm0(ciphertext_base64, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
728
|
+
const len2 = WASM_VECTOR_LEN;
|
|
729
|
+
const ret = wasm.testAesGcmDecrypt(ptr0, len0, ptr1, len1, ptr2, len2);
|
|
730
|
+
if (ret[3]) {
|
|
731
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
732
|
+
}
|
|
733
|
+
var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
734
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
735
|
+
return v4;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* AES-256-GCM encrypt data with a DEK
|
|
740
|
+
*
|
|
741
|
+
* @param dekBytes - 32-byte DEK
|
|
742
|
+
* @param plaintext - Data to encrypt
|
|
743
|
+
* @returns JSON string with {nonce, ciphertext} (both base64 encoded)
|
|
744
|
+
* @param {Uint8Array} dek_bytes
|
|
745
|
+
* @param {Uint8Array} plaintext
|
|
746
|
+
* @returns {string}
|
|
747
|
+
*/
|
|
748
|
+
export function testAesGcmEncrypt(dek_bytes, plaintext) {
|
|
749
|
+
let deferred4_0;
|
|
750
|
+
let deferred4_1;
|
|
751
|
+
try {
|
|
752
|
+
const ptr0 = passArray8ToWasm0(dek_bytes, wasm.__wbindgen_malloc);
|
|
753
|
+
const len0 = WASM_VECTOR_LEN;
|
|
754
|
+
const ptr1 = passArray8ToWasm0(plaintext, wasm.__wbindgen_malloc);
|
|
755
|
+
const len1 = WASM_VECTOR_LEN;
|
|
756
|
+
const ret = wasm.testAesGcmEncrypt(ptr0, len0, ptr1, len1);
|
|
757
|
+
var ptr3 = ret[0];
|
|
758
|
+
var len3 = ret[1];
|
|
759
|
+
if (ret[3]) {
|
|
760
|
+
ptr3 = 0; len3 = 0;
|
|
761
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
762
|
+
}
|
|
763
|
+
deferred4_0 = ptr3;
|
|
764
|
+
deferred4_1 = len3;
|
|
765
|
+
return getStringFromWasm0(ptr3, len3);
|
|
766
|
+
} finally {
|
|
767
|
+
wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Full encryption round-trip test
|
|
773
|
+
*
|
|
774
|
+
* This tests the EXACT flow: derive key -> encrypt DEK with HPKE -> encrypt data with AES-GCM
|
|
775
|
+
* then decrypt in reverse order. If this works, the WASM crypto is correct.
|
|
776
|
+
*
|
|
777
|
+
* @param context - Key derivation context (e.g., "fula-files-v1")
|
|
778
|
+
* @param input - Key derivation input (e.g., credentials)
|
|
779
|
+
* @param plaintext - Data to encrypt and decrypt
|
|
780
|
+
* @returns Original plaintext if successful (proves round-trip works)
|
|
781
|
+
* @param {string} context
|
|
782
|
+
* @param {Uint8Array} input
|
|
783
|
+
* @param {Uint8Array} plaintext
|
|
784
|
+
* @returns {Uint8Array}
|
|
785
|
+
*/
|
|
786
|
+
export function testFullEncryptionRoundtrip(context, input, plaintext) {
|
|
787
|
+
const ptr0 = passStringToWasm0(context, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
788
|
+
const len0 = WASM_VECTOR_LEN;
|
|
789
|
+
const ptr1 = passArray8ToWasm0(input, wasm.__wbindgen_malloc);
|
|
790
|
+
const len1 = WASM_VECTOR_LEN;
|
|
791
|
+
const ptr2 = passArray8ToWasm0(plaintext, wasm.__wbindgen_malloc);
|
|
792
|
+
const len2 = WASM_VECTOR_LEN;
|
|
793
|
+
const ret = wasm.testFullEncryptionRoundtrip(ptr0, len0, ptr1, len1, ptr2, len2);
|
|
794
|
+
if (ret[3]) {
|
|
795
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
796
|
+
}
|
|
797
|
+
var v4 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
798
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
799
|
+
return v4;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Decrypt a wrapped DEK using HPKE with the given secret key
|
|
804
|
+
*
|
|
805
|
+
* This simulates what WebUI WASM should do when decrypting a file.
|
|
806
|
+
*
|
|
807
|
+
* @param secretKeyBytes - 32-byte X25519 secret key
|
|
808
|
+
* @param wrappedDekJson - JSON string from testHpkeEncryptDek
|
|
809
|
+
* @returns 32-byte decrypted DEK
|
|
810
|
+
* @param {Uint8Array} secret_key_bytes
|
|
811
|
+
* @param {string} wrapped_dek_json
|
|
812
|
+
* @returns {Uint8Array}
|
|
813
|
+
*/
|
|
814
|
+
export function testHpkeDecryptDek(secret_key_bytes, wrapped_dek_json) {
|
|
815
|
+
const ptr0 = passArray8ToWasm0(secret_key_bytes, wasm.__wbindgen_malloc);
|
|
816
|
+
const len0 = WASM_VECTOR_LEN;
|
|
817
|
+
const ptr1 = passStringToWasm0(wrapped_dek_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
818
|
+
const len1 = WASM_VECTOR_LEN;
|
|
819
|
+
const ret = wasm.testHpkeDecryptDek(ptr0, len0, ptr1, len1);
|
|
820
|
+
if (ret[3]) {
|
|
821
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
822
|
+
}
|
|
823
|
+
var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
824
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
825
|
+
return v3;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Encrypt a DEK using HPKE with the given public key
|
|
830
|
+
*
|
|
831
|
+
* This simulates what FxFiles does when encrypting a file.
|
|
832
|
+
* Returns JSON string containing the EncryptedData (wrapped DEK).
|
|
833
|
+
*
|
|
834
|
+
* @param publicKeyBytes - 32-byte X25519 public key
|
|
835
|
+
* @param dekBytes - 32-byte DEK to encrypt
|
|
836
|
+
* @returns JSON string with {version, encapsulated_key, ciphertext}
|
|
837
|
+
* @param {Uint8Array} public_key_bytes
|
|
838
|
+
* @param {Uint8Array} dek_bytes
|
|
839
|
+
* @returns {string}
|
|
840
|
+
*/
|
|
841
|
+
export function testHpkeEncryptDek(public_key_bytes, dek_bytes) {
|
|
842
|
+
let deferred4_0;
|
|
843
|
+
let deferred4_1;
|
|
844
|
+
try {
|
|
845
|
+
const ptr0 = passArray8ToWasm0(public_key_bytes, wasm.__wbindgen_malloc);
|
|
846
|
+
const len0 = WASM_VECTOR_LEN;
|
|
847
|
+
const ptr1 = passArray8ToWasm0(dek_bytes, wasm.__wbindgen_malloc);
|
|
848
|
+
const len1 = WASM_VECTOR_LEN;
|
|
849
|
+
const ret = wasm.testHpkeEncryptDek(ptr0, len0, ptr1, len1);
|
|
850
|
+
var ptr3 = ret[0];
|
|
851
|
+
var len3 = ret[1];
|
|
852
|
+
if (ret[3]) {
|
|
853
|
+
ptr3 = 0; len3 = 0;
|
|
854
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
855
|
+
}
|
|
856
|
+
deferred4_0 = ptr3;
|
|
857
|
+
deferred4_1 = len3;
|
|
858
|
+
return getStringFromWasm0(ptr3, len3);
|
|
859
|
+
} finally {
|
|
860
|
+
wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
710
864
|
const EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);
|
|
711
865
|
|
|
712
866
|
async function __wbg_load(module, imports) {
|
|
@@ -1008,7 +1162,7 @@ function __wbg_get_imports() {
|
|
|
1008
1162
|
const a = state0.a;
|
|
1009
1163
|
state0.a = 0;
|
|
1010
1164
|
try {
|
|
1011
|
-
return
|
|
1165
|
+
return wasm_bindgen__convert__closures_____invoke__h4b8cebda0a70f497(a, state0.b, arg0, arg1);
|
|
1012
1166
|
} finally {
|
|
1013
1167
|
state0.a = a;
|
|
1014
1168
|
}
|
|
@@ -1178,6 +1332,11 @@ function __wbg_get_imports() {
|
|
|
1178
1332
|
const ret = getStringFromWasm0(arg0, arg1);
|
|
1179
1333
|
return ret;
|
|
1180
1334
|
};
|
|
1335
|
+
imports.wbg.__wbindgen_cast_3ef92b33ccb01780 = function(arg0, arg1) {
|
|
1336
|
+
// Cast intrinsic for `Closure(Closure { dtor_idx: 323, function: Function { arguments: [Externref], shim_idx: 324, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1337
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h40a33609ceb56b6e, wasm_bindgen__convert__closures_____invoke__h7e10992c477d6050);
|
|
1338
|
+
return ret;
|
|
1339
|
+
};
|
|
1181
1340
|
imports.wbg.__wbindgen_cast_4625c577ab2ec9ee = function(arg0) {
|
|
1182
1341
|
// Cast intrinsic for `U64 -> Externref`.
|
|
1183
1342
|
const ret = BigInt.asUintN(64, arg0);
|
|
@@ -1185,7 +1344,7 @@ function __wbg_get_imports() {
|
|
|
1185
1344
|
};
|
|
1186
1345
|
imports.wbg.__wbindgen_cast_6b8383c0ec1ae211 = function(arg0, arg1) {
|
|
1187
1346
|
// Cast intrinsic for `Closure(Closure { dtor_idx: 289, function: Function { arguments: [], shim_idx: 290, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1188
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1347
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__hde34fe38f5ae6975, wasm_bindgen__convert__closures_____invoke__hb49647253b2911c5);
|
|
1189
1348
|
return ret;
|
|
1190
1349
|
};
|
|
1191
1350
|
imports.wbg.__wbindgen_cast_77bc3e92745e9a35 = function(arg0, arg1) {
|
|
@@ -1195,11 +1354,6 @@ function __wbg_get_imports() {
|
|
|
1195
1354
|
const ret = v0;
|
|
1196
1355
|
return ret;
|
|
1197
1356
|
};
|
|
1198
|
-
imports.wbg.__wbindgen_cast_7d99ab386ec3ade6 = function(arg0, arg1) {
|
|
1199
|
-
// Cast intrinsic for `Closure(Closure { dtor_idx: 324, function: Function { arguments: [Externref], shim_idx: 325, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1200
|
-
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__hf1f5673d74edd4c1, wasm_bindgen__convert__closures_____invoke__hfca1d4c99c3f4fb2);
|
|
1201
|
-
return ret;
|
|
1202
|
-
};
|
|
1203
1357
|
imports.wbg.__wbindgen_cast_9ae0607507abb057 = function(arg0) {
|
|
1204
1358
|
// Cast intrinsic for `I64 -> Externref`.
|
|
1205
1359
|
const ret = arg0;
|
package/fula_js_bg.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@functionland/fula-client",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JavaScript/TypeScript SDK for Fula decentralized storage - client-side encryption with cross-platform key compatibility",
|
|
6
6
|
"main": "fula_js.js",
|