Skip to main content

Solicitar Cambio de Contraseña (Paso 1)

Inicia una sesión de cambio de contraseña y genera un token de validación temporal.

POST

Inicia una sesión de cambio de contraseña y genera token de validación


Contexto de Uso

Este endpoint inicia el proceso de cambio de contraseña creando una sesión temporal en Redis que:

  • Tiene validez de 5 minutos
  • Genera un validationToken único (UUID v4)
  • Detecta automáticamente si el usuario tiene 2FA habilitado
  • Reutiliza sesiones válidas existentes (previene duplicados)

Este es el Paso 1 de un proceso de dos pasos:

Flujo de Dos Pasos

Paso 1: Request (Este endpoint)

  • Crea sesión temporal en Redis (5 minutos)
  • Genera validationToken único (UUID v4)
  • Determina si se requiere verificación 2FA
  • No requiere credenciales en este paso

Paso 2: Execute (Ver documentación)

  • Valida el validationToken obtenido aquí
  • Verifica contraseña actual del usuario
  • Valida código 2FA (si está habilitado)
  • Ejecuta el cambio de contraseña
  • Limpia sesión temporal automáticamente

Autenticación requerida: JWT Token válido en header Authorization: Bearer <token>


Validación de Entrada

Autenticación JWT Requerida

Este endpoint requiere un JWT token válido en el header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

No requiere body en la petición - toda la información se extrae del JWT:

  • userId obtenido de req.user.userId
  • email obtenido de req.user.sub.email

El Guard JwtAuthGuard:

  • Valida automáticamente el token
  • Si falla, retorna 401 Unauthorized
  • Si pasa, extrae información del usuario

Tipos de Respuesta

Respuesta para Usuario SIN 2FA

Sesión Creada - Solo Contraseñas

Código 1010 - Sesión de cambio de contraseña creada exitosamente.

{
"event": {
"code": 1010,
"message": "Password change session created"
},
"data": {
"requiresVerification": true,
"verificationType": "PASSWORD_ONLY",
"message": "Please provide current password and new password",
"fields": ["currentPassword", "newPassword"],
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}
}

Información de la respuesta:

  • verificationType: PASSWORD_ONLY - Solo se requieren contraseñas
  • fields: Lista de campos necesarios en el Paso 2
  • validationToken: UUID v4 válido por 5 minutos
  • requiresVerification: Siempre true

Almacenamiento en Redis:

// Clave: passwordChange:{validationToken}
// Valor: { userId, email, has2FA: false, createdAt }
// TTL: 300000 ms (5 minutos)

Próximos pasos:

  • Guardar validationToken temporalmente
  • Solicitar contraseña actual y nueva al usuario
  • Usar el token en el Paso 2 (execute)

Respuesta para Usuario CON 2FA

Sesión Creada - Requiere 2FA

Código 1010 - Sesión creada, se requiere verificación 2FA adicional.

{
"event": {
"code": 1010,
"message": "Password change session created"
},
"data": {
"requiresVerification": true,
"verificationType": "2FA_REQUIRED",
"message": "Please provide current password, new password, and 2FA code",
"fields": ["currentPassword", "newPassword", "twoFACode"],
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}
}

Información de la respuesta:

  • verificationType: 2FA_REQUIRED - Se necesitan contraseñas + código 2FA
  • fields: Incluye twoFACode adicional
  • validationToken: UUID v4 válido por 5 minutos
  • Usuario debe abrir su app autenticadora

Almacenamiento en Redis:

// Clave: passwordChange:{validationToken}
// Valor: { userId, email, has2FA: true, createdAt }
// TTL: 300000 ms (5 minutos)

Próximos pasos:

  • Guardar validationToken temporalmente
  • Solicitar contraseña actual, nueva y código 2FA
  • Usuario debe obtener código TOTP de su app (Google Authenticator, Authy, etc.)
  • Usar el token y código en el Paso 2 (execute)

Errores Posibles

Usuario No Encontrado

Código 4040 - El usuario del JWT no existe en la base de datos.

{
"code": 4040,
"message": "User not found"
}

