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::{AccessTokenLoginRequest, AccessTokenLoginResponse, login_access_token};
10use crate::{
11 Client,
12 auth::{login::LoginError, renew::renew_token},
13};
14#[cfg(feature = "internal")]
15use crate::{
16 auth::{
17 AuthRequestResponse, AuthValidateError, RegisterKeyResponse,
18 auth_request::{ApproveAuthRequestError, approve_auth_request, new_auth_request},
19 key_connector::{KeyConnectorResponse, make_key_connector_keys},
20 login::{
21 ApiKeyLoginRequest, ApiKeyLoginResponse, NewAuthRequestResponse, PasswordLoginRequest,
22 PasswordLoginResponse, PreloginError, TwoFactorEmailError, TwoFactorEmailRequest,
23 login_api_key, login_password, send_two_factor_email,
24 },
25 password::{
26 MasterPasswordPolicyOptions, password_strength, satisfies_policy, validate_password,
27 validate_password_user_key,
28 },
29 pin::validate_pin,
30 register::make_register_keys,
31 tde::{RegisterTdeKeyResponse, make_register_tde_keys},
32 },
33 client::encryption_settings::EncryptionSettingsError,
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)]
209#[cfg_attr(feature = "uniffi", derive(uniffi::Error), uniffi(flat_error))]
210pub enum TrustDeviceError {
211 #[error(transparent)]
212 Crypto(#[from] bitwarden_crypto::CryptoError),
213}
214
215#[cfg(feature = "internal")]
216fn trust_device(client: &Client) -> Result<TrustDeviceResponse, TrustDeviceError> {
217 use crate::key_management::SymmetricKeyId;
218
219 let key_store = client.internal.get_key_store();
220 let ctx = key_store.context();
221 #[allow(deprecated)]
223 let user_key = ctx.dangerous_get_symmetric_key(SymmetricKeyId::User)?;
224
225 Ok(DeviceKey::trust_device(user_key)?)
226}
227
228impl Client {
229 #[allow(missing_docs)]
230 pub fn auth(&self) -> AuthClient {
231 AuthClient {
232 client: self.clone(),
233 }
234 }
235}