Skip to content
This repository was archived by the owner on May 13, 2026. It is now read-only.

Commit ac0205a

Browse files
committed
invitation features
1 parent 5b12b88 commit ac0205a

9 files changed

Lines changed: 933 additions & 0 deletions

File tree

src/user_management/operations.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ mod list_auth_factors;
2323
mod list_users;
2424
mod reset_password;
2525
mod update_user;
26+
mod send_invitation;
27+
mod get_invitation;
28+
mod get_invitation_by_token;
29+
mod accept_invitation;
30+
mod revoke_invitation;
31+
mod list_invitations;
2632

2733
pub use authenticate_with_code::*;
2834
pub use authenticate_with_email_verification::*;
@@ -49,3 +55,9 @@ pub use list_auth_factors::*;
4955
pub use list_users::*;
5056
pub use reset_password::*;
5157
pub use update_user::*;
58+
pub use send_invitation::*;
59+
pub use get_invitation::*;
60+
pub use get_invitation_by_token::*;
61+
pub use accept_invitation::*;
62+
pub use revoke_invitation::*;
63+
pub use list_invitations::*;
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use async_trait::async_trait;
2+
use thiserror::Error;
3+
4+
use crate::user_management::{Invitation, InvitationId, UserManagement};
5+
use crate::{ResponseExt, WorkOsError, WorkOsResult};
6+
7+
/// An error returned from [`AcceptInvitation`].
8+
#[derive(Debug, Error)]
9+
pub enum AcceptInvitationError {}
10+
11+
impl From<AcceptInvitationError> for WorkOsError<AcceptInvitationError> {
12+
fn from(err: AcceptInvitationError) -> Self {
13+
Self::Operation(err)
14+
}
15+
}
16+
17+
/// [WorkOS Docs: Accept an invitation](https://workos.com/docs/reference/user-management/invitation/accept
18+
#[async_trait]
19+
pub trait AcceptInvitation {
20+
/// Accepts an invitation and, if linked to an organization, activates the user’s membership in that organization.
21+
///
22+
/// [WorkOS Docs: Accept an invitation](https://workos.com/docs/reference/user-management/invitation/accept)
23+
///
24+
/// # Examples
25+
///
26+
/// ```
27+
/// use std::collections::HashSet;
28+
///
29+
/// # use workos_sdk::WorkOsResult;
30+
/// # use workos_sdk::user_management::*;
31+
/// use workos_sdk::{ApiKey, WorkOs}; ///
32+
/// #
33+
/// use workos_sdk::organizations::OrganizationId;
34+
///
35+
/// async fn run() -> WorkOsResult<(), AcceptInvitationError> {
36+
/// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789"));
37+
///
38+
/// let invitation = workos
39+
/// .user_management()
40+
/// .accept_invitation(&InvitationId::from("invitation_01E4ZCR3C56J083X43JQXF3JK5"))
41+
/// .await?;
42+
/// # Ok(())
43+
/// # }
44+
/// ```
45+
async fn accept_invitation(
46+
&self,
47+
id: &InvitationId,
48+
) -> WorkOsResult<Invitation, AcceptInvitationError>;
49+
}
50+
51+
#[async_trait]
52+
impl AcceptInvitation for UserManagement<'_> {
53+
async fn accept_invitation(
54+
&self,
55+
id: &InvitationId,
56+
) -> WorkOsResult<Invitation, AcceptInvitationError> {
57+
let url = self
58+
.workos
59+
.base_url()
60+
.join(&format!("/user_management/invitations/{id}/accept"))?;
61+
62+
let invitation = self
63+
.workos
64+
.client()
65+
.post(url)
66+
.bearer_auth(self.workos.key())
67+
.send()
68+
.await?
69+
.handle_unauthorized_or_generic_error()?
70+
.json::<Invitation>()
71+
.await?;
72+
73+
Ok(invitation)
74+
}
75+
}
76+
77+
#[cfg(test)]
78+
mod test {
79+
use serde_json::json;
80+
use tokio;
81+
82+
use crate::{ApiKey, WorkOs};
83+
84+
use super::*;
85+
86+
#[tokio::test]
87+
async fn it_calls_the_accept_invitation_endpoint() {
88+
let mut server = mockito::Server::new_async().await;
89+
90+
let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789"))
91+
.base_url(&server.url())
92+
.unwrap()
93+
.build();
94+
95+
server
96+
.mock(
97+
"POST",
98+
"/user_management/invitations/invitation_01E4ZCR3C56J083X43JQXF3JK5/accept",
99+
)
100+
.match_header("Authorization", "Bearer sk_example_123456789")
101+
.with_status(200)
102+
.with_body(
103+
json!({
104+
"object": "invitation",
105+
"id": "invitation_01E4ZCR3C56J083X43JQXF3JK5",
106+
"email": "marcelina.davis@example.com",
107+
"state": "pending",
108+
"accepted_at": "2021-07-01T19:07:33.155Z",
109+
"revoked_at": null,
110+
"expires_at": "2021-07-01T19:07:33.155Z",
111+
"token": "Z1uX3RbwcIl5fIGJJJCXXisdI",
112+
"accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
113+
"organization_id": "org_01E4ZCR3C56J083X43JQXF3JK5",
114+
"inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3",
115+
"created_at": "2021-06-25T19:07:33.155Z",
116+
"updated_at": "2021-06-25T19:07:33.155Z"
117+
})
118+
.to_string(),
119+
)
120+
.create_async()
121+
.await;
122+
123+
let invitation = workos
124+
.user_management()
125+
.accept_invitation(&InvitationId::from("invitation_01E4ZCR3C56J083X43JQXF3JK5"))
126+
.await
127+
.unwrap();
128+
129+
assert_eq!(invitation.email, String::from("marcelina.davis@example.com"));
130+
assert!(invitation.accepted_at.is_some());
131+
}
132+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use async_trait::async_trait;
2+
use thiserror::Error;
3+
4+
use crate::user_management::{Invitation, InvitationId, UserManagement};
5+
use crate::{ResponseExt, WorkOsError, WorkOsResult};
6+
7+
/// An error returned from [`GetInvitation`].
8+
#[derive(Debug, Error)]
9+
pub enum GetInvitationError {}
10+
11+
impl From<GetInvitationError> for WorkOsError<GetInvitationError> {
12+
fn from(err: GetInvitationError) -> Self {
13+
Self::Operation(err)
14+
}
15+
}
16+
17+
/// [WorkOS Docs: Get an invitation](https://workos.com/docs/reference/user-management/invitation/get)
18+
#[async_trait]
19+
pub trait GetInvitation {
20+
/// Get the details of an existing invitation.
21+
///
22+
/// [WorkOS Docs: Get an invitation](https://workos.com/docs/reference/user-management/invitation/get)
23+
///
24+
/// # Examples
25+
///
26+
/// ```
27+
/// use std::collections::HashSet;
28+
///
29+
/// # use workos_sdk::WorkOsResult;
30+
/// # use workos_sdk::user_management::*;
31+
/// use workos_sdk::{ApiKey, WorkOs}; ///
32+
/// #
33+
/// use workos_sdk::organizations::OrganizationId;
34+
///
35+
/// async fn run() -> WorkOsResult<(), GetInvitationError> {
36+
/// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789"));
37+
///
38+
/// let invitation = workos
39+
/// .user_management()
40+
/// .get_invitation(&InvitationId::from("invitation_01E4ZCR3C56J083X43JQXF3JK5"))
41+
/// .await?;
42+
/// # Ok(())
43+
/// # }
44+
/// ```
45+
async fn get_invitation(
46+
&self,
47+
id: &InvitationId,
48+
) -> WorkOsResult<Invitation, GetInvitationError>;
49+
}
50+
51+
#[async_trait]
52+
impl GetInvitation for UserManagement<'_> {
53+
async fn get_invitation(
54+
&self,
55+
id: &InvitationId,
56+
) -> WorkOsResult<Invitation, GetInvitationError> {
57+
let url = self
58+
.workos
59+
.base_url()
60+
.join(&format!("user_management/invitations/{id}"))?;
61+
62+
let invitation = self
63+
.workos
64+
.client()
65+
.get(url)
66+
.bearer_auth(self.workos.key())
67+
.send()
68+
.await?
69+
.handle_unauthorized_or_generic_error()?
70+
.json::<Invitation>()
71+
.await?;
72+
73+
Ok(invitation)
74+
}
75+
}
76+
77+
#[cfg(test)]
78+
mod test {
79+
use serde_json::json;
80+
use tokio;
81+
82+
use crate::{ApiKey, WorkOs};
83+
84+
use super::*;
85+
86+
#[tokio::test]
87+
async fn it_calls_the_get_invitation_endpoint() {
88+
let mut server = mockito::Server::new_async().await;
89+
90+
let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789"))
91+
.base_url(&server.url())
92+
.unwrap()
93+
.build();
94+
95+
server
96+
.mock(
97+
"GET",
98+
"/user_management/invitations/invitation_123456789",
99+
)
100+
.match_header("Authorization", "Bearer sk_example_123456789")
101+
.with_status(200)
102+
.with_body(
103+
json!({
104+
"object": "invitation",
105+
"id": "invitation_01E4ZCR3C56J083X43JQXF3JK5",
106+
"email": "marcelina.davis@example.com",
107+
"state": "pending",
108+
"accepted_at": null,
109+
"revoked_at": null,
110+
"expires_at": "2021-07-01T19:07:33.155Z",
111+
"token": "Z1uX3RbwcIl5fIGJJJCXXisdI",
112+
"accept_invitation_url": "https://your-app.com/invite?invitation_token=Z1uX3RbwcIl5fIGJJJCXXisdI",
113+
"organization_id": "org_01E4ZCR3C56J083X43JQXF3JK5",
114+
"inviter_user_id": "user_01HYGBX8ZGD19949T3BM4FW1C3",
115+
"created_at": "2021-06-25T19:07:33.155Z",
116+
"updated_at": "2021-06-25T19:07:33.155Z"
117+
})
118+
.to_string(),
119+
)
120+
.create_async()
121+
.await;
122+
123+
let invitation = workos
124+
.user_management()
125+
.get_invitation(&InvitationId::from("invitation_01E4ZCR3C56J083X43JQXF3JK5"))
126+
.await
127+
.unwrap();
128+
129+
assert_eq!(invitation.id, InvitationId::from("invitation_01E4ZCR3C56J083X43JQXF3JK5"));
130+
}
131+
}

0 commit comments

Comments
 (0)