feat(wasm): configure serde_wasm_bindgen for plain-object HashMap
Maps serialize as JS objects, not Maps — what the extension popup expects. Also ships hand-written TS declarations for the bridge (consumed by Plan 1C). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ pub fn lock(handle: &SessionHandle) -> bool {
|
|||||||
|
|
||||||
// Subsequent wasm_bindgen fns added in Tasks 19-21.
|
// Subsequent wasm_bindgen fns added in Tasks 19-21.
|
||||||
|
|
||||||
use serde_wasm_bindgen::to_value;
|
use serde_wasm_bindgen::Serializer;
|
||||||
use relicario_core::{
|
use relicario_core::{
|
||||||
decrypt_item, decrypt_manifest, decrypt_settings,
|
decrypt_item, decrypt_manifest, decrypt_settings,
|
||||||
encrypt_item, encrypt_manifest, encrypt_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")) }
|
else { Err(JsError::new("invalid or locked session handle")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn js_value_for<T: serde::Serialize>(v: &T) -> Result<JsValue, JsError> {
|
||||||
|
let ser = Serializer::new().serialize_maps_as_objects(true);
|
||||||
|
v.serialize(&ser).map_err(|e| JsError::new(&e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn manifest_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result<JsValue, JsError> {
|
pub fn manifest_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result<JsValue, JsError> {
|
||||||
need_key(handle)?;
|
need_key(handle)?;
|
||||||
let out = session::with(handle.0, |k| decrypt_manifest(encrypted, k))
|
let out = session::with(handle.0, |k| decrypt_manifest(encrypted, k))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map_err(|e| JsError::new(&e.to_string()))?;
|
.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]
|
#[wasm_bindgen]
|
||||||
@@ -83,7 +88,7 @@ pub fn item_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result<JsValue,
|
|||||||
let out = session::with(handle.0, |k| decrypt_item(encrypted, k))
|
let out = session::with(handle.0, |k| decrypt_item(encrypted, k))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map_err(|e| JsError::new(&e.to_string()))?;
|
.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]
|
#[wasm_bindgen]
|
||||||
@@ -102,7 +107,7 @@ pub fn settings_decrypt(handle: &SessionHandle, encrypted: &[u8]) -> Result<JsVa
|
|||||||
let out = session::with(handle.0, |k| decrypt_settings(encrypted, k))
|
let out = session::with(handle.0, |k| decrypt_settings(encrypted, k))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map_err(|e| JsError::new(&e.to_string()))?;
|
.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]
|
#[wasm_bindgen]
|
||||||
@@ -185,10 +190,10 @@ pub fn generate_passphrase(request_json: &str) -> Result<String, JsError> {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn rate_passphrase(p: &str) -> Result<JsValue, JsError> {
|
pub fn rate_passphrase(p: &str) -> Result<JsValue, JsError> {
|
||||||
let est = core_rate_passphrase(p);
|
let est = core_rate_passphrase(p);
|
||||||
to_value(&serde_json::json!({
|
js_value_for(&serde_json::json!({
|
||||||
"score": est.score,
|
"score": est.score,
|
||||||
"guesses_log10": est.guesses_log10,
|
"guesses_log10": est.guesses_log10,
|
||||||
})).map_err(|e| JsError::new(&e.to_string()))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
|||||||
79
extension/src/wasm.d.ts
vendored
79
extension/src/wasm.d.ts
vendored
@@ -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.
|
export class SessionHandle {
|
||||||
// The module specifier must exactly match what's used in import statements.
|
readonly value: number;
|
||||||
|
free(): void;
|
||||||
declare module 'relicario-wasm' {
|
|
||||||
export default function init(input?: string | URL): Promise<void>;
|
|
||||||
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 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<void>;
|
||||||
|
|||||||
Reference in New Issue
Block a user