bitwarden_core/auth/api/request/
password_token_request.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use log::debug;
use serde::{Deserialize, Serialize};

use crate::{
    auth::{
        api::response::IdentityTokenResponse,
        login::{TwoFactorProvider, TwoFactorRequest},
    },
    client::ApiConfigurations,
    error::Result,
    DeviceType,
};

#[derive(Serialize, Deserialize, Debug)]
pub struct PasswordTokenRequest {
    scope: String,
    client_id: String,
    #[serde(rename = "deviceType")]
    device_type: u8,
    #[serde(rename = "deviceIdentifier")]
    device_identifier: String,
    #[serde(rename = "deviceName")]
    device_name: String,
    grant_type: String,
    #[serde(rename = "username")]
    email: String,
    #[serde(rename = "password")]
    master_password_hash: String,

    #[serde(rename = "twoFactorToken")]
    two_factor_token: Option<String>,
    #[serde(rename = "twoFactorProvider")]
    two_factor_provider: Option<TwoFactorProvider>,
    #[serde(rename = "twoFactorRemember")]
    two_factor_remember: Option<bool>,
}

impl PasswordTokenRequest {
    pub fn new(
        email: &str,
        password_hash: &str,
        device_type: DeviceType,
        device_identifier: &str,
        two_factor: &Option<TwoFactorRequest>,
    ) -> Self {
        let tf = two_factor.as_ref();
        let obj = Self {
            scope: "api offline_access".to_string(),
            client_id: "web".to_string(),
            device_type: device_type as u8,
            device_identifier: device_identifier.to_string(),
            device_name: "firefox".to_string(),
            grant_type: "password".to_string(),
            master_password_hash: password_hash.to_string(),
            email: email.to_string(),
            two_factor_token: tf.map(|t| t.token.to_owned()),
            two_factor_provider: tf.map(|t| t.provider.clone()),
            two_factor_remember: tf.map(|t| t.remember),
        };
        debug!("initializing {:?}", obj);
        obj
    }

    pub(crate) async fn send(
        &self,
        configurations: &ApiConfigurations,
    ) -> Result<IdentityTokenResponse> {
        super::send_identity_connect_request(configurations, Some(&self.email), &self).await
    }
}