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_exporters::ExporterClientExt as _;
14use bitwarden_generators::GeneratorClientsExt as _;
15use bitwarden_policies::PoliciesClientExt as _;
16use bitwarden_send::SendClientExt as _;
17use bitwarden_sync::SyncClientExt as _;
18use bitwarden_unlock::UnlockClientExt as _;
19use bitwarden_user_crypto_management::UserCryptoManagementClientExt;
20use bitwarden_vault::{FolderSyncHandler, VaultClientExt as _};
21
22#[cfg(feature = "uniffi")]
23uniffi::setup_scaffolding!();
24
25pub mod clients {
27 pub use bitwarden_auth::AuthClient;
28 pub use bitwarden_core::key_management::CryptoClient;
29 pub use bitwarden_exporters::ExporterClient;
30 pub use bitwarden_generators::GeneratorClient;
31 pub use bitwarden_policies::PolicyClient;
32 pub use bitwarden_send::SendClient;
33 pub use bitwarden_sync::SyncClient;
34 pub use bitwarden_unlock::UnlockClient;
35 pub use bitwarden_vault::VaultClient;
36}
37#[cfg(feature = "bitwarden-license")]
38pub use commercial::CommercialPasswordManagerClient;
39
40mod builder;
41pub mod migrations;
42pub use bitwarden_core::{RehydrationError, SaveStateData};
43pub use bitwarden_unlock::{SessionKey, UnlockError, UnlockMethod};
44pub use builder::PasswordManagerClientBuilder;
45
46pub struct PasswordManagerClient(pub bitwarden_core::Client);
48
49impl PasswordManagerClient {
50 pub fn new(settings: Option<bitwarden_core::ClientSettings>) -> Self {
52 let mut builder = PasswordManagerClientBuilder::new();
53 if let Some(s) = settings {
54 builder = builder.with_settings(s);
55 }
56 builder.build()
57 }
58
59 pub fn builder() -> PasswordManagerClientBuilder {
61 PasswordManagerClientBuilder::new()
62 }
63
64 pub fn new_with_client_tokens(
66 settings: Option<bitwarden_core::ClientSettings>,
67 tokens: Arc<dyn ClientManagedTokens>,
68 ) -> Self {
69 Self(bitwarden_core::Client::new_with_token_handler(
70 settings,
71 ClientManagedTokenHandler::new(tokens),
72 ))
73 }
74
75 pub fn new_with_sync(settings: Option<bitwarden_core::ClientSettings>) -> Self {
80 let client = Self::new(settings);
81
82 client
83 .sync()
84 .register_sync_handler(Arc::new(FolderSyncHandler::from_client(&client.0)));
85
86 client
89 }
90
91 pub fn platform(&self) -> bitwarden_core::platform::PlatformClient {
93 self.0.platform()
94 }
95
96 pub fn auth(&self) -> bitwarden_auth::AuthClient {
98 self.0.auth_new()
99 }
100
101 #[cfg(feature = "bitwarden-license")]
103 pub fn commercial(&self) -> CommercialPasswordManagerClient {
104 CommercialPasswordManagerClient::new(self.0.clone())
105 }
106
107 pub fn crypto(&self) -> bitwarden_core::key_management::CryptoClient {
109 self.0.crypto()
110 }
111
112 pub fn flags(&self) -> bitwarden_core::FlagsClient {
114 self.0.flags()
115 }
116
117 pub fn user_crypto_management(
119 &self,
120 ) -> bitwarden_user_crypto_management::UserCryptoManagementClient {
121 self.0.user_crypto_management()
122 }
123
124 pub fn vault(&self) -> bitwarden_vault::VaultClient {
126 self.0.vault()
127 }
128
129 pub fn exporters(&self) -> bitwarden_exporters::ExporterClient {
131 self.0.exporters()
132 }
133
134 pub fn generator(&self) -> bitwarden_generators::GeneratorClient {
136 self.0.generator()
137 }
138
139 pub fn sends(&self) -> bitwarden_send::SendClient {
141 self.0.sends()
142 }
143
144 pub fn policies(&self) -> bitwarden_policies::PolicyClient {
146 self.0.policies()
147 }
148
149 pub fn sync(&self) -> bitwarden_sync::SyncClient {
151 self.0.sync()
152 }
153
154 pub fn is_unlocked(&self) -> bool {
156 use bitwarden_core::key_management::SymmetricKeySlotId;
157 self.0
158 .internal
159 .get_key_store()
160 .context()
161 .has_symmetric_key(SymmetricKeySlotId::User)
162 }
163
164 pub fn unlock(&self) -> bitwarden_unlock::UnlockClient {
166 self.0.unlock()
167 }
168
169 pub async fn save_to_state(
173 data: SaveStateData,
174 reg: &bitwarden_state::registry::StateRegistry,
175 ) -> Result<(), RehydrationError> {
176 bitwarden_core::Client::save_to_state(data, reg).await
177 }
178
179 pub async fn load_from_state(
183 token_handler: std::sync::Arc<dyn bitwarden_core::auth::auth_tokens::TokenHandler>,
184 registry: bitwarden_state::registry::StateRegistry,
185 ) -> Result<Self, RehydrationError> {
186 let client = bitwarden_core::Client::load_from_state(token_handler, registry).await?;
187 Ok(PasswordManagerClient(client))
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use std::sync::Arc;
194
195 use super::*;
196
197 #[test]
198 fn new_with_server_communication_config_constructs() {
199 struct MockCookieProvider;
200
201 #[async_trait::async_trait]
202 impl bitwarden_server_communication_config::CookieProvider for MockCookieProvider {
203 async fn cookies(&self, _hostname: &str) -> Vec<(String, String)> {
204 vec![]
205 }
206
207 async fn acquire_cookie(
208 &self,
209 _hostname: &str,
210 ) -> Result<(), bitwarden_server_communication_config::AcquireCookieError> {
211 Ok(())
212 }
213
214 async fn needs_bootstrap(&self, _hostname: &str) -> bool {
215 false
216 }
217 }
218
219 let _client = PasswordManagerClient::builder()
220 .with_server_communication_config(Arc::new(MockCookieProvider))
221 .build();
222 }
223}