From cdfbe13ec5db711e4c62c7ae33ece9d09860aca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 18:40:34 +0200 Subject: [PATCH 01/13] Use actual error types in UniFFI --- Cargo.lock | 199 +++++++++++------- Cargo.toml | 9 +- crates/bitwarden-collections/src/error.rs | 2 +- crates/bitwarden-core/src/auth/auth_client.rs | 1 + .../bitwarden-core/src/auth/auth_request.rs | 1 + crates/bitwarden-core/src/auth/mod.rs | 1 + .../src/client/encryption_settings.rs | 2 +- crates/bitwarden-core/src/error.rs | 3 +- .../src/key_management/crypto.rs | 2 +- .../src/platform/generate_fingerprint.rs | 4 +- crates/bitwarden-core/src/uniffi_support.rs | 14 ++ crates/bitwarden-crypto/src/error.rs | 8 +- crates/bitwarden-crypto/src/rsa.rs | 2 +- .../safe/password_protected_key_envelope.rs | 52 ++--- .../src/flat/attribute.rs | 1 + .../src/full/attribute.rs | 1 + crates/bitwarden-exporters/src/cxf/ssh.rs | 2 +- crates/bitwarden-exporters/src/error.rs | 8 +- crates/bitwarden-fido/src/authenticator.rs | 46 ++-- crates/bitwarden-fido/src/client.rs | 3 +- crates/bitwarden-fido/src/client_fido.rs | 3 +- crates/bitwarden-fido/src/lib.rs | 4 +- crates/bitwarden-fido/src/types.rs | 4 +- crates/bitwarden-generators/src/passphrase.rs | 2 +- crates/bitwarden-ipc/src/ipc_client.rs | 4 +- crates/bitwarden-ipc/src/rpc/error.rs | 8 +- crates/bitwarden-ipc/src/rpc/exec/handler.rs | 10 +- .../bitwarden-ipc/src/rpc/request_message.rs | 2 +- crates/bitwarden-send/src/error.rs | 2 +- crates/bitwarden-send/src/send_client.rs | 4 + crates/bitwarden-ssh/src/error.rs | 8 +- crates/bitwarden-ssh/src/export.rs | 12 +- crates/bitwarden-ssh/src/generator.rs | 8 +- crates/bitwarden-ssh/src/import.rs | 28 +-- crates/bitwarden-ssh/src/lib.rs | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- crates/bitwarden-uniffi/src/auth/mod.rs | 49 +---- crates/bitwarden-uniffi/src/crypto.rs | 47 +---- crates/bitwarden-uniffi/src/error.rs | 46 ++-- crates/bitwarden-uniffi/src/lib.rs | 165 ++++++++++++++- crates/bitwarden-uniffi/src/platform/mod.rs | 14 +- .../src/platform/repository.rs | 8 +- crates/bitwarden-uniffi/src/tool/mod.rs | 20 +- crates/bitwarden-uniffi/src/tool/sends.rs | 44 ++-- crates/bitwarden-uniffi/src/tool/ssh.rs | 11 +- .../bitwarden-uniffi/src/vault/attachments.rs | 42 ++-- crates/bitwarden-uniffi/src/vault/ciphers.rs | 18 +- .../bitwarden-uniffi/src/vault/collections.rs | 6 +- crates/bitwarden-uniffi/src/vault/folders.rs | 8 +- crates/bitwarden-uniffi/src/vault/mod.rs | 14 +- .../src/vault/password_history.rs | 6 +- crates/bitwarden-vault/src/cipher/cipher.rs | 6 +- crates/bitwarden-vault/src/error.rs | 2 +- 53 files changed, 533 insertions(+), 437 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8fcb5a8f..b71d28ebd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,6 +169,48 @@ dependencies = [ "zeroize", ] +[[package]] +name = "askama" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "assert-json-diff" version = "2.0.2" @@ -910,16 +952,16 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.15.4" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -1291,7 +1333,7 @@ dependencies = [ "bitflags 2.9.1", "crossterm_winapi", "parking_lot", - "rustix", + "rustix 0.38.44", "winapi", ] @@ -1701,6 +1743,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "ff" version = "0.13.1" @@ -2494,6 +2542,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "litemap" version = "0.8.0" @@ -2862,12 +2916,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pbkdf2" version = "0.12.2" @@ -3354,45 +3402,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rinja" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5" -dependencies = [ - "itoa", - "rinja_derive", -] - -[[package]] -name = "rinja_derive" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b" -dependencies = [ - "basic-toml", - "memchr", - "mime", - "mime_guess", - "proc-macro2", - "quote", - "rinja_parser", - "rustc-hash", - "serde", - "syn", -] - -[[package]] -name = "rinja_parser" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610" -dependencies = [ - "memchr", - "nom", - "serde", -] - [[package]] name = "rsa" version = "0.9.8" @@ -3444,10 +3453,23 @@ dependencies = [ "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", "windows-sys 0.59.0", ] +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + [[package]] name = "rustls" version = "0.23.28" @@ -4098,6 +4120,19 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" +[[package]] +name = "tempfile" +version = "3.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.8", + "windows-sys 0.60.2", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -4545,9 +4580,8 @@ checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "uniffi" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe34585ac0275accf6c284d0080cc2840f3898c551cda869ec291b5a4218712c" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "camino", @@ -4557,6 +4591,7 @@ dependencies = [ "uniffi_build", "uniffi_core", "uniffi_macros", + "uniffi_pipeline", ] [[package]] @@ -4568,32 +4603,33 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a792af1424cc8b3c43b44c1a6cb7935ed1fbe5584a74f70e8bab9799740266d" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", + "askama", "camino", "cargo_metadata", "fs-err", "glob", "goblin", "heck 0.5.0", + "indexmap 2.9.0", "once_cell", - "paste", - "rinja", "serde", + "tempfile", "textwrap", "toml 0.5.11", + "uniffi_internal_macros", "uniffi_meta", + "uniffi_pipeline", "uniffi_udl", ] [[package]] name = "uniffi_build" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c4138211f2ae951018fcce6a978e1fcd1a47c3fd0bc0d5472a520520060db1" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "camino", @@ -4602,9 +4638,8 @@ dependencies = [ [[package]] name = "uniffi_core" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c18baace68a52666d33d12d73ca335ecf27a302202cefb53b1f974512bb72417" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "async-compat", @@ -4615,9 +4650,8 @@ dependencies = [ [[package]] name = "uniffi_internal_macros" -version = "0.29.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64bec2f3a33f2f08df8150e67fa45ba59a2ca740bf20c1beb010d4d791f9a1b" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "indexmap 2.9.0", @@ -4628,9 +4662,8 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d82c82ef945c51082d8763635334b994e63e77650f09d0fae6d28dd08b1de83" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "camino", "fs-err", @@ -4645,20 +4678,31 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6027b971c2aa86350dd180aee9819729c7b99bacd381534511ff29d2c09cea" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "siphasher", "uniffi_internal_macros", + "uniffi_pipeline", +] + +[[package]] +name = "uniffi_pipeline" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.9.0", + "tempfile", + "uniffi_internal_macros", ] [[package]] name = "uniffi_udl" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52300b7a4ab02dc159a038a13d5bfe27aefbad300d91b0b501b3dda094c1e0a2" +version = "0.29.4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "anyhow", "textwrap", @@ -4922,8 +4966,7 @@ dependencies = [ [[package]] name = "weedle2" version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index 827edd519..c64a9b424 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ tokio = { version = "1.36.0", features = ["macros"] } tsify = { version = ">=0.5.5, <0.6", features = [ "js", ], default-features = false } -uniffi = "=0.29.1" +uniffi = "=0.29.4" uuid = { version = ">=1.3.3, <2.0", features = ["serde", "v4", "js"] } validator = { version = ">=0.18.1, <0.21", features = ["derive"] } wasm-bindgen = { version = ">=0.2.91, <0.3", features = ["serde-serialize"] } @@ -89,6 +89,13 @@ wiremock = ">=0.6.0, <0.7" [patch.crates-io] pkcs5 = { git = "https://github.com/bitwarden/rustcrypto-formats.git", rev = "2b27c63034217dd126bbf5ed874da51b84f8c705" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi_internal_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } + [workspace.lints.clippy] unused_async = "deny" unwrap_used = "deny" diff --git a/crates/bitwarden-collections/src/error.rs b/crates/bitwarden-collections/src/error.rs index c7e921ec7..638aa75b1 100644 --- a/crates/bitwarden-collections/src/error.rs +++ b/crates/bitwarden-collections/src/error.rs @@ -15,5 +15,5 @@ pub enum CollectionsParseError { #[error(transparent)] Crypto(#[from] bitwarden_crypto::CryptoError), #[error(transparent)] - MissingFieldError(#[from] bitwarden_core::MissingFieldError), + MissingField(#[from] bitwarden_core::MissingFieldError), } diff --git a/crates/bitwarden-core/src/auth/auth_client.rs b/crates/bitwarden-core/src/auth/auth_client.rs index 9c9b2da8f..7e1921f9f 100644 --- a/crates/bitwarden-core/src/auth/auth_client.rs +++ b/crates/bitwarden-core/src/auth/auth_client.rs @@ -206,6 +206,7 @@ impl AuthClient { #[allow(missing_docs)] #[cfg(feature = "internal")] #[derive(Debug, thiserror::Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum TrustDeviceError { #[error(transparent)] VaultLocked(#[from] crate::VaultLockedError), diff --git a/crates/bitwarden-core/src/auth/auth_request.rs b/crates/bitwarden-core/src/auth/auth_request.rs index a83cc6da0..1bac91544 100644 --- a/crates/bitwarden-core/src/auth/auth_request.rs +++ b/crates/bitwarden-core/src/auth/auth_request.rs @@ -75,6 +75,7 @@ pub(crate) fn auth_request_decrypt_master_key( #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum ApproveAuthRequestError { #[error(transparent)] Crypto(#[from] CryptoError), diff --git a/crates/bitwarden-core/src/auth/mod.rs b/crates/bitwarden-core/src/auth/mod.rs index 7d742b9a9..25b861d05 100644 --- a/crates/bitwarden-core/src/auth/mod.rs +++ b/crates/bitwarden-core/src/auth/mod.rs @@ -51,6 +51,7 @@ pub use key_connector::KeyConnectorResponse; /// Error for authentication related operations #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum AuthValidateError { #[error(transparent)] NotAuthenticated(#[from] NotAuthenticatedError), diff --git a/crates/bitwarden-core/src/client/encryption_settings.rs b/crates/bitwarden-core/src/client/encryption_settings.rs index 2a8ff2c1c..90613454e 100644 --- a/crates/bitwarden-core/src/client/encryption_settings.rs +++ b/crates/bitwarden-core/src/client/encryption_settings.rs @@ -44,7 +44,7 @@ pub enum EncryptionSettingsError { MissingPrivateKey(#[from] MissingPrivateKeyError), #[error(transparent)] - UserIdAlreadySetError(#[from] UserIdAlreadySetError), + UserIdAlreadySet(#[from] UserIdAlreadySetError), #[error("Wrong Pin")] WrongPin, diff --git a/crates/bitwarden-core/src/error.rs b/crates/bitwarden-core/src/error.rs index 996d7d43d..3b7790010 100644 --- a/crates/bitwarden-core/src/error.rs +++ b/crates/bitwarden-core/src/error.rs @@ -30,6 +30,7 @@ macro_rules! impl_bitwarden_error { /// Errors from performing network requests. #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum ApiError { #[error(transparent)] Reqwest(#[from] reqwest::Error), @@ -94,7 +95,7 @@ pub enum StatefulCryptoError { got: u32, }, #[error("Crypto error, {0}")] - CryptoError(#[from] bitwarden_crypto::CryptoError), + Crypto(#[from] bitwarden_crypto::CryptoError), } /// This macro is used to require that a value is present or return an error otherwise. diff --git a/crates/bitwarden-core/src/key_management/crypto.rs b/crates/bitwarden-core/src/key_management/crypto.rs index f5253a9a7..2b5de8a46 100644 --- a/crates/bitwarden-core/src/key_management/crypto.rs +++ b/crates/bitwarden-core/src/key_management/crypto.rs @@ -668,7 +668,7 @@ pub(crate) fn make_v2_keys_for_v1_user( // V1 user must have a private key to upgrade. This should be ensured by the client before // calling the upgrade function. if !ctx.has_asymmetric_key(AsymmetricKeyId::UserPrivateKey) { - return Err(StatefulCryptoError::CryptoError(CryptoError::MissingKeyId( + return Err(StatefulCryptoError::Crypto(CryptoError::MissingKeyId( "UserPrivateKey".to_string(), ))); } diff --git a/crates/bitwarden-core/src/platform/generate_fingerprint.rs b/crates/bitwarden-core/src/platform/generate_fingerprint.rs index 8de1702cd..7c335d773 100644 --- a/crates/bitwarden-core/src/platform/generate_fingerprint.rs +++ b/crates/bitwarden-core/src/platform/generate_fingerprint.rs @@ -33,9 +33,10 @@ pub struct FingerprintResponse { /// Errors that can occur when computing a fingerprint. #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error))] pub enum FingerprintError { #[error(transparent)] - CryptoError(#[from] bitwarden_crypto::CryptoError), + Crypto(#[from] bitwarden_crypto::CryptoError), } pub(crate) fn generate_fingerprint(input: &FingerprintRequest) -> Result { @@ -48,6 +49,7 @@ pub(crate) fn generate_fingerprint(input: &FingerprintRequest) -> Result Result<(), CryptoError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + } +} diff --git a/crates/bitwarden-crypto/src/error.rs b/crates/bitwarden-crypto/src/error.rs index 18b584da9..34092327a 100644 --- a/crates/bitwarden-crypto/src/error.rs +++ b/crates/bitwarden-crypto/src/error.rs @@ -39,10 +39,10 @@ pub enum CryptoError { EncString(#[from] EncStringParseError), #[error("Rsa error, {0}")] - RsaError(#[from] RsaError), + Rsa(#[from] RsaError), #[error("Fingerprint error, {0}")] - FingerprintError(#[from] FingerprintError), + Fingerprint(#[from] FingerprintError), #[error("Argon2 error, {0}")] ArgonError(#[from] argon2::Error), @@ -66,10 +66,10 @@ pub enum CryptoError { InvalidPadding, #[error("Signature error, {0}")] - SignatureError(#[from] SignatureError), + Signature(#[from] SignatureError), #[error("Encoding error, {0}")] - EncodingError(#[from] EncodingError), + Encoding(#[from] EncodingError), } #[derive(Debug, Error)] diff --git a/crates/bitwarden-crypto/src/rsa.rs b/crates/bitwarden-crypto/src/rsa.rs index 66adc5284..d0b2f5806 100644 --- a/crates/bitwarden-crypto/src/rsa.rs +++ b/crates/bitwarden-crypto/src/rsa.rs @@ -61,5 +61,5 @@ pub(super) fn encrypt_rsa2048_oaep_sha1(public_key: &RsaPublicKey, data: &[u8]) let padding = Oaep::new::(); public_key .encrypt(&mut rng, padding, data) - .map_err(|e| CryptoError::RsaError(e.into())) + .map_err(|e| CryptoError::Rsa(e.into())) } diff --git a/crates/bitwarden-crypto/src/safe/password_protected_key_envelope.rs b/crates/bitwarden-crypto/src/safe/password_protected_key_envelope.rs index f41fe07b2..7b1acdeef 100644 --- a/crates/bitwarden-crypto/src/safe/password_protected_key_envelope.rs +++ b/crates/bitwarden-crypto/src/safe/password_protected_key_envelope.rs @@ -64,7 +64,7 @@ impl PasswordProtectedKeyEnvelope { #[allow(deprecated)] let key_ref = ctx .dangerous_get_symmetric_key(key_to_seal) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KeyMissingError)?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::KeyMissing)?; Self::seal_ref(key_ref, password) } @@ -97,7 +97,7 @@ impl PasswordProtectedKeyEnvelope { // The envelope key is directly derived from the KDF and used as the key to encrypt the key // that should be sealed. let envelope_key = derive_key(kdf_settings, password) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KdfError)?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::Kdf)?; let (content_format, key_to_seal_bytes) = match key_to_seal.to_encoded_raw() { EncodedSymmetricKey::BitwardenLegacyKey(key_bytes) => { @@ -145,7 +145,7 @@ impl PasswordProtectedKeyEnvelope { let key = self.unseal_ref(password)?; #[allow(deprecated)] ctx.set_symmetric_key(target_keyslot, key) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KeyStoreError)?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::KeyStore)?; Ok(target_keyslot) } @@ -161,34 +161,32 @@ impl PasswordProtectedKeyEnvelope { .first() .filter(|_| self.cose_encrypt.recipients.len() == 1) .ok_or_else(|| { - PasswordProtectedKeyEnvelopeError::ParsingError( + PasswordProtectedKeyEnvelopeError::Parsing( "Invalid number of recipients".to_string(), ) })?; if recipient.protected.header.alg != Some(coset::Algorithm::PrivateUse(ALG_ARGON2ID13)) { - return Err(PasswordProtectedKeyEnvelopeError::ParsingError( + return Err(PasswordProtectedKeyEnvelopeError::Parsing( "Unknown or unsupported KDF algorithm".to_string(), )); } let kdf_settings: Argon2RawSettings = (&recipient.unprotected).try_into().map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError( + PasswordProtectedKeyEnvelopeError::Parsing( "Invalid or missing KDF parameters".to_string(), ) })?; let envelope_key = derive_key(&kdf_settings, password) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KdfError)?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::Kdf)?; let nonce: [u8; crate::xchacha20::NONCE_SIZE] = self .cose_encrypt .unprotected .iv .clone() .try_into() - .map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError("Invalid IV".to_string()) - })?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::Parsing("Invalid IV".to_string()))?; let key_bytes = self .cose_encrypt @@ -201,9 +199,7 @@ impl PasswordProtectedKeyEnvelope { SymmetricCryptoKey::try_from( match ContentFormat::try_from(&self.cose_encrypt.protected.header).map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError( - "Invalid content format".to_string(), - ) + PasswordProtectedKeyEnvelopeError::Parsing("Invalid content format".to_string()) })? { ContentFormat::BitwardenLegacyKey => EncodedSymmetricKey::BitwardenLegacyKey( BitwardenLegacyKeyBytes::from(key_bytes), @@ -212,15 +208,13 @@ impl PasswordProtectedKeyEnvelope { EncodedSymmetricKey::CoseKey(CoseKeyBytes::from(key_bytes)) } _ => { - return Err(PasswordProtectedKeyEnvelopeError::ParsingError( + return Err(PasswordProtectedKeyEnvelopeError::Parsing( "Unknown or unsupported content format".to_string(), )); } }, ) - .map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError("Failed to decode key".to_string()) - }) + .map_err(|_| PasswordProtectedKeyEnvelopeError::Parsing("Failed to decode key".to_string())) } /// Re-seals the key with new KDF parameters (updated settings, salt), and a new password @@ -268,12 +262,12 @@ impl FromStr for PasswordProtectedKeyEnvelope { fn from_str(s: &str) -> Result { let data = B64::try_from(s).map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError( + PasswordProtectedKeyEnvelopeError::Parsing( "Invalid PasswordProtectedKeyEnvelope Base64 encoding".to_string(), ) })?; Self::try_from(&data.as_bytes().to_vec()).map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError( + PasswordProtectedKeyEnvelopeError::Parsing( "Failed to parse PasswordProtectedKeyEnvelope".to_string(), ) }) @@ -373,7 +367,7 @@ impl TryInto for &Argon2RawSettings { self.parallelism, Some(ENVELOPE_ARGON2_OUTPUT_KEY_SIZE), ) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KdfError) + .map_err(|_| PasswordProtectedKeyEnvelopeError::Kdf) } } @@ -388,9 +382,7 @@ impl TryInto for &Header { salt: extract_bytes(self, ARGON2_SALT, "salt")? .try_into() .map_err(|_| { - PasswordProtectedKeyEnvelopeError::ParsingError( - "Invalid Argon2 salt".to_string(), - ) + PasswordProtectedKeyEnvelopeError::Parsing("Invalid Argon2 salt".to_string()) })?, }) } @@ -415,7 +407,7 @@ fn derive_key( argon2_settings.try_into()?, ) .hash_password_into(password.as_bytes(), &argon2_settings.salt, &mut hash) - .map_err(|_| PasswordProtectedKeyEnvelopeError::KdfError)?; + .map_err(|_| PasswordProtectedKeyEnvelopeError::Kdf)?; Ok(hash) } @@ -428,29 +420,29 @@ pub enum PasswordProtectedKeyEnvelopeError { WrongPassword, /// The envelope could not be parsed correctly, or the KDF parameters are invalid #[error("Parsing error {0}")] - ParsingError(String), + Parsing(String), /// The KDF failed to derive a key, possibly due to invalid parameters or memory allocation /// issues #[error("Kdf error")] - KdfError, + Kdf, /// There is no key for the provided key id in the key store #[error("Key missing error")] - KeyMissingError, + KeyMissing, /// The key store could not be written to, for example due to being read-only #[error("Could not write to key store")] - KeyStoreError, + KeyStore, } impl From for PasswordProtectedKeyEnvelopeError { fn from(err: CoseExtractError) -> Self { let CoseExtractError::MissingValue(label) = err; - PasswordProtectedKeyEnvelopeError::ParsingError(format!("Missing value for {}", label)) + PasswordProtectedKeyEnvelopeError::Parsing(format!("Missing value for {}", label)) } } impl From for PasswordProtectedKeyEnvelopeError { fn from(err: TryFromIntError) -> Self { - PasswordProtectedKeyEnvelopeError::ParsingError(format!("Invalid integer: {}", err)) + PasswordProtectedKeyEnvelopeError::Parsing(format!("Invalid integer: {}", err)) } } diff --git a/crates/bitwarden-error-macro/src/flat/attribute.rs b/crates/bitwarden-error-macro/src/flat/attribute.rs index ee698052d..bc229f4dd 100644 --- a/crates/bitwarden-error-macro/src/flat/attribute.rs +++ b/crates/bitwarden-error-macro/src/flat/attribute.rs @@ -41,6 +41,7 @@ pub(crate) fn bitwarden_error_flat( }); quote! { + #[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] #input #wasm diff --git a/crates/bitwarden-error-macro/src/full/attribute.rs b/crates/bitwarden-error-macro/src/full/attribute.rs index 17cd9628f..f3d45034c 100644 --- a/crates/bitwarden-error-macro/src/full/attribute.rs +++ b/crates/bitwarden-error-macro/src/full/attribute.rs @@ -21,6 +21,7 @@ pub(crate) fn bitwarden_error_full( quote! { #[derive(serde::Serialize)] + #[cfg_attr(feature = "uniffi", derive(uniffi::Error))] #wasm_attributes #input } diff --git a/crates/bitwarden-exporters/src/cxf/ssh.rs b/crates/bitwarden-exporters/src/cxf/ssh.rs index 232c967cb..305c23948 100644 --- a/crates/bitwarden-exporters/src/cxf/ssh.rs +++ b/crates/bitwarden-exporters/src/cxf/ssh.rs @@ -79,7 +79,7 @@ fn extract_key_type(public_key: &str) -> Result { let key_type = public_key .split_whitespace() .next() - .ok_or(SshKeyExportError::KeyConversionError)?; + .ok_or(SshKeyExportError::KeyConversion)?; Ok(key_type.to_string()) } diff --git a/crates/bitwarden-exporters/src/error.rs b/crates/bitwarden-exporters/src/error.rs index 062d7a9de..e4d1cebec 100644 --- a/crates/bitwarden-exporters/src/error.rs +++ b/crates/bitwarden-exporters/src/error.rs @@ -15,14 +15,14 @@ pub enum ExportError { #[error("CSV error: {0}")] Csv(#[from] crate::csv::CsvError), #[error("Credential Exchange error: {0}")] - CxfError(#[from] crate::cxf::CxfError), + Cxf(#[from] crate::cxf::CxfError), #[error("JSON error: {0}")] Json(#[from] crate::json::JsonError), #[error("Encrypted JSON error: {0}")] - EncryptedJsonError(#[from] crate::encrypted_json::EncryptedJsonError), + EncryptedJson(#[from] crate::encrypted_json::EncryptedJsonError), #[error(transparent)] - BitwardenCryptoError(#[from] bitwarden_crypto::CryptoError), + BitwardenCrypto(#[from] bitwarden_crypto::CryptoError), #[error(transparent)] - CipherError(#[from] bitwarden_vault::CipherError), + Cipher(#[from] bitwarden_vault::CipherError), } diff --git a/crates/bitwarden-fido/src/authenticator.rs b/crates/bitwarden-fido/src/authenticator.rs index 8216bb16b..756e1f9aa 100644 --- a/crates/bitwarden-fido/src/authenticator.rs +++ b/crates/bitwarden-fido/src/authenticator.rs @@ -33,14 +33,15 @@ pub enum GetSelectedCredentialError { #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), } #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum MakeCredentialError { #[error(transparent)] - PublicKeyCredentialParametersError(#[from] PublicKeyCredentialParametersError), + PublicKeyCredentialParameters(#[from] PublicKeyCredentialParametersError), #[error(transparent)] UnknownEnum(#[from] UnknownEnum), #[error(transparent)] @@ -53,13 +54,14 @@ pub enum MakeCredentialError { #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum GetAssertionError { #[error(transparent)] UnknownEnum(#[from] UnknownEnum), #[error(transparent)] Serde(#[from] serde_json::Error), #[error(transparent)] - GetSelectedCredentialError(#[from] GetSelectedCredentialError), + GetSelectedCredential(#[from] GetSelectedCredentialError), #[error(transparent)] InvalidGuid(#[from] InvalidGuid), #[error("missing user")] @@ -70,32 +72,34 @@ pub enum GetAssertionError { #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum SilentlyDiscoverCredentialsError { #[error(transparent)] - CipherError(#[from] CipherError), + Cipher(#[from] CipherError), #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] InvalidGuid(#[from] InvalidGuid), #[error(transparent)] - Fido2CallbackError(#[from] Fido2CallbackError), + Fido2Callback(#[from] Fido2CallbackError), #[error(transparent)] - FromCipherViewError(#[from] Fido2CredentialAutofillViewError), + FromCipherView(#[from] Fido2CredentialAutofillViewError), } #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum CredentialsForAutofillError { #[error(transparent)] - CipherError(#[from] CipherError), + Cipher(#[from] CipherError), #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] InvalidGuid(#[from] InvalidGuid), #[error(transparent)] - Fido2CallbackError(#[from] Fido2CallbackError), + Fido2Callback(#[from] Fido2CallbackError), #[error(transparent)] - FromCipherViewError(#[from] Fido2CredentialAutofillViewError), + FromCipherView(#[from] Fido2CredentialAutofillViewError), } #[allow(missing_docs)] @@ -361,11 +365,11 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> { #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] - CipherError(#[from] CipherError), + Cipher(#[from] CipherError), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), #[error(transparent)] - Fido2CallbackError(#[from] Fido2CallbackError), + Fido2Callback(#[from] Fido2CallbackError), } // This is just a wrapper around the actual implementation to allow for ? error handling @@ -445,13 +449,13 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> { #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] - FillCredentialError(#[from] FillCredentialError), + FillCredential(#[from] FillCredentialError), #[error(transparent)] - CipherError(#[from] CipherError), + Cipher(#[from] CipherError), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), #[error(transparent)] - Fido2CallbackError(#[from] Fido2CallbackError), + Fido2Callback(#[from] Fido2CallbackError), #[error("No selected credential available")] NoSelectedCredential, @@ -527,15 +531,15 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> { #[error("Credential ID does not match selected credential")] CredentialIdMismatch, #[error(transparent)] - FillCredentialError(#[from] FillCredentialError), + FillCredential(#[from] FillCredentialError), #[error(transparent)] - CipherError(#[from] CipherError), + Cipher(#[from] CipherError), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), #[error(transparent)] - Fido2CallbackError(#[from] Fido2CallbackError), + Fido2Callback(#[from] Fido2CallbackError), #[error(transparent)] - GetSelectedCredentialError(#[from] GetSelectedCredentialError), + GetSelectedCredential(#[from] GetSelectedCredentialError), } // This is just a wrapper around the actual implementation to allow for ? error handling diff --git a/crates/bitwarden-fido/src/client.rs b/crates/bitwarden-fido/src/client.rs index 9ecaf52e8..3f86b8750 100644 --- a/crates/bitwarden-fido/src/client.rs +++ b/crates/bitwarden-fido/src/client.rs @@ -15,13 +15,14 @@ use crate::types::InvalidOriginError; #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum Fido2ClientError { #[error(transparent)] InvalidOrigin(#[from] InvalidOriginError), #[error(transparent)] Serde(#[from] serde_json::Error), #[error(transparent)] - GetSelectedCredentialError(#[from] GetSelectedCredentialError), + GetSelectedCredential(#[from] GetSelectedCredentialError), #[error("Webauthn error: {0:?}")] Webauthn(WebauthnError), diff --git a/crates/bitwarden-fido/src/client_fido.rs b/crates/bitwarden-fido/src/client_fido.rs index 49af1d10b..6c4cf6786 100644 --- a/crates/bitwarden-fido/src/client_fido.rs +++ b/crates/bitwarden-fido/src/client_fido.rs @@ -15,11 +15,12 @@ pub struct ClientFido2 { #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum DecryptFido2AutofillCredentialsError { #[error(transparent)] VaultLocked(#[from] bitwarden_core::VaultLockedError), #[error(transparent)] - Fido2CredentialAutofillViewError(#[from] Fido2CredentialAutofillViewError), + Fido2CredentialAutofillView(#[from] Fido2CredentialAutofillViewError), } impl ClientFido2 { diff --git a/crates/bitwarden-fido/src/lib.rs b/crates/bitwarden-fido/src/lib.rs index 79a431daa..753a1ef63 100644 --- a/crates/bitwarden-fido/src/lib.rs +++ b/crates/bitwarden-fido/src/lib.rs @@ -78,7 +78,7 @@ impl CipherViewContainer { #[derive(Debug, Error)] pub enum Fido2Error { #[error(transparent)] - DecodeError(#[from] base64::DecodeError), + Decode(#[from] base64::DecodeError), #[error(transparent)] UnknownEnum(#[from] UnknownEnum), @@ -87,7 +87,7 @@ pub enum Fido2Error { InvalidGuid(#[from] InvalidGuid), #[error(transparent)] - PrivateKeyFromSecretKeyError(#[from] PrivateKeyFromSecretKeyError), + PrivateKeyFromSecretKey(#[from] PrivateKeyFromSecretKeyError), #[error("No Fido2 credentials found")] NoFido2CredentialsFound, diff --git a/crates/bitwarden-fido/src/types.rs b/crates/bitwarden-fido/src/types.rs index 1a7a80c61..3bdc1e35a 100644 --- a/crates/bitwarden-fido/src/types.rs +++ b/crates/bitwarden-fido/src/types.rs @@ -58,10 +58,10 @@ pub enum Fido2CredentialAutofillViewError { InvalidGuid(#[from] InvalidGuid), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), #[error(transparent)] - Base64DecodeError(#[from] base64::DecodeError), + Base64Decode(#[from] base64::DecodeError), } impl Fido2CredentialAutofillView { diff --git a/crates/bitwarden-generators/src/passphrase.rs b/crates/bitwarden-generators/src/passphrase.rs index c7921c437..e8aba4139 100644 --- a/crates/bitwarden-generators/src/passphrase.rs +++ b/crates/bitwarden-generators/src/passphrase.rs @@ -10,7 +10,7 @@ use tsify::Tsify; use crate::util::capitalize_first_letter; #[allow(missing_docs)] -#[bitwarden_error(flat)] +#[bitwarden_error(full)] #[derive(Debug, Error)] pub enum PassphraseError { #[error("'num_words' must be between {} and {}", minimum, maximum)] diff --git a/crates/bitwarden-ipc/src/ipc_client.rs b/crates/bitwarden-ipc/src/ipc_client.rs index 43f155631..95495deda 100644 --- a/crates/bitwarden-ipc/src/ipc_client.rs +++ b/crates/bitwarden-ipc/src/ipc_client.rs @@ -127,7 +127,7 @@ pub enum RequestError { Send(String), #[error("Error occured on the remote target: {0}")] - RpcError(#[from] RpcError), + Rpc(#[from] RpcError), } impl IpcClient @@ -313,7 +313,7 @@ where } .try_into() .map_err(|e: serde_utils::DeserializeError| { - RequestError::RpcError(RpcError::RequestSerializationError(e.to_string())) + RequestError::Rpc(RpcError::RequestSerialization(e.to_string())) })?; self.send(message) diff --git a/crates/bitwarden-ipc/src/rpc/error.rs b/crates/bitwarden-ipc/src/rpc/error.rs index eb9ebd5e8..4cce428d2 100644 --- a/crates/bitwarden-ipc/src/rpc/error.rs +++ b/crates/bitwarden-ipc/src/rpc/error.rs @@ -6,16 +6,16 @@ use crate::serde_utils; #[derive(Debug, Error, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum RpcError { #[error("Failed to read request: {0}")] - RequestDeserializationError(String), + RequestDeserialization(String), #[error("Failed to serialize request: {0}")] - RequestSerializationError(String), + RequestSerialization(String), #[error("Failed to read response: {0}")] - ResponseDeserializationError(String), + ResponseDeserialization(String), #[error("Failed to serialize response: {0}")] - ResponseSerializationError(String), + ResponseSerialization(String), #[error("Request could not be completed because no handler has been registered for")] NoHandlerFound, diff --git a/crates/bitwarden-ipc/src/rpc/exec/handler.rs b/crates/bitwarden-ipc/src/rpc/exec/handler.rs index 5c5410588..d9c04c679 100644 --- a/crates/bitwarden-ipc/src/rpc/exec/handler.rs +++ b/crates/bitwarden-ipc/src/rpc/exec/handler.rs @@ -46,21 +46,19 @@ where type Request = T::Request; fn serialize_request(&self, request: Self::Request) -> Result, RpcError> { - serde_utils::to_vec(&request) - .map_err(|e| RpcError::RequestSerializationError(e.to_string())) + serde_utils::to_vec(&request).map_err(|e| RpcError::RequestSerialization(e.to_string())) } fn deserialize_request(&self, request: Vec) -> Result { serde_utils::from_slice(&request) - .map_err(|e| RpcError::RequestDeserializationError(e.to_string())) + .map_err(|e| RpcError::RequestDeserialization(e.to_string())) } fn serialize_response( &self, request: ::Response, ) -> Result, RpcError> { - serde_utils::to_vec(&request) - .map_err(|e| RpcError::ResponseSerializationError(e.to_string())) + serde_utils::to_vec(&request).map_err(|e| RpcError::ResponseSerialization(e.to_string())) } fn deserialize_response( @@ -68,7 +66,7 @@ where request: Vec, ) -> Result<::Response, RpcError> { serde_utils::from_slice(&request) - .map_err(|e| RpcError::ResponseDeserializationError(e.to_string())) + .map_err(|e| RpcError::ResponseDeserialization(e.to_string())) } } diff --git a/crates/bitwarden-ipc/src/rpc/request_message.rs b/crates/bitwarden-ipc/src/rpc/request_message.rs index 8fe4dd07c..3f7c147b6 100644 --- a/crates/bitwarden-ipc/src/rpc/request_message.rs +++ b/crates/bitwarden-ipc/src/rpc/request_message.rs @@ -37,7 +37,7 @@ impl RpcRequestPayload { T: RpcRequest, { serde_utils::from_slice(&self.data) - .map_err(|e| RpcError::RequestDeserializationError(e.to_string())) + .map_err(|e| RpcError::RequestDeserialization(e.to_string())) } } diff --git a/crates/bitwarden-send/src/error.rs b/crates/bitwarden-send/src/error.rs index 6c9ef9788..d224a82ad 100644 --- a/crates/bitwarden-send/src/error.rs +++ b/crates/bitwarden-send/src/error.rs @@ -8,5 +8,5 @@ pub enum SendParseError { #[error(transparent)] Crypto(#[from] bitwarden_crypto::CryptoError), #[error(transparent)] - MissingFieldError(#[from] bitwarden_core::MissingFieldError), + MissingField(#[from] bitwarden_core::MissingFieldError), } diff --git a/crates/bitwarden-send/src/send_client.rs b/crates/bitwarden-send/src/send_client.rs index f703f47f4..f9e413d84 100644 --- a/crates/bitwarden-send/src/send_client.rs +++ b/crates/bitwarden-send/src/send_client.rs @@ -11,6 +11,7 @@ use crate::{Send, SendListView, SendView}; /// Generic error type for send encryption errors. #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum SendEncryptError { #[error(transparent)] Crypto(#[from] bitwarden_crypto::CryptoError), @@ -21,6 +22,7 @@ pub enum SendEncryptError { /// Generic error type for send decryption errors #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum SendDecryptError { #[error(transparent)] Crypto(#[from] bitwarden_crypto::CryptoError), @@ -31,6 +33,7 @@ pub enum SendDecryptError { /// Generic error type for send encryption errors. #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum SendEncryptFileError { #[error(transparent)] Encrypt(#[from] SendEncryptError), @@ -41,6 +44,7 @@ pub enum SendEncryptFileError { /// Generic error type for send decryption errors #[allow(missing_docs)] #[derive(Debug, Error)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))] pub enum SendDecryptFileError { #[error(transparent)] Decrypt(#[from] SendDecryptError), diff --git a/crates/bitwarden-ssh/src/error.rs b/crates/bitwarden-ssh/src/error.rs index 635b7da10..8fb457993 100644 --- a/crates/bitwarden-ssh/src/error.rs +++ b/crates/bitwarden-ssh/src/error.rs @@ -6,9 +6,9 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum KeyGenerationError { #[error("Failed to generate key: {0}")] - KeyGenerationError(ssh_key::Error), + KeyGeneration(ssh_key::Error), #[error("Failed to convert key")] - KeyConversionError, + KeyConversion, } #[allow(missing_docs)] @@ -16,7 +16,7 @@ pub enum KeyGenerationError { #[derive(Error, Debug, PartialEq)] pub enum SshKeyImportError { #[error("Failed to parse key")] - ParsingError, + Parsing, #[error("Password required")] PasswordRequired, #[error("Wrong password")] @@ -30,5 +30,5 @@ pub enum SshKeyImportError { #[derive(Error, Debug, PartialEq)] pub enum SshKeyExportError { #[error("Failed to convert key")] - KeyConversionError, + KeyConversion, } diff --git a/crates/bitwarden-ssh/src/export.rs b/crates/bitwarden-ssh/src/export.rs index 0c4170760..44c0bc3b7 100644 --- a/crates/bitwarden-ssh/src/export.rs +++ b/crates/bitwarden-ssh/src/export.rs @@ -26,27 +26,27 @@ fn convert_rsa_keypair(keypair: &RsaKeypair) -> Result Result, SshKeyExportError> { // Parse the OpenSSH private key let private_key = - PrivateKey::from_openssh(private_key).map_err(|_| SshKeyExportError::KeyConversionError)?; + PrivateKey::from_openssh(private_key).map_err(|_| SshKeyExportError::KeyConversion)?; match private_key.key_data() { ssh_key::private::KeypairData::Ed25519(keypair) => { let sk: ed25519_dalek::SigningKey = keypair .try_into() - .map_err(|_| SshKeyExportError::KeyConversionError)?; + .map_err(|_| SshKeyExportError::KeyConversion)?; Ok(sk .to_pkcs8_der() - .map_err(|_| SshKeyExportError::KeyConversionError)? + .map_err(|_| SshKeyExportError::KeyConversion)? .as_bytes() .to_vec()) } ssh_key::private::KeypairData::Rsa(keypair) => Ok(convert_rsa_keypair(keypair) - .map_err(|_| SshKeyExportError::KeyConversionError)? + .map_err(|_| SshKeyExportError::KeyConversion)? .to_pkcs8_der() - .map_err(|_| SshKeyExportError::KeyConversionError)? + .map_err(|_| SshKeyExportError::KeyConversion)? .as_bytes() .to_vec()), - _ => Err(SshKeyExportError::KeyConversionError), + _ => Err(SshKeyExportError::KeyConversion), } } diff --git a/crates/bitwarden-ssh/src/generator.rs b/crates/bitwarden-ssh/src/generator.rs index 1a95b13bb..fcd16980b 100644 --- a/crates/bitwarden-ssh/src/generator.rs +++ b/crates/bitwarden-ssh/src/generator.rs @@ -36,12 +36,12 @@ fn generate_sshkey_internal( ) -> Result { let private_key = match key_algorithm { KeyAlgorithm::Ed25519 => ssh_key::PrivateKey::random(&mut rng, Algorithm::Ed25519) - .map_err(KeyGenerationError::KeyGenerationError), + .map_err(KeyGenerationError::KeyGeneration), KeyAlgorithm::Rsa3072 => create_rsa_key(&mut rng, 3072), KeyAlgorithm::Rsa4096 => create_rsa_key(&mut rng, 4096), }?; - ssh_private_key_to_view(private_key).map_err(|_| KeyGenerationError::KeyConversionError) + ssh_private_key_to_view(private_key).map_err(|_| KeyGenerationError::KeyConversion) } fn create_rsa_key( @@ -49,10 +49,10 @@ fn create_rsa_key( bits: usize, ) -> Result { let rsa_keypair = ssh_key::private::RsaKeypair::random(&mut rng, bits) - .map_err(KeyGenerationError::KeyGenerationError)?; + .map_err(KeyGenerationError::KeyGeneration)?; let private_key = ssh_key::PrivateKey::new(ssh_key::private::KeypairData::from(rsa_keypair), "") - .map_err(KeyGenerationError::KeyGenerationError)?; + .map_err(KeyGenerationError::KeyGeneration)?; Ok(private_key) } diff --git a/crates/bitwarden-ssh/src/import.rs b/crates/bitwarden-ssh/src/import.rs index e586eb99e..df51dbd72 100644 --- a/crates/bitwarden-ssh/src/import.rs +++ b/crates/bitwarden-ssh/src/import.rs @@ -13,13 +13,13 @@ use crate::{error::SshKeyImportError, ssh_private_key_to_view}; /// - [SshKeyImportError::PasswordRequired] if the key is encrypted and no password is provided /// - [SshKeyImportError::WrongPassword] if the password provided is incorrect /// - [SshKeyImportError::UnsupportedKeyType] if the key type is not supported -/// - [SshKeyImportError::ParsingError] if the key is otherwise malformed and cannot be parsed +/// - [SshKeyImportError::Parsing] if the key is otherwise malformed and cannot be parsed pub fn import_key( encoded_key: String, password: Option, ) -> Result { let label = pem_rfc7468::decode_label(encoded_key.as_bytes()) - .map_err(|_| SshKeyImportError::ParsingError)?; + .map_err(|_| SshKeyImportError::Parsing)?; match label { pkcs8::PrivateKeyInfo::PEM_LABEL => import_pkcs8_key(encoded_key, None), @@ -42,11 +42,11 @@ fn import_pkcs8_key( pkcs8::Error::EncryptedPrivateKey(pkcs5::Error::DecryptFailed) => { SshKeyImportError::WrongPassword } - _ => SshKeyImportError::ParsingError, + _ => SshKeyImportError::Parsing, }, )? } else { - SecretDocument::from_pkcs8_pem(&encoded_key).map_err(|_| SshKeyImportError::ParsingError)? + SecretDocument::from_pkcs8_pem(&encoded_key).map_err(|_| SshKeyImportError::Parsing)? }; import_pkcs8_der_key(doc.as_bytes()) @@ -56,29 +56,29 @@ fn import_pkcs8_key( /// importing SSH keys from other Credential Managers through Credential Exchange. pub fn import_pkcs8_der_key(encoded_key: &[u8]) -> Result { let private_key_info = - PrivateKeyInfo::from_der(encoded_key).map_err(|_| SshKeyImportError::ParsingError)?; + PrivateKeyInfo::from_der(encoded_key).map_err(|_| SshKeyImportError::Parsing)?; let private_key = match private_key_info.algorithm.oid { ed25519::pkcs8::ALGORITHM_OID => { let private_key: ed25519::KeypairBytes = private_key_info .try_into() - .map_err(|_| SshKeyImportError::ParsingError)?; + .map_err(|_| SshKeyImportError::Parsing)?; ssh_key::private::PrivateKey::from(Ed25519Keypair::from(&private_key.secret_key.into())) } rsa::pkcs1::ALGORITHM_OID => { let private_key: rsa::RsaPrivateKey = private_key_info .try_into() - .map_err(|_| SshKeyImportError::ParsingError)?; + .map_err(|_| SshKeyImportError::Parsing)?; ssh_key::private::PrivateKey::from( - RsaKeypair::try_from(private_key).map_err(|_| SshKeyImportError::ParsingError)?, + RsaKeypair::try_from(private_key).map_err(|_| SshKeyImportError::Parsing)?, ) } _ => return Err(SshKeyImportError::UnsupportedKeyType), }; - ssh_private_key_to_view(private_key).map_err(|_| SshKeyImportError::ParsingError) + ssh_private_key_to_view(private_key).map_err(|_| SshKeyImportError::Parsing) } fn import_openssh_key( @@ -90,7 +90,7 @@ fn import_openssh_key( ssh_key::Error::AlgorithmUnknown | ssh_key::Error::AlgorithmUnsupported { .. } => { SshKeyImportError::UnsupportedKeyType } - _ => SshKeyImportError::ParsingError, + _ => SshKeyImportError::Parsing, })?; let private_key = if private_key.is_encrypted() { @@ -102,7 +102,7 @@ fn import_openssh_key( private_key }; - ssh_private_key_to_view(private_key).map_err(|_| SshKeyImportError::ParsingError) + ssh_private_key_to_view(private_key).map_err(|_| SshKeyImportError::Parsing) } #[cfg(test)] @@ -182,7 +182,7 @@ mod tests { #[test] fn import_non_key_error() { let result = import_key("not a key".to_string(), Some("".to_string())); - assert_eq!(result.unwrap_err(), SshKeyImportError::ParsingError); + assert_eq!(result.unwrap_err(), SshKeyImportError::Parsing); } #[test] @@ -207,7 +207,7 @@ mod tests { fn import_key_ed25519_putty() { let private_key = include_str!("../resources/import/ed25519_putty_openssh_unencrypted"); let result = import_key(private_key.to_string(), Some("".to_string())); - assert_eq!(result.unwrap_err(), SshKeyImportError::ParsingError); + assert_eq!(result.unwrap_err(), SshKeyImportError::Parsing); } // Putty-exported keys should be supported, but are not due to a parser incompatibility. @@ -218,7 +218,7 @@ mod tests { fn import_key_rsa_openssh_putty() { let private_key = include_str!("../resources/import/rsa_putty_openssh_unencrypted"); let result = import_key(private_key.to_string(), Some("".to_string())); - assert_eq!(result.unwrap_err(), SshKeyImportError::ParsingError); + assert_eq!(result.unwrap_err(), SshKeyImportError::Parsing); } #[test] diff --git a/crates/bitwarden-ssh/src/lib.rs b/crates/bitwarden-ssh/src/lib.rs index febbf0498..92a9629c5 100644 --- a/crates/bitwarden-ssh/src/lib.rs +++ b/crates/bitwarden-ssh/src/lib.rs @@ -20,7 +20,7 @@ uniffi::setup_scaffolding!(); fn ssh_private_key_to_view(value: PrivateKey) -> Result { let private_key_openssh = value .to_openssh(LineEnding::LF) - .map_err(|_| SshKeyExportError::KeyConversionError)?; + .map_err(|_| SshKeyExportError::KeyConversion)?; Ok(SshKeyView { private_key: private_key_openssh.to_string(), diff --git a/crates/bitwarden-uniffi/kotlin/gradle/wrapper/gradle-wrapper.properties b/crates/bitwarden-uniffi/kotlin/gradle/wrapper/gradle-wrapper.properties index 035ba24e7..b52ceb6d5 100644 --- a/crates/bitwarden-uniffi/kotlin/gradle/wrapper/gradle-wrapper.properties +++ b/crates/bitwarden-uniffi/kotlin/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Jul 24 14:16:42 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/crates/bitwarden-uniffi/src/auth/mod.rs b/crates/bitwarden-uniffi/src/auth/mod.rs index 796596c79..a25e8470b 100644 --- a/crates/bitwarden-uniffi/src/auth/mod.rs +++ b/crates/bitwarden-uniffi/src/auth/mod.rs @@ -5,7 +5,7 @@ use bitwarden_core::auth::{ use bitwarden_crypto::{EncString, HashPurpose, Kdf, TrustDeviceResponse, UnsignedSharedKey}; use bitwarden_encoding::B64; -use crate::error::{Error, Result}; +use crate::error::Result; #[derive(uniffi::Object)] pub struct AuthClient(pub(crate) bitwarden_core::Client); @@ -46,8 +46,7 @@ impl AuthClient { .0 .kdf() .hash_password(email, password, kdf_params, purpose) - .await - .map_err(Error::Crypto)?) + .await?) } /// Generate keys needed for registration process @@ -57,11 +56,7 @@ impl AuthClient { password: String, kdf: Kdf, ) -> Result { - Ok(self - .0 - .auth() - .make_register_keys(email, password, kdf) - .map_err(Error::Crypto)?) + Ok(self.0.auth().make_register_keys(email, password, kdf)?) } /// Generate keys needed for TDE process @@ -74,17 +69,12 @@ impl AuthClient { Ok(self .0 .auth() - .make_register_tde_keys(email, org_public_key, remember_device) - .map_err(Error::EncryptionSettings)?) + .make_register_tde_keys(email, org_public_key, remember_device)?) } /// Generate keys needed to onboard a new user without master key to key connector pub fn make_key_connector_keys(&self) -> Result { - Ok(self - .0 - .auth() - .make_key_connector_keys() - .map_err(Error::Crypto)?) + Ok(self.0.auth().make_key_connector_keys()?) } /// Validate the user password @@ -93,11 +83,7 @@ impl AuthClient { /// `HashPurpose::LocalAuthentication` during login and persist it. If the login method has no /// password, use the email OTP. pub fn validate_password(&self, password: String, password_hash: B64) -> Result { - Ok(self - .0 - .auth() - .validate_password(password, password_hash) - .map_err(Error::AuthValidate)?) + Ok(self.0.auth().validate_password(password, password_hash)?) } /// Validate the user password without knowing the password hash @@ -114,8 +100,7 @@ impl AuthClient { Ok(self .0 .auth() - .validate_password_user_key(password, encrypted_user_key) - .map_err(Error::AuthValidate)?) + .validate_password_user_key(password, encrypted_user_key)?) } /// Validate the user PIN @@ -126,33 +111,21 @@ impl AuthClient { /// This works by comparing the decrypted user key with the current user key, so the client must /// be unlocked. pub fn validate_pin(&self, pin: String, pin_protected_user_key: EncString) -> Result { - Ok(self - .0 - .auth() - .validate_pin(pin, pin_protected_user_key) - .map_err(Error::AuthValidate)?) + Ok(self.0.auth().validate_pin(pin, pin_protected_user_key)?) } /// Initialize a new auth request pub fn new_auth_request(&self, email: String) -> Result { - Ok(self - .0 - .auth() - .new_auth_request(&email) - .map_err(Error::Crypto)?) + Ok(self.0.auth().new_auth_request(&email)?) } /// Approve an auth request pub fn approve_auth_request(&self, public_key: B64) -> Result { - Ok(self - .0 - .auth() - .approve_auth_request(public_key) - .map_err(Error::ApproveAuthRequest)?) + Ok(self.0.auth().approve_auth_request(public_key)?) } /// Trust the current device pub fn trust_device(&self) -> Result { - Ok(self.0.auth().trust_device().map_err(Error::TrustDevice)?) + Ok(self.0.auth().trust_device()?) } } diff --git a/crates/bitwarden-uniffi/src/crypto.rs b/crates/bitwarden-uniffi/src/crypto.rs index 9dc9a87a7..6267cccd4 100644 --- a/crates/bitwarden-uniffi/src/crypto.rs +++ b/crates/bitwarden-uniffi/src/crypto.rs @@ -5,7 +5,7 @@ use bitwarden_core::key_management::crypto::{ use bitwarden_crypto::{EncString, UnsignedSharedKey}; use bitwarden_encoding::B64; -use crate::error::{Error, Result}; +use crate::error::Result; #[allow(missing_docs)] #[derive(uniffi::Object)] @@ -16,63 +16,45 @@ impl CryptoClient { /// Initialization method for the user crypto. Needs to be called before any other crypto /// operations. pub async fn initialize_user_crypto(&self, req: InitUserCryptoRequest) -> Result<()> { - Ok(self - .0 - .initialize_user_crypto(req) - .await - .map_err(Error::EncryptionSettings)?) + Ok(self.0.initialize_user_crypto(req).await?) } /// Initialization method for the organization crypto. Needs to be called after /// `initialize_user_crypto` but before any other crypto operations. pub async fn initialize_org_crypto(&self, req: InitOrgCryptoRequest) -> Result<()> { - Ok(self - .0 - .initialize_org_crypto(req) - .await - .map_err(Error::EncryptionSettings)?) + Ok(self.0.initialize_org_crypto(req).await?) } /// Get the uses's decrypted encryption key. Note: It's very important /// to keep this key safe, as it can be used to decrypt all of the user's data pub async fn get_user_encryption_key(&self) -> Result { - Ok(self - .0 - .get_user_encryption_key() - .await - .map_err(Error::MobileCrypto)?) + Ok(self.0.get_user_encryption_key().await?) } /// Update the user's password, which will re-encrypt the user's encryption key with the new /// password. This returns the new encrypted user key and the new password hash. pub fn update_password(&self, new_password: String) -> Result { - Ok(self - .0 - .update_password(new_password) - .map_err(Error::MobileCrypto)?) + Ok(self.0.update_password(new_password)?) } /// Generates a PIN protected user key from the provided PIN. The result can be stored and later /// used to initialize another client instance by using the PIN and the PIN key with /// `initialize_user_crypto`. pub fn derive_pin_key(&self, pin: String) -> Result { - Ok(self.0.derive_pin_key(pin).map_err(Error::MobileCrypto)?) + Ok(self.0.derive_pin_key(pin)?) } /// Derives the pin protected user key from encrypted pin. Used when pin requires master /// password on first unlock. pub fn derive_pin_user_key(&self, encrypted_pin: EncString) -> Result { - Ok(self - .0 - .derive_pin_user_key(encrypted_pin) - .map_err(Error::MobileCrypto)?) + Ok(self.0.derive_pin_user_key(encrypted_pin)?) } /// Protects the current user key with the provided PIN. The result can be stored and later /// used to initialize another client instance by using the PIN and the PIN key with /// `initialize_user_crypto`. pub fn enroll_pin(&self, pin: String) -> Result { - Ok(self.0.enroll_pin(pin).map_err(Error::MobileCrypto)?) + Ok(self.0.enroll_pin(pin)?) } /// Protects the current user key with the provided PIN. The result can be stored and later @@ -84,22 +66,15 @@ impl CryptoClient { ) -> Result { Ok(self .0 - .enroll_pin_with_encrypted_pin(encrypted_pin.to_string()) - .map_err(Error::MobileCrypto)?) + .enroll_pin_with_encrypted_pin(encrypted_pin.to_string())?) } pub fn enroll_admin_password_reset(&self, public_key: B64) -> Result { - Ok(self - .0 - .enroll_admin_password_reset(public_key) - .map_err(Error::EnrollAdminPasswordReset)?) + Ok(self.0.enroll_admin_password_reset(public_key)?) } /// Derive the master key for migrating to the key connector pub fn derive_key_connector(&self, request: DeriveKeyConnectorRequest) -> Result { - Ok(self - .0 - .derive_key_connector(request) - .map_err(Error::DeriveKeyConnector)?) + Ok(self.0.derive_key_connector(request)?) } } diff --git a/crates/bitwarden-uniffi/src/error.rs b/crates/bitwarden-uniffi/src/error.rs index cccd21e3b..5e0185583 100644 --- a/crates/bitwarden-uniffi/src/error.rs +++ b/crates/bitwarden-uniffi/src/error.rs @@ -3,43 +3,13 @@ use std::fmt::{Display, Formatter}; use bitwarden_exporters::ExportError; use bitwarden_generators::{PassphraseError, PasswordError, UsernameError}; +pub type Result = std::result::Result; +pub type Error = BitwardenError; + // Name is converted from *Error to *Exception, so we can't just name the enum Error because // Exception already exists -#[derive(uniffi::Error, Debug)] -#[uniffi(flat_error)] +#[derive(uniffi::Error, thiserror::Error, Debug)] pub enum BitwardenError { - E(Error), - ConversionError(Box), -} - -impl From for BitwardenError { - fn from(e: Error) -> Self { - Self::E(e) - } -} - -impl Display for BitwardenError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Self::E(e) => Display::fmt(e, f), - Self::ConversionError(e) => Display::fmt(e, f), - } - } -} - -impl std::error::Error for BitwardenError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - BitwardenError::E(e) => Some(e), - BitwardenError::ConversionError(e) => Some(e.as_ref()), - } - } -} - -pub type Result = std::result::Result; - -#[derive(thiserror::Error, Debug)] -pub enum Error { #[error(transparent)] Api(#[from] bitwarden_core::ApiError), #[error(transparent)] @@ -122,4 +92,12 @@ pub enum Error { SshGeneration(#[from] bitwarden_ssh::error::KeyGenerationError), #[error(transparent)] SshImport(#[from] bitwarden_ssh::error::SshKeyImportError), + + ConversionError(String), +} + +impl Display for BitwardenError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + todo!() + } } diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 92e61c759..26401b615 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -3,7 +3,7 @@ uniffi::setup_scaffolding!(); use auth::AuthClient; -use bitwarden_core::ClientSettings; +use bitwarden_core::{auth::AuthValidateError, ClientSettings, WrongPasswordError}; #[allow(missing_docs)] pub mod auth; @@ -103,7 +103,7 @@ impl Client { .await .map_err(|e| Error::Api(e.into()))?; - Ok(res.text().await.map_err(|e| Error::Api(e.into()))?) + res.text().await.map_err(|e| Error::Api(e.into())) } } @@ -129,6 +129,165 @@ fn init_logger() { /// Check [`bitwarden_uniffi_error`] for more details fn setup_error_converter() { bitwarden_uniffi_error::set_error_to_uniffi_error(|e| { - crate::error::BitwardenError::ConversionError(e).into() + crate::error::BitwardenError::ConversionError(e.to_string()).into() }); } + +mod workarounds { + use bitwarden_core::{ + auth::{auth_client::*, *}, + client::encryption_settings::*, + key_management::crypto::*, + platform::*, + ApiError, + }; + use bitwarden_crypto::*; + use bitwarden_exporters::*; + use bitwarden_fido::*; + use bitwarden_generators::*; + use bitwarden_send::*; + use bitwarden_ssh::error::*; + use bitwarden_vault::*; + + #[derive(uniffi::Object)] + pub struct WorkaroundsDoNotUse {} + + #[uniffi::export] + impl WorkaroundsDoNotUse { + pub fn api(&self) -> Result<(), ApiError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn approve_auth_request(&self) -> Result<(), ApproveAuthRequestError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn auth_validate(&self) -> Result<(), AuthValidateError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn cipher(&self) -> Result<(), CipherError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn credentials_for_autofill(&self) -> Result<(), CredentialsForAutofillError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn crypto_client(&self) -> Result<(), CryptoClientError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn crypto(&self) -> Result<(), CryptoError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn decrypt(&self) -> Result<(), DecryptError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn decrypt_fido2_autofill_credentials( + &self, + ) -> Result<(), DecryptFido2AutofillCredentialsError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn decrypt_file(&self) -> Result<(), DecryptFileError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn derive_key_connector(&self) -> Result<(), DeriveKeyConnectorError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn encrypt(&self) -> Result<(), EncryptError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn encrypt_file(&self) -> Result<(), EncryptFileError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn encryption_settings(&self) -> Result<(), EncryptionSettingsError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn enroll_admin_password_reset(&self) -> Result<(), EnrollAdminPasswordResetError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn export(&self) -> Result<(), ExportError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn fido2_client(&self) -> Result<(), Fido2ClientError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn fingerprint(&self) -> Result<(), FingerprintError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn get_assertion(&self) -> Result<(), GetAssertionError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn key_generation(&self) -> Result<(), KeyGenerationError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn make_credential(&self) -> Result<(), MakeCredentialError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn passphrase(&self) -> Result<(), PassphraseError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn password(&self) -> Result<(), PasswordError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn send_decrypt(&self) -> Result<(), SendDecryptError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn send_decrypt_file(&self) -> Result<(), SendDecryptFileError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn send_encrypt(&self) -> Result<(), SendEncryptError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn send_encrypt_file(&self) -> Result<(), SendEncryptFileError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn silently_discover_credentials( + &self, + ) -> Result<(), SilentlyDiscoverCredentialsError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn ssh_key_import(&self) -> Result<(), SshKeyImportError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn totp(&self) -> Result<(), TotpError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn trust_device(&self) -> Result<(), TrustDeviceError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn user_fingerprint(&self) -> Result<(), UserFingerprintError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + + pub fn username(&self) -> Result<(), UsernameError> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + } +} diff --git a/crates/bitwarden-uniffi/src/platform/mod.rs b/crates/bitwarden-uniffi/src/platform/mod.rs index 798307967..ad72af094 100644 --- a/crates/bitwarden-uniffi/src/platform/mod.rs +++ b/crates/bitwarden-uniffi/src/platform/mod.rs @@ -5,7 +5,7 @@ use bitwarden_fido::ClientFido2Ext; use bitwarden_vault::Cipher; use repository::UniffiRepositoryBridge; -use crate::error::{Error, Result}; +use crate::error::Result; mod fido2; mod repository; @@ -17,20 +17,12 @@ pub struct PlatformClient(pub(crate) bitwarden_core::Client); impl PlatformClient { /// Fingerprint (public key) pub fn fingerprint(&self, req: FingerprintRequest) -> Result { - Ok(self - .0 - .platform() - .fingerprint(&req) - .map_err(Error::Fingerprint)?) + Ok(self.0.platform().fingerprint(&req)?) } /// Fingerprint using logged in user's public key pub fn user_fingerprint(&self, fingerprint_material: String) -> Result { - Ok(self - .0 - .platform() - .user_fingerprint(fingerprint_material) - .map_err(Error::UserFingerprint)?) + Ok(self.0.platform().user_fingerprint(fingerprint_material)?) } /// Load feature flags into the client diff --git a/crates/bitwarden-uniffi/src/platform/repository.rs b/crates/bitwarden-uniffi/src/platform/repository.rs index 73036fe75..cfe93726d 100644 --- a/crates/bitwarden-uniffi/src/platform/repository.rs +++ b/crates/bitwarden-uniffi/src/platform/repository.rs @@ -15,7 +15,6 @@ impl std::fmt::Debug for UniffiRepositoryBridge { } #[derive(uniffi::Error, thiserror::Error, Debug)] -#[uniffi(flat_error)] pub enum RepositoryError { #[error("Internal error: {0}")] Internal(String), @@ -64,12 +63,7 @@ macro_rules! create_uniffi_repository { async fn has( &self, id: String, - ) -> Result { - match self.get(id).await { - Ok(x) => Ok(x.is_some()), - Err(e) => Err(e), - } - } + ) -> Result; } #[async_trait::async_trait] diff --git a/crates/bitwarden-uniffi/src/tool/mod.rs b/crates/bitwarden-uniffi/src/tool/mod.rs index dc6a168b1..fcd0906c7 100644 --- a/crates/bitwarden-uniffi/src/tool/mod.rs +++ b/crates/bitwarden-uniffi/src/tool/mod.rs @@ -5,7 +5,7 @@ use bitwarden_generators::{ }; use bitwarden_vault::{Cipher, Folder}; -use crate::error::{Error, Result}; +use crate::error::Result; mod sends; pub use sends::SendClient; @@ -20,17 +20,17 @@ pub struct GeneratorClients(pub(crate) bitwarden_generators::GeneratorClient); impl GeneratorClients { /// Generate Password pub fn password(&self, settings: PasswordGeneratorRequest) -> Result { - Ok(self.0.password(settings).map_err(Error::Password)?) + Ok(self.0.password(settings)?) } /// Generate Passphrase pub fn passphrase(&self, settings: PassphraseGeneratorRequest) -> Result { - Ok(self.0.passphrase(settings).map_err(Error::Passphrase)?) + Ok(self.0.passphrase(settings)?) } /// Generate Username pub async fn username(&self, settings: UsernameGeneratorRequest) -> Result { - Ok(self.0.username(settings).await.map_err(Error::Username)?) + Ok(self.0.username(settings).await?) } } @@ -46,10 +46,7 @@ impl ExporterClient { ciphers: Vec, format: ExportFormat, ) -> Result { - Ok(self - .0 - .export_vault(folders, ciphers, format) - .map_err(Error::Export)?) + Ok(self.0.export_vault(folders, ciphers, format)?) } /// Export organization vault @@ -61,8 +58,7 @@ impl ExporterClient { ) -> Result { Ok(self .0 - .export_organization_vault(collections, ciphers, format) - .map_err(Error::Export)?) + .export_organization_vault(collections, ciphers, format)?) } /// Credential Exchange Format (CXF) @@ -72,7 +68,7 @@ impl ExporterClient { /// For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager). /// Ideally the output should be immediately deserialized to [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount). pub fn export_cxf(&self, account: Account, ciphers: Vec) -> Result { - Ok(self.0.export_cxf(account, ciphers).map_err(Error::Export)?) + Ok(self.0.export_cxf(account, ciphers)?) } /// Credential Exchange Format (CXF) @@ -82,6 +78,6 @@ impl ExporterClient { /// For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager). /// Ideally the input should be immediately serialized from [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount). pub fn import_cxf(&self, payload: String) -> Result> { - Ok(self.0.import_cxf(payload).map_err(Error::Export)?) + Ok(self.0.import_cxf(payload)?) } } diff --git a/crates/bitwarden-uniffi/src/tool/sends.rs b/crates/bitwarden-uniffi/src/tool/sends.rs index b2e104243..6be523ea5 100644 --- a/crates/bitwarden-uniffi/src/tool/sends.rs +++ b/crates/bitwarden-uniffi/src/tool/sends.rs @@ -2,7 +2,7 @@ use std::path::Path; use bitwarden_send::{Send, SendListView, SendView}; -use crate::{error::Error, Result}; +use crate::Result; #[derive(uniffi::Object)] pub struct SendClient(pub(crate) bitwarden_send::SendClient); @@ -11,15 +11,12 @@ pub struct SendClient(pub(crate) bitwarden_send::SendClient); impl SendClient { /// Encrypt send pub fn encrypt(&self, send: SendView) -> Result { - Ok(self.0.encrypt(send).map_err(Error::SendEncrypt)?) + Ok(self.0.encrypt(send)?) } /// Encrypt a send file in memory pub fn encrypt_buffer(&self, send: Send, buffer: Vec) -> Result> { - Ok(self - .0 - .encrypt_buffer(send, &buffer) - .map_err(Error::SendEncrypt)?) + Ok(self.0.encrypt_buffer(send, &buffer)?) } /// Encrypt a send file located in the file system @@ -29,32 +26,26 @@ impl SendClient { decrypted_file_path: String, encrypted_file_path: String, ) -> Result<()> { - Ok(self - .0 - .encrypt_file( - send, - Path::new(&decrypted_file_path), - Path::new(&encrypted_file_path), - ) - .map_err(Error::SendEncryptFile)?) + Ok(self.0.encrypt_file( + send, + Path::new(&decrypted_file_path), + Path::new(&encrypted_file_path), + )?) } /// Decrypt send pub fn decrypt(&self, send: Send) -> Result { - Ok(self.0.decrypt(send).map_err(Error::SendDecrypt)?) + Ok(self.0.decrypt(send)?) } /// Decrypt send list pub fn decrypt_list(&self, sends: Vec) -> Result> { - Ok(self.0.decrypt_list(sends).map_err(Error::SendDecrypt)?) + Ok(self.0.decrypt_list(sends)?) } /// Decrypt a send file in memory pub fn decrypt_buffer(&self, send: Send, buffer: Vec) -> Result> { - Ok(self - .0 - .decrypt_buffer(send, &buffer) - .map_err(Error::SendDecrypt)?) + Ok(self.0.decrypt_buffer(send, &buffer)?) } /// Decrypt a send file located in the file system @@ -64,13 +55,10 @@ impl SendClient { encrypted_file_path: String, decrypted_file_path: String, ) -> Result<()> { - Ok(self - .0 - .decrypt_file( - send, - Path::new(&encrypted_file_path), - Path::new(&decrypted_file_path), - ) - .map_err(Error::SendDecryptFile)?) + Ok(self.0.decrypt_file( + send, + Path::new(&encrypted_file_path), + Path::new(&decrypted_file_path), + )?) } } diff --git a/crates/bitwarden-uniffi/src/tool/ssh.rs b/crates/bitwarden-uniffi/src/tool/ssh.rs index fdb188e62..42a71011c 100644 --- a/crates/bitwarden-uniffi/src/tool/ssh.rs +++ b/crates/bitwarden-uniffi/src/tool/ssh.rs @@ -1,9 +1,6 @@ use bitwarden_vault::SshKeyView; -use crate::{ - error::{BitwardenError, Error}, - Result, -}; +use crate::Result; #[derive(uniffi::Object)] pub struct SshClient(); @@ -14,8 +11,7 @@ impl SshClient { &self, key_algorithm: bitwarden_ssh::generator::KeyAlgorithm, ) -> Result { - bitwarden_ssh::generator::generate_sshkey(key_algorithm) - .map_err(|e| BitwardenError::E(Error::SshGeneration(e))) + bitwarden_ssh::generator::generate_sshkey(key_algorithm).map_err(Into::into) } pub fn import_ssh_key( @@ -23,7 +19,6 @@ impl SshClient { imported_key: String, password: Option, ) -> Result { - bitwarden_ssh::import::import_key(imported_key, password) - .map_err(|e| BitwardenError::E(Error::SshImport(e))) + bitwarden_ssh::import::import_key(imported_key, password).map_err(Into::into) } } diff --git a/crates/bitwarden-uniffi/src/vault/attachments.rs b/crates/bitwarden-uniffi/src/vault/attachments.rs index 98ffc1a67..095809c80 100644 --- a/crates/bitwarden-uniffi/src/vault/attachments.rs +++ b/crates/bitwarden-uniffi/src/vault/attachments.rs @@ -2,7 +2,7 @@ use std::path::Path; use bitwarden_vault::{Attachment, AttachmentEncryptResult, AttachmentView, Cipher}; -use crate::{error::Error, Result}; +use crate::Result; #[derive(uniffi::Object)] pub struct AttachmentsClient(pub(crate) bitwarden_vault::AttachmentsClient); @@ -16,10 +16,7 @@ impl AttachmentsClient { attachment: AttachmentView, buffer: Vec, ) -> Result { - Ok(self - .0 - .encrypt_buffer(cipher, attachment, &buffer) - .map_err(Error::Encrypt)?) + Ok(self.0.encrypt_buffer(cipher, attachment, &buffer)?) } /// Encrypt an attachment file located in the file system @@ -30,15 +27,12 @@ impl AttachmentsClient { decrypted_file_path: String, encrypted_file_path: String, ) -> Result { - Ok(self - .0 - .encrypt_file( - cipher, - attachment, - Path::new(&decrypted_file_path), - Path::new(&encrypted_file_path), - ) - .map_err(Error::EncryptFile)?) + Ok(self.0.encrypt_file( + cipher, + attachment, + Path::new(&decrypted_file_path), + Path::new(&encrypted_file_path), + )?) } /// Decrypt an attachment file in memory pub fn decrypt_buffer( @@ -47,10 +41,7 @@ impl AttachmentsClient { attachment: AttachmentView, buffer: Vec, ) -> Result> { - Ok(self - .0 - .decrypt_buffer(cipher, attachment, &buffer) - .map_err(Error::Decrypt)?) + Ok(self.0.decrypt_buffer(cipher, attachment, &buffer)?) } /// Decrypt an attachment file located in the file system @@ -61,14 +52,11 @@ impl AttachmentsClient { encrypted_file_path: String, decrypted_file_path: String, ) -> Result<()> { - Ok(self - .0 - .decrypt_file( - cipher, - attachment, - Path::new(&encrypted_file_path), - Path::new(&decrypted_file_path), - ) - .map_err(Error::DecryptFile)?) + Ok(self.0.decrypt_file( + cipher, + attachment, + Path::new(&encrypted_file_path), + Path::new(&decrypted_file_path), + )?) } } diff --git a/crates/bitwarden-uniffi/src/vault/ciphers.rs b/crates/bitwarden-uniffi/src/vault/ciphers.rs index ee55302a0..6508558eb 100644 --- a/crates/bitwarden-uniffi/src/vault/ciphers.rs +++ b/crates/bitwarden-uniffi/src/vault/ciphers.rs @@ -4,7 +4,7 @@ use bitwarden_vault::{ Fido2CredentialView, }; -use crate::{error::Error, Result}; +use crate::Result; #[allow(missing_docs)] #[derive(uniffi::Object)] @@ -14,17 +14,17 @@ pub struct CiphersClient(pub(crate) bitwarden_vault::CiphersClient); impl CiphersClient { /// Encrypt cipher pub fn encrypt(&self, cipher_view: CipherView) -> Result { - Ok(self.0.encrypt(cipher_view).map_err(Error::Encrypt)?) + Ok(self.0.encrypt(cipher_view)?) } /// Decrypt cipher pub fn decrypt(&self, cipher: Cipher) -> Result { - Ok(self.0.decrypt(cipher).map_err(Error::Decrypt)?) + Ok(self.0.decrypt(cipher)?) } /// Decrypt cipher list pub fn decrypt_list(&self, ciphers: Vec) -> Result> { - Ok(self.0.decrypt_list(ciphers).map_err(Error::Decrypt)?) + Ok(self.0.decrypt_list(ciphers)?) } /// Decrypt cipher list with failures @@ -42,10 +42,7 @@ impl CiphersClient { &self, cipher_view: CipherView, ) -> Result> { - Ok(self - .0 - .decrypt_fido2_credentials(cipher_view) - .map_err(Error::Decrypt)?) + Ok(self.0.decrypt_fido2_credentials(cipher_view)?) } /// Move a cipher to an organization, reencrypting the cipher key if necessary @@ -54,9 +51,6 @@ impl CiphersClient { cipher: CipherView, organization_id: OrganizationId, ) -> Result { - Ok(self - .0 - .move_to_organization(cipher, organization_id) - .map_err(Error::Cipher)?) + Ok(self.0.move_to_organization(cipher, organization_id)?) } } diff --git a/crates/bitwarden-uniffi/src/vault/collections.rs b/crates/bitwarden-uniffi/src/vault/collections.rs index 77eb381f6..26e307ffc 100644 --- a/crates/bitwarden-uniffi/src/vault/collections.rs +++ b/crates/bitwarden-uniffi/src/vault/collections.rs @@ -6,7 +6,7 @@ use bitwarden_collections::{ }; use uuid::Uuid; -use crate::{error::Error, Result}; +use crate::Result; #[allow(missing_docs)] #[derive(uniffi::Object)] @@ -16,12 +16,12 @@ pub struct CollectionsClient(pub(crate) bitwarden_vault::collection_client::Coll impl CollectionsClient { /// Decrypt collection pub fn decrypt(&self, collection: Collection) -> Result { - Ok(self.0.decrypt(collection).map_err(Error::Decrypt)?) + Ok(self.0.decrypt(collection)?) } /// Decrypt collection list pub fn decrypt_list(&self, collections: Vec) -> Result> { - Ok(self.0.decrypt_list(collections).map_err(Error::Decrypt)?) + Ok(self.0.decrypt_list(collections)?) } /// diff --git a/crates/bitwarden-uniffi/src/vault/folders.rs b/crates/bitwarden-uniffi/src/vault/folders.rs index 18a108cfd..1273e06bb 100644 --- a/crates/bitwarden-uniffi/src/vault/folders.rs +++ b/crates/bitwarden-uniffi/src/vault/folders.rs @@ -1,6 +1,6 @@ use bitwarden_vault::{Folder, FolderView}; -use crate::{error::Error, Result}; +use crate::Result; #[allow(missing_docs)] #[derive(uniffi::Object)] @@ -10,16 +10,16 @@ pub struct FoldersClient(pub(crate) bitwarden_vault::FoldersClient); impl FoldersClient { /// Encrypt folder pub fn encrypt(&self, folder: FolderView) -> Result { - Ok(self.0.encrypt(folder).map_err(Error::Encrypt)?) + Ok(self.0.encrypt(folder)?) } /// Decrypt folder pub fn decrypt(&self, folder: Folder) -> Result { - Ok(self.0.decrypt(folder).map_err(Error::Decrypt)?) + Ok(self.0.decrypt(folder)?) } /// Decrypt folder list pub fn decrypt_list(&self, folders: Vec) -> Result> { - Ok(self.0.decrypt_list(folders).map_err(Error::Decrypt)?) + Ok(self.0.decrypt_list(folders)?) } } diff --git a/crates/bitwarden-uniffi/src/vault/mod.rs b/crates/bitwarden-uniffi/src/vault/mod.rs index ba7c5b1e5..ec5d83187 100644 --- a/crates/bitwarden-uniffi/src/vault/mod.rs +++ b/crates/bitwarden-uniffi/src/vault/mod.rs @@ -1,7 +1,7 @@ use bitwarden_vault::{CipherListView, TotpResponse}; use chrono::{DateTime, Utc}; -use crate::error::{Error, Result}; +use crate::error::Result; #[allow(missing_docs)] pub mod attachments; @@ -52,11 +52,7 @@ impl VaultClient { /// - OTP Auth URI /// - Steam URI pub fn generate_totp(&self, key: String, time: Option>) -> Result { - Ok(self - .0 - .totp() - .generate_totp(key, time) - .map_err(Error::Totp)?) + Ok(self.0.totp().generate_totp(key, time)?) } /// Generate a TOTP code from a provided cipher list view. @@ -65,10 +61,6 @@ impl VaultClient { view: CipherListView, time: Option>, ) -> Result { - Ok(self - .0 - .totp() - .generate_totp_cipher_view(view, time) - .map_err(Error::Totp)?) + Ok(self.0.totp().generate_totp_cipher_view(view, time)?) } } diff --git a/crates/bitwarden-uniffi/src/vault/password_history.rs b/crates/bitwarden-uniffi/src/vault/password_history.rs index 4aeece64a..61f533b51 100644 --- a/crates/bitwarden-uniffi/src/vault/password_history.rs +++ b/crates/bitwarden-uniffi/src/vault/password_history.rs @@ -1,6 +1,6 @@ use bitwarden_vault::{PasswordHistory, PasswordHistoryView}; -use crate::{error::Error, Result}; +use crate::Result; #[allow(missing_docs)] #[derive(uniffi::Object)] @@ -10,11 +10,11 @@ pub struct PasswordHistoryClient(pub(crate) bitwarden_vault::PasswordHistoryClie impl PasswordHistoryClient { /// Encrypt password history pub fn encrypt(&self, password_history: PasswordHistoryView) -> Result { - Ok(self.0.encrypt(password_history).map_err(Error::Encrypt)?) + Ok(self.0.encrypt(password_history)?) } /// Decrypt password history pub fn decrypt_list(&self, list: Vec) -> Result> { - Ok(self.0.decrypt_list(list).map_err(Error::Decrypt)?) + Ok(self.0.decrypt_list(list)?) } } diff --git a/crates/bitwarden-vault/src/cipher/cipher.rs b/crates/bitwarden-vault/src/cipher/cipher.rs index cc96a028e..e854b52a1 100644 --- a/crates/bitwarden-vault/src/cipher/cipher.rs +++ b/crates/bitwarden-vault/src/cipher/cipher.rs @@ -40,13 +40,13 @@ uuid_newtype!(pub CipherId); #[derive(Debug, Error)] pub enum CipherError { #[error(transparent)] - MissingFieldError(#[from] MissingFieldError), + MissingField(#[from] MissingFieldError), #[error(transparent)] VaultLocked(#[from] VaultLockedError), #[error(transparent)] - CryptoError(#[from] CryptoError), + Crypto(#[from] CryptoError), #[error(transparent)] - EncryptError(#[from] EncryptError), + Encrypt(#[from] EncryptError), #[error("This cipher contains attachments without keys. Those attachments will need to be reuploaded to complete the operation")] AttachmentsWithoutKeys, } diff --git a/crates/bitwarden-vault/src/error.rs b/crates/bitwarden-vault/src/error.rs index e014da04a..cf4b63177 100644 --- a/crates/bitwarden-vault/src/error.rs +++ b/crates/bitwarden-vault/src/error.rs @@ -33,5 +33,5 @@ pub enum VaultParseError { #[error(transparent)] Crypto(#[from] bitwarden_crypto::CryptoError), #[error(transparent)] - MissingFieldError(#[from] bitwarden_core::MissingFieldError), + MissingField(#[from] bitwarden_core::MissingFieldError), } From b5b94ce7f704c9e2fc543a4cdc588dfa59c63c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 19:02:25 +0200 Subject: [PATCH 02/13] Document and simplify workaround --- crates/bitwarden-core/src/uniffi_support.rs | 2 + crates/bitwarden-uniffi/src/lib.rs | 193 ++++++-------------- 2 files changed, 58 insertions(+), 137 deletions(-) diff --git a/crates/bitwarden-core/src/uniffi_support.rs b/crates/bitwarden-core/src/uniffi_support.rs index 80ceebe32..79d6c9136 100644 --- a/crates/bitwarden-core/src/uniffi_support.rs +++ b/crates/bitwarden-core/src/uniffi_support.rs @@ -47,6 +47,8 @@ mod workarounds { #[derive(uniffi::Object)] pub struct WorkaroundsCoreDoNotUse {} + /// Workaround for invalid code generation when an error type is not used directly by the crate. + /// See the comment in `bitwarden-uniffi/src/lib.rs` for more details. #[uniffi::export] impl WorkaroundsCoreDoNotUse { pub fn crypto(&self) -> Result<(), CryptoError> { diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 26401b615..8fd59bf5f 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -152,142 +152,61 @@ mod workarounds { #[derive(uniffi::Object)] pub struct WorkaroundsDoNotUse {} - #[uniffi::export] - impl WorkaroundsDoNotUse { - pub fn api(&self) -> Result<(), ApiError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn approve_auth_request(&self) -> Result<(), ApproveAuthRequestError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn auth_validate(&self) -> Result<(), AuthValidateError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn cipher(&self) -> Result<(), CipherError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn credentials_for_autofill(&self) -> Result<(), CredentialsForAutofillError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn crypto_client(&self) -> Result<(), CryptoClientError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn crypto(&self) -> Result<(), CryptoError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn decrypt(&self) -> Result<(), DecryptError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn decrypt_fido2_autofill_credentials( - &self, - ) -> Result<(), DecryptFido2AutofillCredentialsError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn decrypt_file(&self) -> Result<(), DecryptFileError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn derive_key_connector(&self) -> Result<(), DeriveKeyConnectorError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn encrypt(&self) -> Result<(), EncryptError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn encrypt_file(&self) -> Result<(), EncryptFileError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn encryption_settings(&self) -> Result<(), EncryptionSettingsError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn enroll_admin_password_reset(&self) -> Result<(), EnrollAdminPasswordResetError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn export(&self) -> Result<(), ExportError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn fido2_client(&self) -> Result<(), Fido2ClientError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn fingerprint(&self) -> Result<(), FingerprintError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn get_assertion(&self) -> Result<(), GetAssertionError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn key_generation(&self) -> Result<(), KeyGenerationError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn make_credential(&self) -> Result<(), MakeCredentialError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn passphrase(&self) -> Result<(), PassphraseError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn password(&self) -> Result<(), PasswordError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn send_decrypt(&self) -> Result<(), SendDecryptError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn send_decrypt_file(&self) -> Result<(), SendDecryptFileError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn send_encrypt(&self) -> Result<(), SendEncryptError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn send_encrypt_file(&self) -> Result<(), SendEncryptFileError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn silently_discover_credentials( - &self, - ) -> Result<(), SilentlyDiscoverCredentialsError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn ssh_key_import(&self) -> Result<(), SshKeyImportError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn totp(&self) -> Result<(), TotpError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn trust_device(&self) -> Result<(), TrustDeviceError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn user_fingerprint(&self) -> Result<(), UserFingerprintError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - - pub fn username(&self) -> Result<(), UsernameError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } + /// UniFFI is not generating the correct code when an Error type is only used as part of another + /// Error, instead of directly by the crate. This is an open issue in UniFFI, and the current + /// workaround is to have a dummy function that uses each error type directly as an error. Open + /// issue: https://github.com/mozilla/uniffi-rs/issues/2636 + /// + /// This also needs to be done in crates that also use error types from different crates. In + /// those cases, a workaround like this needs to be added to their uniffi_support.rs file as + /// well. Currently this is also the case for bitwarden-core. + macro_rules! workaround_fns { + ( $( $ty:ident )+ ) => { + $( + #[uniffi::export] + impl WorkaroundsDoNotUse { + #[allow(non_snake_case)] + pub fn $ty(&self) -> Result<(), $ty> { + panic!("Do not use this function, it is only here to work around a uniffi limitation"); + } + } + )+ + }; } + + workaround_fns!( + ApiError + ApproveAuthRequestError + AuthValidateError + CipherError + CredentialsForAutofillError + CryptoClientError + CryptoError + DecryptError + DecryptFido2AutofillCredentialsError + DecryptFileError + DeriveKeyConnectorError + EncryptError + EncryptFileError + EncryptionSettingsError + EnrollAdminPasswordResetError + ExportError + Fido2ClientError + FingerprintError + GetAssertionError + KeyGenerationError + MakeCredentialError + PassphraseError + PasswordError + SendDecryptError + SendDecryptFileError + SendEncryptError + SendEncryptFileError + SilentlyDiscoverCredentialsError + SshKeyImportError + TotpError + TrustDeviceError + UserFingerprintError + UsernameError + ); } From 18b987e372fb3eb790ced1bb534a9ad879c42d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 19:21:06 +0200 Subject: [PATCH 03/13] Allow features lint --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c64a9b424..bce55b1de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,10 @@ string_slice = "warn" [workspace.lints.rust] missing_docs = "warn" +unexpected_cfgs = { level = "warn", check-cfg = [ + 'cfg(feature, values("uniffi", "wasm"))', +] } + # Compile all dependencies with some optimizations when building this crate on debug # This slows down clean builds by about 50%, but the resulting binaries can be orders of magnitude faster From 6d7e1e3e2ba1d681578bf743f0d7a5dc8733e82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 19:26:26 +0200 Subject: [PATCH 04/13] Fix lints --- crates/bitwarden-uniffi/src/error.rs | 9 +-------- crates/bitwarden-uniffi/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/bitwarden-uniffi/src/error.rs b/crates/bitwarden-uniffi/src/error.rs index 5e0185583..fbc6f812e 100644 --- a/crates/bitwarden-uniffi/src/error.rs +++ b/crates/bitwarden-uniffi/src/error.rs @@ -1,5 +1,3 @@ -use std::fmt::{Display, Formatter}; - use bitwarden_exporters::ExportError; use bitwarden_generators::{PassphraseError, PasswordError, UsernameError}; @@ -93,11 +91,6 @@ pub enum BitwardenError { #[error(transparent)] SshImport(#[from] bitwarden_ssh::error::SshKeyImportError), + #[error("A conversion error occurred: {0}")] ConversionError(String), } - -impl Display for BitwardenError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - todo!() - } -} diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 8fd59bf5f..fbdc9c585 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -3,7 +3,7 @@ uniffi::setup_scaffolding!(); use auth::AuthClient; -use bitwarden_core::{auth::AuthValidateError, ClientSettings, WrongPasswordError}; +use bitwarden_core::ClientSettings; #[allow(missing_docs)] pub mod auth; From b9b41d7b799e505b12ebb080d9e2349413841978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 19:34:12 +0200 Subject: [PATCH 05/13] cargo sort --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bce55b1de..6fd1e1d43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,6 @@ unexpected_cfgs = { level = "warn", check-cfg = [ 'cfg(feature, values("uniffi", "wasm"))', ] } - # Compile all dependencies with some optimizations when building this crate on debug # This slows down clean builds by about 50%, but the resulting binaries can be orders of magnitude faster # As clean builds won't occur very often, this won't slow down the development process From fbaa3a09c4c45dc8de6d730fa990ac217bfedb3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 3 Sep 2025 19:42:07 +0200 Subject: [PATCH 06/13] fix url --- crates/bitwarden-uniffi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index fbdc9c585..048429269 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -155,7 +155,7 @@ mod workarounds { /// UniFFI is not generating the correct code when an Error type is only used as part of another /// Error, instead of directly by the crate. This is an open issue in UniFFI, and the current /// workaround is to have a dummy function that uses each error type directly as an error. Open - /// issue: https://github.com/mozilla/uniffi-rs/issues/2636 + /// issue: /// /// This also needs to be done in crates that also use error types from different crates. In /// those cases, a workaround like this needs to be added to their uniffi_support.rs file as From 8a5beb978ac907aaa16f14dbbf06ed66df15c74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Thu, 4 Sep 2025 16:34:18 +0200 Subject: [PATCH 07/13] Use uniffi in state --- Cargo.lock | 1 + crates/bitwarden-state/Cargo.toml | 3 ++- crates/bitwarden-state/src/lib.rs | 3 +++ crates/bitwarden-state/uniffi.toml | 9 +++++++++ crates/bitwarden-uniffi/src/lib.rs | 2 ++ crates/bitwarden-uniffi/src/platform/mod.rs | 4 ++-- 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 crates/bitwarden-state/uniffi.toml diff --git a/Cargo.lock b/Cargo.lock index 33c1087fd..2ae9e828a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,6 +718,7 @@ dependencies = [ "thiserror 2.0.12", "tokio", "tsify", + "uniffi", ] [[package]] diff --git a/crates/bitwarden-state/Cargo.toml b/crates/bitwarden-state/Cargo.toml index c1c548792..8aaff7351 100644 --- a/crates/bitwarden-state/Cargo.toml +++ b/crates/bitwarden-state/Cargo.toml @@ -10,7 +10,7 @@ license-file.workspace = true keywords.workspace = true [features] -uniffi = [] +uniffi = ["dep:uniffi"] wasm = ["bitwarden-threading/wasm"] [dependencies] @@ -29,6 +29,7 @@ tsify = { workspace = true } [target.'cfg(not(target_arch="wasm32"))'.dependencies] rusqlite = { version = ">=0.37.0, <0.38", features = ["bundled"] } +uniffi = { workspace = true, optional = true } [dev-dependencies] tokio = { workspace = true, features = ["rt"] } diff --git a/crates/bitwarden-state/src/lib.rs b/crates/bitwarden-state/src/lib.rs index ec172cdd1..869d91ced 100644 --- a/crates/bitwarden-state/src/lib.rs +++ b/crates/bitwarden-state/src/lib.rs @@ -1,5 +1,8 @@ #![doc = include_str!("../README.md")] +#[cfg(feature = "uniffi")] +uniffi::setup_scaffolding!(); + /// This module provides a generic repository interface for storing and retrieving items. pub mod repository; diff --git a/crates/bitwarden-state/uniffi.toml b/crates/bitwarden-state/uniffi.toml new file mode 100644 index 000000000..7fc034f1d --- /dev/null +++ b/crates/bitwarden-state/uniffi.toml @@ -0,0 +1,9 @@ +[bindings.kotlin] +package_name = "com.bitwarden.state" +generate_immutable_records = true +android = true + +[bindings.swift] +ffi_module_name = "BitwardenStateFFI" +module_name = "BitwardenState" +generate_immutable_records = true diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 048429269..c77c52c5a 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -147,6 +147,7 @@ mod workarounds { use bitwarden_generators::*; use bitwarden_send::*; use bitwarden_ssh::error::*; + use bitwarden_state::registry::*; use bitwarden_vault::*; #[derive(uniffi::Object)] @@ -204,6 +205,7 @@ mod workarounds { SendEncryptFileError SilentlyDiscoverCredentialsError SshKeyImportError + StateRegistryError TotpError TrustDeviceError UserFingerprintError diff --git a/crates/bitwarden-uniffi/src/platform/mod.rs b/crates/bitwarden-uniffi/src/platform/mod.rs index 5f2d34800..1f23941d9 100644 --- a/crates/bitwarden-uniffi/src/platform/mod.rs +++ b/crates/bitwarden-uniffi/src/platform/mod.rs @@ -70,8 +70,8 @@ impl StateClient { .platform() .state() .initialize_database(configuration.into(), sdk_managed_repositories) - .await - .map_err(Error::StateRegistry)?; + .await?; + Ok(()) } } From e1cb692640563788eb90debdf18855b6729df7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 17 Sep 2025 14:13:32 +0200 Subject: [PATCH 08/13] Missed one --- crates/bitwarden-uniffi/src/crypto.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bitwarden-uniffi/src/crypto.rs b/crates/bitwarden-uniffi/src/crypto.rs index e85047b63..d43881ed0 100644 --- a/crates/bitwarden-uniffi/src/crypto.rs +++ b/crates/bitwarden-uniffi/src/crypto.rs @@ -92,9 +92,6 @@ impl CryptoClient { /// re-encrypted for the password under the new kdf settings. This returns the new encrypted /// user key and the new password hash but does not update sdk state. pub fn make_update_kdf(&self, password: String, kdf: Kdf) -> Result { - Ok(self - .0 - .make_update_kdf(password, kdf) - .map_err(Error::MobileCrypto)?) + Ok(self.0.make_update_kdf(password, kdf)?) } } From 3c90c0c258650535ff8bdb9a58bb128f0236e0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 17 Sep 2025 14:18:58 +0200 Subject: [PATCH 09/13] Missed uniffi for auth --- crates/bitwarden-auth/src/lib.rs | 3 +++ crates/bitwarden-auth/uniffi.toml | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 crates/bitwarden-auth/uniffi.toml diff --git a/crates/bitwarden-auth/src/lib.rs b/crates/bitwarden-auth/src/lib.rs index 380f97d13..d0abae41f 100644 --- a/crates/bitwarden-auth/src/lib.rs +++ b/crates/bitwarden-auth/src/lib.rs @@ -1,5 +1,8 @@ #![doc = include_str!("../README.md")] +#[cfg(feature = "uniffi")] +uniffi::setup_scaffolding!(); + mod auth_client; pub mod send_access; diff --git a/crates/bitwarden-auth/uniffi.toml b/crates/bitwarden-auth/uniffi.toml new file mode 100644 index 000000000..34b842428 --- /dev/null +++ b/crates/bitwarden-auth/uniffi.toml @@ -0,0 +1,9 @@ +[bindings.kotlin] +package_name = "com.bitwarden.auth" +generate_immutable_records = true +android = true + +[bindings.swift] +ffi_module_name = "BitwardenAuthFFI" +module_name = "BitwardenAuth" +generate_immutable_records = true From 5b97222b5af395396e5a82890b773783efc68119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 17 Sep 2025 14:21:27 +0200 Subject: [PATCH 10/13] just remove uniffi from auth for now --- Cargo.lock | 1 - crates/bitwarden-auth/Cargo.toml | 2 -- crates/bitwarden-auth/src/lib.rs | 3 --- crates/bitwarden-auth/uniffi.toml | 9 --------- 4 files changed, 15 deletions(-) delete mode 100644 crates/bitwarden-auth/uniffi.toml diff --git a/Cargo.lock b/Cargo.lock index aaa3dbb94..bb011cc37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,7 +401,6 @@ dependencies = [ "thiserror 2.0.12", "tokio", "tsify", - "uniffi", "wasm-bindgen", "wasm-bindgen-futures", "wiremock", diff --git a/crates/bitwarden-auth/Cargo.toml b/crates/bitwarden-auth/Cargo.toml index 88285b58d..cc062f909 100644 --- a/crates/bitwarden-auth/Cargo.toml +++ b/crates/bitwarden-auth/Cargo.toml @@ -15,7 +15,6 @@ license-file.workspace = true keywords.workspace = true [features] -uniffi = ["bitwarden-core/uniffi", "dep:uniffi"] # Uniffi bindings wasm = [ "bitwarden-core/wasm", "dep:tsify", @@ -35,7 +34,6 @@ serde_qs = { workspace = true } serde_urlencoded = ">=0.7.1, <0.8" thiserror = { workspace = true } tsify = { workspace = true, optional = true } -uniffi = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } wasm-bindgen-futures = { workspace = true, optional = true } diff --git a/crates/bitwarden-auth/src/lib.rs b/crates/bitwarden-auth/src/lib.rs index d0abae41f..380f97d13 100644 --- a/crates/bitwarden-auth/src/lib.rs +++ b/crates/bitwarden-auth/src/lib.rs @@ -1,8 +1,5 @@ #![doc = include_str!("../README.md")] -#[cfg(feature = "uniffi")] -uniffi::setup_scaffolding!(); - mod auth_client; pub mod send_access; diff --git a/crates/bitwarden-auth/uniffi.toml b/crates/bitwarden-auth/uniffi.toml deleted file mode 100644 index 34b842428..000000000 --- a/crates/bitwarden-auth/uniffi.toml +++ /dev/null @@ -1,9 +0,0 @@ -[bindings.kotlin] -package_name = "com.bitwarden.auth" -generate_immutable_records = true -android = true - -[bindings.swift] -ffi_module_name = "BitwardenAuthFFI" -module_name = "BitwardenAuth" -generate_immutable_records = true From 7feba0b3091488c5937a80236893f0cc5d02a512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Wed, 17 Sep 2025 16:24:59 +0200 Subject: [PATCH 11/13] Update uniffi and remove workaround --- Cargo.lock | 35 ++++----- Cargo.toml | 12 ++-- crates/bitwarden-core/src/uniffi_support.rs | 16 ----- crates/bitwarden-uniffi/src/lib.rs | 80 --------------------- 4 files changed, 19 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb011cc37..b1d76453f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4445,15 +4445,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.8.23" @@ -4599,7 +4590,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.8.23", + "toml", ] [[package]] @@ -4686,7 +4677,7 @@ checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "uniffi" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "camino", @@ -4709,7 +4700,7 @@ dependencies = [ [[package]] name = "uniffi_bindgen" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "askama", @@ -4724,7 +4715,7 @@ dependencies = [ "serde", "tempfile", "textwrap", - "toml 0.5.11", + "toml", "uniffi_internal_macros", "uniffi_meta", "uniffi_pipeline", @@ -4734,7 +4725,7 @@ dependencies = [ [[package]] name = "uniffi_build" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "camino", @@ -4744,7 +4735,7 @@ dependencies = [ [[package]] name = "uniffi_core" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "async-compat", @@ -4756,7 +4747,7 @@ dependencies = [ [[package]] name = "uniffi_internal_macros" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "indexmap 2.9.0", @@ -4768,7 +4759,7 @@ dependencies = [ [[package]] name = "uniffi_macros" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "camino", "fs-err", @@ -4777,14 +4768,14 @@ dependencies = [ "quote", "serde", "syn", - "toml 0.5.11", + "toml", "uniffi_meta", ] [[package]] name = "uniffi_meta" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "siphasher", @@ -4795,7 +4786,7 @@ dependencies = [ [[package]] name = "uniffi_pipeline" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "heck 0.5.0", @@ -4807,7 +4798,7 @@ dependencies = [ [[package]] name = "uniffi_udl" version = "0.29.4" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "anyhow", "textwrap", @@ -5077,7 +5068,7 @@ dependencies = [ [[package]] name = "weedle2" version = "5.0.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=c3a2127332d18ba9dbde1e23778b3af8f355cbac#c3a2127332d18ba9dbde1e23778b3af8f355cbac" +source = "git+https://github.com/mozilla/uniffi-rs?rev=6d46b3f756dde3213357c477d86771a0fc5da7b4#6d46b3f756dde3213357c477d86771a0fc5da7b4" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index 255b498cc..37323c140 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,12 +91,12 @@ wiremock = ">=0.6.0, <0.7" [patch.crates-io] pkcs5 = { git = "https://github.com/bitwarden/rustcrypto-formats.git", rev = "2b27c63034217dd126bbf5ed874da51b84f8c705" } -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } -uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } -uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } -uniffi_internal_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } -uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "c3a2127332d18ba9dbde1e23778b3af8f355cbac" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } +uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } +uniffi_internal_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d46b3f756dde3213357c477d86771a0fc5da7b4" } [workspace.lints.clippy] unused_async = "deny" diff --git a/crates/bitwarden-core/src/uniffi_support.rs b/crates/bitwarden-core/src/uniffi_support.rs index 79d6c9136..6a24dd437 100644 --- a/crates/bitwarden-core/src/uniffi_support.rs +++ b/crates/bitwarden-core/src/uniffi_support.rs @@ -40,19 +40,3 @@ uniffi::custom_type!(PasswordProtectedKeyEnvelope, String, { .map(PasswordProtectedKeyEnvelope)), lower: |obj| obj.0.into(), }); - -mod workarounds { - use bitwarden_crypto::*; - - #[derive(uniffi::Object)] - pub struct WorkaroundsCoreDoNotUse {} - - /// Workaround for invalid code generation when an error type is not used directly by the crate. - /// See the comment in `bitwarden-uniffi/src/lib.rs` for more details. - #[uniffi::export] - impl WorkaroundsCoreDoNotUse { - pub fn crypto(&self) -> Result<(), CryptoError> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - } -} diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index c77c52c5a..f7ef61027 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -132,83 +132,3 @@ fn setup_error_converter() { crate::error::BitwardenError::ConversionError(e.to_string()).into() }); } - -mod workarounds { - use bitwarden_core::{ - auth::{auth_client::*, *}, - client::encryption_settings::*, - key_management::crypto::*, - platform::*, - ApiError, - }; - use bitwarden_crypto::*; - use bitwarden_exporters::*; - use bitwarden_fido::*; - use bitwarden_generators::*; - use bitwarden_send::*; - use bitwarden_ssh::error::*; - use bitwarden_state::registry::*; - use bitwarden_vault::*; - - #[derive(uniffi::Object)] - pub struct WorkaroundsDoNotUse {} - - /// UniFFI is not generating the correct code when an Error type is only used as part of another - /// Error, instead of directly by the crate. This is an open issue in UniFFI, and the current - /// workaround is to have a dummy function that uses each error type directly as an error. Open - /// issue: - /// - /// This also needs to be done in crates that also use error types from different crates. In - /// those cases, a workaround like this needs to be added to their uniffi_support.rs file as - /// well. Currently this is also the case for bitwarden-core. - macro_rules! workaround_fns { - ( $( $ty:ident )+ ) => { - $( - #[uniffi::export] - impl WorkaroundsDoNotUse { - #[allow(non_snake_case)] - pub fn $ty(&self) -> Result<(), $ty> { - panic!("Do not use this function, it is only here to work around a uniffi limitation"); - } - } - )+ - }; - } - - workaround_fns!( - ApiError - ApproveAuthRequestError - AuthValidateError - CipherError - CredentialsForAutofillError - CryptoClientError - CryptoError - DecryptError - DecryptFido2AutofillCredentialsError - DecryptFileError - DeriveKeyConnectorError - EncryptError - EncryptFileError - EncryptionSettingsError - EnrollAdminPasswordResetError - ExportError - Fido2ClientError - FingerprintError - GetAssertionError - KeyGenerationError - MakeCredentialError - PassphraseError - PasswordError - SendDecryptError - SendDecryptFileError - SendEncryptError - SendEncryptFileError - SilentlyDiscoverCredentialsError - SshKeyImportError - StateRegistryError - TotpError - TrustDeviceError - UserFingerprintError - UsernameError - ); -} From f35ea0476d878932089b96cd0fcf08a6fd39a7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 23 Sep 2025 18:27:36 +0200 Subject: [PATCH 12/13] Remove deleted feature --- crates/bitwarden-pm/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bitwarden-pm/Cargo.toml b/crates/bitwarden-pm/Cargo.toml index 60a6a833e..0e0d29464 100644 --- a/crates/bitwarden-pm/Cargo.toml +++ b/crates/bitwarden-pm/Cargo.toml @@ -19,7 +19,6 @@ no-memory-hardening = [ "bitwarden-core/no-memory-hardening" ] # Disable memory hardening features uniffi = [ - "bitwarden-auth/uniffi", "bitwarden-core/uniffi", "bitwarden-exporters/uniffi", "bitwarden-fido/uniffi", From e8a43ecbe0fdda6a3a5b25890d937d9d2d74db52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Tue, 23 Sep 2025 18:36:31 +0200 Subject: [PATCH 13/13] Remove unused dep --- Cargo.lock | 1 - crates/bitwarden-pm/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faf63d5fc..04b614b68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -660,7 +660,6 @@ dependencies = [ "bitwarden-generators", "bitwarden-send", "bitwarden-vault", - "thiserror 1.0.69", "tsify", "uniffi", "wasm-bindgen", diff --git a/crates/bitwarden-pm/Cargo.toml b/crates/bitwarden-pm/Cargo.toml index 0e0d29464..6ce547bdf 100644 --- a/crates/bitwarden-pm/Cargo.toml +++ b/crates/bitwarden-pm/Cargo.toml @@ -47,7 +47,6 @@ bitwarden-generators = { workspace = true } bitwarden-send = { workspace = true } bitwarden-vault = { workspace = true } -thiserror = { workspace = true } tsify = { workspace = true, optional = true } uniffi = { workspace = true, optional = true, features = ["tokio"] } wasm-bindgen = { workspace = true, optional = true }