Skip to main content

bitwarden_emergency_access/
accept.rs

1use bitwarden_api_api::models::EmergencyAccessAcceptRequestModel;
2use bitwarden_core::ApiError;
3use bitwarden_error::bitwarden_error;
4use thiserror::Error;
5
6use crate::{EmergencyAccessClient, EmergencyAccessId};
7
8/// Errors returned when accepting an emergency access invite.
9#[bitwarden_error(flat)]
10#[derive(Debug, Error)]
11pub enum EmergencyAccessAcceptError {
12    /// The request to the server failed.
13    #[error(transparent)]
14    Api(#[from] ApiError),
15}
16
17#[bitwarden_ffi::wasm_export]
18impl EmergencyAccessClient {
19    /// Accepts an emergency access invite with the `token` from the invite email. Step 2 of the
20    /// setup; the grantor confirms next.
21    ///
22    /// Called by the grantee.
23    pub async fn accept(
24        &self,
25        emergency_access_id: EmergencyAccessId,
26        token: String,
27    ) -> Result<(), EmergencyAccessAcceptError> {
28        let request = EmergencyAccessAcceptRequestModel { token };
29
30        self.api_configurations
31            .api_client
32            .emergency_access_api()
33            .accept(emergency_access_id.into(), Some(request))
34            .await?;
35
36        Ok(())
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use bitwarden_core::client::test_accounts::test_bitwarden_com_account_v2;
43
44    use super::*;
45    use crate::{
46        EmergencyAccessClientExt,
47        test_support::{api_error, is_test_id, test_client, test_id},
48    };
49
50    const TEST_TOKEN: &str = "invite-token";
51
52    #[tokio::test]
53    async fn sends_token() {
54        let client = test_client(test_bitwarden_com_account_v2(), |mock| {
55            mock.emergency_access_api
56                .expect_accept()
57                .withf(|id, request| {
58                    is_test_id(id)
59                        && *request
60                            == Some(EmergencyAccessAcceptRequestModel {
61                                token: TEST_TOKEN.to_owned(),
62                            })
63                })
64                .returning(|_, _| Ok(()))
65                .once();
66        })
67        .await;
68
69        client
70            .emergency_access()
71            .accept(test_id(), TEST_TOKEN.to_owned())
72            .await
73            .unwrap();
74    }
75
76    #[tokio::test]
77    async fn fails_when_request_fails() {
78        let client = test_client(test_bitwarden_com_account_v2(), |mock| {
79            mock.emergency_access_api
80                .expect_accept()
81                .returning(|_, _| api_error())
82                .once();
83        })
84        .await;
85
86        let result = client
87            .emergency_access()
88            .accept(test_id(), TEST_TOKEN.to_owned())
89            .await;
90
91        assert!(matches!(result, Err(EmergencyAccessAcceptError::Api(_))));
92    }
93}