use crate::constants::StaticConstraints; use crate::controllers::HttpResult; use crate::services::rate_limiter_service::RatedAction; use crate::services::{rate_limiter_service, users_service}; use actix_remote_ip::RemoteIP; use actix_web::{web, HttpResponse}; #[derive(serde::Deserialize)] pub struct CreateAccountBody { name: String, email: String, } /// Create a new account pub async fn create_account(remote_ip: RemoteIP, req: web::Json) -> HttpResult { // Rate limiting if rate_limiter_service::should_block_action(remote_ip.0, RatedAction::CreateAccount).await? { return Ok(HttpResponse::TooManyRequests().finish()); } rate_limiter_service::record_action(remote_ip.0, RatedAction::CreateAccount).await?; // Check if email is valid if !mailchecker::is_valid(&req.email) { return Ok(HttpResponse::BadRequest().json("Email address is invalid!")); } // Check parameters let constraints = StaticConstraints::default(); if !constraints.user_name_len.validate(&req.name) || !constraints.mail_len.validate(&req.email) { return Ok(HttpResponse::BadRequest().json("Size constraints were not respected!")); } // Check if email is already attached to an account if users_service::exists_email(&req.email).await? { return Ok( HttpResponse::Conflict().json("An account with the same email address already exists!") ); } // Create the account let mut user = users_service::create_account(&req.name, &req.email).await?; // Trigger reset password (send mail) users_service::request_reset_password(&mut user).await?; // TODO : cleanup in a cron not validated accounts after 24 hours // Account successfully created Ok(HttpResponse::Created().finish()) }