use axum::{
extract::State,
http::{header, HeaderValue},
response::IntoResponse,
};
use axum_extra::extract::Host;
use tower_cookies::{Cookie, Cookies};
use crate::{
client_server::{
extractors::PubkyHost, layers::authz::session_secret_from_cookies,
routes::auth::configure_session_cookie, AppState,
},
persistence::sql::session::SessionRepository,
shared::{HttpError, HttpResult},
};
pub async fn session(
State(state): State<AppState>,
cookies: Cookies,
pubky: PubkyHost,
) -> HttpResult<impl IntoResponse> {
state
.user_service
.get_or_http_error(pubky.public_key(), false)
.await?;
if let Some(secret) = session_secret_from_cookies(&cookies, pubky.public_key()) {
if let Ok(session) =
SessionRepository::get_by_secret(&secret, &mut state.sql_db.pool().into()).await
{
let legacy_session = session.to_legacy();
let mut resp = legacy_session.serialize().into_response();
resp.headers_mut().insert(
header::CONTENT_TYPE,
HeaderValue::from_static("application/octet-stream"),
);
resp.headers_mut()
.insert(header::VARY, HeaderValue::from_static("cookie, pubky-host"));
resp.headers_mut().insert(
header::CACHE_CONTROL,
HeaderValue::from_static("private, must-revalidate"),
);
return Ok(resp);
};
}
Err(HttpError::not_found())
}
pub async fn signout(
State(state): State<AppState>,
cookies: Cookies,
Host(host): Host,
pubky: PubkyHost,
) -> HttpResult<impl IntoResponse> {
if let Some(secret) = session_secret_from_cookies(&cookies, pubky.public_key()) {
SessionRepository::delete(&secret, &mut state.sql_db.pool().into()).await?;
}
let mut removal = Cookie::new(pubky.public_key().z32(), String::new());
removal.make_removal();
configure_session_cookie(&mut removal, &host);
cookies.add(removal);
Ok(())
}