about summary refs log tree commit diff
path: root/splorm/src/handler/api
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2026-09-25 22:53:50 -0500
committergennyble <gen@nyble.dev>2026-09-25 22:53:50 -0500
commita57518c42f01e7e40a2f54c04350d8f0ea33c1c4 (patch)
tree9badb7229db7445a05064fbe8e27501e2090de61 /splorm/src/handler/api
parentfdbca76c341711e8516252b52e981ff0ebba133f (diff)
allow logout
Diffstat (limited to 'splorm/src/handler/api')
-rw-r--r--splorm/src/handler/api/auth.rs38
-rw-r--r--splorm/src/handler/api/mod.rs1
2 files changed, 37 insertions, 2 deletions
diff --git a/splorm/src/handler/api/auth.rs b/splorm/src/handler/api/auth.rs
index ff1e990..c91cee5 100644
--- a/splorm/src/handler/api/auth.rs
+++ b/splorm/src/handler/api/auth.rs
@@ -1,8 +1,11 @@
-use axum::{body::Body, extract::State, response::Response};
+use std::time::Duration;
+
+use axum::{body::Body, extract::State, http::StatusCode, response::Response};
 use gny::web::cookie::{self, SetCookie};
 use sessionhash::RequestContext;
+use somethings::auth::Session;
 
-use crate::{Query, RuntimeError, state::SplormState};
+use crate::{Query, RuntimeError, extractor::Wrap, state::SplormState};
 
 /// POST /auth/register
 pub async fn register(
@@ -85,3 +88,34 @@ pub async fn login(
 		.body(Body::from(format!("registered user {name}")))
 		.map_err(|_| RuntimeError::Unknown)
 }
+
+/// POST /auth/logout
+pub async fn logout(
+	State(state): State<SplormState>,
+	Wrap(session): Wrap<Session>,
+	ctx: RequestContext,
+) -> Result<Response, RuntimeError> {
+	tracing::trace!("{ctx} GET /api/logout");
+
+	let result = knowing::remove_session(state.database(), session.sessionid().as_str()).await;
+	match result {
+		Ok(_) => (),
+		Err(knowing::Error::DatabaseError(dbe)) => return Err(dbe.into()),
+		_ => unreachable!(),
+	}
+
+	let session_cookie = SetCookie::new("sid", "")
+		.max_age(Some(Duration::from_secs(0)))
+		.secure(true)
+		.httponly(true)
+		.path(Some("/"));
+
+	tracing::info!("user {} logged out", session.user().name());
+
+	Response::builder()
+		.status(StatusCode::SEE_OTHER)
+		.header("Location", "/")
+		.header("Set-Cookie", session_cookie.as_string())
+		.body(Body::from(format!("goodbye {}", session.user().name())))
+		.map_err(|_| RuntimeError::Unknown)
+}
diff --git a/splorm/src/handler/api/mod.rs b/splorm/src/handler/api/mod.rs
index 2616f83..c12b9c1 100644
--- a/splorm/src/handler/api/mod.rs
+++ b/splorm/src/handler/api/mod.rs
@@ -16,6 +16,7 @@ pub fn routes() -> Router<SplormState> {
 	Router::new()
 		.route("/auth/register", post(auth::register))
 		.route("/auth/login", post(auth::login))
+		.route("/auth/logout", post(auth::logout))
 		.route("/stats/now/{name}", get(stats))
 }