feat(web): add logout button
parent
b04955d70e
commit
957387bed7
|
@ -1,21 +1,21 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
|
Form, RequestExt, Router,
|
||||||
extract::{Request, State},
|
extract::{Request, State},
|
||||||
http::HeaderMap,
|
http::HeaderMap,
|
||||||
middleware::{self, Next},
|
middleware::{self, Next},
|
||||||
response::{IntoResponse, Redirect, Response},
|
response::{IntoResponse, Redirect, Response},
|
||||||
routing::get,
|
routing::{get, post},
|
||||||
Form, RequestExt, Router,
|
|
||||||
};
|
};
|
||||||
use axum_extra::{extract::CookieJar, headers::UserAgent, TypedHeader};
|
use axum_extra::{TypedHeader, extract::CookieJar, headers::UserAgent};
|
||||||
use cookie::{time::Duration, Cookie};
|
use cookie::{Cookie, time::Duration};
|
||||||
use gpodder::{AuthErr, Session};
|
use gpodder::{AuthErr, Session};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::web::{Page, TemplateExt, TemplateResponse, View};
|
use crate::web::{Page, TemplateExt, TemplateResponse, View};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
error::{AppError, AppResult},
|
|
||||||
Context,
|
Context,
|
||||||
|
error::{AppError, AppResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
const SESSION_ID_COOKIE: &str = "sessionid";
|
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
|
// Login route needs to be handled differently, as the middleware turns it into a redirect
|
||||||
// loop
|
// loop
|
||||||
.route("/login", get(get_login).post(post_login))
|
.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>> {
|
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>> {
|
async fn extract_session(ctx: Context, jar: &CookieJar) -> AppResult<Option<Session>> {
|
||||||
if let Some(session_id) = jar
|
if let Some(session_id) = jar
|
||||||
.get(SESSION_ID_COOKIE)
|
.get(SESSION_ID_COOKIE)
|
||||||
|
|
|
@ -15,6 +15,13 @@ a:hover {
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<nav>
|
<nav>
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a hx-post="/logout" hx-target="#inner">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<article id="inner">
|
<article id="inner">
|
||||||
{{ inner | safe }}
|
{{ inner | safe }}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<article>
|
<article>
|
||||||
<form hx-post="/login" hx-target="#inner">
|
<form hx-post="/login" hx-target="#inner" hx-push-url="/">
|
||||||
<label for="username">Username:</label>
|
<label for="username">Username:</label>
|
||||||
<input type="text" id="username" name="username">
|
<input type="text" id="username" name="username">
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
|
|
Loading…
Reference in New Issue