Compare commits

...

4 Commits

Author SHA1 Message Date
spinline
a948215538 Change cookie SameSite policy to Lax to fix login redirection issue
All checks were successful
Build MIPS Binary / build (push) Successful in 4m6s
2026-02-07 15:38:56 +03:00
spinline
13424fceeb Demote 'Torrent status changed' log from INFO to DEBUG to reduce console noise
All checks were successful
Build MIPS Binary / build (push) Successful in 4m6s
2026-02-07 15:33:16 +03:00
spinline
e3eb5fbca9 Add detailed logging to login handler and use full page reload for auth navigation
All checks were successful
Build MIPS Binary / build (push) Successful in 4m7s
2026-02-07 15:28:44 +03:00
spinline
08f2f540fe Fix unused import and dead code warnings
All checks were successful
Build MIPS Binary / build (push) Successful in 4m6s
2026-02-07 15:20:23 +03:00
4 changed files with 37 additions and 16 deletions

View File

@@ -85,7 +85,7 @@ pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult {
has_changes = true;
// Log status changes for debugging
tracing::info!(
tracing::debug!(
"Torrent status changed: {} ({}) {:?} -> {:?}",
new_t.name, new_t.hash, old_t.status, new_t.status
);

View File

@@ -1,4 +1,4 @@
use crate::{db::Db, AppState};
use crate::AppState;
use axum::{
extract::{State, Json},
http::StatusCode,
@@ -15,6 +15,7 @@ pub struct LoginRequest {
password: String,
}
#[allow(dead_code)]
#[derive(Serialize, ToSchema)]
pub struct UserResponse {
username: String,
@@ -35,11 +36,16 @@ pub async fn login_handler(
jar: CookieJar,
Json(payload): Json<LoginRequest>,
) -> impl IntoResponse {
tracing::info!("Login attempt for user: {}", payload.username);
let user = match state.db.get_user_by_username(&payload.username).await {
Ok(Some(u)) => u,
Ok(None) => return (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response(),
Ok(None) => {
tracing::warn!("Login failed: User not found for {}", payload.username);
return (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response();
}
Err(e) => {
tracing::error!("DB error during login: {}", e);
tracing::error!("DB error during login for {}: {}", payload.username, e);
return (StatusCode::INTERNAL_SERVER_ERROR, "Database error").into_response();
}
};
@@ -48,6 +54,8 @@ pub async fn login_handler(
match bcrypt::verify(&payload.password, &password_hash) {
Ok(true) => {
tracing::info!("Password verified for user: {}", payload.username);
// Create session
let token: String = (0..32).map(|_| {
use rand::{distributions::Alphanumeric, Rng};
@@ -59,20 +67,28 @@ pub async fn login_handler(
let expires_at = time::OffsetDateTime::now_utc().unix_timestamp() + expires_in;
if let Err(e) = state.db.create_session(user_id, &token, expires_at).await {
tracing::error!("Failed to create session: {}", e);
tracing::error!("Failed to create session for {}: {}", payload.username, e);
return (StatusCode::INTERNAL_SERVER_ERROR, "Failed to create session").into_response();
}
let cookie = Cookie::build(("auth_token", token))
.path("/")
.http_only(true)
.same_site(SameSite::Strict)
.same_site(SameSite::Lax)
.max_age(Duration::seconds(expires_in))
.build();
tracing::info!("Session created and cookie set for user: {}", payload.username);
(StatusCode::OK, jar.add(cookie), "Login successful").into_response()
}
_ => (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response(),
Ok(false) => {
tracing::warn!("Login failed: Invalid password for {}", payload.username);
(StatusCode::UNAUTHORIZED, "Invalid credentials").into_response()
}
Err(e) => {
tracing::error!("Bcrypt error for {}: {}", payload.username, e);
(StatusCode::INTERNAL_SERVER_ERROR, "Auth error").into_response()
}
}
}

View File

@@ -1,6 +1,6 @@
use leptos::*;
use leptos_router::*;
use serde::{Deserialize, Serialize};
use serde::Serialize;
#[derive(Serialize)]
struct LoginRequest {
@@ -20,6 +20,8 @@ pub fn Login() -> impl IntoView {
set_loading.set(true);
set_error.set(None);
logging::log!("Attempting login for user: {}", username.get());
spawn_local(async move {
let req = LoginRequest {
username: username.get(),
@@ -32,15 +34,19 @@ pub fn Login() -> impl IntoView {
match client.send().await {
Ok(resp) => {
logging::log!("Login response status: {}", resp.status());
if resp.ok() {
// Redirect to home on success
let navigate = use_navigate();
navigate("/", Default::default());
logging::log!("Login successful, redirecting...");
// Force a full reload to re-run auth checks in App.rs
let _ = window().location().set_href("/");
} else {
let text = resp.text().await.unwrap_or_default();
logging::error!("Login failed: {}", text);
set_error.set(Some("Kullanıcı adı veya şifre hatalı".to_string()));
}
}
Err(_) => {
Err(e) => {
logging::error!("Network error: {}", e);
set_error.set(Some("Bağlantı hatası".to_string()));
}
}

View File

@@ -1,6 +1,6 @@
use leptos::*;
use leptos_router::*;
use serde::{Deserialize, Serialize};
use serde::Serialize;
#[derive(Serialize)]
struct SetupRequest {
@@ -49,9 +49,8 @@ pub fn Setup() -> impl IntoView {
match client.send().await {
Ok(resp) => {
if resp.ok() {
// Redirect to login after setup
let navigate = use_navigate();
navigate("/login", Default::default());
// Redirect to login after setup (full reload to be safe)
let _ = window().location().set_href("/login");
} else {
let text = resp.text().await.unwrap_or_default();
set_error.set(Some(format!("Hata: {}", text)));