diff --git a/crates/relicario-wasm/src/lib.rs b/crates/relicario-wasm/src/lib.rs index 03ce2ed..3e8d604 100644 --- a/crates/relicario-wasm/src/lib.rs +++ b/crates/relicario-wasm/src/lib.rs @@ -46,7 +46,7 @@ pub fn lock(handle: &SessionHandle) -> bool { // Subsequent wasm_bindgen fns added in Tasks 19-21. -use serde_wasm_bindgen::to_value; +use serde_wasm_bindgen::Serializer; use relicario_core::{ decrypt_item, decrypt_manifest, decrypt_settings, encrypt_item, encrypt_manifest, encrypt_settings, @@ -58,13 +58,18 @@ fn need_key(handle: &SessionHandle) -> Result<(), JsError> { else { Err(JsError::new("invalid or locked session handle")) } } +fn js_value_for(v: &T) -> Result { + let ser = Serializer::new().serialize_maps_as_objects(true); + v.serialize(&ser).map_err(|e| JsError::new(&e.to_string())) +} + #[wasm_bindgen] pub fn manifest_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result { need_key(handle)?; let out = session::with(handle.0, |k| decrypt_manifest(encrypted, k)) .unwrap() .map_err(|e| JsError::new(&e.to_string()))?; - to_value(&out).map_err(|e| JsError::new(&e.to_string())) + js_value_for(&out) } #[wasm_bindgen] @@ -83,7 +88,7 @@ pub fn item_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result Result Result { #[wasm_bindgen] pub fn rate_passphrase(p: &str) -> Result { let est = core_rate_passphrase(p); - to_value(&serde_json::json!({ + js_value_for(&serde_json::json!({ "score": est.score, "guesses_log10": est.guesses_log10, - })).map_err(|e| JsError::new(&e.to_string())) + })) } #[wasm_bindgen] diff --git a/extension/src/wasm.d.ts b/extension/src/wasm.d.ts index e63ee64..5b2f5cb 100644 --- a/extension/src/wasm.d.ts +++ b/extension/src/wasm.d.ts @@ -1,25 +1,58 @@ -/// Type declarations for the relicario WASM module produced by wasm-pack. +// Thin TypeScript declarations for the relicario-wasm bindings. +// These are hand-written to mirror the #[wasm_bindgen] signatures in +// crates/relicario-wasm/src/lib.rs; keep them in sync manually. -// Ambient module declarations for the WASM glue code. -// The module specifier must exactly match what's used in import statements. - -declare module 'relicario-wasm' { - export default function init(input?: string | URL): Promise; - export function derive_master_key( - passphrase: string, - image_secret: Uint8Array, - salt: Uint8Array, - params_json: string, - ): Uint8Array; - export function encrypt(plaintext: Uint8Array, key: Uint8Array): Uint8Array; - export function decrypt(ciphertext: Uint8Array, key: Uint8Array): Uint8Array; - export function extract_image_secret(jpeg_bytes: Uint8Array): Uint8Array; - export function embed_image_secret(carrier_jpeg: Uint8Array, secret: Uint8Array): Uint8Array; - export function encrypt_entry(entry_json: string, key: Uint8Array): Uint8Array; - export function decrypt_entry(ciphertext: Uint8Array, key: Uint8Array): string; - export function encrypt_manifest(manifest_json: string, key: Uint8Array): Uint8Array; - export function decrypt_manifest(ciphertext: Uint8Array, key: Uint8Array): string; - export function generate_totp(secret_base32: string, timestamp_secs: bigint): string; - export function generate_password(length: number): string; - export function generate_entry_id(): string; +export class SessionHandle { + readonly value: number; + free(): void; } + +export class EncryptedAttachment { + readonly aid: string; + readonly bytes: Uint8Array; + free(): void; +} + +export class TotpCode { + readonly code: string; + readonly expires_at: number; + free(): void; +} + +export function unlock( + passphrase: string, + image_bytes: Uint8Array, + salt: Uint8Array, + params_json: string, +): SessionHandle; + +export function lock(handle: SessionHandle): boolean; + +export function manifest_decrypt(handle: SessionHandle, encrypted: Uint8Array): unknown; +export function manifest_encrypt(handle: SessionHandle, manifest_json: string): Uint8Array; +export function item_decrypt(handle: SessionHandle, encrypted: Uint8Array): unknown; +export function item_encrypt(handle: SessionHandle, item_json: string): Uint8Array; +export function settings_decrypt(handle: SessionHandle, encrypted: Uint8Array): unknown; +export function settings_encrypt(handle: SessionHandle, settings_json: string): Uint8Array; + +export function attachment_encrypt( + handle: SessionHandle, + plaintext: Uint8Array, + max_bytes: bigint, +): EncryptedAttachment; +export function attachment_decrypt(handle: SessionHandle, encrypted: Uint8Array): Uint8Array; + +export function new_item_id(): string; +export function new_field_id(): string; + +export function generate_password(request_json: string): string; +export function generate_passphrase(request_json: string): string; +export function rate_passphrase(p: string): { score: number; guesses_log10: number }; + +export function extract_image_secret(image_bytes: Uint8Array): Uint8Array; +export function embed_image_secret(carrier: Uint8Array, secret: Uint8Array): Uint8Array; + +export function totp_compute(config_json: string, now_unix_seconds: bigint): TotpCode; + +// Initializer (wasm-bindgen's default init function). +export default function init(module_or_path?: unknown): Promise;