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