Skip to content

Commit

Permalink
added email sign up confirmation result to handle different possible …
Browse files Browse the repository at this point in the history
…responses from supabase
  • Loading branch information
Raflos10 committed Feb 27, 2025
1 parent 8906ecb commit 65c757d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 16 additions & 12 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ use crate::{
SupabaseHTTPError,
},
models::{
AuthClient, AuthServerHealth, AuthServerSettings, IdTokenCredentials, InviteParams,
LoginAnonymouslyOptions, LoginAnonymouslyPayload, LoginEmailOtpParams,
LoginWithEmailAndPasswordPayload, LoginWithEmailOtpPayload, LoginWithOAuthOptions,
LoginWithPhoneAndPasswordPayload, LoginWithSSO, LogoutScope, OAuthResponse, OTPResponse,
Provider, RefreshSessionPayload, RequestMagicLinkPayload, ResendParams,
ResetPasswordForEmailPayload, ResetPasswordOptions, SendSMSOtpPayload, Session,
SignUpWithEmailAndPasswordPayload, SignUpWithPasswordOptions,
AuthClient, AuthServerHealth, AuthServerSettings, EmailSignUpConfirmation,
EmailSignUpResult, IdTokenCredentials, InviteParams, LoginAnonymouslyOptions,
LoginAnonymouslyPayload, LoginEmailOtpParams, LoginWithEmailAndPasswordPayload,
LoginWithEmailOtpPayload, LoginWithOAuthOptions, LoginWithPhoneAndPasswordPayload,
LoginWithSSO, LogoutScope, OAuthResponse, OTPResponse, Provider, RefreshSessionPayload,
RequestMagicLinkPayload, ResendParams, ResetPasswordForEmailPayload, ResetPasswordOptions,
SendSMSOtpPayload, Session, SignUpWithEmailAndPasswordPayload, SignUpWithPasswordOptions,
SignUpWithPhoneAndPasswordPayload, UpdatedUser, User, VerifyOtpParams, AUTH_V1,
},
};
Expand Down Expand Up @@ -183,19 +183,19 @@ impl AuthClient {
/// Sign up a new user with an email and password
/// # Example
/// ```
/// let session = auth_client
/// let result = auth_client
/// .sign_up_with_email_and_password(demo_email, demo_password)
/// .await
/// .unwrap();
///
/// assert!(session.user.email == demo_email)
/// assert!(result.session.user.email == demo_email)
///```
pub async fn sign_up_with_email_and_password(
&self,
email: &str,
password: &str,
options: Option<SignUpWithPasswordOptions>,
) -> Result<Session, Error> {
) -> Result<EmailSignUpResult, Error> {
let redirect_to = options
.as_ref()
.and_then(|o| o.email_redirect_to.as_deref().map(str::to_owned));
Expand Down Expand Up @@ -224,8 +224,12 @@ impl AuthClient {
let res_status = response.status();
let res_body = response.text().await?;

if let Ok(session) = from_str(&res_body) {
return Ok(session);
if let Ok(session) = from_str::<Session>(&res_body) {
return Ok(EmailSignUpResult::SessionResult(session));
}

if let Ok(result) = from_str::<EmailSignUpConfirmation>(&res_body) {
return Ok(EmailSignUpResult::ConfirmationResult(result));
}

if let Ok(error) = from_str::<SupabaseHTTPError>(&res_body) {
Expand Down
30 changes: 29 additions & 1 deletion src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use core::fmt;
use reqwest::{Client, Url};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use uuid::Uuid;
use std::{collections::HashMap, fmt::Display};
use uuid::Uuid;

/// Supabase Auth Client
#[derive(Clone)]
Expand Down Expand Up @@ -98,6 +98,34 @@ pub struct UserMetadata {
pub custom: HashMap<String, Value>,
}

#[derive(Debug)]
pub enum EmailSignUpResult {
SessionResult(Session),
ConfirmationResult(EmailSignUpConfirmation),
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct EmailSignUpConfirmation {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub aud: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub confirmation_sent_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_anonymous: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct IdTokenCredentials {
/// Provider name or OIDC `iss` value identifying which provider should be used to verify the provided token.
Expand Down
60 changes: 34 additions & 26 deletions tests/client_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use std::{collections::HashMap, env, thread};
use supabase_auth::{
error::Error,
models::{
AuthClient, LoginEmailOtpParams, LoginWithOAuthOptions, LoginWithSSO, LogoutScope,
ResendParams, ResetPasswordOptions, SignUpWithPasswordOptions, UpdatedUser,
AuthClient, EmailSignUpResult, LoginEmailOtpParams, LoginWithOAuthOptions, LoginWithSSO,
LogoutScope, ResendParams, ResetPasswordOptions, SignUpWithPasswordOptions, UpdatedUser,
},
};

Expand Down Expand Up @@ -73,7 +73,7 @@ async fn sign_up_with_email_test_valid() {
..Default::default()
};

let session = auth_client
let result = auth_client
.sign_up_with_email_and_password(demo_email.as_ref(), demo_password, Some(options))
.await
.unwrap();
Expand All @@ -82,19 +82,21 @@ async fn sign_up_with_email_test_valid() {
let one_minute = time::Duration::from_secs(60);
thread::sleep(one_minute);

assert!(session.user.email == demo_email);
assert!(session.user.user_metadata.name.unwrap() == "test");
assert!(
session
.user
.user_metadata
.custom
.get("test")
.unwrap()
.as_str()
.unwrap()
== "test"
)
if let EmailSignUpResult::SessionResult(session) = result {
assert!(session.user.email == demo_email);
assert!(session.user.user_metadata.name.unwrap() == "test");
assert!(
session
.user
.user_metadata
.custom
.get("test")
.unwrap()
.as_str()
.unwrap()
== "test"
)
}
}

#[tokio::test]
Expand Down Expand Up @@ -164,8 +166,8 @@ fn login_with_oauth_test() {
skip_brower_redirect: Some(true),
};

let response = auth_client
.login_with_oauth(supabase_auth::models::Provider::Github, Some(options));
let response =
auth_client.login_with_oauth(supabase_auth::models::Provider::Github, Some(options));

if response.is_err() {
println!("SIGN IN WITH OAUTH TEST RESPONSE -- \n{:?}", response);
Expand All @@ -191,8 +193,8 @@ fn sign_up_with_oauth_test() {
skip_brower_redirect: Some(true),
};

let response = auth_client
.sign_up_with_oauth(supabase_auth::models::Provider::Github, Some(options));
let response =
auth_client.sign_up_with_oauth(supabase_auth::models::Provider::Github, Some(options));

if response.is_err() {
println!("SIGN IN WITH OAUTH TEST RESPONSE -- \n{:?}", response);
Expand All @@ -217,8 +219,7 @@ fn login_with_oauth_no_options_test() {
// eprintln!("{:?}", session.as_ref().unwrap_err())
// }

let response = auth_client
.login_with_oauth(supabase_auth::models::Provider::Github, None);
let response = auth_client.login_with_oauth(supabase_auth::models::Provider::Github, None);

println!(
"SIGN IN WITH OAUTH \n NO OPTIONS TEST RESPONSE -- \n{:?}",
Expand Down Expand Up @@ -379,12 +380,12 @@ async fn resend_email_test() {
let demo_email = format!("signup__{}@demo.com", uuid);
let demo_password = "ciJUAojfZZYKfCxkiUWH";

let session = auth_client
let result = auth_client
.sign_up_with_email_and_password(&demo_email, demo_password, None)
.await;

if session.is_err() {
eprintln!("{:?}", session.as_ref().unwrap_err())
if result.is_err() {
eprintln!("{:?}", result.as_ref().unwrap_err())
}

let credentials = ResendParams {
Expand All @@ -403,7 +404,14 @@ async fn resend_email_test() {
println!("{:?}", response)
}

assert!(response.is_ok() && session.unwrap().user.email == demo_email)
match result.unwrap() {
EmailSignUpResult::SessionResult(session) => {
assert!(response.is_ok() && session.user.email == demo_email)
}
EmailSignUpResult::ConfirmationResult(email_sign_up_confirmation) => {
assert!(response.is_ok() && email_sign_up_confirmation.email.unwrap() == demo_email)
}
}
}

#[tokio::test]
Expand Down

0 comments on commit 65c757d

Please sign in to comment.