feat: redirect after login

This commit is contained in:
Max Hohlfeld 2025-01-29 16:07:31 +01:00
parent ec5e4cc23d
commit 128fca8138
6 changed files with 32 additions and 9 deletions

View File

@ -1,21 +1,34 @@
use actix_identity::Identity; use actix_identity::Identity;
use actix_web::{http::header::LOCATION, HttpResponse, Responder}; use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use rinja::Template; use rinja::Template;
use serde::Deserialize;
use crate::utils::ApplicationError; use crate::utils::ApplicationError;
#[derive(Template)] #[derive(Template)]
#[template(path = "user/login.html")] #[template(path = "user/login.html")]
struct LoginTemplate {} struct LoginTemplate {
next: Option<String>,
}
#[derive(Deserialize)]
struct LoginQuery {
next: Option<String>,
}
#[actix_web::get("/login")] #[actix_web::get("/login")]
async fn get(user: Option<Identity>) -> Result<impl Responder, ApplicationError> { async fn get(
user: Option<Identity>,
query: web::Query<LoginQuery>,
) -> Result<impl Responder, ApplicationError> {
if user.is_some() { if user.is_some() {
Ok(HttpResponse::Found() Ok(HttpResponse::Found()
.insert_header((LOCATION, "/")) .insert_header((LOCATION, query.next.clone().unwrap_or("/".to_string())))
.finish()) .finish())
} else { } else {
let template = LoginTemplate {}; let template = LoginTemplate {
next: query.next.clone(),
};
Ok(HttpResponse::Ok().body(template.render()?)) Ok(HttpResponse::Ok().body(template.render()?))
} }

View File

@ -9,6 +9,7 @@ use crate::{models::User, utils::auth::hash_plain_password_with_salt};
pub struct LoginForm { pub struct LoginForm {
pub email: String, pub email: String,
pub password: String, pub password: String,
pub next: Option<String>,
} }
#[actix_web::post("/login")] #[actix_web::post("/login")]
@ -28,9 +29,11 @@ async fn post(
.await .await
.unwrap(); .unwrap();
let location = form.next.unwrap_or("/".to_string());
return HttpResponse::Found() return HttpResponse::Found()
.insert_header(("LOCATION", "/")) .insert_header(("LOCATION", location.clone()))
.insert_header(("HX-LOCATION", "/")) .insert_header(("HX-LOCATION", location))
.finish(); .finish();
} }
} }

View File

@ -56,9 +56,10 @@ where
&& !request.path().starts_with("/static") && !request.path().starts_with("/static")
{ {
let (request, _pl) = request.into_parts(); let (request, _pl) = request.into_parts();
let next_location = format!("/login?next={}", request.uri());
let response = HttpResponse::Found() let response = HttpResponse::Found()
.insert_header((http::header::LOCATION, "/login")) .insert_header((http::header::LOCATION, next_location))
.finish() .finish()
// constructed responses map to "right" body // constructed responses map to "right" body
.map_into_right_body(); .map_into_right_body();

View File

@ -59,6 +59,7 @@ where
let login_form = LoginForm { let login_form = LoginForm {
email: "abc".to_string(), email: "abc".to_string(),
password: "abc".to_string(), password: "abc".to_string(),
next: None
}; };
let login_req = test::TestRequest::post() let login_req = test::TestRequest::post()

View File

@ -74,7 +74,7 @@
{% let f = "%H:%M" %} {% let f = "%H:%M" %}
<div class="field"> <div class="field">
<input class="input" type="time" id="from" name="from" required value="{% if let Some(event)=event <input class="input" type="time" id="from" name="from" required value="{% if let Some(event)=event
%}{{ event.start_time.format(f) }}{% else %}0:00{% endif %}" {{ disabled|cond_show("disabled") }} /> %}{{ event.start_time.format(f) }}{% else %}00:00{% endif %}" {{ disabled|cond_show("disabled") }} />
</div> </div>
<div class="field"> <div class="field">
<input class="input" type="time" id="till" name="till" required value="{% if let Some(event)=event <input class="input" type="time" id="till" name="till" required value="{% if let Some(event)=event

View File

@ -6,6 +6,11 @@
<h1 class="title">Brass - Anmeldung</h1> <h1 class="title">Brass - Anmeldung</h1>
<form class="box" action="/login" method="post" hx-boost="true" hx-target-400="#error-message" <form class="box" action="/login" method="post" hx-boost="true" hx-target-400="#error-message"
hx-on:change="document.getElementById('error-message').innerHTML = ''"> hx-on:change="document.getElementById('error-message').innerHTML = ''">
{% if let Some(next) = next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
<div class="field"> <div class="field">
<label class="label" for="email">E-Mail:</label> <label class="label" for="email">E-Mail:</label>
<div class="control"> <div class="control">