use axum::{ extract::{Json, Path, State}, http::StatusCode, response::{IntoResponse, Response}, }; use crate::{ app::App, clock::RequestedAt, empty::Empty, error::{Internal, NotFound}, invite::{app, handlers::PathInfo}, name::Name, password::Password, token::extract::IdentityCookie, }; #[cfg(test)] mod test; pub async fn handler( State(app): State, RequestedAt(accepted_at): RequestedAt, identity: IdentityCookie, Path(invite): Path, Json(request): Json, ) -> Result<(IdentityCookie, Empty), Error> { let secret = app .invites() .accept(&invite, &request.name, &request.password, &accepted_at) .await .map_err(Error)?; let identity = identity.set(secret); Ok((identity, Empty)) } #[derive(serde::Deserialize)] pub struct Request { pub name: Name, pub password: Password, } #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct Error(pub app::AcceptError); impl IntoResponse for Error { fn into_response(self) -> Response { let Self(error) = self; match error { app::AcceptError::NotFound(_) => NotFound(error).into_response(), app::AcceptError::InvalidName(_) => { (StatusCode::BAD_REQUEST, error.to_string()).into_response() } app::AcceptError::DuplicateLogin(_) => { (StatusCode::CONFLICT, error.to_string()).into_response() } other => Internal::from(other).into_response(), } } }