bitwarden_emergency_access/
invite.rs1use bitwarden_api_api::models::EmergencyAccessInviteRequestModel;
2use bitwarden_core::ApiError;
3use bitwarden_error::bitwarden_error;
4use thiserror::Error;
5
6use crate::{EmergencyAccessClient, EmergencyAccessType};
7
8#[bitwarden_error(flat)]
10#[derive(Debug, Error)]
11pub enum EmergencyAccessInviteError {
12 #[error(transparent)]
14 Api(#[from] ApiError),
15}
16
17#[bitwarden_ffi::wasm_export]
18impl EmergencyAccessClient {
19 pub async fn invite(
24 &self,
25 grantee_email: String,
26 r#type: EmergencyAccessType,
27 wait_time_days: i32,
28 ) -> Result<(), EmergencyAccessInviteError> {
29 let request = EmergencyAccessInviteRequestModel {
30 email: grantee_email.trim().to_owned(),
31 r#type: r#type.into(),
32 wait_time_days,
33 };
34
35 self.api_configurations
36 .api_client
37 .emergency_access_api()
38 .invite(Some(request))
39 .await?;
40
41 Ok(())
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use bitwarden_api_api::models::EmergencyAccessType as ApiEmergencyAccessType;
48 use bitwarden_core::client::test_accounts::test_bitwarden_com_account;
49
50 use super::*;
51 use crate::{
52 EmergencyAccessClientExt,
53 test_support::{api_error, test_client},
54 };
55
56 const TEST_EMAIL: &str = "[email protected]";
57 const TEST_WAIT_TIME_DAYS: i32 = 7;
58
59 #[tokio::test]
60 async fn sends_trimmed_invite() {
61 let client = test_client(test_bitwarden_com_account(), |mock| {
62 mock.emergency_access_api
63 .expect_invite()
64 .withf(|request| {
65 *request
66 == Some(EmergencyAccessInviteRequestModel {
67 email: TEST_EMAIL.to_owned(),
68 r#type: ApiEmergencyAccessType::Takeover,
69 wait_time_days: TEST_WAIT_TIME_DAYS,
70 })
71 })
72 .returning(|_| Ok(()))
73 .once();
74 })
75 .await;
76
77 client
78 .emergency_access()
79 .invite(
80 format!(" {TEST_EMAIL} "),
81 EmergencyAccessType::Takeover,
82 TEST_WAIT_TIME_DAYS,
83 )
84 .await
85 .unwrap();
86 }
87
88 #[tokio::test]
89 async fn fails_when_request_fails() {
90 let client = test_client(test_bitwarden_com_account(), |mock| {
91 mock.emergency_access_api
92 .expect_invite()
93 .returning(|_| api_error())
94 .once();
95 })
96 .await;
97
98 let result = client
99 .emergency_access()
100 .invite(
101 TEST_EMAIL.to_owned(),
102 EmergencyAccessType::View,
103 TEST_WAIT_TIME_DAYS,
104 )
105 .await;
106
107 assert!(matches!(result, Err(EmergencyAccessInviteError::Api(_))));
108 }
109}