1#![doc = include_str!("../README.md")]
2
3#[cfg(feature = "bitwarden-license")]
4mod commercial;
5
6use std::sync::Arc;
7
8use bitwarden_auth::AuthClientExt as _;
9use bitwarden_core::{
10 FromClient,
11 auth::{ClientManagedTokenHandler, ClientManagedTokens},
12};
13use bitwarden_crypto_cipher_suite::CryptoCipherSuiteClientExt as _;
14#[cfg(not(target_arch = "wasm32"))]
15use bitwarden_crypto_sync_handler::CryptoSyncHandler;
16use bitwarden_crypto_sync_handler::CryptoSyncHandlerClientExt as _;
17use bitwarden_exporters::ExporterClientExt as _;
18use bitwarden_generators::GeneratorClientsExt as _;
19use bitwarden_importers::ImporterClientExt as _;
20use bitwarden_organization_invite_link::InviteLinkClientExt as _;
21use bitwarden_policies::PoliciesClientExt as _;
22use bitwarden_send::SendClientExt as _;
23use bitwarden_sync::SyncClientExt as _;
24use bitwarden_unlock::UnlockClientExt as _;
25use bitwarden_user_crypto_management::UserCryptoManagementClientExt;
26use bitwarden_vault::{FolderSyncHandler, VaultClientExt as _};
27
28#[cfg(feature = "uniffi")]
29uniffi::setup_scaffolding!();
30
31pub mod clients {
33 pub use bitwarden_auth::AuthClient;
34 pub use bitwarden_core::key_management::CryptoClient;
35 pub use bitwarden_crypto_cipher_suite::CryptoCipherSuiteClient;
36 pub use bitwarden_crypto_sync_handler::CryptoSyncHandlerClient;
37 pub use bitwarden_exporters::ExporterClient;
38 pub use bitwarden_generators::GeneratorClient;
39 pub use bitwarden_importers::ImporterClient;
40 pub use bitwarden_organization_invite_link::InviteLinkClient;
41 pub use bitwarden_policies::PolicyClient;
42 pub use bitwarden_send::SendClient;
43 pub use bitwarden_sync::SyncClient;
44 pub use bitwarden_unlock::UnlockClient;
45 pub use bitwarden_vault::VaultClient;
46}
47#[cfg(feature = "bitwarden-license")]
48pub use commercial::CommercialPasswordManagerClient;
49
50mod builder;
51pub mod migrations;
52pub use bitwarden_core::{RehydrationError, SaveStateData};
53pub use bitwarden_unlock::{SessionKey, UnlockError, UnlockMethod};
54pub use builder::PasswordManagerClientBuilder;
55
56pub struct PasswordManagerClient(pub bitwarden_core::Client);
58
59impl PasswordManagerClient {
60 pub fn new(settings: Option<bitwarden_core::ClientSettings>) -> Self {
62 let mut builder = PasswordManagerClientBuilder::new();
63 if let Some(s) = settings {
64 builder = builder.with_settings(s);
65 }
66 builder.build()
67 }
68
69 pub fn builder() -> PasswordManagerClientBuilder {
71 PasswordManagerClientBuilder::new()
72 }
73
74 pub fn new_with_client_tokens(
76 settings: Option<bitwarden_core::ClientSettings>,
77 tokens: Arc<dyn ClientManagedTokens>,
78 ) -> Self {
79 Self(bitwarden_core::Client::new_with_token_handler(
80 settings,
81 ClientManagedTokenHandler::new(tokens),
82 ))
83 }
84
85 pub fn new_with_sync(settings: Option<bitwarden_core::ClientSettings>) -> Self {
90 let client = Self::new(settings);
91
92 let sync = client.sync();
93 #[cfg(not(target_arch = "wasm32"))]
94 sync.register_sync_handler(Arc::new(CryptoSyncHandler::new(client.0.clone())));
95 sync.register_sync_handler(Arc::new(FolderSyncHandler::from_client(&client.0)));
96
97 client
100 }
101
102 pub fn platform(&self) -> bitwarden_core::platform::PlatformClient {
104 self.0.platform()
105 }
106
107 pub fn auth(&self) -> bitwarden_auth::AuthClient {
109 self.0.auth_new()
110 }
111
112 #[cfg(feature = "bitwarden-license")]
114 pub fn commercial(&self) -> CommercialPasswordManagerClient {
115 CommercialPasswordManagerClient::new(self.0.clone())
116 }
117
118 pub fn crypto(&self) -> bitwarden_core::key_management::CryptoClient {
120 self.0.crypto()
121 }
122
123 pub fn crypto_cipher_suite(&self) -> bitwarden_crypto_cipher_suite::CryptoCipherSuiteClient {
125 self.0.crypto_cipher_suite()
126 }
127
128 pub fn flags(&self) -> bitwarden_core::FlagsClient {
130 self.0.flags()
131 }
132
133 pub fn crypto_sync_handler(&self) -> bitwarden_crypto_sync_handler::CryptoSyncHandlerClient {
135 self.0.crypto_sync_handler()
136 }
137
138 pub fn user_crypto_management(
140 &self,
141 ) -> bitwarden_user_crypto_management::UserCryptoManagementClient {
142 self.0.user_crypto_management()
143 }
144
145 pub fn vault(&self) -> bitwarden_vault::VaultClient {
147 self.0.vault()
148 }
149
150 pub fn exporters(&self) -> bitwarden_exporters::ExporterClient {
152 self.0.exporters()
153 }
154
155 pub fn importers(&self) -> bitwarden_importers::ImporterClient {
157 self.0.importers()
158 }
159
160 pub fn generator(&self) -> bitwarden_generators::GeneratorClient {
162 self.0.generator()
163 }
164
165 pub fn sends(&self) -> bitwarden_send::SendClient {
167 self.0.sends()
168 }
169
170 pub fn policies(&self) -> bitwarden_policies::PolicyClient {
172 self.0.policies()
173 }
174
175 pub fn invite_link(&self) -> bitwarden_organization_invite_link::InviteLinkClient {
177 self.0.invite_link()
178 }
179
180 pub fn sync(&self) -> bitwarden_sync::SyncClient {
182 self.0.sync()
183 }
184
185 pub fn is_unlocked(&self) -> bool {
187 use bitwarden_core::key_management::SymmetricKeySlotId;
188 self.0
189 .internal
190 .get_key_store()
191 .context()
192 .has_symmetric_key(SymmetricKeySlotId::User)
193 }
194
195 pub fn unlock(&self) -> bitwarden_unlock::UnlockClient {
197 self.0.unlock()
198 }
199
200 pub async fn save_to_state(
204 data: SaveStateData,
205 reg: &bitwarden_state::registry::StateRegistry,
206 ) -> Result<(), RehydrationError> {
207 bitwarden_core::Client::save_to_state(data, reg).await
208 }
209
210 pub async fn load_from_state(
214 token_handler: std::sync::Arc<dyn bitwarden_core::auth::auth_tokens::TokenHandler>,
215 registry: bitwarden_state::registry::StateRegistry,
216 ) -> Result<Self, RehydrationError> {
217 let client = bitwarden_core::Client::load_from_state(token_handler, registry).await?;
218 Ok(PasswordManagerClient(client))
219 }
220}
221
222#[cfg(test)]
223mod tests {
224 use std::sync::Arc;
225
226 use super::*;
227
228 #[test]
229 fn new_with_server_communication_config_constructs() {
230 struct MockCookieProvider;
231
232 #[async_trait::async_trait]
233 impl bitwarden_server_communication_config::CookieProvider for MockCookieProvider {
234 async fn cookies(&self, _hostname: &str) -> Vec<(String, String)> {
235 vec![]
236 }
237
238 async fn acquire_cookie(
239 &self,
240 _hostname: &str,
241 ) -> Result<(), bitwarden_server_communication_config::AcquireCookieError> {
242 Ok(())
243 }
244
245 async fn needs_bootstrap(&self, _hostname: &str) -> bool {
246 false
247 }
248 }
249
250 let _client = PasswordManagerClient::builder()
251 .with_server_communication_config(Arc::new(MockCookieProvider))
252 .build();
253 }
254}