bitwarden_core/client/
client.rs1use std::sync::{Arc, OnceLock, RwLock};
2
3use bitwarden_crypto::KeyStore;
4#[cfg(feature = "internal")]
5use bitwarden_state::registry::StateRegistry;
6use reqwest::header::{self, HeaderValue};
7
8use super::internal::InternalClient;
9#[cfg(feature = "internal")]
10use crate::client::flags::Flags;
11use crate::client::{
12 client_settings::ClientSettings,
13 internal::{ApiConfigurations, Tokens},
14};
15
16#[derive(Debug, Clone)]
18pub struct Client {
19 #[doc(hidden)]
24 pub internal: Arc<InternalClient>,
25}
26
27impl Client {
28 #[allow(missing_docs)]
29 pub fn new(settings_input: Option<ClientSettings>) -> Self {
30 let settings = settings_input.unwrap_or_default();
31
32 fn new_client_builder() -> reqwest::ClientBuilder {
33 #[allow(unused_mut)]
34 let mut client_builder = reqwest::Client::builder();
35
36 #[cfg(not(target_arch = "wasm32"))]
37 {
38 use rustls::ClientConfig;
39 use rustls_platform_verifier::ConfigVerifierExt;
40 client_builder = client_builder.use_preconfigured_tls(
41 ClientConfig::with_platform_verifier()
42 .expect("Failed to create platform verifier"),
43 );
44 }
45
46 client_builder
47 }
48
49 let external_client = new_client_builder().build().expect("Build should not fail");
50
51 let mut headers = header::HeaderMap::new();
52 headers.append(
53 "Device-Type",
54 HeaderValue::from_str(&(settings.device_type as u8).to_string())
55 .expect("All numbers are valid ASCII"),
56 );
57 let client_builder = new_client_builder().default_headers(headers);
58
59 let client = client_builder.build().expect("Build should not fail");
60
61 let identity = bitwarden_api_identity::apis::configuration::Configuration {
62 base_path: settings.identity_url,
63 user_agent: Some(settings.user_agent.clone()),
64 client: client.clone(),
65 basic_auth: None,
66 oauth_access_token: None,
67 bearer_access_token: None,
68 api_key: None,
69 };
70
71 let api = bitwarden_api_api::apis::configuration::Configuration {
72 base_path: settings.api_url,
73 user_agent: Some(settings.user_agent),
74 client,
75 basic_auth: None,
76 oauth_access_token: None,
77 bearer_access_token: None,
78 api_key: None,
79 };
80
81 Self {
82 internal: Arc::new(InternalClient {
83 user_id: OnceLock::new(),
84 tokens: RwLock::new(Tokens::default()),
85 login_method: RwLock::new(None),
86 #[cfg(feature = "internal")]
87 flags: RwLock::new(Flags::default()),
88 __api_configurations: RwLock::new(Arc::new(ApiConfigurations {
89 identity,
90 api,
91 device_type: settings.device_type,
92 })),
93 external_client,
94 key_store: KeyStore::default(),
95 #[cfg(feature = "internal")]
96 repository_map: StateRegistry::new(),
97 }),
98 }
99 }
100}