feat: account deletion endpoints
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::html::forms::DeleteAccountForm;
|
||||
use crate::html::helpers::build_page_context;
|
||||
use crate::html::templates::{
|
||||
ProfileSettingsTemplate, RemoteActorDisplay, UserSummaryView, UsersTemplate,
|
||||
@@ -13,11 +14,16 @@ use application::users::{
|
||||
update_profile_fields,
|
||||
};
|
||||
use axum::{
|
||||
Form,
|
||||
extract::{Extension, Multipart, Path, Query, State},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use domain::{errors::DomainError, value_objects::Username};
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
value_objects::{UserId, Username},
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub async fn get_users_list(
|
||||
OptionalCookieUser(user_id): OptionalCookieUser,
|
||||
@@ -76,6 +82,7 @@ pub async fn get_user_by_username(
|
||||
#[derive(serde::Deserialize, Default)]
|
||||
pub struct SavedQuery {
|
||||
pub saved: Option<String>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn get_profile_settings(
|
||||
@@ -109,6 +116,7 @@ pub async fn get_profile_settings(
|
||||
also_known_as: settings.also_known_as.as_deref(),
|
||||
profile_fields: &settings.fields,
|
||||
saved,
|
||||
error: params.error.as_deref(),
|
||||
embed_url: format!(
|
||||
"{}/users/{}?embed=true",
|
||||
state.app_ctx.config.base_url,
|
||||
@@ -177,3 +185,61 @@ pub async fn post_profile_settings(
|
||||
|
||||
axum::response::Redirect::to("/settings/profile?saved=1").into_response()
|
||||
}
|
||||
|
||||
async fn delete_account(
|
||||
state: &AppState,
|
||||
actor: UserId,
|
||||
target: UserId,
|
||||
password: &str,
|
||||
) -> Result<(), DomainError> {
|
||||
application::users::request_account_deletion::execute(
|
||||
&state.app_ctx.deps.users.request_account_deletion,
|
||||
actor,
|
||||
target,
|
||||
password,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn post_delete_own_account(
|
||||
RequiredCookieUser(user_id): RequiredCookieUser,
|
||||
State(state): State<AppState>,
|
||||
Extension(csrf): Extension<CsrfToken>,
|
||||
Form(form): Form<DeleteAccountForm>,
|
||||
) -> impl IntoResponse {
|
||||
if crate::html::csrf::mismatch(&csrf, &form.csrf_token) {
|
||||
return StatusCode::FORBIDDEN.into_response();
|
||||
}
|
||||
match delete_account(&state, user_id.clone(), user_id, &form.password).await {
|
||||
Ok(()) => super::auth::get_logout(State(state)).await.into_response(),
|
||||
Err(e) => axum::response::Redirect::to(&format!(
|
||||
"/settings/profile?error={}",
|
||||
crate::html::helpers::encode_domain_error(&e)
|
||||
))
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn post_delete_user(
|
||||
RequiredCookieUser(actor): RequiredCookieUser,
|
||||
State(state): State<AppState>,
|
||||
Extension(csrf): Extension<CsrfToken>,
|
||||
Path(target): Path<Uuid>,
|
||||
Form(form): Form<DeleteAccountForm>,
|
||||
) -> impl IntoResponse {
|
||||
if crate::html::csrf::mismatch(&csrf, &form.csrf_token) {
|
||||
return StatusCode::FORBIDDEN.into_response();
|
||||
}
|
||||
let target_id = UserId::from_uuid(target);
|
||||
let own = actor == target_id;
|
||||
match delete_account(&state, actor, target_id, &form.password).await {
|
||||
// An admin removing their own account ends their own session too.
|
||||
Ok(()) if own => super::auth::get_logout(State(state)).await.into_response(),
|
||||
Ok(()) => axum::response::Redirect::to("/users").into_response(),
|
||||
Err(e) => axum::response::Redirect::to(&format!(
|
||||
"/users/{target}?error={}",
|
||||
crate::html::helpers::encode_domain_error(&e)
|
||||
))
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user