Skip to content

Commit ab086d2

Browse files
authored
feat!: move operations to nested Auth and User structs (#30)
1 parent c8f0840 commit ab086d2

File tree

11 files changed

+376
-528
lines changed

11 files changed

+376
-528
lines changed

README.md

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,6 @@ Find more details about Passkey Flex on our [Passkey Flex Documentation](https:/
5959

6060
## API Reference
6161

62-
### Retrieve App Info
63-
64-
To retrieve information about the app, use the `get_app` method.
65-
66-
```rust
67-
use passage_flex::PassageFlex;
68-
69-
let passage_flex = PassageFlex::new(
70-
std::env::var("PASSAGE_APP_ID").unwrap(),
71-
std::env::var("PASSAGE_API_KEY").unwrap(),
72-
);
73-
74-
let app_info = passage_flex.get_app().await.unwrap();
75-
println!("{}", app_info.auth_origin);
76-
```
77-
7862
### Create a Registration Transaction
7963

8064
To create a transaction to start a user passkey registration, use the `create_register_transaction` method.
@@ -92,6 +76,7 @@ let passkey_display_name =
9276
"the label for the user's passkey that they will see when logging in".to_string();
9377

9478
let transaction = passage_flex
79+
.auth
9580
.create_register_transaction(external_id, passkey_display_name)
9681
.await
9782
.unwrap();
@@ -112,6 +97,7 @@ let passage_flex = PassageFlex::new(
11297
let external_id = "a unique immutable string that represents your user".to_string();
11398

11499
let transaction = passage_flex
100+
.auth
115101
.create_authenticate_transaction(external_id)
116102
.await
117103
.unwrap();
@@ -132,7 +118,7 @@ let passage_flex = PassageFlex::new(
132118
let nonce =
133119
"a unique single-use value received from the client after a passkey ceremony".to_string();
134120

135-
match passage_flex.verify_nonce(nonce).await {
121+
match passage_flex.auth.verify_nonce(nonce).await {
136122
Ok(external_id) => {
137123
// use external_id to do things like generate and send your own auth token
138124
}
@@ -144,7 +130,7 @@ match passage_flex.verify_nonce(nonce).await {
144130

145131
## Retrieve User Info
146132

147-
To retrieve information about a user by their external ID -- which is the unique, immutable ID you supply to associate the Passage user with your user -- use the `get_user` method.
133+
To retrieve information about a user by their external ID -- which is the unique, immutable ID you supply to associate the Passage user with your user -- use the `get` method.
148134

149135
```rust
150136
use passage_flex::PassageFlex;
@@ -158,13 +144,13 @@ let passage_flex = PassageFlex::new(
158144
let external_id = your_user.id;
159145

160146
// get user info
161-
let user_info = passage_flex.get_user(external_id).await.unwrap();
162-
println!("{:?}", user_info.webauthn_devices);
147+
let passage_user = passage_flex.user.get(external_id).await.unwrap();
148+
println!("{:?}", passage_user.webauthn_devices);
163149
```
164150

165151
## Retrieve a user's passkey devices
166152

167-
To retrieve information about a user's passkey devices, use the `get_devices` method.
153+
To retrieve information about a user's passkey devices, use the `list_devices` method.
168154

169155
```rust
170156
use passage_flex::PassageFlex;
@@ -177,8 +163,8 @@ let passage_flex = PassageFlex::new(
177163
// this is the same value used when creating a transaction
178164
let external_id = your_user.id;
179165

180-
// get devices
181-
let passkey_devices = passage_flex.get_devices(external_id).await.unwrap();
166+
// list devices
167+
let passkey_devices = passage_flex.user.list_devices(external_id).await.unwrap();
182168
for device in passkey_devices {
183169
println!("{}", device.usage_count);
184170
}
@@ -201,8 +187,8 @@ let passage_flex = PassageFlex::new(
201187
let external_id = your_user.id;
202188
let last_year = Utc::now().naive_utc().date() - Duration::days(365);
203189

204-
// get devices
205-
let passkey_devices = passage_flex.get_devices(external_id.clone()).await.unwrap();
190+
// list devices
191+
let passkey_devices = passage_flex.user.list_devices(external_id.clone()).await.unwrap();
206192

207193
for device in passkey_devices {
208194
// revoke old devices that haven't been used in the last year
@@ -211,6 +197,7 @@ for device in passkey_devices {
211197

212198
if last_login_at_parsed < last_year {
213199
if let Err(err) = passage_flex
200+
.user
214201
.revoke_device(external_id.clone(), device.id)
215202
.await
216203
{

examples/poem-openapi/src/main.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ impl Api {
119119
let transaction_id = self
120120
.state
121121
.passage_client
122+
.auth
122123
.create_register_transaction(user_id.clone(), req.0.email.clone())
123124
.await
124125
.map_err(|e| {
@@ -155,6 +156,7 @@ impl Api {
155156
let transaction_id = self
156157
.state
157158
.passage_client
159+
.auth
158160
.create_authenticate_transaction(user_id)
159161
.await
160162
.map_err(|e| match e {
@@ -180,7 +182,7 @@ impl Api {
180182
#[oai(path = "/auth/verify", method = "post")]
181183
async fn verify_nonce(&self, req: Json<VerifyRequest>) -> poem::Result<Json<VerifyResponse>> {
182184
// Verify the nonce using the Passage SDK
183-
match self.state.passage_client.verify_nonce(req.0.nonce).await {
185+
match self.state.passage_client.auth.verify_nonce(req.0.nonce).await {
184186
Ok(user_id) => {
185187
// Find the user in the database and set the auth token
186188
let mut users = self.state.users.lock().await;
@@ -225,6 +227,7 @@ impl Api {
225227
let transaction_id = self
226228
.state
227229
.passage_client
230+
.auth
228231
.create_register_transaction(user.id.clone(), user.email.clone())
229232
.await
230233
.map_err(|e| {
@@ -261,7 +264,8 @@ impl Api {
261264
let passkeys = self
262265
.state
263266
.passage_client
264-
.get_devices(user.id.clone())
267+
.user
268+
.list_devices(user.id.clone())
265269
.await
266270
.map(|devices| {
267271
devices
@@ -306,6 +310,7 @@ impl Api {
306310
// Revoke the passkey device using the Passage SDK
307311
self.state
308312
.passage_client
313+
.user
309314
.revoke_device(user.id.clone(), req.0.passkey_id.clone())
310315
.await
311316
.map_err(|e| {

src/auth.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use crate::openapi::apis::configuration::Configuration;
2+
use crate::openapi::apis::{authenticate_api, transactions_api};
3+
use crate::Error;
4+
5+
pub struct Auth {
6+
pub(crate) configuration: Configuration,
7+
}
8+
9+
impl Auth {
10+
/// Creates a new instance of the `Auth` struct.
11+
pub fn new(configuration: Configuration) -> Self {
12+
Self { configuration }
13+
}
14+
15+
/// Creates a transaction to start a user's registration process.
16+
///
17+
/// # Arguments
18+
///
19+
/// * `external_id` - A unique, immutable string that represents the user.
20+
/// * `passkey_display_name` - The label for the user's passkey that they will see when logging in.
21+
///
22+
/// # Returns
23+
///
24+
/// A `Result` containing the transaction ID as a string or an `Error`.
25+
///
26+
/// # Examples
27+
///
28+
/// ```ignore
29+
/// use passage_flex::PassageFlex;
30+
///
31+
/// let passage_flex = PassageFlex::new(
32+
/// std::env::var("PASSAGE_APP_ID").unwrap(),
33+
/// std::env::var("PASSAGE_API_KEY").unwrap(),
34+
/// );
35+
///
36+
/// let transaction = passage_flex
37+
/// .auth
38+
/// .create_register_transaction(
39+
/// "00000000-0000-0000-0000-000000000001".to_string(),
40+
/// "user@example.com".to_string(),
41+
/// )
42+
/// .await
43+
/// .unwrap();
44+
/// ```
45+
pub async fn create_register_transaction(
46+
&self,
47+
external_id: String,
48+
passkey_display_name: String,
49+
) -> Result<String, Error> {
50+
transactions_api::create_register_transaction(
51+
&self.configuration,
52+
crate::openapi::models::CreateTransactionRegisterRequest {
53+
external_id,
54+
passkey_display_name,
55+
},
56+
)
57+
.await
58+
.map(|response| response.transaction_id)
59+
.map_err(Into::into)
60+
}
61+
62+
/// Creates a transaction to start a user's authentication process.
63+
///
64+
/// # Arguments
65+
///
66+
/// * `external_id` - A unique, immutable string that represents the user.
67+
///
68+
/// # Returns
69+
///
70+
/// A `Result` containing the transaction ID as a string or an `Error`.
71+
///
72+
/// # Examples
73+
///
74+
/// ```ignore
75+
/// use passage_flex::PassageFlex;
76+
///
77+
/// let passage_flex = PassageFlex::new(
78+
/// std::env::var("PASSAGE_APP_ID").unwrap(),
79+
/// std::env::var("PASSAGE_API_KEY").unwrap(),
80+
/// );
81+
///
82+
/// let transaction = passage_flex
83+
/// .auth
84+
/// .create_authenticate_transaction(
85+
/// "00000000-0000-0000-0000-000000000001".to_string(),
86+
/// )
87+
/// .await
88+
/// .unwrap();
89+
/// ```
90+
pub async fn create_authenticate_transaction(
91+
&self,
92+
external_id: String,
93+
) -> Result<String, Error> {
94+
transactions_api::create_authenticate_transaction(
95+
&self.configuration,
96+
crate::openapi::models::CreateTransactionAuthenticateRequest { external_id },
97+
)
98+
.await
99+
.map(|response| response.transaction_id)
100+
.map_err(Into::into)
101+
}
102+
103+
/// Verifies the nonce received from a WebAuthn registration or authentication ceremony.
104+
///
105+
/// # Arguments
106+
///
107+
/// * `nonce` - The nonce string to be verified.
108+
///
109+
/// # Returns
110+
///
111+
/// A `Result` containing the external ID as a string or an `Error`.
112+
///
113+
/// # Examples
114+
///
115+
/// ```ignore
116+
/// use passage_flex::PassageFlex;
117+
///
118+
/// let passage_flex = PassageFlex::new(
119+
/// std::env::var("PASSAGE_APP_ID").unwrap(),
120+
/// std::env::var("PASSAGE_API_KEY").unwrap(),
121+
/// );
122+
///
123+
/// match passage_flex.auth.verify_nonce("01234567890123456789".to_string()).await {
124+
/// Ok(external_id) => {
125+
/// // use external_id to do things like generate and send your own auth token
126+
/// }
127+
/// Err(err) => {
128+
/// // nonce was invalid or unable to be verified
129+
/// }
130+
/// }
131+
/// ```
132+
pub async fn verify_nonce(&self, nonce: String) -> Result<String, Error> {
133+
authenticate_api::authenticate_verify_nonce(
134+
&self.configuration,
135+
crate::openapi::models::Nonce { nonce },
136+
)
137+
.await
138+
.map(|response| response.external_id)
139+
.map_err(Into::into)
140+
}
141+
}

src/error.rs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::openapi::apis::{
2-
apps_api, authenticate_api, transactions_api, user_devices_api, users_api,
3-
};
1+
use crate::openapi::apis::{authenticate_api, transactions_api, user_devices_api, users_api};
42
use crate::Error;
53

64
// This function converts an openapi error into a crate error
@@ -16,17 +14,6 @@ fn convert_error<Src>(error: crate::openapi::apis::Error<Src>, map_fn: fn(Src) -
1614
}
1715
}
1816

19-
impl From<crate::openapi::apis::Error<apps_api::GetAppError>> for Error {
20-
fn from(e: crate::openapi::apis::Error<apps_api::GetAppError>) -> Self {
21-
convert_error(e, |e| match e {
22-
apps_api::GetAppError::Status401(model) => model.into(),
23-
apps_api::GetAppError::Status404(model) => model.into(),
24-
apps_api::GetAppError::Status500(model) => model.into(),
25-
apps_api::GetAppError::UnknownValue(v) => Error::Other(v.to_string()),
26-
})
27-
}
28-
}
29-
3017
impl From<crate::openapi::apis::Error<transactions_api::CreateRegisterTransactionError>> for Error {
3118
fn from(
3219
e: crate::openapi::apis::Error<transactions_api::CreateRegisterTransactionError>,

src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
//! std::env::var("PASSAGE_APP_ID").unwrap(),
1111
//! std::env::var("PASSAGE_API_KEY").unwrap(),
1212
//! );
13-
//!
14-
//! let app_info = passage_flex.get_app().await.unwrap();
15-
//! println!("{}", app_info.auth_origin);
1613
//! ```
1714
1815
use std::fmt;
@@ -62,5 +59,7 @@ pub mod models;
6259
#[rustfmt::skip]
6360
pub mod openapi;
6461

62+
pub mod auth;
6563
pub mod passage_flex;
64+
pub mod user;
6665
pub use passage_flex::PassageFlex;

src/models/app_info.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/models/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
mod app_info;
2-
mod user_info;
1+
mod passage_user;
32

4-
pub use app_info::AppInfo;
5-
pub use user_info::UserInfo;
3+
pub use passage_user::PassageUser;

src/models/user_info.rs renamed to src/models/passage_user.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use serde::{Deserialize, Serialize};
22

33
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
4-
pub struct UserInfo {
4+
pub struct PassageUser {
55
#[serde(rename = "created_at")]
66
pub created_at: String,
77
/// The external ID of the user. Only set if the user was created in a Flex app.

0 commit comments

Comments
 (0)