Files
relicario/extension/src/wasm.d.ts
adlee-was-taken 288956c089 feat(core,wasm): filter_by_collections single-source + org_manifest_decrypt_filtered
Add OrgManifest::filter_by_collections(&[String]) as the single source of
grant-filter logic. Refactor filter_for_member to delegate to it (no
duplicated loop). Add org_manifest_decrypt_filtered WASM binding that
decrypts + filters in core so ungranted entries never cross to JS (phase-1
SOFT/UX filter; per-collection crypto isolation is phase-2). Declare the
binding in extension/src/wasm.d.ts. Vec<String> compiled cleanly for
wasm32-unknown-unknown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s527M917W47LDrfQ4t47g
2026-06-26 22:19:55 -04:00

122 lines
5.2 KiB
TypeScript

// 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.
//
// Declared under the bare specifier 'relicario-wasm' so `typeof
// import('relicario-wasm')` resolves in setup.ts. Webpack doesn't
// actually resolve the module — setup.ts loads the auto-generated
// wasm/relicario_wasm.js via a webpackIgnore dynamic import at runtime.
declare module 'relicario-wasm' {
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: bigint;
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 default_vault_settings_json(): string;
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;
// Pure parsers (no session needed)
export function parse_month_year(s: string): { month: number; year: number };
export function base32_decode_lenient(s: string): Uint8Array;
export function guess_mime(filename: string): string;
export function totp_compute(config_json: string, now_unix_seconds: bigint): TotpCode;
export function register_device(name: string): {
signing_public_key: string;
deploy_public_key: string;
};
export function sign_for_git(data: Uint8Array): {
signature: string;
};
export function get_device_info(): {
name: string;
signing_public_key: string;
deploy_public_key: string;
} | null;
export function clear_device(): void;
export function get_field_history(item_json: string): unknown;
export function wasm_generate_recovery_qr(handle: SessionHandle, passphrase: string): string;
export function wasm_unwrap_recovery_qr(payload_b64: string, passphrase: string): Uint8Array;
/** Unwrap an ECIES-wrapped org master key using the registered device key in DEVICE_STATE. */
export function org_unwrap_key(keys_blob: Uint8Array): SessionHandle;
export function org_manifest_decrypt(handle: SessionHandle, encrypted: Uint8Array): unknown;
export function org_manifest_encrypt(handle: SessionHandle, manifest_json: string): Uint8Array;
/**
* Decrypt an org manifest AND filter it to the granted collection slugs.
* Filtering happens in core (SOFT/UX filter — phase-1 only; the member holds
* the org key and can decrypt everything; per-collection crypto isolation is
* phase-2). Use for READ paths only; writes must use org_manifest_decrypt to
* avoid wiping ungranted collections on re-encrypt.
*/
export function org_manifest_decrypt_filtered(handle: SessionHandle, encrypted: Uint8Array, granted: string[]): unknown;
/**
* Encrypt the registered device key under the vault master key.
* Returns CIPHERTEXT — the device private key never crosses to JS.
* Store the returned bytes in chrome.storage.local as `device_key_enc`.
*/
export function persist_device_key(handle: SessionHandle): Uint8Array;
/**
* Decrypt a persisted device-key blob under the master key and repopulate
* DEVICE_STATE. Decryption happens inside WASM; plaintext never reaches JS.
* Call at unlock time with the `device_key_enc` blob from chrome.storage.local.
*/
export function restore_device_key(handle: SessionHandle, encrypted: Uint8Array): void;
// Pluggable second factor: key-file bindings (Task 3)
export function unlock_with_secret(passphrase: string, secret: Uint8Array, salt: Uint8Array, params_json: string): SessionHandle;
export function keyfile_encode(secret: Uint8Array): Uint8Array;
export function keyfile_decode(bytes: Uint8Array): Uint8Array;
export default function init(module_or_path?: unknown): Promise<void>;
export function initSync(args: { module: WebAssembly.Module }): void;
}