diff --git a/src/routes/admin.rs b/src/routes/admin.rs index 5cf8cbd..d4aa6a0 100644 --- a/src/routes/admin.rs +++ b/src/routes/admin.rs @@ -1,8 +1,9 @@ -pub mod change_password; -pub mod dashboard; -pub mod newsletters; +mod change_password; +mod dashboard; +mod logout; +mod newsletters; -use crate::{routes::error_chain_fmt, session_state::TypedSession, templates::ErrorTemplate}; +use crate::{routes::error_chain_fmt, templates::ErrorTemplate}; use askama::Template; use axum::{ Json, @@ -10,6 +11,7 @@ use axum::{ }; pub use change_password::*; pub use dashboard::*; +pub use logout::*; pub use newsletters::*; use reqwest::StatusCode; @@ -69,9 +71,3 @@ impl IntoResponse for AdminError { } } } - -#[tracing::instrument(name = "Logging out", skip(session))] -pub async fn logout(session: TypedSession) -> Result { - session.clear().await; - Ok(Redirect::to("/login").into_response()) -} diff --git a/src/routes/admin/html/change_password_form.html b/src/routes/admin/html/change_password_form.html deleted file mode 100644 index dbf70a9..0000000 --- a/src/routes/admin/html/change_password_form.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Change password - - -
- - - - -
- {} -

Back

- - diff --git a/src/routes/admin/html/dashboard.html b/src/routes/admin/html/dashboard.html deleted file mode 100644 index 75fa9a3..0000000 --- a/src/routes/admin/html/dashboard.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Admin dashboard - - -

Welcome {}!

-

Available actions:

-
    -
  1. Change password
  2. -
  3. Send a newsletter
  4. -
  5. -
    - -
    -
  6. -
- - diff --git a/src/routes/admin/html/send_newsletter_form.html b/src/routes/admin/html/send_newsletter_form.html deleted file mode 100644 index 0371dbf..0000000 --- a/src/routes/admin/html/send_newsletter_form.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - Send a newsletter - - -
- - - - - -
- {} -

Back

- - diff --git a/src/routes/admin/logout.rs b/src/routes/admin/logout.rs new file mode 100644 index 0000000..b26af16 --- /dev/null +++ b/src/routes/admin/logout.rs @@ -0,0 +1,14 @@ +use crate::{routes::AdminError, session_state::TypedSession}; +use axum::{ + http::HeaderMap, + response::{IntoResponse, Response}, +}; +use reqwest::StatusCode; + +#[tracing::instrument(name = "Logging out", skip(session))] +pub async fn logout(session: TypedSession) -> Result { + session.clear().await; + let mut headers = HeaderMap::new(); + headers.insert("HX-Redirect", "/login".parse().unwrap()); + Ok((StatusCode::OK, headers).into_response()) +} diff --git a/src/routes/login.rs b/src/routes/login.rs index 9ab268d..08dfb05 100644 --- a/src/routes/login.rs +++ b/src/routes/login.rs @@ -6,12 +6,12 @@ use crate::{ templates::ErrorTemplate, }; use askama::Template; +use axum::http::{HeaderMap, StatusCode}; use axum::{ Form, Json, extract::State, - response::{Html, IntoResponse, Redirect, Response}, + response::{Html, IntoResponse, Response}, }; -use reqwest::StatusCode; use secrecy::SecretString; #[derive(thiserror::Error)] @@ -75,7 +75,7 @@ pub async fn post_login( connection_pool, .. }): State, Form(form): Form, -) -> Result { +) -> Result { let credentials = Credentials { username: form.username.clone(), password: form.password, @@ -104,7 +104,10 @@ pub async fn post_login( .insert_username(form.username) .await .map_err(|e| LoginError::UnexpectedError(e.into()))?; - Ok(Redirect::to("/admin/dashboard")) + + let mut headers = HeaderMap::new(); + headers.insert("HX-Redirect", "/admin/dashboard".parse().unwrap()); + Ok((StatusCode::OK, headers).into_response()) } } } diff --git a/templates/dashboard.html b/templates/dashboard.html index b7c5180..2157b9e 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -7,15 +7,14 @@

Connected as {{ username }}

-
- -
+
diff --git a/tests/api/login.rs b/tests/api/login.rs index 60c3d0b..f2f612d 100644 --- a/tests/api/login.rs +++ b/tests/api/login.rs @@ -1,7 +1,7 @@ use crate::helpers::{TestApp, assert_is_redirect_to}; #[tokio::test] -async fn an_error_flash_message_is_set_on_failure() { +async fn an_error_html_fragment_is_returned_on_failure() { let app = TestApp::spawn().await; let login_body = serde_json::json!({ @@ -11,11 +11,10 @@ async fn an_error_flash_message_is_set_on_failure() { let response = app.post_login(&login_body).await; - assert_eq!(response.status().as_u16(), 303); - assert_is_redirect_to(&response, "/login"); + assert_eq!(response.status().as_u16(), 200); - let login_page_html = app.get_login_html().await; - assert!(login_page_html.contains("Authentication failed")); + let response_html = response.text().await.unwrap(); + assert!(response_html.contains("Invalid credentials")); } #[tokio::test] @@ -31,5 +30,6 @@ async fn login_redirects_to_admin_dashboard_after_login_success() { assert_is_redirect_to(&response, "/admin/dashboard"); let html_page = app.get_admin_dashboard_html().await; - assert!(html_page.contains(&format!("Welcome {}", app.test_user.username))); + assert!(html_page.contains("Connected as")); + assert!(html_page.contains(&app.test_user.username)); }