Skip to content

Commit fb7c8f6

Browse files
committed
fix reregister
1 parent 0c91e0a commit fb7c8f6

3 files changed

Lines changed: 94 additions & 18 deletions

File tree

src/auth/service.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::error::AppError;
1+
use crate::{error::AppError, models::UpdateUser};
22
use crate::schema::users;
33
use crate::utils::enums::Role;
44
use crate::utils::helpers::generate_numeric_code;
@@ -26,7 +26,7 @@ use diesel::pg::PgConnection;
2626
use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation, TokenData};
2727
use serde::{Serialize, Deserialize};
2828
use uuid::Uuid;
29-
use chrono::Utc;
29+
use chrono::{DateTime, Utc};
3030
use chrono::Duration;
3131

3232
#[derive(Debug, Serialize, Deserialize)]
@@ -37,36 +37,58 @@ pub struct Claims {
3737

3838
pub fn create_user(
3939
conn: &mut PgConnection,
40-
email: &str,
41-
password: &str,
42-
role: Role,
40+
user_email: &str,
41+
raw_password: &str,
42+
user_role: Role,
4343
) -> Result<User> {
44+
use diesel::prelude::*;
45+
use crate::schema::users::dsl::*;
4446

45-
// ---- Hash password using Argon2 ----
47+
// Find soft-deleted user
48+
let deleted = users
49+
.filter(email.eq(user_email))
50+
.filter(deleted_at.is_not_null())
51+
.first::<User>(conn)
52+
.optional()?;
53+
54+
// ---- Hash password ----
4655
let argon2 = Argon2::default();
4756
let salt = SaltString::generate(&mut OsRng);
4857

49-
let password_hash = argon2
50-
.hash_password(password.as_bytes(), &salt)
58+
let hashed_password = argon2
59+
.hash_password(raw_password.as_bytes(), &salt)
5160
.map_err(|e| anyhow!("failed to hash password: {}", e))?
5261
.to_string();
5362

54-
// ---- Prepare new user struct ----
63+
// ---- Restore soft-deleted user ----
64+
if let Some(deleted_user) = deleted {
65+
let restored = diesel::update(users.find(deleted_user.id))
66+
.set((
67+
password_hash.eq(&hashed_password),
68+
role.eq(user_role),
69+
deleted_at.eq::<Option<DateTime<Utc>>>(None), // ✅ FORCE NULL
70+
))
71+
.returning(User::as_returning())
72+
.get_result::<User>(conn)?;
73+
74+
return Ok(restored);
75+
}
76+
77+
// ---- Insert new user ----
5578
let new_user = NewUser {
5679
first_name: "",
5780
last_name: "",
58-
email,
81+
email: user_email,
5982
phone: None,
6083
gender: None,
6184
address: None,
6285
dob: None,
6386
image_url: None,
64-
password_hash: &password_hash,
65-
role,
87+
password_hash: &hashed_password,
88+
role: user_role,
6689
};
6790

68-
// ---- Insert and return the newly created user ----
69-
let user = diesel::insert_into(users::table)
91+
let user = diesel::insert_into(users)
7092
.values(&new_user)
7193
.returning(User::as_returning())
7294
.get_result::<User>(conn)?;

src/handlers/auth.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,52 @@ pub async fn register(
146146
.first::<User>(&mut conn)
147147
.optional()?;
148148

149-
if existing_user.is_some() {
150-
return Err(AppError::UserAlreadyExists);
151-
}
152-
153149
let other_role = payload
154150
.role
155151
.parse::<Role>()?;
156152

153+
if let Some(user) = existing_user {
154+
if user.deleted_at.is_some() {
155+
if user.email_verified {
156+
// Email already verified: send welcome back email instead
157+
let mail_service = state.mail_service.clone();
158+
let email_clone = user.email.clone();
159+
tokio::spawn(async move {
160+
let _ = mail_service.send_notification(
161+
&email_clone,
162+
"Welcome back to HealthBridge",
163+
"<p>Welcome back! Your email is already verified.</p>",
164+
Some("Welcome back! Your email is already verified."),
165+
).await;
166+
});
167+
168+
let user = auth::create_user(
169+
&mut conn,
170+
&payload.email,
171+
&payload.password,
172+
other_role,
173+
)?;
174+
175+
return Ok(ApiResponse::success_with_message(
176+
"Welcome back! Your email is already verified.",
177+
AuthResponse {
178+
token: "".to_string(),
179+
refresh_token: "".to_string(),
180+
user: user.into(),
181+
},
182+
));
183+
} else {
184+
return Err(AppError::UserAlreadyExists);
185+
}
186+
}
187+
}
188+
189+
info!("User not deletedddd");
190+
191+
// let other_role = payload
192+
// .role
193+
// .parse::<Role>()?;
194+
157195
let user = auth::create_user(
158196
&mut conn,
159197
&payload.email,

src/models.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ pub struct NewUser<'a> {
7676
pub role: Role,
7777
}
7878

79+
#[derive(AsChangeset)]
80+
#[diesel(table_name = users)]
81+
pub struct UpdateUser<'a> {
82+
pub first_name: &'a str,
83+
pub last_name: &'a str,
84+
pub phone: Option<&'a str>,
85+
pub gender: Option<Gender>,
86+
pub address: Option<&'a str>,
87+
pub dob: Option<NaiveDate>,
88+
pub image_url: Option<&'a str>,
89+
pub password_hash: &'a str,
90+
pub role: Role,
91+
pub deleted_at: Option<DateTime<Utc>>,
92+
}
93+
94+
7995
#[derive(Debug, Queryable, Selectable, Identifiable)]
8096
#[diesel(table_name = email_verification_tokens)]
8197
#[diesel(check_for_backend(diesel::pg::Pg))]

0 commit comments

Comments
 (0)