diff --git a/src/controllers/user/me.rs b/src/controllers/user/me.rs index 13b2cd91d79..e181c90b88e 100644 --- a/src/controllers/user/me.rs +++ b/src/controllers/user/me.rs @@ -5,6 +5,7 @@ use axum::Json; use diesel::prelude::*; use diesel_async::async_connection_wrapper::AsyncConnectionWrapper; use http::request::Parts; +use lettre::Address; use secrecy::{ExposeSecret, SecretString}; use serde_json::Value; use std::collections::HashMap; @@ -152,6 +153,10 @@ pub async fn update_user( return Err(bad_request("empty email rejected")); } + user_email + .parse::
() + .map_err(|_| bad_request("invalid email address"))?; + conn.transaction::<_, BoxedAppError, _>(|conn| { let new_email = NewEmail { user_id: user.id, diff --git a/src/tests/routes/users/update.rs b/src/tests/routes/users/update.rs index 39224d6d0bd..bbda0d69545 100644 --- a/src/tests/routes/users/update.rs +++ b/src/tests/routes/users/update.rs @@ -96,3 +96,13 @@ async fn test_other_users_cannot_change_my_email() { assert_eq!(response.status(), StatusCode::FORBIDDEN); assert_snapshot!(response.text(), @r###"{"errors":[{"detail":"this action requires authentication"}]}"###); } + +#[tokio::test(flavor = "multi_thread")] +async fn test_invalid_email_address() { + let (_app, _, user) = TestApp::init().with_user(); + let model = user.as_model(); + + let response = user.update_email_more_control(model.id, Some("foo")).await; + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + assert_snapshot!(response.text(), @r###"{"errors":[{"detail":"invalid email address"}]}"###); +}