Skip to main content

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}