Implement authentication system with SQLite: Add login/setup pages, auth middleware, and database integration
Some checks failed
Build MIPS Binary / build (push) Failing after 3m42s
Some checks failed
Build MIPS Binary / build (push) Failing after 3m42s
This commit is contained in:
@@ -18,6 +18,9 @@ use shared::{
|
||||
};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub mod auth;
|
||||
pub mod setup;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "../frontend/dist"]
|
||||
pub struct Asset;
|
||||
@@ -709,8 +712,8 @@ pub async fn subscribe_push_handler(
|
||||
Json(subscription): Json<push::PushSubscription>,
|
||||
) -> impl IntoResponse {
|
||||
tracing::info!("Received push subscription: {:?}", subscription);
|
||||
|
||||
|
||||
state.push_store.add_subscription(subscription).await;
|
||||
|
||||
|
||||
(StatusCode::OK, "Subscription saved").into_response()
|
||||
}
|
||||
|
||||
66
backend/src/handlers/setup.rs
Normal file
66
backend/src/handlers/setup.rs
Normal file
@@ -0,0 +1,66 @@
|
||||
use crate::{db::Db, AppState};
|
||||
use axum::{
|
||||
extract::{State, Json},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct SetupRequest {
|
||||
username: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SetupStatusResponse {
|
||||
completed: bool,
|
||||
}
|
||||
|
||||
pub async fn get_setup_status_handler(State(state): State<AppState>) -> impl IntoResponse {
|
||||
let completed = match state.db.has_users().await {
|
||||
Ok(has) => has,
|
||||
Err(e) => {
|
||||
tracing::error!("DB error checking users: {}", e);
|
||||
false
|
||||
}
|
||||
};
|
||||
Json(SetupStatusResponse { completed }).into_response()
|
||||
}
|
||||
|
||||
pub async fn setup_handler(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<SetupRequest>,
|
||||
) -> impl IntoResponse {
|
||||
// 1. Check if setup is already completed (i.e., users exist)
|
||||
match state.db.has_users().await {
|
||||
Ok(true) => return (StatusCode::FORBIDDEN, "Setup already completed").into_response(),
|
||||
Err(e) => {
|
||||
tracing::error!("DB error checking users: {}", e);
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Database error").into_response();
|
||||
}
|
||||
Ok(false) => {} // Proceed
|
||||
}
|
||||
|
||||
// 2. Validate input
|
||||
if payload.username.len() < 3 || payload.password.len() < 6 {
|
||||
return (StatusCode::BAD_REQUEST, "Username must be at least 3 chars, password at least 6").into_response();
|
||||
}
|
||||
|
||||
// 3. Create User
|
||||
let password_hash = match bcrypt::hash(&payload.password, bcrypt::DEFAULT_COST) {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to hash password: {}", e);
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Failed to process password").into_response();
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = state.db.create_user(&payload.username, &password_hash).await {
|
||||
tracing::error!("Failed to create user: {}", e);
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Failed to create user").into_response();
|
||||
}
|
||||
|
||||
(StatusCode::OK, "Setup completed successfully").into_response()
|
||||
}
|
||||
Reference in New Issue
Block a user