feat(web): add logout button

main
Jef Roosens 2025-06-07 10:20:49 +02:00
parent b04955d70e
commit 957387bed7
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
3 changed files with 26 additions and 6 deletions

View File

@ -1,21 +1,21 @@
use axum::{
Form, RequestExt, Router,
extract::{Request, State},
http::HeaderMap,
middleware::{self, Next},
response::{IntoResponse, Redirect, Response},
routing::get,
Form, RequestExt, Router,
routing::{get, post},
};
use axum_extra::{extract::CookieJar, headers::UserAgent, TypedHeader};
use cookie::{time::Duration, Cookie};
use axum_extra::{TypedHeader, extract::CookieJar, headers::UserAgent};
use cookie::{Cookie, time::Duration};
use gpodder::{AuthErr, Session};
use serde::Deserialize;
use crate::web::{Page, TemplateExt, TemplateResponse, View};
use super::{
error::{AppError, AppResult},
Context,
error::{AppError, AppResult},
};
const SESSION_ID_COOKIE: &str = "sessionid";
@ -30,6 +30,7 @@ pub fn router(ctx: Context) -> Router<Context> {
// Login route needs to be handled differently, as the middleware turns it into a redirect
// loop
.route("/login", get(get_login).post(post_login))
.route("/logout", post(post_logout))
}
async fn get_index(State(ctx): State<Context>, headers: HeaderMap) -> TemplateResponse<Page<View>> {
@ -96,6 +97,18 @@ async fn post_login(
}
}
/// Log out the user by simply removing the session
async fn post_logout(
State(ctx): State<Context>,
jar: CookieJar,
) -> AppResult<(CookieJar, Redirect)> {
if let Some(session) = extract_session(ctx.clone(), &jar).await? {
ctx.store.remove_session(session.id)?;
}
Ok((jar.remove(SESSION_ID_COOKIE), Redirect::to("/")))
}
async fn extract_session(ctx: Context, jar: &CookieJar) -> AppResult<Option<Session>> {
if let Some(session_id) = jar
.get(SESSION_ID_COOKIE)

View File

@ -15,6 +15,13 @@ a:hover {
<body>
<main>
<nav>
<ul>
</ul>
<ul>
<li>
<a hx-post="/logout" hx-target="#inner">Logout</a>
</li>
</ul>
</nav>
<article id="inner">
{{ inner | safe }}

View File

@ -1,5 +1,5 @@
<article>
<form hx-post="/login" hx-target="#inner">
<form hx-post="/login" hx-target="#inner" hx-push-url="/">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>