use axum::{
http::HeaderMap,
response::{IntoResponse, Redirect, Response},
};
use crate::{
components::{SharedChromeFolder, SlotCtx},
html_form::HtmlFormBody,
http::Cap,
plugins::users::{
auth,
session::{self, clear_auth_cookie, is_secure_request, set_auth_cookie},
state::UsersState,
templates::{LoginPage, UnauthenticatedPage},
},
web::{Htmx, html_built_page_or_app_layout},
};
use crate::plugins::users::forms::LoginForm;
pub async fn login_get(Cap(chrome): Cap<SharedChromeFolder>, htmx: Htmx) -> maud::Markup {
let page = LoginPage {
error: String::new(),
};
html_built_page_or_app_layout(&page, &htmx, &chrome, &SlotCtx::default())
}
pub async fn login_post(
Cap(state): Cap<UsersState>,
Cap(chrome): Cap<SharedChromeFolder>,
htmx: Htmx,
headers: HeaderMap,
HtmlFormBody(form): HtmlFormBody<LoginForm>,
) -> Response {
match auth::authenticate(&state.db, &form.email, &form.password).await {
Ok(user) => match auth::login_token(&user, &state.signing_key, &state.jwt_issuer) {
Ok(token) => {
let mut response = htmx.redirect("/users/success");
set_auth_cookie(response.headers_mut(), &token, is_secure_request(&headers));
response
}
Err(_) => {
let page = LoginPage {
error: "Could not create session".into(),
};
html_built_page_or_app_layout(&page, &htmx, &chrome, &SlotCtx::default())
.into_response()
}
},
Err(_) => {
let page = LoginPage {
error: "Invalid email or password".into(),
};
html_built_page_or_app_layout(&page, &htmx, &chrome, &SlotCtx::default())
.into_response()
}
}
}
pub async fn logout(htmx: Htmx, headers: HeaderMap) -> Response {
let mut response = htmx.redirect("/users/login");
clear_auth_cookie(response.headers_mut(), is_secure_request(&headers));
let _ = session::AUTH_COOKIE;
response
}
pub async fn unauthenticated(Cap(chrome): Cap<SharedChromeFolder>, htmx: Htmx) -> maud::Markup {
let page = UnauthenticatedPage {};
html_built_page_or_app_layout(&page, &htmx, &chrome, &SlotCtx::default())
}
pub async fn login_success() -> Redirect {
Redirect::to("/dashboard/")
}