2024-10-03 10:05:30 -04:00
|
|
|
use std::sync::mpsc::Sender;
|
|
|
|
|
2024-09-29 09:57:02 -04:00
|
|
|
use crate::{
|
2024-10-03 10:05:30 -04:00
|
|
|
db::{insert_new_user, DbPool, NewUserEntity, UserEntity},
|
2024-10-03 15:55:38 -04:00
|
|
|
models::{ApiResponse, AppError},
|
2024-09-29 09:57:02 -04:00
|
|
|
requests::AppState,
|
2024-09-30 00:15:19 -04:00
|
|
|
services::{auth_token::generate_new_user_token, hash_string, UserConfirmationMessage},
|
2024-09-29 09:57:02 -04:00
|
|
|
};
|
|
|
|
use axum::{
|
2024-10-03 10:05:30 -04:00
|
|
|
debug_handler,
|
2024-09-29 09:57:02 -04:00
|
|
|
extract::State,
|
|
|
|
response::{IntoResponse, Response},
|
|
|
|
Json,
|
|
|
|
};
|
|
|
|
use http::StatusCode;
|
2024-10-03 10:05:30 -04:00
|
|
|
use pasetors::{keys::SymmetricKey, version4::V4};
|
|
|
|
use tracing::debug;
|
2024-09-29 09:57:02 -04:00
|
|
|
|
|
|
|
use super::models::{UserRegistrationRequest, UserRegistrationResponse};
|
|
|
|
|
2024-10-03 10:05:30 -04:00
|
|
|
#[debug_handler]
|
2024-09-29 09:57:02 -04:00
|
|
|
pub async fn user_registration_post_handler(
|
2024-10-03 10:05:30 -04:00
|
|
|
State(state): State<AppState>,
|
2024-09-29 09:57:02 -04:00
|
|
|
Json(request): Json<UserRegistrationRequest>,
|
2024-10-03 15:55:38 -04:00
|
|
|
) -> Result<Response, AppError> {
|
2024-10-03 10:05:30 -04:00
|
|
|
let env = state.env();
|
|
|
|
|
|
|
|
register_new_user_request(
|
|
|
|
request,
|
|
|
|
state.pool(),
|
|
|
|
env.token_key(),
|
|
|
|
env.send_verification_email(),
|
|
|
|
env.email_sender(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn register_new_user_request(
|
|
|
|
body: UserRegistrationRequest,
|
|
|
|
pool: &DbPool,
|
|
|
|
signing_key: &SymmetricKey<V4>,
|
|
|
|
send_verification_email: bool,
|
|
|
|
email_sender: &Sender<UserConfirmationMessage>,
|
2024-10-03 15:55:38 -04:00
|
|
|
) -> Result<Response, AppError> {
|
2024-10-03 10:05:30 -04:00
|
|
|
debug!(?body, send_verification_email);
|
|
|
|
|
2024-09-29 09:57:02 -04:00
|
|
|
let UserRegistrationRequest {
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
email,
|
|
|
|
name,
|
2024-10-03 10:05:30 -04:00
|
|
|
} = body;
|
2024-09-29 09:57:02 -04:00
|
|
|
|
|
|
|
let hashed_password = hash_string(password);
|
|
|
|
|
|
|
|
let new_user = NewUserEntity {
|
|
|
|
username,
|
|
|
|
password: hashed_password.to_string(),
|
|
|
|
email,
|
|
|
|
name,
|
|
|
|
};
|
|
|
|
|
2024-10-03 15:55:38 -04:00
|
|
|
let UserEntity {
|
|
|
|
id: user_id,
|
|
|
|
name,
|
|
|
|
email,
|
|
|
|
..
|
|
|
|
} = insert_new_user(pool, new_user).await.map_err(|err| {
|
|
|
|
if err.is_duplicate_record() {
|
|
|
|
AppError::duplicate_record(
|
|
|
|
"There is already an account associated with this username or email address.",
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
err
|
|
|
|
}
|
|
|
|
})?;
|
2024-09-29 09:57:02 -04:00
|
|
|
|
2024-10-03 15:27:30 -04:00
|
|
|
let (verification_token, expiration) = generate_new_user_token(signing_key, user_id);
|
2024-09-29 09:57:02 -04:00
|
|
|
|
2024-10-03 10:05:30 -04:00
|
|
|
let response_body = if send_verification_email {
|
|
|
|
let new_user_confirmation_message = UserConfirmationMessage {
|
|
|
|
email,
|
|
|
|
name,
|
2024-10-03 15:27:30 -04:00
|
|
|
verification_token: verification_token.clone(),
|
2024-10-03 10:05:30 -04:00
|
|
|
};
|
2024-09-29 09:57:02 -04:00
|
|
|
|
2024-10-03 10:05:30 -04:00
|
|
|
let _ = email_sender
|
2024-10-02 12:41:25 -04:00
|
|
|
.send(new_user_confirmation_message)
|
|
|
|
.inspect_err(|err| {
|
|
|
|
eprintln!("Got the rollowing error while sending across the channel: {err}");
|
|
|
|
});
|
2024-09-29 09:57:02 -04:00
|
|
|
|
2024-10-03 10:05:30 -04:00
|
|
|
UserRegistrationResponse {
|
|
|
|
id: user_id,
|
|
|
|
expiration,
|
2024-10-03 15:27:30 -04:00
|
|
|
verification_token: None,
|
2024-10-03 10:05:30 -04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
UserRegistrationResponse {
|
2024-09-29 09:57:02 -04:00
|
|
|
id: user_id,
|
|
|
|
expiration,
|
2024-10-03 15:27:30 -04:00
|
|
|
verification_token: Some(verification_token),
|
2024-10-03 10:05:30 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let response = (
|
|
|
|
StatusCode::CREATED,
|
|
|
|
ApiResponse::new(response_body).into_json_response(),
|
2024-09-29 09:57:02 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
Ok(response.into_response())
|
|
|
|
}
|