Eliminar Cuenta de Usuario
Eliminación permanente de la cuenta del usuario autenticado mediante sistema de soft delete con auditoría completa.
Marca la cuenta como eliminada, preservando datos para auditoría y posible recuperación
Contexto de Uso
Este endpoint permite a un usuario autenticado solicitar la eliminación permanente de su cuenta. El sistema implementa una eliminación suave (soft delete) donde:
- La cuenta se marca con
isDeleted: true - Los datos se copian a la colección
DeletedUserspara auditoría - El usuario no puede iniciar sesión nuevamente
- Los datos se preservan para recuperación y cumplimiento legal
- No se elimina información físicamente de la base de datos
Autenticación requerida: JWT Token válido en header Authorization: Bearer <token>
Validación de Entrada
Autenticación JWT
Token de Acceso Requerido
Este endpoint requiere un JWT token válido en el header de autorización:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Extracción de identidad:
- El email del usuario se obtiene de
req.user.sub.email - Este campo proviene del payload decodificado del JWT
- No se requieren parámetros adicionales en el body
Validación automática:
- Guard
JwtAuthGuardvalida el token - Si falla, retorna
401 Unauthorized - Si pasa, el controlador tiene acceso a
req.user
Sin Parámetros de Body
Sin Parámetros Requeridos
Este endpoint no requiere body en la petición:
- No se envían datos en el cuerpo de la solicitud
- La identidad del usuario se obtiene completamente del JWT
- El método HTTP DELETE no espera payload
// Correcto
await fetch('/auth/account', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
});
// No necesitas body
Tipos de Respuesta
Respuesta Exitosa
Cuenta Eliminada Exitosamente
Código 1012 - La cuenta se marcó como eliminada correctamente.
{
"code": 1012,
"message": "Account deleted successfully",
"data": {
"status": "success"
}
}
Efectos de la eliminación:
- Campo
isDeleted: trueen el usuario - Registro creado en colección
DeletedUsers - Usuario no puede iniciar sesión nuevamente
- Datos preservados para auditoría
- Timestamp de eliminación registrado
Próximos pasos:
- Limpiar tokens del cliente
- Cerrar todas las sesiones activas
- Redirigir a página de despedida
- Mostrar confirmación al usuario
Errores de Validación
Token JWT Inválido o Expirado
HTTP 401 Unauthorized - El token JWT no es válido o ha expirado.
{
"statusCode": 401,
"message": "Unauthorized"
}
Causas comunes:
- Token JWT no enviado en header
- Token JWT inválido o mal formado
- Token JWT expirado
- Firma del token incorrecta
- Header
Authorizationmal formado
Acción requerida:
- Usuario debe iniciar sesión nuevamente
- Obtener un nuevo
accessToken - Reintentar la operación con token válido
Usuario No Encontrado
Código 4001 - El usuario especificado en el JWT no existe en la base de datos.
{
"code": 4001,
"message": "User not found"
}
Causas posibles:
- Email en JWT no existe en MongoDB
- Usuario ya fue eliminado previamente
- Base de datos inconsistente
- Token JWT contiene datos inválidos
Acción requerida:
- Verificar que el token corresponda a un usuario válido
- Si ya fue eliminado, informar al usuario
- Limpiar sesión y redirigir a login
Error del Servidor
Código 5003 - Error interno al procesar la eliminación.
{
"code": 5003,
"message": "Error deleting user",
"statusCode": 500
}
Causas posibles:
- Error de conexión con MongoDB
- Fallo al crear registro en
DeletedUsers - Error al actualizar campo
isDeleted - Timeout de base de datos
Respuesta genérica alternativa:
{
"statusCode": 500,
"message": "Error deleting account."
}
Acción requerida:
- Reintentar la operación
- Si persiste, contactar soporte
- Verificar estado del servidor
Flujo de Eliminación
Diagrama de Secuencia
sequenceDiagram
participant U as Usuario
participant C as Cliente
participant API as API
participant JWT as JWTGuard
participant DB as MongoDB
participant DU as DeletedUsers
U->>C: Solicita eliminar cuenta
C->>API: DELETE /auth/account<br/>Authorization: Bearer token
API->>JWT: Validar JWT token
alt Token inválido
JWT-->>API: Error validación
API-->>C: 401 Unauthorized
C-->>U: Sesión expirada
else Token válido
JWT-->>API: Usuario autenticado
API->>API: Extraer email de JWT
API->>DB: Buscar usuario por email
alt Usuario no existe
DB-->>API: null
API-->>C: 404 (code: 4001)
C-->>U: Usuario no encontrado
else Usuario existe
DB-->>API: Datos del usuario
API->>DU: Crear registro eliminación
Note over DU: email, deletedAt, reason
API->>DB: UPDATE isDeleted = true
alt Error en proceso
API-->>C: 500 (code: 5003)
C-->>U: Error del servidor
else Eliminación exitosa
API-->>C: 200 (code: 1012)
C->>C: Limpiar tokens
C->>C: Cerrar sesiones
C-->>U: Cuenta eliminada
Note over U,DU: Redirigir a página despedida
end
end
end
Proceso Interno del Endpoint
Flujo de Procesamiento
Pasos del Proceso de Eliminación
1. Validación de Autenticación
@UseGuards(JwtAuthGuard)
@Delete('account')
async deleteAccount(@Request() req) {
// Guard valida automáticamente el token
// Si falla, retorna 401 Unauthorized
}
2. Extracción de Email del Usuario
const email = req.user.sub.email;
// Email obtenido del payload decodificado del JWT
// Formato: { sub: { email: "user@example.com" } }
3. Búsqueda del Usuario
const user = await this.userModel.findOne({ email });
if (!user) {
throw new NotFoundException({
code: 4001,
message: 'User not found'
});
}
4. Creación de Registro en DeletedUsers
await this.deletedUserModel.create({
email: user.email,
deletedAt: new Date(),
reason: 'User requested deletion'
});
// Preserva evidencia de la eliminación para auditoría
5. Marcado como Eliminado (Soft Delete)
await this.userModel.findOneAndUpdate(
{ email: user.email },
{ $set: { isDeleted: true } }
);
// No elimina el documento, solo marca el campo
6. Respuesta Exitosa
return {
code: 1012,
message: 'Account deleted successfully',
data: {
status: 'success'
}
};
7. Manejo de Errores
try {
// Proceso de eliminación...
} catch (error) {
throw new InternalServerErrorException({
code: 5003,
message: 'Error deleting user',
statusCode: 500
});
}
Seguridad y Auditoría
Características de Seguridad
Protecciones Implementadas
Autenticación Estricta:
- Solo usuarios autenticados pueden eliminar su cuenta
- JWT Guard valida automáticamente el token
- No se permite eliminación de cuentas ajenas
- El email se extrae del JWT, no del body (previene manipulación)
Eliminación Suave (Soft Delete):
- No elimina datos físicamente de la base de datos
- Marca usuario con
isDeleted: true - Preserva toda la información histórica
- Permite auditorías y cumplimiento legal
Registro de Auditoría:
// Colección DeletedUsers almacena:
{
email: string, // Email del usuario eliminado
deletedAt: Date, // Timestamp exacto de eliminación
reason: string, // Motivo: "User requested deletion"
_id: ObjectId // ID único del registro
}
Prevención de Re-uso:
- Email queda bloqueado en
DeletedUsers - Usuario no puede crear nueva cuenta con mismo email
- Previene fraude y abuso del sistema
- Requiere limpieza manual para liberar email
Datos Preservados
Información Mantenida Post-Eliminación
Colección Users:
- Todos los datos del usuario intactos
- Campo
isDeleted: trueagregado - Historial completo preservado
- Wallets y balances mantenidos
- Transacciones históricas disponibles
- Configuraciones de seguridad guardadas
Colección DeletedUsers:
- Email del usuario eliminado
- Fecha y hora exacta de eliminación
- Razón de la eliminación
- Referencia cruzada con Users
Propósito de Preservación:
- Cumplimiento de regulaciones (GDPR, etc.)
- Auditorías de seguridad
- Investigaciones de fraude
- Recuperación en casos especiales
- Análisis de churn y retención
Ejemplos de Implementación
JavaScript (Fetch API)
async function deleteAccount(accessToken) {
try {
const response = await fetch('https://api.swapbits.co/auth/account', {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});
const result = await response.json();
if (response.ok && result.code === 1012) {
console.log('Cuenta eliminada correctamente');
// Limpiar tokens
localStorage.removeItem('accessToken');
sessionStorage.clear();
// Redirigir
window.location.href = '/goodbye';
return result;
} else {
throw new Error(result.message || 'Error al eliminar cuenta');
}
} catch (error) {
console.error('Error:', error);
throw error;
}
}
async function confirmAndDeleteAccount(accessToken) {
// Primera confirmación
const confirmed = confirm(
'⚠️ ADVERTENCIA: Eliminación de Cuenta\n\n' +
'Esta acción eliminará permanentemente:\n' +
'• Todos tus datos personales\n' +
'• Tus wallets y balances\n' +
'• Tu historial de transacciones\n' +
'• Todas tus configuraciones\n\n' +
'¿Estás seguro de que deseas continuar?'
);
if (!confirmed) {
console.log('Eliminación cancelada por el usuario');
return { cancelled: true };
}
// Segunda confirmación con texto
const confirmation = prompt(
'Para confirmar, escribe "ELIMINAR" (en mayúsculas):'
);
if (confirmation !== 'ELIMINAR') {
alert('Confirmación incorrecta. Eliminación cancelada.');
return { cancelled: true };
}
try {
const result = await deleteAccount(accessToken);
return { success: true, data: result };
} catch (error) {
alert(`Error: ${error.message}`);
return { success: false, error: error.message };
}
}
// Uso
const accessToken = localStorage.getItem('accessToken');
confirmAndDeleteAccount(accessToken)
.then(result => {
if (result.success) {
console.log('Cuenta eliminada exitosamente');
} else if (result.cancelled) {
console.log('Usuario canceló la operación');
}
});
TypeScript (Axios)
import axios, { AxiosError } from 'axios';
interface DeleteAccountResponse {
code: number;
message: string;
data: {
status: string;
};
}
interface ErrorResponse {
code?: number;
message: string;
statusCode?: number;
}
class AccountDeletionService {
private readonly apiUrl = 'https://api.swapbits.co';
private accessToken: string;
constructor(accessToken: string) {
if (!accessToken) {
throw new Error('Token de acceso requerido');
}
this.accessToken = accessToken;
}
/**
* Elimina la cuenta del usuario autenticado
*/
async deleteAccount(): Promise<DeleteAccountResponse> {
try {
const response = await axios.delete<DeleteAccountResponse>(
`${this.apiUrl}/auth/account`,
{
headers: {
'Authorization': `Bearer ${this.accessToken}`
}
}
);
if (response.data.code === 1012) {
// Limpiar datos locales después de eliminación exitosa
this.clearAuthData();
}
return response.data;
} catch (error) {
throw this.handleError(error);
}
}
/**
* Maneja errores de la petición
*/
private handleError(error: unknown): Error {
if (axios.isAxiosError(error)) {
const axiosError = error as AxiosError<ErrorResponse>;
const errorData = axiosError.response?.data;
const status = axiosError.response?.status;
switch (status) {
case 401:
return new Error('Sesión expirada. Inicia sesión nuevamente.');
case 404:
if (errorData?.code === 4001) {
return new Error('Usuario no encontrado.');
}
return new Error('Recurso no encontrado.');
case 500:
if (errorData?.code === 5003) {
return new Error('Error del servidor al eliminar cuenta. Intenta más tarde.');
}
return new Error('Error interno del servidor.');
default:
return new Error(errorData?.message || 'Error desconocido');
}
}
return new Error('Error de conexión');
}
/**
* Limpia todos los datos de autenticación
*/
private clearAuthData(): void {
// Limpiar localStorage
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
// Limpiar sessionStorage
sessionStorage.removeItem('pinAuthToken');
sessionStorage.clear();
// Limpiar cookies
document.cookie.split(";").forEach((cookie) => {
document.cookie = cookie
.replace(/^ +/, "")
.replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
});
}
/**
* Valida que la cuenta puede ser eliminada
*/
async canDelete(): Promise<{ canDelete: boolean; reason?: string }> {
// Aquí puedes agregar validaciones adicionales
// Por ejemplo: verificar saldo, transacciones pendientes, etc.
return { canDelete: true };
}
}
// Hook de React para eliminación de cuenta
export function useDeleteAccount() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState(false);
const deleteAccount = async (accessToken: string): Promise<boolean> => {
setLoading(true);
setError(null);
setSuccess(false);
try {
const service = new AccountDeletionService(accessToken);
const result = await service.deleteAccount();
setSuccess(true);
return true;
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Error desconocido';
setError(errorMessage);
return false;
} finally {
setLoading(false);
}
};
return { loading, error, success, deleteAccount };
}
Python (requests)
import requests
from typing import Dict, Any, Optional
from datetime import datetime
class AccountDeletionClient:
"""Cliente para eliminación de cuenta de usuario"""
def __init__(self, access_token: str, api_url: str = 'https://api.swapbits.co'):
if not access_token:
raise ValueError('Token de acceso requerido')
self.access_token = access_token
self.api_url = api_url
self.headers = {
'Authorization': f'Bearer {access_token}'
}
def delete_account(self) -> Dict[str, Any]:
"""
Elimina la cuenta del usuario autenticado
Returns:
Respuesta del servidor con código y mensaje
Raises:
Exception: Si hay error en la solicitud
"""
url = f'{self.api_url}/auth/account'
try:
response = requests.delete(url, headers=self.headers, timeout=10)
response_data = response.json()
# Manejar respuesta exitosa
if response.status_code == 200 and response_data.get('code') == 1012:
return {
'success': True,
'code': response_data['code'],
'message': response_data['message'],
'data': response_data['data']
}
# Manejar errores específicos
return self._handle_error(response.status_code, response_data)
except requests.exceptions.Timeout:
raise Exception('Tiempo de espera agotado. Intenta nuevamente.')
except requests.exceptions.ConnectionError:
raise Exception('Error de conexión. Verifica tu internet.')
except requests.exceptions.RequestException as e:
raise Exception(f'Error en la solicitud: {str(e)}')
except ValueError:
raise Exception('Respuesta inválida del servidor')
def _handle_error(self, status_code: int, response_data: Dict) -> Dict:
"""Maneja errores de la API"""
error_code = response_data.get('code')
message = response_data.get('message', 'Error desconocido')
error_map = {
401: 'Sesión expirada. Inicia sesión nuevamente.',
404: 'Usuario no encontrado.' if error_code == 4001 else message,
500: 'Error del servidor. Intenta más tarde.' if error_code == 5003 else message
}
error_message = error_map.get(status_code, message)
return {
'success': False,
'error': error_message,
'code': error_code,
'status_code': status_code
}
def confirm_deletion() -> bool:
"""Solicita confirmación al usuario antes de eliminar"""
print("\n" + "=" * 70)
print("⚠️ ADVERTENCIA: ELIMINACIÓN PERMANENTE DE CUENTA")
print("=" * 70)
print("\nEstás a punto de eliminar tu cuenta permanentemente.")
print("\nPerderás acceso a:")
print(" • Todos tus datos personales")
print(" • Tus wallets y balances de criptomonedas")
print(" • Tu historial completo de transacciones")
print(" • Todas tus configuraciones y preferencias")
print(" • Cualquier beneficio o recompensa acumulada")
print("\n" + "=" * 70)
# Primera confirmación
response = input("\n¿Estás seguro de que deseas continuar? (sí/no): ").strip().lower()
if response not in ['sí', 'si', 'yes', 's']:
print("\n✓ Eliminación cancelada.")
return False
# Segunda confirmación con texto específico
print("\nPara confirmar, escribe exactamente: ELIMINAR")
confirmation = input("Confirmación: ").strip()
if confirmation != 'ELIMINAR':
print("\n✗ Confirmación incorrecta. Eliminación cancelada.")
return False
return True
def delete_account_interactive(access_token: str) -> None:
"""Función interactiva para eliminar cuenta"""
try:
# Solicitar confirmación
if not confirm_deletion():
return
# Crear cliente y eliminar cuenta
print("\nProcesando eliminación...")
client = AccountDeletionClient(access_token)
result = client.delete_account()
if result['success']:
print(f"\n✓ {result['message']}")
print(f"Código: {result['code']}")
print(f"Estado: {result['data']['status']}")
print("\nGracias por usar nuestros servicios.")
print("Tu cuenta ha sido marcada para eliminación.")
else:
print(f"\n✗ Error: {result['error']}")
print(f"Código: {result.get('code', 'N/A')}")
except Exception as e:
print(f"\n✗ Error inesperado: {e}")
# Ejemplo de uso
if __name__ == '__main__':
print("Sistema de Eliminación de Cuenta\n")
# Obtener token (en producción vendría de archivo seguro o variable de entorno)
access_token = input('Ingresa tu token de acceso: ').strip()
if not access_token:
print("Error: Token requerido")
exit(1)
delete_account_interactive(access_token)
cURL
curl -X DELETE 'https://api.swapbits.co/auth/account' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
#!/bin/bash
# Script para eliminación de cuenta con confirmaciones
API_URL="https://api.swapbits.co/auth/account"
# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Función de confirmación
confirm_deletion() {
echo -e "${RED}═══════════════════════════════════════════════════════════${NC}"
echo -e "${RED} ⚠️ ADVERTENCIA: ELIMINACIÓN DE CUENTA ⚠️${NC}"
echo -e "${RED}═══════════════════════════════════════════════════════════${NC}"
echo ""
echo "Esta acción eliminará permanentemente:"
echo " • Todos tus datos personales"
echo " • Tus wallets y balances"
echo " • Tu historial de transacciones"
echo " • Todas tus configuraciones"
echo ""
read -p "¿Deseas continuar? (sí/no): " confirm
if [[ ! "$confirm" =~ ^(sí|si|yes|s|SI|SÍ)$ ]]; then
echo -e "${GREEN}✓ Eliminación cancelada${NC}"
return 1
fi
echo ""
echo -e "${YELLOW}Para confirmar, escribe exactamente: ELIMINAR${NC}"
read -p "Confirmación: " double_confirm
if [ "$double_confirm" != "ELIMINAR" ]; then
echo -e "${RED}✗ Confirmación incorrecta. Eliminación cancelada.${NC}"
return 1
fi
return 0
}
# Función principal de eliminación
delete_account() {
local token=$1
if [ -z "$token" ]; then
echo -e "${RED}✗ Token de acceso requerido${NC}"
return 1
fi
echo -e "${YELLOW}Procesando eliminación...${NC}"
# Hacer petición a la API
response=$(curl -s -w "\n%{http_code}" -X DELETE "$API_URL" \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json")
# Separar body y status code
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
# Verificar si jq está instalado
if ! command -v jq &> /dev/null; then
echo "Respuesta: $body"
[ "$http_code" -eq 200 ] && echo -e "${GREEN}✓ Eliminación exitosa${NC}" || echo -e "${RED}✗ Error${NC}"
return
fi
# Parsear JSON
code=$(echo "$body" | jq -r '.code // empty')
message=$(echo "$body" | jq -r '.message // empty')
# Manejar respuesta
case $http_code in
200)
if [ "$code" = "1012" ]; then
echo -e "${GREEN}✓ Cuenta eliminada exitosamente${NC}"
echo "Mensaje: $message"
echo ""
echo "Gracias por usar nuestros servicios."
else
echo -e "${YELLOW}Respuesta inesperada${NC}"
echo "Código: $code"
echo "Mensaje: $message"
fi
;;
401)
echo -e "${RED}✗ Sesión expirada${NC}"
echo "Por favor, inicia sesión nuevamente."
;;
404)
echo -e "${RED}✗ Usuario no encontrado${NC}"
echo "Código: $code"
;;
500)
echo -e "${RED}✗ Error del servidor${NC}"
echo "Mensaje: $message"
echo "Intenta nuevamente más tarde."
;;
*)
echo -e "${RED}✗ Error desconocido${NC}"
echo "HTTP Status: $http_code"
echo "Respuesta: $body"
;;
esac
}
# Modo interactivo
if [ "$#" -eq 0 ]; then
echo "Sistema de Eliminación de Cuenta"
echo ""
read -p "Token de acceso: " access_token
echo ""
if confirm_deletion; then
echo ""
delete_account "$access_token"
fi
else
# Modo con parámetro
delete_account "$1"
fi
Consideraciones de Seguridad
Protecciones Implementadas
Medidas de Seguridad
1. Autenticación Estricta
// Solo el propietario puede eliminar su cuenta
@UseGuards(JwtAuthGuard)
async deleteAccount(@Request() req) {
const email = req.user.sub.email;
// Email extraído del JWT, no del body
// Previene manipulación de parámetros
}
2. Validación de Permisos
// No se permite eliminar cuentas ajenas
class AccountDeletionValidator {
canDelete(tokenEmail: string, targetEmail: string): boolean {
return tokenEmail === targetEmail;
}
}
3. Soft Delete (Preservación de Datos)
// No se eliminan datos físicamente
await userModel.findOneAndUpdate(
{ email },
{ $set: { isDeleted: true } }
);
// Datos intactos para auditoría
4. Registro de Auditoría
// Cada eliminación se registra
await deletedUserModel.create({
email: user.email,
deletedAt: new Date(),
reason: 'User requested deletion',
deletedBy: 'self' // o ID de admin si aplica
});
5. Prevención de Re-uso de Email
// Email bloqueado en DeletedUsers
// Previene creación de nueva cuenta con mismo email
// Requiere limpieza manual para liberar
Recomendaciones de Implementación
Mejores Prácticas
1. Período de Gracia (Recomendado)
// Implementar período de 30 días antes de eliminación final
interface DeletionRequest {
email: string;
requestedAt: Date;
scheduledFor: Date; // requestedAt + 30 días
status: 'pending' | 'cancelled' | 'completed';
}
// Permitir cancelación dentro del período
async cancelDeletion(email: string) {
await deletionRequestModel.updateOne(
{ email, status: 'pending' },
{ $set: { status: 'cancelled' } }
);
}
2. Notificación por Email
// Enviar confirmación de eliminación
await emailService.send({
to: user.email,
subject: 'Confirmación de eliminación de cuenta',
template: 'account-deletion-confirmation',
data: {
userName: user.name,
deletionDate: new Date(),
cancellationLink: generateCancellationLink(user.email)
}
});
3. Limpieza de Datos Relacionados
// Cancelar servicios y limpiar datos asociados
async cleanupUserData(userId: string) {
await Promise.all([
walletService.closeWallets(userId),
transactionService.archiveHistory(userId),
sessionService.revokeAll(userId),
subscriptionService.cancel(userId),
notificationService.unsubscribe(userId)
]);
}
4. Verificación de Transacciones Pendientes
async canDeleteAccount(userId: string): Promise<boolean> {
const pendingTx = await transactionModel.countDocuments({
userId,
status: 'pending'
});
return pendingTx === 0;
}
5. Backup de Datos Críticos
// Crear respaldo antes de marcar como eliminado
async backupUserData(user: User) {
await backupModel.create({
userId: user._id,
email: user.email,
data: user.toObject(),
wallets: await walletModel.find({ userId: user._id }),
transactions: await txModel.find({ userId: user._id }).limit(1000),
createdAt: new Date(),
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 días
});
}
Proceso de Eliminación
Estado Actual (Soft Delete Inmediato)
graph TD
A[Usuario solicita eliminación] --> B{Token válido?}
B -->|No| C[Error 401]
B -->|Sí| D[Buscar usuario]
D --> E{Usuario existe?}
E -->|No| F[Error 4001]
E -->|Sí| G[Crear registro DeletedUsers]
G --> H[Marcar isDeleted = true]
H --> I[Respuesta exitosa 1012]
I --> J[Usuario no puede iniciar sesión]
J --> K[Datos preservados]
style I fill:#90EE90
style C fill:#FFB6C1
style F fill:#FFB6C1
Proceso Recomendado (Con Período de Gracia)
graph TD
A[Usuario solicita eliminación] --> B[Marcar deletionRequested = true]
B --> C[Establecer deletionDate = now + 30 días]
C --> D[Enviar email confirmación]
D --> E[Crear DeletionRequest pendiente]
E --> F{Usuario cancela?}
F -->|Sí| G[Actualizar status = cancelled]
G --> H[Usuario puede seguir usando cuenta]
F -->|No| I{30 días pasaron?}
I -->|No| F
I -->|Sí| J[Job automático ejecuta eliminación]
J --> K[Marcar isDeleted = true]
K --> L[Mover a DeletedUsers]
L --> M[Limpiar datos relacionados]
style G fill:#90EE90
style L fill:#FFD700
Códigos de Respuesta
| Código | HTTP Status | Descripción | Acción Sugerida |
|---|---|---|---|
| 1012 | 200 | Cuenta eliminada exitosamente | Limpiar tokens y redirigir |
| 4001 | 404 | Usuario no encontrado | Verificar JWT y base de datos |
| 5003 | 500 | Error al eliminar usuario | Reintentar o contactar soporte |
| - | 401 | Token JWT inválido/expirado | Iniciar sesión nuevamente |
| - | 500 | Error genérico del servidor | Reintentar más tarde |
Notas Importantes
Aspectos Críticos del Endpoint
-
Eliminación Suave: La cuenta no se elimina físicamente, solo se marca con
isDeleted: true -
Preservación de Datos: Todos los datos se mantienen intactos para auditoría y cumplimiento legal
-
Sin Período de Gracia Actual: La eliminación es inmediata (se recomienda implementar período de espera de 30 días)
-
Recuperación Posible: Con asistencia de soporte técnico, la cuenta puede ser reactivada
-
Registro en DeletedUsers: Email y fecha de eliminación se almacenan permanentemente
-
Bloqueo de Email: El email queda bloqueado hasta limpieza manual, no permite re-registro
-
Sesiones Inválidas: Todas las sesiones activas quedan inmediatamente invalidadas
-
Sin Limpieza de Datos: Wallets, transacciones y configuraciones permanecen en la base de datos
-
Auditoría Completa: Cada eliminación se registra con timestamp exacto y razón
-
Solo Auto-Eliminación: Usuario solo puede eliminar su propia cuenta, no la de otros
Probar esta API
API Explorer
En el API Explorer podrás:
- Enviar peticiones reales con tu token JWT
- Ver respuestas en tiempo real
- Experimentar con diferentes tokens
- Simular errores de autenticación
- Ver ejemplos de código generados automáticamente
Enlaces Relacionados
Gestión de Cuenta
- Solicitar Cambio de Contraseña - Solicitar cambio de contraseña
- Ejecutar Cambio de Contraseña - Confirmar cambio de contraseña
Autenticación
- Login - POST /auth/login
Seguridad
- Sistema 2FA - Configurar autenticación de dos factores