1#[cfg(feature = "internal")]
2use bitwarden_crypto::{
3 CryptoError, DeviceKey, EncString, Kdf, TrustDeviceResponse, UnsignedSharedKey,
4};
5
6#[cfg(feature = "secrets")]
7use crate::auth::login::{login_access_token, AccessTokenLoginRequest, AccessTokenLoginResponse};
8#[cfg(feature = "internal")]
9use crate::{
10 auth::{
11 auth_request::{approve_auth_request, new_auth_request, ApproveAuthRequestError},
12 key_connector::{make_key_connector_keys, KeyConnectorResponse},
13 login::{
14 login_api_key, login_password, send_two_factor_email, ApiKeyLoginRequest,
15 ApiKeyLoginResponse, NewAuthRequestResponse, PasswordLoginRequest,
16 PasswordLoginResponse, PreloginError, TwoFactorEmailError, TwoFactorEmailRequest,
17 },
18 password::{
19 password_strength, satisfies_policy, validate_password, validate_password_user_key,
20 MasterPasswordPolicyOptions,
21 },
22 pin::validate_pin,
23 register::make_register_keys,
24 tde::{make_register_tde_keys, RegisterTdeKeyResponse},
25 AuthRequestResponse, AuthValidateError, RegisterKeyResponse,
26 },
27 client::encryption_settings::EncryptionSettingsError,
28};
29use crate::{
30 auth::{login::LoginError, renew::renew_token},
31 Client,
32};
33
34#[allow(missing_docs)]
35pub struct AuthClient {
36 pub(crate) client: crate::Client,
37}
38
39impl AuthClient {
40 #[allow(missing_docs)]
41 pub async fn renew_token(&self) -> Result<(), LoginError> {
42 renew_token(&self.client.internal).await
43 }
44
45 #[allow(missing_docs)]
46 #[cfg(feature = "secrets")]
47 pub async fn login_access_token(
48 &self,
49 input: &AccessTokenLoginRequest,
50 ) -> Result<AccessTokenLoginResponse, LoginError> {
51 login_access_token(&self.client, input).await
52 }
53}
54
55#[cfg(feature = "internal")]
56impl AuthClient {
57 #[allow(missing_docs)]
58 pub fn password_strength(
59 &self,
60 password: String,
61 email: String,
62 additional_inputs: Vec<String>,
63 ) -> u8 {
64 password_strength(password, email, additional_inputs)
65 }
66
67 #[allow(missing_docs)]
68 pub fn satisfies_policy(
69 &self,
70 password: String,
71 strength: u8,
72 policy: &MasterPasswordPolicyOptions,
73 ) -> bool {
74 satisfies_policy(password, strength, policy)
75 }
76
77 #[allow(missing_docs)]
78 pub fn make_register_keys(
79 &self,
80 email: String,
81 password: String,
82 kdf: Kdf,
83 ) -> Result<RegisterKeyResponse, CryptoError> {
84 make_register_keys(email, password, kdf)
85 }
86
87 #[allow(missing_docs)]
88 pub fn make_register_tde_keys(
89 &self,
90 email: String,
91 org_public_key: String,
92 remember_device: bool,
93 ) -> Result<RegisterTdeKeyResponse, EncryptionSettingsError> {
94 make_register_tde_keys(&self.client, email, org_public_key, remember_device)
95 }
96
97 #[allow(missing_docs)]
98 pub fn make_key_connector_keys(&self) -> Result<KeyConnectorResponse, CryptoError> {
99 let mut rng = rand::thread_rng();
100 make_key_connector_keys(&mut rng)
101 }
102
103 #[allow(missing_docs)]
104 pub async fn prelogin(&self, email: String) -> Result<Kdf, PreloginError> {
105 use crate::auth::login::prelogin;
106
107 prelogin(&self.client, email).await
108 }
109
110 #[allow(missing_docs)]
111 pub async fn login_password(
112 &self,
113 input: &PasswordLoginRequest,
114 ) -> Result<PasswordLoginResponse, LoginError> {
115 login_password(&self.client, input).await
116 }
117
118 #[allow(missing_docs)]
119 pub async fn login_api_key(
120 &self,
121 input: &ApiKeyLoginRequest,
122 ) -> Result<ApiKeyLoginResponse, LoginError> {
123 login_api_key(&self.client, input).await
124 }
125
126 #[allow(missing_docs)]
127 pub async fn send_two_factor_email(
128 &self,
129 tf: &TwoFactorEmailRequest,
130 ) -> Result<(), TwoFactorEmailError> {
131 send_two_factor_email(&self.client, tf).await
132 }
133
134 #[allow(missing_docs)]
135 pub fn validate_password(
136 &self,
137 password: String,
138 password_hash: String,
139 ) -> Result<bool, AuthValidateError> {
140 validate_password(&self.client, password, password_hash)
141 }
142
143 #[allow(missing_docs)]
144 pub fn validate_password_user_key(
145 &self,
146 password: String,
147 encrypted_user_key: String,
148 ) -> Result<String, AuthValidateError> {
149 validate_password_user_key(&self.client, password, encrypted_user_key)
150 }
151
152 #[allow(missing_docs)]
153 pub fn validate_pin(
154 &self,
155 pin: String,
156 pin_protected_user_key: EncString,
157 ) -> Result<bool, AuthValidateError> {
158 validate_pin(&self.client, pin, pin_protected_user_key)
159 }
160
161 #[allow(missing_docs)]
162 pub fn new_auth_request(&self, email: &str) -> Result<AuthRequestResponse, CryptoError> {
163 new_auth_request(email)
164 }
165
166 #[allow(missing_docs)]
167 pub fn approve_auth_request(
168 &self,
169 public_key: String,
170 ) -> Result<UnsignedSharedKey, ApproveAuthRequestError> {
171 approve_auth_request(&self.client, public_key)
172 }
173
174 #[allow(missing_docs)]
175 pub fn trust_device(&self) -> Result<TrustDeviceResponse, TrustDeviceError> {
176 trust_device(&self.client)
177 }
178}
179
180#[cfg(feature = "internal")]
181impl AuthClient {
182 #[allow(missing_docs)]
183 pub async fn login_device(
184 &self,
185 email: String,
186 device_identifier: String,
187 ) -> Result<NewAuthRequestResponse, LoginError> {
188 use crate::auth::login::send_new_auth_request;
189
190 send_new_auth_request(&self.client, email, device_identifier).await
191 }
192
193 #[allow(missing_docs)]
194 pub async fn login_device_complete(
195 &self,
196 auth_req: NewAuthRequestResponse,
197 ) -> Result<(), LoginError> {
198 use crate::auth::login::complete_auth_request;
199
200 complete_auth_request(&self.client, auth_req).await
201 }
202}
203
204#[allow(missing_docs)]
205#[cfg(feature = "internal")]
206#[derive(Debug, thiserror::Error)]
207pub enum TrustDeviceError {
208 #[error(transparent)]
209 VaultLocked(#[from] crate::VaultLockedError),
210 #[error(transparent)]
211 Crypto(#[from] bitwarden_crypto::CryptoError),
212}
213
214#[cfg(feature = "internal")]
215fn trust_device(client: &Client) -> Result<TrustDeviceResponse, TrustDeviceError> {
216 use crate::key_management::SymmetricKeyId;
217
218 let key_store = client.internal.get_key_store();
219 let ctx = key_store.context();
220 #[allow(deprecated)]
222 let user_key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
223
224 Ok(DeviceKey::trust_device(user_key)?)
225}
226
227impl Client {
228 #[allow(missing_docs)]
229 pub fn auth(&self) -> AuthClient {
230 AuthClient {
231 client: self.clone(),
232 }
233 }
234}