Compare commits

..

1 Commits

Author SHA1 Message Date
spinline
315a2f9a53 fix(auth): fix 500 error and server function registration on Mac
All checks were successful
Build MIPS Binary / build (push) Successful in 5m13s
2026-02-11 23:22:38 +03:00
12 changed files with 34 additions and 58 deletions

6
.gitignore vendored
View File

@@ -8,9 +8,3 @@ backend.log
.runner .runner
.env .env
backend/.env backend/.env
*.db
*.db-shm
*.db-wal
*.sqlite
*.sqlite-shm
*.sqlite-wal

1
Cargo.lock generated
View File

@@ -3761,7 +3761,6 @@ dependencies = [
"struct-patch", "struct-patch",
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
"tracing",
"utoipa", "utoipa",
] ]

View File

@@ -44,6 +44,6 @@ tower_governor = "0.8.0"
governor = "0.10.4" governor = "0.10.4"
# Leptos # Leptos
leptos = { version = "0.8.15", features = ["nightly", "msgpack"] } leptos = { version = "0.8.15", features = ["nightly"] }
leptos_axum = { version = "0.8.7" } leptos_axum = { version = "0.8.7" }
jsonwebtoken = "9" jsonwebtoken = "9"

View File

@@ -52,18 +52,22 @@ async fn auth_middleware(
request: Request<Body>, request: Request<Body>,
next: Next, next: Next,
) -> Result<Response, StatusCode> { ) -> Result<Response, StatusCode> {
// Skip auth for public paths // Skip auth for public server functions
let path = request.uri().path(); let path = request.uri().path();
if path.starts_with("/api/server_fns/Login") // Login server fn if path.starts_with("/api/server_fns/Login")
|| path.starts_with("/api/server_fns/login")
|| path.starts_with("/api/server_fns/GetSetupStatus") || path.starts_with("/api/server_fns/GetSetupStatus")
|| path.starts_with("/api/server_fns/get_setup_status")
|| path.starts_with("/api/server_fns/Setup") || path.starts_with("/api/server_fns/Setup")
|| path.starts_with("/api/server_fns/setup")
|| path.starts_with("/swagger-ui") || path.starts_with("/swagger-ui")
|| path.starts_with("/api-docs") || path.starts_with("/api-docs")
|| !path.starts_with("/api/") // Allow static files (frontend) || !path.starts_with("/api/")
{ {
return Ok(next.run(request).await); return Ok(next.run(request).await);
} }
// Check token // Check token
if let Some(token) = jar.get("auth_token") { if let Some(token) = jar.get("auth_token") {
use jsonwebtoken::{decode, Validation, DecodingKey}; use jsonwebtoken::{decode, Validation, DecodingKey};
@@ -221,6 +225,18 @@ async fn main() {
tracing::info!("Socket: {}", args.socket); tracing::info!("Socket: {}", args.socket);
tracing::info!("Port: {}", args.port); tracing::info!("Port: {}", args.port);
// Force linking of server functions from shared crate for registration on Mac
{
use shared::server_fns::auth::*;
let _ = get_setup_status;
let _ = setup;
let _ = login;
let _ = logout;
let _ = get_user;
tracing::info!("Server functions linked successfully.");
}
// ... rest of the main function ... // ... rest of the main function ...
// Startup Health Check // Startup Health Check
let socket_path = std::path::Path::new(&args.socket); let socket_path = std::path::Path::new(&args.socket);

View File

@@ -7,7 +7,7 @@ edition = "2021"
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
leptos = { version = "0.8.15", features = ["csr", "msgpack"] } leptos = { version = "0.8.15", features = ["csr", "msgpack", "nightly"] }
leptos_router = { version = "0.8.11" } leptos_router = { version = "0.8.11" }
console_error_panic_hook = "0.1" console_error_panic_hook = "0.1"

View File

@@ -41,8 +41,7 @@ pub fn Setup() -> impl IntoView {
} }
Err(e) => { Err(e) => {
log::error!("Setup failed: {:?}", e); log::error!("Setup failed: {:?}", e);
// Hatanın sadece mesaj kısmını almaya çalışalım, yoksa full struct basılabilir error.1.set(Some("Kurulum sırasında bir hata oluştu".to_string()));
error.1.set(Some(format!("Hata: {}", e)));
loading.1.set(false); loading.1.set(false);
} }
} }

View File

@@ -10,7 +10,6 @@ struct-patch = "0.5"
rmp-serde = "1.3" rmp-serde = "1.3"
bytes = "1" bytes = "1"
http = "1" http = "1"
tracing = "0.1"
# Leptos 0.8.7 # Leptos 0.8.7
leptos = { version = "0.8.15", features = ["nightly", "msgpack"] } leptos = { version = "0.8.15", features = ["nightly", "msgpack"] }

View File

@@ -28,17 +28,8 @@ impl Db {
} }
async fn run_migrations(&self) -> Result<()> { async fn run_migrations(&self) -> Result<()> {
tracing::info!("Starting database migrations..."); sqlx::migrate!("./migrations").run(&self.pool).await?;
match sqlx::migrate!("./migrations").run(&self.pool).await { Ok(())
Ok(_) => {
tracing::info!("Database migrations completed successfully.");
Ok(())
}
Err(e) => {
tracing::error!("Database migration failed: {}", e);
Err(e.into())
}
}
} }
// --- User Operations --- // --- User Operations ---

