diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index 8ff904bb288..9d2993844b9 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -1,11 +1,11 @@ [workspace] resolver = "2" members = [ + "autofill_provider", "autotype", "bitwarden_chromium_import_helper", "chromium_importer", "core", - "autofill_provider", "napi", "process_isolation", "proxy", diff --git a/apps/desktop/desktop_native/autofill_provider/Cargo.toml b/apps/desktop/desktop_native/autofill_provider/Cargo.toml index c23333b2d5f..f9efc7f379d 100644 --- a/apps/desktop/desktop_native/autofill_provider/Cargo.toml +++ b/apps/desktop/desktop_native/autofill_provider/Cargo.toml @@ -14,7 +14,7 @@ name = "uniffi-bindgen" path = "uniffi-bindgen.rs" [dependencies] -base64 = { workspace = true} +base64 = { workspace = true } desktop_core = { path = "../core" } futures = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/apps/desktop/desktop_native/autofill_provider/src/lib.rs b/apps/desktop/desktop_native/autofill_provider/src/lib.rs index 300f01d8982..3b948add84e 100644 --- a/apps/desktop/desktop_native/autofill_provider/src/lib.rs +++ b/apps/desktop/desktop_native/autofill_provider/src/lib.rs @@ -5,6 +5,8 @@ mod registration; mod util; mod window_handle_query; +#[cfg(target_os = "macos")] +use std::sync::Once; use std::{ collections::HashMap, error::Error, @@ -17,10 +19,15 @@ use std::{ time::{Duration, Instant}, }; -#[cfg(target_os = "macos")] -use std::sync::Once; - +pub use assertion::{ + PasskeyAssertionRequest, PasskeyAssertionResponse, PasskeyAssertionWithoutUserInterfaceRequest, + PreparePasskeyAssertionCallback, +}; use futures::FutureExt; +pub use lock_status::LockStatusResponse; +pub use registration::{ + PasskeyRegistrationRequest, PasskeyRegistrationResponse, PreparePasskeyRegistrationCallback, +}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tracing::{error, info}; #[cfg(target_os = "macos")] @@ -29,22 +36,13 @@ use tracing_subscriber::{ layer::SubscriberExt, util::SubscriberInitExt, }; +pub use window_handle_query::WindowHandleQueryResponse; use crate::{ lock_status::{GetLockStatusCallback, LockStatusRequest}, window_handle_query::{GetWindowHandleQueryCallback, WindowHandleQueryRequest}, }; -pub use assertion::{ - PasskeyAssertionRequest, PasskeyAssertionResponse, PasskeyAssertionWithoutUserInterfaceRequest, - PreparePasskeyAssertionCallback, -}; -pub use lock_status::LockStatusResponse; -pub use registration::{ - PasskeyRegistrationRequest, PasskeyRegistrationResponse, PreparePasskeyRegistrationCallback, -}; -pub use window_handle_query::WindowHandleQueryResponse; - #[cfg(target_os = "macos")] uniffi::setup_scaffolding!(); @@ -147,8 +145,6 @@ impl AutofillProviderClient { #[cfg_attr(target_os = "macos", uniffi::export)] impl AutofillProviderClient { - // FIXME: Remove unwraps! They panic and terminate the whole application. - #[allow(clippy::unwrap_used)] #[cfg_attr(target_os = "macos", uniffi::constructor)] pub fn connect() -> Self { #[cfg(target_os = "macos")] @@ -210,7 +206,7 @@ impl AutofillProviderClient { Ok(SerializedMessage::Message { sequence_number, value, - }) => match queue.lock().unwrap().remove(&sequence_number) { + }) => match queue.lock().expect("not poisoned").remove(&sequence_number) { Some((cb, request_start_time)) => { info!( "Time to process request: {:?}", @@ -302,7 +298,6 @@ enum SerializedMessage { } impl AutofillProviderClient { - #[allow(clippy::unwrap_used)] fn add_callback(&self, callback: Box) -> u32 { let sequence_number = self .response_callbacks_counter @@ -316,7 +311,6 @@ impl AutofillProviderClient { sequence_number } - #[allow(clippy::unwrap_used)] fn send_message( &self, message: impl Serialize + DeserializeOwned, @@ -328,13 +322,24 @@ impl AutofillProviderClient { NO_CALLBACK_INDICATOR }; - let message = serde_json::to_string(&SerializedMessage::Message { - sequence_number, - value: Ok(serde_json::to_value(message).unwrap()), - }) - .expect("Can't serialize message"); - - if let Err(e) = self.to_server_send.blocking_send(message) { + fn inner( + sequence_number: u32, + message: impl Serialize + DeserializeOwned, + tx: &tokio::sync::mpsc::Sender, + ) -> Result<(), String> { + let value = serde_json::to_value(message) + .map_err(|err| format!("Could not represent message as JSON: {err}"))?; + let message = SerializedMessage::Message { + sequence_number, + value: Ok(value), + }; + let json = serde_json::to_string(&message) + .map_err(|err| format!("Could not serialize message as JSON: {err}"))?; + tx.blocking_send(json) + .map_err(|err| format!("Error sending message: {err}"))?; + Ok(()) + } + if let Err(e) = inner(sequence_number, message, &self.to_server_send) { // Make sure we remove the callback from the queue if we can't send the message if sequence_number != NO_CALLBACK_INDICATOR { if let Some((callback, _)) = self @@ -368,9 +373,17 @@ impl Display for CallbackError { } impl std::error::Error for CallbackError {} +type CallbackResponse = Result; + pub struct TimedCallback { - tx: Arc>>>>, - rx: Arc>>>, + tx: Arc>>>>, + rx: Arc>>>, +} + +impl Default for TimedCallback { + fn default() -> Self { + Self::new() + } } impl TimedCallback { @@ -392,7 +405,11 @@ impl TimedCallback { let tx2 = tx.clone(); let cancellation_token = Mutex::new(cancellation_token); std::thread::spawn(move || { - if let Ok(()) = cancellation_token.lock().unwrap().recv_timeout(timeout) { + if let Ok(()) = cancellation_token + .lock() + .expect("not poisoned") + .recv_timeout(timeout) + { tracing::debug!("Forwarding cancellation"); _ = tx2.send(Err(CallbackError::Cancelled)); } @@ -400,7 +417,11 @@ impl TimedCallback { } let response_rx = self.rx.clone(); std::thread::spawn(move || { - if let Ok(response) = response_rx.lock().unwrap().recv_timeout(timeout) { + if let Ok(response) = response_rx + .lock() + .expect("not poisoned") + .recv_timeout(timeout) + { _ = tx.send(Ok(response)); } }); @@ -420,9 +441,9 @@ impl TimedCallback { } fn send(&self, response: Result) { - match self.tx.lock().unwrap().take() { + match self.tx.lock().expect("not poisoned").take() { Some(tx) => { - if let Err(_) = tx.send(response) { + if tx.send(response).is_err() { tracing::error!("Windows provider channel closed before receiving IPC response from Electron") } }