Skip to main content

bitwarden_core/auth/api/response/
identity_success_response.rs

1use std::{collections::HashMap, num::NonZeroU32};
2
3use bitwarden_api_identity::models::KdfType;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7use crate::auth::api::response::user_decryption_options_response::UserDecryptionOptionsResponseModel;
8
9#[derive(Serialize, Deserialize, Debug, PartialEq)]
10pub(crate) struct IdentityTokenSuccessResponse {
11    pub access_token: String,
12    pub expires_in: u64,
13    pub refresh_token: Option<String>,
14    token_type: String,
15
16    #[serde(rename = "privateKey", alias = "PrivateKey")]
17    pub(crate) private_key: Option<String>,
18    #[serde(alias = "Key")]
19    pub(crate) key: Option<String>,
20    #[serde(rename = "twoFactorToken")]
21    two_factor_token: Option<String>,
22    #[serde(alias = "Kdf")]
23    kdf: KdfType,
24    #[serde(rename = "kdfIterations", alias = "KdfIterations")]
25    kdf_iterations: NonZeroU32,
26
27    // Defaulted for forward compatibility: newer servers omit these top-level flags, having moved
28    // the data into `userDecryptionOptions` / `masterPasswordPolicy`. A missing field would
29    // otherwise fail success-response parsing and degrade the login into a refresh response.
30    #[serde(default, rename = "resetMasterPassword", alias = "ResetMasterPassword")]
31    pub reset_master_password: bool,
32    #[serde(default, rename = "forcePasswordReset", alias = "ForcePasswordReset")]
33    pub force_password_reset: bool,
34    #[serde(rename = "apiUseKeyConnector", alias = "ApiUseKeyConnector")]
35    api_use_key_connector: Option<bool>,
36    #[serde(rename = "keyConnectorUrl", alias = "KeyConnectorUrl")]
37    key_connector_url: Option<String>,
38
39    #[serde(rename = "userDecryptionOptions", alias = "UserDecryptionOptions")]
40    pub(crate) user_decryption_options: Option<UserDecryptionOptionsResponseModel>,
41
42    /// Stores unknown api response fields
43    extra: Option<HashMap<String, Value>>,
44}
45
46#[cfg(test)]
47mod test {
48    use bitwarden_crypto::Kdf;
49
50    use super::*;
51
52    impl Default for IdentityTokenSuccessResponse {
53        fn default() -> Self {
54            let Kdf::PBKDF2 { iterations } = Kdf::default_pbkdf2() else {
55                panic!("Expected default KDF to be PBKDF2");
56            };
57
58            Self {
59                access_token: Default::default(),
60                expires_in: Default::default(),
61                refresh_token: Default::default(),
62                token_type: Default::default(),
63                private_key: Default::default(),
64                key: Default::default(),
65                two_factor_token: Default::default(),
66                kdf: KdfType::PBKDF2_SHA256,
67                kdf_iterations: iterations,
68                reset_master_password: Default::default(),
69                force_password_reset: Default::default(),
70                api_use_key_connector: Default::default(),
71                key_connector_url: Default::default(),
72                user_decryption_options: Default::default(),
73                extra: Default::default(),
74            }
75        }
76    }
77}