From b6775fae9b00fe3ac04eaa83160dad50121b6f93 Mon Sep 17 00:00:00 2001 From: Fabrice Bellamy <12b@distrilab.fr> Date: Thu, 24 Oct 2024 00:45:28 +0200 Subject: [PATCH] refactoring and code cleanup --- nixin_farm_ssr/src/controllers/home.rs | 54 +++++++++++++------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/nixin_farm_ssr/src/controllers/home.rs b/nixin_farm_ssr/src/controllers/home.rs index 6a8bd27..4c831e4 100644 --- a/nixin_farm_ssr/src/controllers/home.rs +++ b/nixin_farm_ssr/src/controllers/home.rs @@ -48,6 +48,21 @@ pub struct RegisterFormParams { pub password: Option, } +/// build a response that will cause a redirect without full +/// page reload using httpx +/// +/// # Errors +/// +/// When there is an issue with rendering the view. +fn httpx_redirect(url: &str) -> Result { + let mut headers = HeaderMap::new(); + //ToDo: modifiy below to avoid using ugly unwrap + headers.insert("HX-Location", url.parse().unwrap()); + + Ok(headers.into_response()) +} + + #[debug_handler] pub async fn home( auth: auth_no_error::JWTWithUserOpt, @@ -128,11 +143,7 @@ pub async fn do_register( let res = AuthMailer::send_welcome(&ctx, &user).await; match res { Ok(()) => { - let mut headers = HeaderMap::new(); - //ToDo: modifiy below to avoid using ugly unwrap - headers.insert("HX-Location", "/".parse().unwrap()); - - return Ok(headers.into_response()); + return httpx_redirect("/"); } Err(err) => { return views::home::error(&v,&format!("failed to send welcome email: {}",err.to_string())); @@ -184,15 +195,8 @@ pub async fn do_login( return Ok((jar, views::home::error(&v,"Login failed: invalid email or password"))); }; - // We do not really need to return the index view in the response body - // because the HX-Location header will trigger htmx to fetch it from - // the client. - // We are doing it here only to test if it allows degrading gracefully - // on java script disabled clients. - // See do_register() for an implementation of htmx redirect with - // an empty body - - // Also we tried returning the JWT token both in an authorisation header + // Notes about old code we have tested before : + // We tried returning the JWT token both in an authorisation header // But only the cookie version is working. Web browsers do not seem to be // able to get the token from the header to send it back. // Anyway, using a cookie, with attributes Secure, HttpOnly and @@ -200,24 +204,18 @@ pub async fn do_login( // to avoid XSS and CSRF attacks // ToDo: manage reset token - //ToDo: modifiy below to avoid using ugly unwraps - - let mut headers = HeaderMap::new(); - //headers.insert(header::AUTHORIZATION, HeaderValue::from_str(&format!("Bearer {}", token)).unwrap()); - headers.insert("HX-Location", "/".parse().unwrap()); - //This is how to set the token cookie without using the CookieJar : + //This is how we could set the token cookie without using the CookieJar //headers.insert(header::SET_COOKIE, HeaderValue::from_str(&format!("token={}; Secure; HttpOnly; SameSite=Strict", token)).unwrap()); + // - not tested but should work + // - if used instead of CookieJar maybe it should be moved to the httpx_redirect() function? - let index_view = views::home::index(&v,&user).unwrap(); - let mut cookie = Cookie::new("token", token); cookie.set_secure(true); cookie.set_http_only(true); cookie.set_same_site(SameSite::Strict); - Ok(( - jar.add(cookie), - Ok((headers, index_view).into_response()),)) + Ok((jar.add(cookie), + httpx_redirect("/"),)) } _ => { return Ok((jar, views::home::error(&v,"Login failed: you need to provide an email and a password"))); @@ -230,10 +228,10 @@ pub async fn do_login( pub async fn logout( State(_ctx): State, jar: CookieJar) - -> Result<(CookieJar, Redirect), StatusCode> { + -> Result<(CookieJar, impl IntoResponse), StatusCode> { - println!("Cookie jar: {:?}",jar); - Ok((jar.remove(Cookie::from("token")), Redirect::to("/"),)) + Ok((jar.remove(Cookie::from("token")), + httpx_redirect("/"),)) } #[debug_handler]