fix otp and password validation

This commit is contained in:
Bakunya
2025-04-06 19:15:01 +07:00
parent 09a7f4371a
commit d2b098ed92
3 changed files with 28 additions and 7 deletions
+17 -4
View File
@@ -3,10 +3,23 @@ use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use validator::Validate;
use validator::{Validate, ValidationError};
lazy_static! {
static ref PASSWORD_REGEX: Regex = Regex::new(r"^[A-Za-z\d@$!%*?&]{8,}$").unwrap();
static ref PASSWORD_REGEX: Regex = Regex::new(r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$").unwrap();
}
fn validate_password_complexity(password: &str) -> Result<(), ValidationError> {
let has_uppercase = password.chars().any(|c| c.is_ascii_uppercase());
let has_lowercase = password.chars().any(|c| c.is_ascii_lowercase());
let has_digit = password.chars().any(|c| c.is_ascii_digit());
let has_special = password.chars().any(|c| "@$!%*?&".contains(c));
if has_uppercase && has_lowercase && has_digit && has_special {
Ok(())
} else {
Err(ValidationError::new("complexity"))
}
}
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema, Validate)]
@@ -56,8 +69,8 @@ pub struct AuthRegisterRequestDto {
min = 8,
message = "Password must have at least 8 characters"
))]
#[validate(regex(
path = "PASSWORD_REGEX",
#[validate(custom(
function = "validate_password_complexity",
message = "Password must include uppercase, lowercase, number, and special character"
))]
pub password: String,
@@ -88,7 +88,7 @@ impl<'a> AuthRepository<'a> {
pub async fn query_store_otp(&self, email: String, otp: u32) -> Result<String> {
let expires_at = Utc::now() + Duration::seconds(300);
let table = ResourceEnum::OtpCache.to_string();
let table: String = ResourceEnum::OtpCache.to_string();
let record: Option<AuthOtpSchema> = self
.state
.surrealdb_mem
+10 -2
View File
@@ -202,10 +202,18 @@ impl AuthService {
if let Err((status, message)) = validate_request(&payload) {
return common_response(status, &message);
}
let repository = AuthRepository::new(state);
let user_repo = UsersRepository::new(state);
if user_repo.query_user_by_email(payload.email.clone()).await.is_err() {
return common_response(StatusCode::BAD_REQUEST, "User not found");
}
let auth_repo = AuthRepository::new(state);
let _ = auth_repo.query_get_stored_otp(payload.email.clone()).await;
let otp = generate_otp::OtpManager::generate_otp();
let message = format!("Your OTP code is {}", otp);
match repository.query_store_otp(payload.email.clone(), otp).await {
match auth_repo.query_store_otp(payload.email.clone(), otp).await {
Ok(_) => match send_email(&payload.email, "OTP Verification", &message) {
Ok(_) => common_response(StatusCode::OK, "OTP resent successfully"),
Err(err) => common_response(StatusCode::BAD_REQUEST, &err.to_string()),