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, ClientManagedTokens, SdkManagedTokens, Tokens},
14};
15
16#[derive(Debug, Clone)]
18pub struct Client {
19 #[doc(hidden)]
24 pub internal: Arc<InternalClient>,
25}
26
27impl Client {
28 pub fn new(settings: Option<ClientSettings>) -> Self {
30 Self::new_internal(settings, Tokens::SdkManaged(SdkManagedTokens::default()))
31 }
32
33 pub fn new_with_client_tokens(
35 settings: Option<ClientSettings>,
36 tokens: Arc<dyn ClientManagedTokens>,
37 ) -> Self {
38 Self::new_internal(settings, Tokens::ClientManaged(tokens))
39 }
40
41 fn new_internal(settings_input: Option<ClientSettings>, tokens: Tokens) -> Self {
42 let settings = settings_input.unwrap_or_default();
43
44 fn new_client_builder() -> reqwest::ClientBuilder {
45 #[allow(unused_mut)]
46 let mut client_builder = reqwest::Client::builder();
47
48 #[cfg(not(target_arch = "wasm32"))]
49 {
50 use rustls::ClientConfig;
51 use rustls_platform_verifier::ConfigVerifierExt;
52 client_builder = client_builder.use_preconfigured_tls(
53 ClientConfig::with_platform_verifier()
54 .expect("Failed to create platform verifier"),
55 );
56
57 #[cfg(not(debug_assertions))]
59 {
60 client_builder = client_builder.https_only(true);
61 }
62 }
63
64 client_builder
65 }
66
67 let external_client = new_client_builder().build().expect("Build should not fail");
68
69 let mut headers = header::HeaderMap::new();
70 headers.append(
71 "Device-Type",
72 HeaderValue::from_str(&(settings.device_type as u8).to_string())
73 .expect("All numbers are valid ASCII"),
74 );
75 let client_builder = new_client_builder().default_headers(headers);
76
77 let client = client_builder.build().expect("Build should not fail");
78
79 let identity = bitwarden_api_identity::apis::configuration::Configuration {
80 base_path: settings.identity_url,
81 user_agent: Some(settings.user_agent.clone()),
82 client: client.clone(),
83 basic_auth: None,
84 oauth_access_token: None,
85 bearer_access_token: None,
86 api_key: None,
87 };
88
89 let api = bitwarden_api_api::apis::configuration::Configuration {
90 base_path: settings.api_url,
91 user_agent: Some(settings.user_agent),
92 client,
93 basic_auth: None,
94 oauth_access_token: None,
95 bearer_access_token: None,
96 api_key: None,
97 };
98
99 Self {
100 internal: Arc::new(InternalClient {
101 user_id: OnceLock::new(),
102 tokens: RwLock::new(tokens),
103 login_method: RwLock::new(None),
104 #[cfg(feature = "internal")]
105 flags: RwLock::new(Flags::default()),
106 __api_configurations: RwLock::new(Arc::new(ApiConfigurations {
107 identity,
108 api,
109 device_type: settings.device_type,
110 })),
111 external_client,
112 key_store: KeyStore::default(),
113 #[cfg(feature = "internal")]
114 security_state: RwLock::new(None),
115 #[cfg(feature = "internal")]
116 repository_map: StateRegistry::new(),
117 }),
118 }
119 }
120}