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