Skip to main content

bitwarden_core/auth/api/request/
password_token_request.rs

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