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