Skip to main content

Ejecutar Cambio de Contraseña (Paso 2)

Ejecuta el cambio real de contraseña usando el token de validación del Paso 1.

PATCH

Ejecuta el cambio de contraseña usando el token de validación del Paso 1

📋 Parámetros

passwordstringrequerido

Contraseña actual del usuario

newPasswordstringrequerido

Nueva contraseña (debe cumplir requisitos)

validationTokenstringrequerido

Token UUID del Paso 1

twoFACodestring

Código TOTP de 6 dígitos (si 2FA habilitado)


Contexto de Uso

Este endpoint ejecuta el cambio real de contraseña después de:

  1. Obtener validationToken del Paso 1 (request)
  2. Recopilar credenciales del usuario
  3. Validar código 2FA (si aplica)

Proceso interno:

  • Valida token de sesión en Redis
  • Verifica contraseña actual con Argon2id
  • Valida código TOTP si 2FA está habilitado
  • Hashea nueva contraseña con parámetros seguros
  • Actualiza registro en MongoDB
  • Limpia sesión temporal

Validación de Entrada

Requisitos de Contraseña

La nueva contraseña debe cumplir con requisitos estrictos de seguridad:

Requisitos obligatorios:

  • ✅ Mínimo 9 caracteres
  • ✅ Al menos 1 letra mayúscula (A-Z)
  • ✅ Al menos 1 letra minúscula (a-z)
  • ✅ Al menos 1 número (0-9)
  • ✅ Al menos 1 carácter especial (!@#$%^&*()_+-=[]|;:,.<>?)
  • NO puede ser igual a la contraseña actual

Regex de validación:

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{9,}$/

Validación de Token

El validationToken debe:

  • Ser un UUID v4 válido
  • Provenir del Paso 1 (request)
  • Estar activo en Redis (no expirado)
  • Corresponder al usuario actual
  • Tener menos de 5 minutos de antigüedad

Almacenamiento en Redis:

// Database: 6
// Clave: passwordChange:{uuid}
// Valor: { userId, email, has2FA, createdAt }
// TTL: 300000 ms (5 minutos)

Código 2FA (Condicional)

Si el usuario tiene 2FA habilitado, debe proporcionar:

Formato del código:

  • Exactamente 6 dígitos numéricos
  • Generado por app autenticadora (Google Authenticator, Authy, etc.)
  • Basado en protocolo TOTP (RFC 6238)
  • Válido por 30 segundos
  • Ventana de tolerancia: ±1 período (90 segundos total)

Request Body

Usuario SIN 2FA

{
"password": "MiPasswordActual123!",
"newPassword": "MiNuevaPassword456!",
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}

Usuario CON 2FA

{
"password": "MiPasswordActual123!",
"newPassword": "MiNuevaPassword456!",
"twoFACode": "123456",
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}

Tipos de Respuesta

Respuesta Exitosa

Contraseña Actualizada Exitosamente

Código 1003 - Contraseña cambiada correctamente.

{
"event": {
"code": 1003,
"message": "Password updated successfully"
},
"data": {
"status": "success",
"message": "Password changed successfully"
}
}

Acciones ejecutadas automáticamente:

  • ✅ Contraseña hasheada con Argon2id
  • ✅ Parámetros: memory 65536 KB, iterations 3, parallelism 4
  • ✅ Campo password actualizado en MongoDB
  • ✅ Sesión temporal eliminada de Redis

Errores de Validación

Datos Inválidos (4006)

Los datos enviados están incompletos o tienen formato inválido.

{
"code": 4006,
"message": "Invalid data"
}

Contraseña Actual Incorrecta (4007)

La contraseña actual proporcionada no coincide.

{
"code": 4007,
"message": "Current password is incorrect"
}

Nueva Contraseña No Cumple Requisitos (4008)

La nueva contraseña no cumple con los requisitos de seguridad.

{
"code": 4008,
"message": "Password does not meet security requirements"
}

Nueva Contraseña Igual a la Actual (4029)

La nueva contraseña es idéntica a la actual.

{
"code": 4029,
"message": "New password cannot be the same as current password"
}

Errores de Token

Token Requerido (4031)

No se proporcionó el token de validación.

{
"code": 4031,
"message": "Validation token is required. Please request password change first."
}

Acción: Ejecutar Paso 1 (request) primero.

Token Inválido o Expirado (4032)

El token no existe en Redis o ya expiró.

{
"code": 4032,
"message": "Invalid or expired validation token"
}

Acción: Solicitar nuevo token (Paso 1).

Token No Coincide (4033)

El token no pertenece al usuario actual.

{
"code": 4033,
"message": "Validation token does not match current user"
}

Errores de 2FA

Código 2FA Requerido (4034)

Usuario tiene 2FA habilitado pero no proporcionó código.

{
"code": 4034,
"message": "Two-factor authentication code is required for users with 2FA enabled"
}

Código 2FA Inválido (4005)

El código 2FA proporcionado no es válido.

{
"code": 4005,
"message": "Invalid two-factor authentication code"
}

Ejemplos de Implementación

JavaScript

async function changePassword(accessToken, currentPassword, newPassword, validationToken, twoFACode) {
const payload = {
password: currentPassword,
newPassword,
validationToken
};

if (twoFACode) {
payload.twoFACode = twoFACode;
}

const response = await fetch('https://api.swapbits.co/auth/account/password', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});

const result = await response.json();

if (result.event.code === 1003) {
console.log('Contraseña cambiada exitosamente');
return result;
} else {
throw new Error(`Error ${result.code}: ${result.message}`);
}
}

