this repo has no description
1use crate::auth::BearerAuthAdmin; 2use crate::state::AppState; 3use axum::{ 4 Json, 5 extract::State, 6 http::StatusCode, 7 response::{IntoResponse, Response}, 8}; 9use serde::Deserialize; 10use serde_json::json; 11use tracing::{error, warn}; 12 13#[derive(Deserialize)] 14pub struct DeleteAccountInput { 15 pub did: String, 16} 17 18pub async fn delete_account( 19 State(state): State<AppState>, 20 _auth: BearerAuthAdmin, 21 Json(input): Json<DeleteAccountInput>, 22) -> Response { 23 let did = input.did.trim(); 24 if did.is_empty() { 25 return ( 26 StatusCode::BAD_REQUEST, 27 Json(json!({"error": "InvalidRequest", "message": "did is required"})), 28 ) 29 .into_response(); 30 } 31 let user = sqlx::query!("SELECT id, handle FROM users WHERE did = $1", did) 32 .fetch_optional(&state.db) 33 .await; 34 let (user_id, handle) = match user { 35 Ok(Some(row)) => (row.id, row.handle), 36 Ok(None) => { 37 return ( 38 StatusCode::NOT_FOUND, 39 Json(json!({"error": "AccountNotFound", "message": "Account not found"})), 40 ) 41 .into_response(); 42 } 43 Err(e) => { 44 error!("DB error in delete_account: {:?}", e); 45 return ( 46 StatusCode::INTERNAL_SERVER_ERROR, 47 Json(json!({"error": "InternalError"})), 48 ) 49 .into_response(); 50 } 51 }; 52 let mut tx = match state.db.begin().await { 53 Ok(tx) => tx, 54 Err(e) => { 55 error!("Failed to begin transaction for account deletion: {:?}", e); 56 return ( 57 StatusCode::INTERNAL_SERVER_ERROR, 58 Json(json!({"error": "InternalError"})), 59 ) 60 .into_response(); 61 } 62 }; 63 if let Err(e) = sqlx::query!("DELETE FROM session_tokens WHERE did = $1", did) 64 .execute(&mut *tx) 65 .await 66 { 67 error!("Failed to delete session tokens for {}: {:?}", did, e); 68 return ( 69 StatusCode::INTERNAL_SERVER_ERROR, 70 Json(json!({"error": "InternalError", "message": "Failed to delete session tokens"})), 71 ) 72 .into_response(); 73 } 74 if let Err(e) = sqlx::query!("DELETE FROM used_refresh_tokens WHERE session_id IN (SELECT id FROM session_tokens WHERE did = $1)", did) 75 .execute(&mut *tx) 76 .await 77 { 78 error!("Failed to delete used refresh tokens for {}: {:?}", did, e); 79 } 80 if let Err(e) = sqlx::query!("DELETE FROM records WHERE repo_id = $1", user_id) 81 .execute(&mut *tx) 82 .await 83 { 84 error!("Failed to delete records for user {}: {:?}", user_id, e); 85 return ( 86 StatusCode::INTERNAL_SERVER_ERROR, 87 Json(json!({"error": "InternalError", "message": "Failed to delete records"})), 88 ) 89 .into_response(); 90 } 91 if let Err(e) = sqlx::query!("DELETE FROM repos WHERE user_id = $1", user_id) 92 .execute(&mut *tx) 93 .await 94 { 95 error!("Failed to delete repos for user {}: {:?}", user_id, e); 96 return ( 97 StatusCode::INTERNAL_SERVER_ERROR, 98 Json(json!({"error": "InternalError", "message": "Failed to delete repos"})), 99 ) 100 .into_response(); 101 } 102 if let Err(e) = sqlx::query!("DELETE FROM blobs WHERE created_by_user = $1", user_id) 103 .execute(&mut *tx) 104 .await 105 { 106 error!("Failed to delete blobs for user {}: {:?}", user_id, e); 107 return ( 108 StatusCode::INTERNAL_SERVER_ERROR, 109 Json(json!({"error": "InternalError", "message": "Failed to delete blobs"})), 110 ) 111 .into_response(); 112 } 113 if let Err(e) = sqlx::query!("DELETE FROM app_passwords WHERE user_id = $1", user_id) 114 .execute(&mut *tx) 115 .await 116 { 117 error!( 118 "Failed to delete app passwords for user {}: {:?}", 119 user_id, e 120 ); 121 return ( 122 StatusCode::INTERNAL_SERVER_ERROR, 123 Json(json!({"error": "InternalError", "message": "Failed to delete app passwords"})), 124 ) 125 .into_response(); 126 } 127 if let Err(e) = sqlx::query!( 128 "DELETE FROM invite_code_uses WHERE used_by_user = $1", 129 user_id 130 ) 131 .execute(&mut *tx) 132 .await 133 { 134 error!( 135 "Failed to delete invite code uses for user {}: {:?}", 136 user_id, e 137 ); 138 } 139 if let Err(e) = sqlx::query!( 140 "DELETE FROM invite_codes WHERE created_by_user = $1", 141 user_id 142 ) 143 .execute(&mut *tx) 144 .await 145 { 146 error!( 147 "Failed to delete invite codes for user {}: {:?}", 148 user_id, e 149 ); 150 } 151 if let Err(e) = sqlx::query!("DELETE FROM user_keys WHERE user_id = $1", user_id) 152 .execute(&mut *tx) 153 .await 154 { 155 error!("Failed to delete user keys for user {}: {:?}", user_id, e); 156 return ( 157 StatusCode::INTERNAL_SERVER_ERROR, 158 Json(json!({"error": "InternalError", "message": "Failed to delete user keys"})), 159 ) 160 .into_response(); 161 } 162 if let Err(e) = sqlx::query!("DELETE FROM users WHERE id = $1", user_id) 163 .execute(&mut *tx) 164 .await 165 { 166 error!("Failed to delete user {}: {:?}", user_id, e); 167 return ( 168 StatusCode::INTERNAL_SERVER_ERROR, 169 Json(json!({"error": "InternalError", "message": "Failed to delete user"})), 170 ) 171 .into_response(); 172 } 173 if let Err(e) = tx.commit().await { 174 error!("Failed to commit account deletion transaction: {:?}", e); 175 return ( 176 StatusCode::INTERNAL_SERVER_ERROR, 177 Json(json!({"error": "InternalError", "message": "Failed to commit deletion"})), 178 ) 179 .into_response(); 180 } 181 if let Err(e) = 182 crate::api::repo::record::sequence_account_event(&state, did, false, Some("deleted")).await 183 { 184 warn!( 185 "Failed to sequence account deletion event for {}: {}", 186 did, e 187 ); 188 } 189 let _ = state.cache.delete(&format!("handle:{}", handle)).await; 190 (StatusCode::OK, Json(json!({}))).into_response() 191}