debt-pirate/api/src/requests/user/new_user/request.rs

76 lines
2.3 KiB
Rust

use std::time::Duration;
use axum::{
extract::State,
response::{IntoResponse, Response},
routing::post,
Json, Router,
};
use http::StatusCode;
use crate::{
db::{insert_new_user, NewUserEntity, UserEntity},
models::ApiResponse,
requests::AppState,
services::{auth_token::generate_token, hash_string, UserConfirmationMessage},
};
use super::models::{UserPostRequest, UserPostResponse};
static FIFTEEN_MINUTES: u64 = 60 * 15;
pub fn request(app_state: AppState) -> Router {
Router::new()
.route("/", post(user_post_handler))
.with_state(app_state)
}
async fn user_post_handler(
State(app_state): State<AppState>,
Json(request): Json<UserPostRequest>,
) -> Result<Response, Response> {
let UserPostRequest {
username,
password,
email,
name,
} = request;
let hashed_password = hash_string(password.as_str());
let new_user = NewUserEntity::new(username, email.clone(), hashed_password, name.clone());
let UserEntity { id: user_id, name, email , ..} = insert_new_user(app_state.pool(), new_user).await
.map_err(|err| {
if err.is_duplicate_record() {
(StatusCode::CONFLICT, ApiResponse::error("There is already an account associated with this username or email address.").into_json_response()).into_response()
} else {
(StatusCode::INTERNAL_SERVER_ERROR, ApiResponse::error("An error occurred while creating your new user account. Please try again later.").into_json_response()).into_response()
}
})?;
let (auth_token, expiration) = generate_token(
app_state.env().token_key(),
user_id,
Some(Duration::from_secs(FIFTEEN_MINUTES)),
Some(format!("/user/{user_id}/verify").as_str()),
);
let new_user_confirmation_message =
UserConfirmationMessage::new(email.as_str(), name.as_str(), auth_token.as_str());
let _ = app_state
.env()
.email_sender()
.send(new_user_confirmation_message)
.inspect_err(|err| {
eprintln!("Got the rollowing error while sending across the channel: {err}");
});
let response = (
StatusCode::CREATED,
Json(ApiResponse::<UserPostResponse>::new(UserPostResponse::new(
user_id, auth_token, expiration,
))),
);
Ok(response.into_response())
}