1#![doc = include_str!("../README.md")]
2
3uniffi::setup_scaffolding!();
4
5use std::sync::Arc;
6
7use auth::AuthClient;
8use bitwarden_core::{ClientSettings, client::internal::ClientManagedTokens};
9
10#[allow(missing_docs)]
11pub mod auth;
12#[allow(missing_docs)]
13pub mod crypto;
14mod error;
15#[allow(missing_docs)]
16pub mod platform;
17#[allow(missing_docs)]
18pub mod tool;
19mod uniffi_support;
20#[allow(missing_docs)]
21pub mod vault;
22
23#[cfg(target_os = "android")]
24mod android_support;
25
26use crypto::CryptoClient;
27use error::{Error, Result};
28use platform::PlatformClient;
29use tool::{ExporterClient, GeneratorClients, SendClient, SshClient};
30use vault::VaultClient;
31
32#[allow(missing_docs)]
33#[derive(uniffi::Object)]
34pub struct Client(pub(crate) bitwarden_pm::PasswordManagerClient);
35
36#[uniffi::export(async_runtime = "tokio")]
37impl Client {
38 #[uniffi::constructor]
40 pub fn new(
41 token_provider: Arc<dyn ClientManagedTokens>,
42 settings: Option<ClientSettings>,
43 ) -> Self {
44 init_logger();
45 setup_error_converter();
46
47 #[cfg(target_os = "android")]
48 android_support::init();
49
50 Self(bitwarden_pm::PasswordManagerClient::new_with_client_tokens(
51 settings,
52 token_provider,
53 ))
54 }
55
56 pub fn crypto(&self) -> CryptoClient {
58 CryptoClient(self.0.crypto())
59 }
60
61 pub fn vault(&self) -> VaultClient {
63 VaultClient(self.0.vault())
64 }
65
66 #[allow(missing_docs)]
67 pub fn platform(&self) -> PlatformClient {
68 PlatformClient(self.0.0.clone())
69 }
70
71 pub fn generators(&self) -> GeneratorClients {
73 GeneratorClients(self.0.generator())
74 }
75
76 pub fn exporters(&self) -> ExporterClient {
78 ExporterClient(self.0.exporters())
79 }
80
81 pub fn sends(&self) -> SendClient {
83 SendClient(self.0.sends())
84 }
85
86 pub fn ssh(&self) -> SshClient {
88 SshClient()
89 }
90
91 pub fn auth(&self) -> AuthClient {
93 AuthClient(self.0.0.clone())
94 }
95
96 pub fn echo(&self, msg: String) -> String {
98 msg
99 }
100
101 pub async fn http_get(&self, url: String) -> Result<String> {
103 let client = self.0.0.internal.get_http_client();
104 let res = client
105 .get(&url)
106 .send()
107 .await
108 .map_err(|e| Error::Api(e.into()))?;
109
110 res.text().await.map_err(|e| Error::Api(e.into()))
111 }
112}
113
114fn init_logger() {
115 #[cfg(not(any(target_os = "android", target_os = "ios")))]
116 let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
117 .try_init();
118
119 #[cfg(target_os = "ios")]
120 let _ = oslog::OsLogger::new("com.8bit.bitwarden")
121 .level_filter(log::LevelFilter::Info)
122 .init();
123
124 #[cfg(target_os = "android")]
125 android_logger::init_once(
126 android_logger::Config::default()
127 .with_tag("com.bitwarden.sdk")
128 .with_max_level(log::LevelFilter::Info),
129 );
130}
131
132fn setup_error_converter() {
135 bitwarden_uniffi_error::set_error_to_uniffi_error(|e| {
136 crate::error::BitwardenError::Conversion(e.to_string()).into()
137 });
138}