Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 125 additions & 92 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,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"] }
Expand All @@ -92,13 +92,23 @@ 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 = "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"
unwrap_used = "deny"
string_slice = "warn"

[workspace.lints.rust]
missing_docs = "warn"
unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(feature, values("uniffi", "wasm"))',
] }

[workspace.metadata.dylint]
libraries = [{ path = "support/lints" }]
Expand Down
2 changes: 0 additions & 2 deletions crates/bitwarden-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -32,7 +31,6 @@ reqwest = { workspace = true }
serde = { workspace = true }
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 }

Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-core/src/auth/auth_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Crypto(#[from] bitwarden_crypto::CryptoError),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-core/src/auth/auth_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-core/src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions crates/bitwarden-core/src/platform/generate_fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ 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)]
Crypto(#[from] bitwarden_crypto::CryptoError),
Expand All @@ -48,6 +49,7 @@ pub(crate) fn generate_fingerprint(input: &FingerprintRequest) -> Result<String,
/// Errors that can occur when computing a fingerprint.
#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum UserFingerprintError {
#[error(transparent)]
Crypto(#[from] bitwarden_crypto::CryptoError),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-error-macro/src/flat/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub(crate) fn bitwarden_error_flat(
});

quote! {
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
#input
#wasm

Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-error-macro/src/full/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(crate) fn bitwarden_error_full(

quote! {
#[derive(serde::Serialize)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error))]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is different than what WASM is doing. The WASM part is generating the code based on the wasm feature flag of the macro crate itself, while the UniFFI is always emmitting the cfg_attr code, which means it's the feature flag of the final crate that gets evaluated.

I've needed to do this because I couldn't quite get it working the other way, I think the workspace feature unification was causing issues and generating the UniFFI code all the time, even when not needed (like for the bitwarden-ipc crate).

Doing it this new way has one negative effect, which is that it's not obvious that the final crate has to have a uniffi feature, and otherwise you'll get a warning (that I've had to silence in the root cargo.toml because of wasm-only crates like bitwarden-ipc)

#wasm_attributes
#input
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bitwarden-fido/src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum GetSelectedCredentialError {

#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum MakeCredentialError {
#[error(transparent)]
PublicKeyCredentialParameters(#[from] PublicKeyCredentialParametersError),
Expand All @@ -51,6 +52,7 @@ 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] UnknownEnumError),
Expand All @@ -68,6 +70,7 @@ pub enum GetAssertionError {

#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum SilentlyDiscoverCredentialsError {
#[error(transparent)]
Cipher(#[from] CipherError),
Expand All @@ -81,6 +84,7 @@ pub enum SilentlyDiscoverCredentialsError {

#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum CredentialsForAutofillError {
#[error(transparent)]
Cipher(#[from] CipherError),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-fido/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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),
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-fido/src/client_fido.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct ClientFido2 {

#[allow(missing_docs)]
#[derive(Debug, Error)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
pub enum DecryptFido2AutofillCredentialsError {
#[error(transparent)]
Fido2CredentialAutofillView(#[from] Fido2CredentialAutofillViewError),
Expand Down
2 changes: 1 addition & 1 deletion crates/bitwarden-generators/src/passphrase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 0 additions & 2 deletions crates/bitwarden-pm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -48,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 }
Expand Down
4 changes: 4 additions & 0 deletions crates/bitwarden-send/src/send_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -19,6 +20,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),
Expand All @@ -27,6 +29,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),
Expand All @@ -37,6 +40,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),
Expand Down
3 changes: 2 additions & 1 deletion crates/bitwarden-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license-file.workspace = true
keywords.workspace = true

[features]
uniffi = []
uniffi = ["dep:uniffi"]
wasm = ["bitwarden-threading/wasm"]

[dependencies]
Expand All @@ -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"] }
Expand Down
3 changes: 3 additions & 0 deletions crates/bitwarden-state/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
9 changes: 9 additions & 0 deletions crates/bitwarden-state/uniffi.toml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
49 changes: 11 additions & 38 deletions crates/bitwarden-uniffi/src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -57,11 +56,7 @@ impl AuthClient {
password: String,
kdf: Kdf,
) -> Result<RegisterKeyResponse> {
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
Expand All @@ -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<KeyConnectorResponse> {
Ok(self
.0
.auth()
.make_key_connector_keys()
.map_err(Error::Crypto)?)
Ok(self.0.auth().make_key_connector_keys()?)
}

/// Validate the user password
Expand All @@ -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<bool> {
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
Expand All @@ -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
Expand All @@ -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<bool> {
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<AuthRequestResponse> {
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<UnsignedSharedKey> {
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<TrustDeviceResponse> {
Ok(self.0.auth().trust_device().map_err(Error::TrustDevice)?)
Ok(self.0.auth().trust_device()?)
}
}
Loading
Loading