This repository has been archived on 2024-08-23. You can view files and clone it, but cannot push or open issues or pull requests.
project/src/endpoints/users/register.rs
2024-08-15 20:41:59 +03:00

65 lines
1.8 KiB
Rust

use axum::Form;
use itertools::Itertools;
use validator::{Validate, ValidationError};
use crate::{
auth::{HashedBytes, Token},
prelude::*,
};
#[derive(Deserialize, Debug, Validate)]
pub struct Params {
#[validate(length(min = 3, max = 10))]
username: String,
#[validate(email)]
email: String,
#[validate(length(min = 6), custom(function = "validate_password"))]
password: String,
}
fn validate_password(password: &str) -> Result<(), ValidationError> {
let mut has_lower = false;
let mut has_upper = false;
let mut has_number = false;
let mut has_special = false;
for char in password.chars() {
if char.is_lowercase() {
has_lower = true;
} else if char.is_uppercase() {
has_upper = true;
} else if char.is_ascii_digit() {
has_number = true;
} else {
has_special = true;
}
}
let msg = [has_lower, has_upper, has_number, has_special]
.into_iter()
.zip(["No lower", "No upper", "No numbers", "No special"])
.filter_map(|(param, msg)| (!param).then_some(msg))
.format(" ")
.to_string();
if !msg.is_empty() {
return Err(ValidationError::new("invalid_password").with_message(msg.into()));
}
Ok(())
}
pub async fn register(
State(pool): State<Pool>,
Form(params): Form<Params>,
) -> GeneralResult<Json<Token>> {
params.validate()?;
let password = HashedBytes::hash_bytes(params.password.as_bytes()).as_bytes();
let id = db::users::create_user(&params.username, &params.email, &password, &pool)
.await
.handle_internal("Error creating the user")?
.handle(
StatusCode::BAD_REQUEST,
"The username or the email are taken",
)?;
Claims::new(id).encode().map(Json)
}