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