bitwarden_core/auth/api/request/
password_token_request.rs

1use log::debug;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5    auth::{
6        api::response::IdentityTokenResponse,
7        login::{LoginError, TwoFactorProvider, TwoFactorRequest},
8    },
9    client::ApiConfigurations,
10    DeviceType,
11};
12
13#[derive(Serialize, Deserialize, Debug)]
14pub struct PasswordTokenRequest {
15    scope: String,
16    client_id: String,
17    #[serde(rename = "deviceType")]
18    device_type: u8,
19    #[serde(rename = "deviceIdentifier")]
20    device_identifier: String,
21    #[serde(rename = "deviceName")]
22    device_name: String,
23    grant_type: String,
24    #[serde(rename = "username")]
25    email: String,
26    #[serde(rename = "password")]
27    master_password_hash: String,
28
29    #[serde(rename = "twoFactorToken")]
30    two_factor_token: Option<String>,
31    #[serde(rename = "twoFactorProvider")]
32    two_factor_provider: Option<TwoFactorProvider>,
33    #[serde(rename = "twoFactorRemember")]
34    two_factor_remember: Option<bool>,
35}
36
37impl PasswordTokenRequest {
38    pub fn new(
39        email: &str,
40        password_hash: &str,
41        device_type: DeviceType,
42        device_identifier: &str,
43        two_factor: &Option<TwoFactorRequest>,
44    ) -> Self {
45        let tf = two_factor.as_ref();
46        let obj = Self {
47            scope: "api offline_access".to_string(),
48            client_id: "web".to_string(),
49            device_type: device_type as u8,
50            device_identifier: device_identifier.to_string(),
51            device_name: "firefox".to_string(),
52            grant_type: "password".to_string(),
53            master_password_hash: password_hash.to_string(),
54            email: email.to_string(),
55            two_factor_token: tf.map(|t| t.token.to_owned()),
56            two_factor_provider: tf.map(|t| t.provider.clone()),
57            two_factor_remember: tf.map(|t| t.remember),
58        };
59        debug!("initializing {:?}", obj);
60        obj
61    }
62
63    pub(crate) async fn send(
64        &self,
65        configurations: &ApiConfigurations,
66    ) -> Result<IdentityTokenResponse, LoginError> {
67        super::send_identity_connect_request(configurations, Some(&self.email), &self).await
68    }
69}