supabase_auth_redux/
delete_user.rs

1use crate::util::handle_response_code;
2use crate::AuthClient;
3use crate::AuthError;
4use serde::{Deserialize, Serialize};
5use tracing::{debug, instrument};
6use uuid::Uuid;
7
8#[derive(Debug, Deserialize, Serialize)]
9struct DeleteBody {
10    should_soft_delete: bool,
11}
12
13impl AuthClient {
14    /// Soft deletes a user, marking them as deleted but preserving their data
15    ///
16    /// This operation requires a service role key to be configured on the AuthClient.
17    /// The user will be marked as deleted but their data will be retained in the database.
18    ///
19    /// # Arguments
20    ///
21    /// * `user_id` - The UUID of the user to soft delete
22    ///
23    /// # Errors
24    ///
25    /// Returns `AuthError::ServiceRoleKeyRequired` if no service role key is configured.
26    /// Returns `AuthError::Http` if the API request fails.
27    ///
28    /// # Example
29    ///
30    /// ```rust,no_run
31    /// # use supabase_auth_redux::AuthClient;
32    /// # use uuid::Uuid;
33    /// # async fn example() -> Result<(), supabase_auth_redux::AuthError> {
34    /// let admin_client = AuthClient::builder()
35    ///     .api_url("https://your-project.supabase.co")
36    ///     .anon_key("your-anon-key")
37    ///     .service_role_key("your-service-role-key")
38    ///     .build()?;
39    ///
40    /// let user_id = Uuid::parse_str("123e4567-e89b-12d3-a456-426614174000").unwrap();
41    /// admin_client.soft_delete_user(user_id).await?;
42    /// # Ok(())
43    /// # }
44    /// ```
45    #[instrument(skip_all)]
46    pub async fn soft_delete_user(&self, user_id: Uuid) -> Result<(), AuthError> {
47        let service_role_key = self
48            .supabase_service_role_key
49            .as_ref()
50            .ok_or(AuthError::ServiceRoleKeyRequired)?;
51
52        let resp = match self
53            .http_client
54            .delete(format!(
55                "{}/auth/v1/admin/users/{}",
56                self.supabase_api_url, user_id
57            ))
58            .json(&DeleteBody {
59                should_soft_delete: true,
60            })
61            .bearer_auth(service_role_key)
62            .header("apiKey", service_role_key)
63            .send()
64            .await
65        {
66            Ok(resp) => resp,
67            Err(e) => {
68                debug!("{}", e);
69                return Err(AuthError::Http);
70            }
71        };
72
73        let resp_code_result = handle_response_code(resp.status()).await;
74        let resp_text = match resp.text().await {
75            Ok(resp_text) => resp_text,
76            Err(e) => {
77                log::error!("{}", e);
78                return Err(AuthError::Http);
79            }
80        };
81        debug!("resp_text: {}", resp_text);
82        resp_code_result
83    }
84
85    /// Permanently deletes a user and all their associated data
86    ///
87    /// This operation requires a service role key to be configured on the AuthClient.
88    /// The user and all their data will be permanently removed from the database.
89    /// This action cannot be undone.
90    ///
91    /// # Arguments
92    ///
93    /// * `user_id` - The UUID of the user to permanently delete
94    ///
95    /// # Errors
96    ///
97    /// Returns `AuthError::ServiceRoleKeyRequired` if no service role key is configured.
98    /// Returns `AuthError::Http` if the API request fails.
99    ///
100    /// # Example
101    ///
102    /// ```rust,no_run
103    /// # use supabase_auth_redux::AuthClient;
104    /// # use uuid::Uuid;
105    /// # async fn example() -> Result<(), supabase_auth_redux::AuthError> {
106    /// let admin_client = AuthClient::builder()
107    ///     .api_url("https://your-project.supabase.co")
108    ///     .anon_key("your-anon-key")
109    ///     .service_role_key("your-service-role-key")
110    ///     .build()?;
111    ///
112    /// let user_id = Uuid::parse_str("123e4567-e89b-12d3-a456-426614174000").unwrap();
113    /// admin_client.hard_delete_user(user_id).await?;
114    /// # Ok(())
115    /// # }
116    /// ```
117    #[instrument(skip_all)]
118    pub async fn hard_delete_user(&self, user_id: Uuid) -> Result<(), AuthError> {
119        let service_role_key = self
120            .supabase_service_role_key
121            .as_ref()
122            .ok_or(AuthError::ServiceRoleKeyRequired)?;
123
124        let resp = match self
125            .http_client
126            .delete(format!(
127                "{}/auth/v1/admin/users/{}",
128                self.supabase_api_url, user_id
129            ))
130            .json(&DeleteBody {
131                should_soft_delete: false,
132            })
133            .bearer_auth(service_role_key)
134            .header("apiKey", service_role_key)
135            .send()
136            .await
137        {
138            Ok(resp) => resp,
139            Err(e) => {
140                debug!("{}", e);
141                return Err(AuthError::Http);
142            }
143        };
144
145        let resp_code_result = handle_response_code(resp.status()).await;
146        let resp_text = match resp.text().await {
147            Ok(resp_text) => resp_text,
148            Err(e) => {
149                log::error!("{}", e);
150                return Err(AuthError::Http);
151            }
152        };
153        debug!("resp_text: {}", resp_text);
154        resp_code_result
155    }
156}