diff --git a/Cargo.lock b/Cargo.lock index 0a01bbd4..2bc2e548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2813,6 +2813,7 @@ dependencies = [ "jsonwebtoken", "lettre", "rand_core", + "regex", "reqwest", "sailfish", "sanitize-filename", diff --git a/Cargo.toml b/Cargo.toml index 4f7eab1c..aac24c81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,3 +50,5 @@ tokio = {version = "1.13", features = ["macros", "io-util", "net", "time", "rt-m lettre = { version = "0.10.0-rc.3", features = ["builder", "tokio1", "tokio1-rustls-tls", "smtp-transport"]} sailfish = "0.3.3" + +regex = "1.6.0" diff --git a/src/errors.rs b/src/errors.rs index 707c7491..eef4f851 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -21,8 +21,8 @@ pub enum ServiceError { #[display(fmt = "Email is required")] //405j EmailMissing, - #[display(fmt = "The value you entered for email is not an email")] //405j - NotAnEmail, + #[display(fmt = "Please enter a valid email address")] //405j + EmailInvalid, #[display(fmt = "The value you entered for URL is not a URL")] //405j NotAUrl, @@ -130,7 +130,7 @@ impl ResponseError for ServiceError { fn status_code(&self) -> StatusCode { match self { ServiceError::ClosedForRegistration => StatusCode::FORBIDDEN, - ServiceError::NotAnEmail => StatusCode::BAD_REQUEST, + ServiceError::EmailInvalid => StatusCode::BAD_REQUEST, ServiceError::NotAUrl => StatusCode::BAD_REQUEST, ServiceError::WrongPasswordOrUsername => StatusCode::FORBIDDEN, ServiceError::UsernameNotFound => StatusCode::NOT_FOUND, diff --git a/src/handlers/user.rs b/src/handlers/user.rs index a8882911..4fc4ff08 100644 --- a/src/handlers/user.rs +++ b/src/handlers/user.rs @@ -11,6 +11,7 @@ use crate::config::EmailOnSignup; use crate::models::response::OkResponse; use crate::models::response::TokenResponse; use crate::mailer::VerifyClaims; +use crate::utils::regex::validate_email_address; use crate::utils::time::current_time; pub fn init_routes(cfg: &mut web::ServiceConfig) { @@ -63,6 +64,13 @@ pub async fn register(req: HttpRequest, mut payload: web::Json, app_da _ => {} } + if let Some(email) = &payload.email { + // check if email address is valid + if !validate_email_address(email) { + return Err(ServiceError::EmailInvalid) + } + } + if payload.password != payload.confirm_password { return Err(ServiceError::PasswordsDontMatch) } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 57dc1c84..7226920a 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,3 +1,4 @@ pub mod parse_torrent; pub mod time; pub mod hex; +pub mod regex; diff --git a/src/utils/regex.rs b/src/utils/regex.rs new file mode 100644 index 00000000..4c5b55ff --- /dev/null +++ b/src/utils/regex.rs @@ -0,0 +1,31 @@ +use regex::Regex; + +pub fn validate_email_address(email_address_to_be_checked: &str) -> bool { + let email_regex = Regex::new(r"^([a-z\d_+]([a-z\d_+.]*[a-z\d_+])?)@([a-z\d]+([\-.][a-z\d]+)*\.[a-z]{2,6})").unwrap(); + + email_regex.is_match(email_address_to_be_checked) +} + +#[cfg(test)] +mod tests { + use crate::utils::regex::validate_email_address; + + #[test] + fn validate_email_address_test() { + assert!(!validate_email_address("test")); + + assert!(!validate_email_address("test@")); + + assert!(!validate_email_address("test@torrust")); + + assert!(!validate_email_address("test@torrust.")); + + assert!(!validate_email_address("test@.")); + + assert!(!validate_email_address("test@.com")); + + assert!(validate_email_address("test@torrust.com")); + + assert!(validate_email_address("t@torrust.org")) + } +}