use axum::response::{AppendHeaders, Html, IntoResponse};
use axum::{Extension, Form};
use axum_extra::extract::PrivateCookieJar;
use cookie::Cookie;
use http::HeaderMap;
use uuid::Uuid;
use validator::{ValidateEmail, ValidateLength};
use crate::auth::{ConfirmationKey, TokenMeta};
use crate::axum::{ConfigExt, DbExt};
use crate::{util, ErrorKind, Result, User};
#[derive(Debug, Deserialize)]
pub struct SignupUserData {
email: String,
password: String,
#[serde(default)]
consent: bool,
}
pub async fn signup(
Extension(db): DbExt,
Extension(config): ConfigExt,
headers: HeaderMap,
mut cookies: PrivateCookieJar,
Form(user_data): Form<SignupUserData>,
) -> Result<(PrivateCookieJar, impl IntoResponse)> {
if !user_data.email.validate_email() {
return Err(ErrorKind::BadInput("invalid email".to_string()).into());
}
if !user_data.password.validate_length(Some(8), Some(24), None) {
return Err(ErrorKind::BadInput("invalid password length".to_string()).into());
}
let mut user = User::new(&db)?;
user.email = user_data.email;
user.password_hash = Some(crate::auth::hash_password(&user_data.password)?);
db.set(&user)?;
let key = ConfirmationKey {
user: user.id,
key: Uuid::new_v4(),
};
db.set(&key)?;
crate::email::confirmation(user.email, key.key.to_string(), &config)?;
if config.auth.require_confirmed_email {
Ok((cookies, AppendHeaders([("HX-Redirect", "/verify")])))
} else {
cookies = cookies.add(crate::auth::login::log_in_user_id(&user.id, &db)?);
Ok((cookies, AppendHeaders([("HX-Redirect", "/")])))
}
}