use axum::{ extract::{Json, State}, http::StatusCode, response::{IntoResponse, Response}, }; use crate::{ app::App, clock::RequestedAt, error::Internal, login::{Login, Password}, name::Name, setup::app, token::extract::IdentityCookie, }; pub async fn handler( State(app): State, RequestedAt(setup_at): RequestedAt, identity: IdentityCookie, Json(request): Json, ) -> Result<(IdentityCookie, Json), Error> { let (login, secret) = app .setup() .initial(&request.name, &request.password, &setup_at) .await .map_err(Error)?; let identity = identity.set(secret); Ok((identity, Json(login))) } #[derive(serde::Deserialize)] pub struct Request { pub name: Name, pub password: Password, } #[derive(Debug)] pub struct Error(pub app::Error); impl IntoResponse for Error { fn into_response(self) -> Response { let Self(error) = self; match error { app::Error::InvalidName(_) => { (StatusCode::BAD_REQUEST, error.to_string()).into_response() } app::Error::SetupCompleted => (StatusCode::CONFLICT, error.to_string()).into_response(), other => Internal::from(other).into_response(), } } }