View File

@@ -20,64 +20,42 @@ pub struct SetupStatus {
pub completed: bool, pub completed: bool,
} }
#[server(GetSetupStatus, "/api/server_fns/GetSetupStatus", input = MsgPack, output = MsgPack)] #[server(GetSetupStatus, "/api/server_fns", input = MsgPack, output = MsgPack)]
pub async fn get_setup_status() -> Result<SetupStatus, ServerFnError> { pub async fn get_setup_status() -> Result<SetupStatus, ServerFnError> {
use crate::DbContext; use crate::DbContext;
tracing::info!("Checking setup status..."); let db_context = use_context::<DbContext>().ok_or_else(|| ServerFnError::new("DB Context missing"))?;
let db_context = use_context::<DbContext>().ok_or_else(|| {
tracing::error!("DB Context missing in GetSetupStatus");
ServerFnError::new("DB Context missing")
})?;
let has_users = db_context.db.has_users().await let has_users = db_context.db.has_users().await
.map_err(|e| { .map_err(|e| ServerFnError::new(format!("DB error: {}", e)))?;
tracing::error!("DB error in GetSetupStatus: {}", e);
ServerFnError::new(format!("DB error: {}", e))
})?;
tracing::info!("Setup status: completed={}", has_users);
Ok(SetupStatus { Ok(SetupStatus {
completed: has_users, completed: has_users,
}) })
} }
#[server(Setup, "/api/server_fns/Setup", input = MsgPack, output = MsgPack)] #[server(Setup, "/api/server_fns", input = MsgPack, output = MsgPack)]
pub async fn setup(username: String, password: String) -> Result<(), ServerFnError> { pub async fn setup(username: String, password: String) -> Result<(), ServerFnError> {
use crate::DbContext; use crate::DbContext;
tracing::info!("Attempting setup for user: {}", username); let db_context = use_context::<DbContext>().ok_or_else(|| ServerFnError::new("DB Context missing"))?;
let db_context = use_context::<DbContext>().ok_or_else(|| {
tracing::error!("DB Context missing in Setup");
ServerFnError::new("DB Context missing")
})?;
// Check if setup is already done // Check if setup is already done
let has_users = db_context.db.has_users().await.unwrap_or(false); let has_users = db_context.db.has_users().await.unwrap_or(false);
if has_users { if has_users {
tracing::warn!("Setup attempt blocked: Setup already completed");
return Err(ServerFnError::new("Setup already completed")); return Err(ServerFnError::new("Setup already completed"));
} }
// Hash password (low cost for MIPS) // Hash password (low cost for MIPS)
let password_hash = bcrypt::hash(&password, 6) let password_hash = bcrypt::hash(&password, 6)
.map_err(|e| { .map_err(|_| ServerFnError::new("Hashing error"))?;
tracing::error!("Hashing error: {}", e);
ServerFnError::new("Hashing error")
})?;
db_context.db.create_user(&username, &password_hash).await db_context.db.create_user(&username, &password_hash).await
.map_err(|e| { .map_err(|e| ServerFnError::new(format!("DB error: {}", e)))?;
tracing::error!("Failed to create user: {}", e);
ServerFnError::new(format!("DB error: {}", e))
})?;
tracing::info!("Setup completed successfully for user: {}", username);
Ok(()) Ok(())
} }
#[server(Login, "/api/server_fns/Login", input = MsgPack, output = MsgPack)] #[server(Login, "/api/server_fns", input = MsgPack, output = MsgPack)]
pub async fn login(username: String, password: String) -> Result<UserResponse, ServerFnError> { pub async fn login(username: String, password: String) -> Result<UserResponse, ServerFnError> {
use crate::DbContext; use crate::DbContext;
use leptos_axum::ResponseOptions; use leptos_axum::ResponseOptions;
@@ -133,7 +111,7 @@ pub async fn login(username: String, password: String) -> Result<UserResponse, S
} }
} }
#[server(Logout, "/api/server_fns/Logout", input = MsgPack, output = MsgPack)] #[server(Logout, "/api/server_fns", input = MsgPack, output = MsgPack)]
pub async fn logout() -> Result<(), ServerFnError> { pub async fn logout() -> Result<(), ServerFnError> {
use leptos_axum::ResponseOptions; use leptos_axum::ResponseOptions;
use cookie::{Cookie, SameSite}; use cookie::{Cookie, SameSite};
@@ -154,7 +132,7 @@ pub async fn logout() -> Result<(), ServerFnError> {
Ok(()) Ok(())
} }
#[server(GetUser, "/api/server_fns/GetUser", input = MsgPack, output = MsgPack)] #[server(GetUser, "/api/server_fns", input = MsgPack, output = MsgPack)]
pub async fn get_user() -> Result<Option<UserResponse>, ServerFnError> { pub async fn get_user() -> Result<Option<UserResponse>, ServerFnError> {
use axum::http::HeaderMap; use axum::http::HeaderMap;
use leptos_axum::extract; use leptos_axum::extract;

Binary file not shown.

BIN
vibetorrent.db-shm Normal file

Binary file not shown.

BIN
vibetorrent.db-wal Normal file

Binary file not shown.