TypeScript

interface PasswordChangeRequest {
password: string;
newPassword: string;
validationToken: string;
twoFACode?: string;
}

async function executePasswordChange(
accessToken: string,
data: PasswordChangeRequest
): Promise<boolean> {
const response = await fetch('https://api.swapbits.co/auth/account/password', {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});

const result = await response.json();

if (result.event.code !== 1003) {
throw new Error(result.message);
}

return true;
}

Python

import requests

def execute_password_change(
access_token: str,
current_password: str,
new_password: str,
validation_token: str,
two_fa_code: str = None
) -> dict:
"""Ejecuta cambio de contraseña (Paso 2)"""
url = 'https://api.swapbits.co/auth/account/password'

headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}

payload = {
'password': current_password,
'newPassword': new_password,
'validationToken': validation_token
}

if two_fa_code:
payload['twoFACode'] = two_fa_code

response = requests.patch(url, headers=headers, json=payload)
result = response.json()

if result.get('event', {}).get('code') == 1003:
return result
else:
raise Exception(f"Error {result.get('code')}: {result.get('message')}")

cURL

# Sin 2FA
curl -X PATCH 'https://api.swapbits.co/auth/account/password' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"password": "CurrentPass123!",
"newPassword": "NewSecurePass456!",
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}'

# Con 2FA
curl -X PATCH 'https://api.swapbits.co/auth/account/password' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"password": "CurrentPass123!",
"newPassword": "NewSecurePass456!",
"twoFACode": "123456",
"validationToken": "550e8400-e29b-41d4-a716-446655440000"
}'

Seguridad y Auditoría

Hashing con Argon2id

Parámetros de Argon2id:

{
memory: 65536, // 64 MB
iterations: 3, // 3 pases
parallelism: 4, // 4 threads
hashLength: 32 // 32 bytes output
}

Argon2id es el algoritmo recomendado por OWASP para hashing de contraseñas.

Protecciones de Seguridad

  1. Token de validación único: Previene ataques de repetición
  2. Expiración de 5 minutos: Reduce ventana de ataque
  3. Verificación cruzada usuario-token: Previene uso indebido
  4. Comparación de contraseña con timing constante: Anti timing attacks
  5. Validación estricta de requisitos: Fortalece seguridad
  6. Limpieza automática de sesiones: No deja rastros en Redis

Códigos de Respuesta

CódigoDescripciónEndpoint
1003Contraseña actualizada exitosamentePATCH
4006Datos inválidosPATCH
4007Contraseña actual incorrectaPATCH
4008Nueva contraseña no cumple requisitosPATCH
4029Nueva contraseña igual a actualPATCH
4031Token de validación requeridoPATCH
4032Token inválido o expiradoPATCH
4033Token no coincide con usuarioPATCH
4034Código 2FA requeridoPATCH
4005Código 2FA inválidoPATCH

Probar esta API

API Explorer


Enlaces Relacionados

Proceso de Cambio de Contraseña

Autenticación y Seguridad

Recuperación de Cuenta

Gestión de Cuenta