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 client::persisted_state::SESSION_PROTECTED_USER_KEY,
13};
14use bitwarden_exporters::ExporterClientExt as _;
15use bitwarden_generators::GeneratorClientsExt as _;
16use bitwarden_policies::PoliciesClientExt as _;
17use bitwarden_send::SendClientExt as _;
18use bitwarden_sync::SyncClientExt 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_vault::VaultClient;
35}
36#[cfg(feature = "bitwarden-license")]
37pub use commercial::CommercialPasswordManagerClient;
38
39mod builder;
40pub mod migrations;
41pub use bitwarden_core::{RehydrationError, SaveStateData};
42pub use builder::PasswordManagerClientBuilder;
43
44pub struct PasswordManagerClient(pub bitwarden_core::Client);
46
47impl PasswordManagerClient {
48 pub fn new(settings: Option<bitwarden_core::ClientSettings>) -> Self {
50 let mut builder = PasswordManagerClientBuilder::new();
51 if let Some(s) = settings {
52 builder = builder.with_settings(s);
53 }
54 builder.build()
55 }
56
57 pub fn builder() -> PasswordManagerClientBuilder {
59 PasswordManagerClientBuilder::new()
60 }
61
62 pub fn new_with_client_tokens(
64 settings: Option<bitwarden_core::ClientSettings>,
65 tokens: Arc<dyn ClientManagedTokens>,
66 ) -> Self {
67 Self(bitwarden_core::Client::new_with_token_handler(
68 settings,
69 ClientManagedTokenHandler::new(tokens),
70 ))
71 }
72
73 pub fn new_with_sync(settings: Option<bitwarden_core::ClientSettings>) -> Self {
78 let client = Self::new(settings);
79
80 client
81 .sync()
82 .register_sync_handler(Arc::new(FolderSyncHandler::from_client(&client.0)));
83
84 client
87 }
88
89 pub fn platform(&self) -> bitwarden_core::platform::PlatformClient {
91 self.0.platform()
92 }
93
94 pub fn auth(&self) -> bitwarden_auth::AuthClient {
96 self.0.auth_new()
97 }
98
99 #[cfg(feature = "bitwarden-license")]
101 pub fn commercial(&self) -> CommercialPasswordManagerClient {
102 CommercialPasswordManagerClient::new(self.0.clone())
103 }
104
105 pub fn crypto(&self) -> bitwarden_core::key_management::CryptoClient {
107 self.0.crypto()
108 }
109
110 pub fn user_crypto_management(
112 &self,
113 ) -> bitwarden_user_crypto_management::UserCryptoManagementClient {
114 self.0.user_crypto_management()
115 }
116
117 pub fn vault(&self) -> bitwarden_vault::VaultClient {
119 self.0.vault()
120 }
121
122 pub fn exporters(&self) -> bitwarden_exporters::ExporterClient {
124 self.0.exporters()
125 }
126
127 pub fn generator(&self) -> bitwarden_generators::GeneratorClient {
129 self.0.generator()
130 }
131
132 pub fn sends(&self) -> bitwarden_send::SendClient {
134 self.0.sends()
135 }
136
137 pub fn policies(&self) -> bitwarden_policies::PolicyClient {
139 self.0.policies()
140 }
141
142 pub fn sync(&self) -> bitwarden_sync::SyncClient {
144 self.0.sync()
145 }
146
147 pub fn is_unlocked(&self) -> bool {
149 use bitwarden_core::key_management::SymmetricKeySlotId;
150 self.0
151 .internal
152 .get_key_store()
153 .context()
154 .has_symmetric_key(SymmetricKeySlotId::User)
155 }
156
157 pub async fn invalidate_session_key(&self) -> Result<(), bitwarden_state::SettingsError> {
164 self.0
165 .platform()
166 .state()
167 .setting(SESSION_PROTECTED_USER_KEY)?
168 .delete()
169 .await
170 }
171
172 pub async fn save_to_state(
176 data: SaveStateData,
177 reg: &bitwarden_state::registry::StateRegistry,
178 ) -> Result<(), RehydrationError> {
179 bitwarden_core::Client::save_to_state(data, reg).await
180 }
181
182 pub async fn load_from_state(
186 token_handler: std::sync::Arc<dyn bitwarden_core::auth::auth_tokens::TokenHandler>,
187 registry: bitwarden_state::registry::StateRegistry,
188 ) -> Result<Self, RehydrationError> {
189 let client = bitwarden_core::Client::load_from_state(token_handler, registry).await?;
190 Ok(PasswordManagerClient(client))
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use std::sync::Arc;
197
198 use super::*;
199
200 #[test]
201 fn new_with_server_communication_config_constructs() {
202 struct MockCookieProvider;
203
204 #[async_trait::async_trait]
205 impl bitwarden_server_communication_config::CookieProvider for MockCookieProvider {
206 async fn cookies(&self, _hostname: &str) -> Vec<(String, String)> {
207 vec![]
208 }
209
210 async fn acquire_cookie(
211 &self,
212 _hostname: &str,
213 ) -> Result<(), bitwarden_server_communication_config::AcquireCookieError> {
214 Ok(())
215 }
216
217 async fn needs_bootstrap(&self, _hostname: &str) -> bool {
218 false
219 }
220 }
221
222 let _client = PasswordManagerClient::builder()
223 .with_server_communication_config(Arc::new(MockCookieProvider))
224 .build();
225 }
226}