Add kv-wasm: the core compiled to WebAssembly for the web vault
New crate crates/kv-wasm runs the same crypto, item model and sync engine in the browser: - WebStore: in-memory replica of kv-store's Store, each changed entry written to IndexedDB (ciphertext only) before the JS call resolves. - Device key: non-extractable WebCrypto ECDSA P-256 key in IndexedDB (raw r||s signatures). - WebCore mirrors kv-ffi's VaultCore; wasm-bindgen surface in camelCase with TypeScript types, plus a Web Worker wrapper (connectVault) so Argon2id never blocks the page. - Tests: Chrome (IndexedDB, WebCrypto, RFC 9421 verify), shared envelope fixtures both ways with kv-ffi, native sync with kv-ffi via the test server, Node smoke of the built package. Small changes to shared crates so they build for wasm32: - kv-store: SqliteStore moved to a native-only module. - kv-sync: rustls/pinning/tokio native only (fetch on wasm); DeviceSigner::sign_async (default wraps sign) used by ApiClient; unix_now() instead of SystemTime/now_utc. - kv-model: Public Suffix List behind a default `psl` feature (kv-ffi keeps it; the web build drops ~0.9 MB of code and matches same-host only). - wasm-release profile (opt-level z, Argon2 at 3) and a wasm CI job. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -34,12 +34,24 @@ pub fn match_url(item_url: &str, page_url: &str) -> MatchLevel {
|
||||
MatchLevel::Host
|
||||
};
|
||||
}
|
||||
match (psl::domain_str(&ih), psl::domain_str(&ph)) {
|
||||
same_registrable_domain(&ih, &ph)
|
||||
}
|
||||
|
||||
#[cfg(feature = "psl")]
|
||||
fn same_registrable_domain(a: &str, b: &str) -> MatchLevel {
|
||||
match (psl::domain_str(a), psl::domain_str(b)) {
|
||||
(Some(a), Some(b)) if a == b => MatchLevel::Domain,
|
||||
_ => MatchLevel::None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Without the Public Suffix List there is no safe way to tell `a.example.com` / `b.example.com`
|
||||
/// (same site) from `a.github.io` / `b.github.io` (different sites), so different hosts never match.
|
||||
#[cfg(not(feature = "psl"))]
|
||||
fn same_registrable_domain(_: &str, _: &str) -> MatchLevel {
|
||||
MatchLevel::None
|
||||
}
|
||||
|
||||
fn parse(s: &str) -> Option<Url> {
|
||||
let s = s.trim();
|
||||
// Saved URLs are often stored without a scheme ("example.com/login").
|
||||
|
||||
Reference in New Issue
Block a user