bitwarden_uniffi/auth/login.rs
1use bitwarden_auth::login::{
2 login_via_password::{PasswordLoginRequest, PasswordPreloginResponse},
3 models::LoginResponse,
4};
5
6use crate::error::BitwardenError;
7
8// This wrapper exists so each exported method declares `BitwardenError` as its error type.
9// UniFFI panics when an argument fails to lift and the produced error type does not match the
10// method's declared error type. The converter registered by `setup_error_converter` always
11// produces a `BitwardenError`.
12// Exporting `bitwarden_auth::login::LoginClient` directly would declare `PasswordPreloginError`
13// or `PasswordLoginError` instead. That mismatch would make the method panic instead of
14// returning an error.
15// A caller can trigger this panic in `login_via_password` through a zero value in a
16// `NonZeroU32` KDF field.
17
18/// Client for authenticating a user against the Identity API.
19///
20/// Obtain one via [`crate::auth::AuthClient::login`].
21#[derive(uniffi::Object)]
22pub struct LoginClient(pub(crate) bitwarden_auth::login::LoginClient);
23
24#[uniffi::export(async_runtime = "tokio")]
25impl LoginClient {
26 /// Retrieves the data required before authenticating with a password.
27 pub async fn get_password_prelogin(
28 &self,
29 email: String,
30 ) -> Result<PasswordPreloginResponse, BitwardenError> {
31 Ok(self.0.get_password_prelogin(email).await?)
32 }
33
34 /// Authenticates a user via email and master password.
35 ///
36 /// Derives the master password hash using the prelogin response, then sends
37 /// the authentication request to obtain access tokens and vault keys.
38 pub async fn login_via_password(
39 &self,
40 request: PasswordLoginRequest,
41 ) -> Result<LoginResponse, BitwardenError> {
42 Ok(self.0.login_via_password(request).await?)
43 }
44}