summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-03-27 12:14:57 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-03-27 12:15:16 -0500
commite3cb1a5f3c57b3c857107f735651268e0a78692b (patch)
tree78445b28dc08a62370c3e8fb7cc14ea5348244da /src
parentce961ca85ba96813ccdca9be1d18ee11e4e0d25c (diff)
feat: add registration email format validation
Diffstat (limited to 'src')
-rw-r--r--src/error.rs10
-rw-r--r--src/model.rs14
-rw-r--r--src/routes.rs2
3 files changed, 20 insertions, 6 deletions
diff --git a/src/error.rs b/src/error.rs
index 54075da..351c01a 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -35,11 +35,11 @@ pub enum Error {
#[error("User with that email already exists")]
EmailExists,
- #[error("Email is invalid")]
- EmailInvalid,
+ #[error("Invalid email: {0}")]
+ EmailInvalid(#[from] email_address::Error),
- #[error("Password is invalid")]
- PasswordInvalid,
+ #[error("Invalid email or password")]
+ LoginInvalid,
#[error("{0}")]
Other(String),
@@ -50,7 +50,7 @@ impl From<&Error> for StatusCode {
match value {
Error::UserNotFound => StatusCode::NOT_FOUND,
Error::EmailExists => StatusCode::CONFLICT,
- Error::EmailInvalid | Error::PasswordInvalid => StatusCode::UNPROCESSABLE_ENTITY,
+ Error::EmailInvalid(_) => StatusCode::UNPROCESSABLE_ENTITY,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
diff --git a/src/model.rs b/src/model.rs
index 5f6111e..51ce493 100644
--- a/src/model.rs
+++ b/src/model.rs
@@ -1,7 +1,12 @@
+use std::str::FromStr;
+
use serde::{Deserialize, Serialize};
+use sqlx::FromRow;
use time::OffsetDateTime;
-#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
+use crate::Error;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, FromRow)]
#[serde(rename_all = "camelCase")]
pub struct User {
pub id: uuid::Uuid,
@@ -28,6 +33,13 @@ pub struct RegisterSchema {
pub password: String,
}
+impl RegisterSchema {
+ pub fn validate(&self) -> Result<(), Error> {
+ email_address::EmailAddress::from_str(&self.email)?;
+ Ok(())
+ }
+}
+
#[derive(Debug, Serialize, Deserialize)]
pub struct LoginSchema {
pub email: String,
diff --git a/src/routes.rs b/src/routes.rs
index 0bf34b2..2692f1a 100644
--- a/src/routes.rs
+++ b/src/routes.rs
@@ -77,6 +77,8 @@ impl Register {
State(state): State<Arc<AppState>>,
Json(register_schema): Json<RegisterSchema>,
) -> impl IntoResponse {
+ register_schema.validate()?;
+
let exists: Option<bool> =
sqlx::query_scalar("SELECT EXISTS(SELECT 1 FROM users WHERE email = $1)")
.bind(register_schema.email.to_ascii_lowercase())