backend/src/web/register.rs

57 lines
1.8 KiB
Rust
Raw Normal View History

2024-12-28 21:35:45 +03:00
use axum::{
extract::{Json as ExtractJson, State},
response::IntoResponse,
http::StatusCode
};
use serde::Deserialize;
use bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use tokio_postgres::NoTls;
use argon2_kdf::{Algorithm, Hasher};
use std::sync::Arc;
#[derive(Deserialize)]
pub struct RegisterRequest {
username: String,
password: String,
email: String,
}
// Регистрация
pub async fn register (
State(pool): State<Arc<Pool<PostgresConnectionManager<NoTls>>>>,
ExtractJson(payload): ExtractJson<RegisterRequest>,
) -> impl IntoResponse {
// Валидация данных
if payload.password.len() < 8 { return (StatusCode::BAD_REQUEST, "Password must be at least 8 characters long").into_response() }
if payload.username.len() < 4 { return (StatusCode::BAD_REQUEST, "Username must be at least 4 characters long").into_response() }
let conn = match pool.get().await {
Ok(conn) => conn, Err(_e) => return (StatusCode::INTERNAL_SERVER_ERROR, "Failed to get DB connection").into_response()
};
// ГЕНЕРАЦИЯ ПАРОЛЯ
let hashed_password = generate_hash(&payload.password);
let insert_query = "INSERT INTO accounts (username, password, email) VALUES ($1, $2, $3)";
if conn.execute(insert_query, &[&payload.username, &hashed_password, &payload.email]).await.is_err() {
return (StatusCode::INTERNAL_SERVER_ERROR, "Failed to register user").into_response();
}
(StatusCode::OK, "User registered successfully").into_response()
}
fn generate_hash(password: &str) -> String {
Hasher::new()
.algorithm(Algorithm::Argon2d)
.salt_length(24)
.hash_length(42)
.iterations(1)
.memory_cost_kib(262144)
.threads(10)
.hash(password.as_bytes())
.unwrap()
.to_string()
}