refactoring and code cleanup

This commit is contained in:
Douze Bé 2024-10-24 00:45:28 +02:00
parent a73851d26f
commit b6775fae9b

View file

@ -48,6 +48,21 @@ pub struct RegisterFormParams {
pub password: Option<String>, pub password: Option<String>,
} }
/// 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<Response> {
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] #[debug_handler]
pub async fn home( pub async fn home(
auth: auth_no_error::JWTWithUserOpt<users::Model>, auth: auth_no_error::JWTWithUserOpt<users::Model>,
@ -128,11 +143,7 @@ pub async fn do_register(
let res = AuthMailer::send_welcome(&ctx, &user).await; let res = AuthMailer::send_welcome(&ctx, &user).await;
match res { match res {
Ok(()) => { Ok(()) => {
let mut headers = HeaderMap::new(); return httpx_redirect("/");
//ToDo: modifiy below to avoid using ugly unwrap
headers.insert("HX-Location", "/".parse().unwrap());
return Ok(headers.into_response());
} }
Err(err) => { Err(err) => {
return views::home::error(&v,&format!("failed to send welcome email: {}",err.to_string())); 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"))); 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 // Notes about old code we have tested before :
// because the HX-Location header will trigger htmx to fetch it from // We tried returning the JWT token both in an authorisation header
// 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
// But only the cookie version is working. Web browsers do not seem to be // 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. // able to get the token from the header to send it back.
// Anyway, using a cookie, with attributes Secure, HttpOnly and // Anyway, using a cookie, with attributes Secure, HttpOnly and
@ -200,24 +204,18 @@ pub async fn do_login(
// to avoid XSS and CSRF attacks // to avoid XSS and CSRF attacks
// ToDo: manage reset token // ToDo: manage reset token
//ToDo: modifiy below to avoid using ugly unwraps //This is how we could set the token cookie without using the CookieJar
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 :
//headers.insert(header::SET_COOKIE, HeaderValue::from_str(&format!("token={}; Secure; HttpOnly; SameSite=Strict", token)).unwrap()); //headers.insert(header::SET_COOKIE, HeaderValue::from_str(&format!("token={}; Secure; HttpOnly; SameSite=Strict", token)).unwrap());
// - not tested but should work
let index_view = views::home::index(&v,&user).unwrap(); // - if used instead of CookieJar maybe it should be moved to the httpx_redirect() function?
let mut cookie = Cookie::new("token", token); let mut cookie = Cookie::new("token", token);
cookie.set_secure(true); cookie.set_secure(true);
cookie.set_http_only(true); cookie.set_http_only(true);
cookie.set_same_site(SameSite::Strict); cookie.set_same_site(SameSite::Strict);
Ok(( Ok((jar.add(cookie),
jar.add(cookie), httpx_redirect("/"),))
Ok((headers, index_view).into_response()),))
} }
_ => { _ => {
return Ok((jar, views::home::error(&v,"Login failed: you need to provide an email and a password"))); 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( pub async fn logout(
State(_ctx): State<AppContext>, State(_ctx): State<AppContext>,
jar: CookieJar) jar: CookieJar)
-> Result<(CookieJar, Redirect), StatusCode> { -> Result<(CookieJar, impl IntoResponse), StatusCode> {
println!("Cookie jar: {:?}",jar); Ok((jar.remove(Cookie::from("token")),
Ok((jar.remove(Cookie::from("token")), Redirect::to("/"),)) httpx_redirect("/"),))
} }
#[debug_handler] #[debug_handler]