Causas posibles:

  • Email en JWT no corresponde a ningún usuario
  • Usuario fue eliminado después de obtener el JWT
  • Base de datos inconsistente

Acción requerida:

  • Usuario debe cerrar sesión e iniciar sesión nuevamente
  • Verificar integridad de la base de datos

Ejemplos de Implementación

JavaScript

async function requestPasswordChange(accessToken) {
try {
const response = await fetch('https://api.swapbits.co/auth/account/password/request', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

const result = await response.json();

if (result.event.code === 1010) {
console.log('Sesión creada:', result.data.verificationType);
console.log('Token:', result.data.validationToken);
console.log('Campos requeridos:', result.data.fields);

// Guardar token para el Paso 2
sessionStorage.setItem('validationToken', result.data.validationToken);
sessionStorage.setItem('requires2FA', result.data.verificationType === '2FA_REQUIRED');

return result.data;
}
} catch (error) {
console.error('Error:', error);
throw error;
}
}

TypeScript

interface PasswordChangeSession {
requiresVerification: boolean;
verificationType: 'PASSWORD_ONLY' | '2FA_REQUIRED';
message: string;
fields: string[];
validationToken: string;
}

async function requestPasswordChange(accessToken: string): Promise<PasswordChangeSession> {
const response = await fetch('https://api.swapbits.co/auth/account/password/request', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

const result = await response.json();

if (result.event.code !== 1010) {
throw new Error(result.message || 'Error al solicitar cambio de contraseña');
}

return result.data;
}

Python

import requests

def request_password_change(access_token: str) -> dict:
"""Solicita inicio de sesión de cambio de contraseña"""
url = 'https://api.swapbits.co/auth/account/password/request'
headers = {'Authorization': f'Bearer {access_token}'}

response = requests.post(url, headers=headers)
result = response.json()

if result.get('event', {}).get('code') == 1010:
data = result['data']
print(f"Tipo: {data['verificationType']}")
print(f"Token: {data['validationToken']}")
print(f"Campos: {', '.join(data['fields'])}")
return data
else:
raise Exception(result.get('message', 'Error desconocido'))

cURL

curl -X POST 'https://api.swapbits.co/auth/account/password/request' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'

Proceso Interno

Flujo del Endpoint

1. Autenticación

// Guard valida JWT automáticamente
const userId = req.user.userId;
const email = req.user.sub.email;

2. Buscar Usuario

const user = await userModel.findOne({ email });
if (!user) throw new NotFoundException({ code: 4040 });

3. Verificar Sesión Existente

// Reutiliza token si ya existe sesión válida
const existingToken = await redis.get(`userToPasswordChange:${userId}`);
if (existingToken) {
const session = await redis.get(`passwordChange:${existingToken}`);
if (session) return existingToken; // Reutiliza
}

4. Detectar Estado 2FA

const has2FA = user.oauth2?.twofa?.is_enabled || false;

5. Generar Token

import { v4 as uuidv4 } from 'uuid';
const validationToken = uuidv4();

6. Almacenar en Redis

const sessionData = {
userId: user._id,
email: user.email,
has2FA,
createdAt: new Date()
};

await redis.setex(
`passwordChange:${validationToken}`,
300, // 5 minutos
JSON.stringify(sessionData)
);

await redis.setex(
`userToPasswordChange:${userId}`,
300,
validationToken
);

7. Retornar Respuesta

return {
event: { code: 1010, message: "Password change session created" },
data: {
requiresVerification: true,
verificationType: has2FA ? '2FA_REQUIRED' : 'PASSWORD_ONLY',
message: has2FA
? "Please provide current password, new password, and 2FA code"
: "Please provide current password and new password",
fields: has2FA
? ['currentPassword', 'newPassword', 'twoFACode']
: ['currentPassword', 'newPassword'],
validationToken
}
};

Códigos de Respuesta

CódigoHTTP StatusDescripciónAcción
1010200Sesión creada exitosamenteContinuar al Paso 2
4040404Usuario no encontradoReautenticar usuario

Probar esta API

API Explorer


Enlaces Relacionados

Proceso de Cambio de Contraseña

Autenticación y Seguridad

Gestión de Cuenta