Skip to main content

Overview

The password recovery flow consists of three steps:
  1. Request Reset Code: User provides email and receives a 6-digit verification code
  2. Verify Code: User submits the code to verify ownership of the email
  3. Reset Password: User provides the code and new password to complete the reset
Reset codes expire after 30 minutes for security.

Step 1: Request Reset Code

POST /api/users/forgot-password
Generates a 6-digit reset code and stores it with a 30-minute expiration. In non-production environments, the code is logged to the console for testing purposes.

Request Body

email
string
required
Email address of the account to recover.

Response

message
string
Generic success message: “Si el correo existe, recibirás un código de recuperación”Note: The same message is returned whether the email exists or not to prevent email enumeration attacks.

Code Examples

curl -X POST https://api.mediguide.com/api/users/forgot-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]"
  }'

Response Example

Success Response (200)
{
  "message": "Si el correo existe, recibirás un código de recuperación"
}

Error Responses

Missing Email (400)
{
  "error": "Correo requerido"
}
Server Error (500)
{
  "error": "Error interno del servidor"
}

Implementation Details

  • Reset code is a 6-digit random number generated from Math.random()
  • Code expires after exactly 30 minutes from generation
  • In non-production environments, code is logged to console for testing
  • Generic response prevents email enumeration attacks
  • Source: src/routes/users.js:87

Step 2: Verify Reset Code

POST /api/users/verify-reset-code
Verifies that the provided reset code matches the stored code for the given email and has not expired.

Request Body

email
string
required
Email address of the account.
resetCode
string
required
The 6-digit verification code received via email.

Response

message
string
Success message: “Código verificado exitosamente”
userId
integer
The user ID associated with the verified email. Can be used for additional verification in subsequent steps.

Code Examples

curl -X POST https://api.mediguide.com/api/users/verify-reset-code \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "resetCode": "123456"
  }'

Response Example

Success Response (200)
{
  "message": "Código verificado exitosamente",
  "userId": 42
}

Error Responses

Missing Fields (400)
{
  "error": "Correo y código requeridos"
}
Invalid Code (401)
{
  "error": "Código de recuperación inválido"
}
Expired Code (401)
{
  "error": "El código de recuperación ha expirado"
}
Server Error (500)
{
  "error": "Error interno del servidor"
}

Implementation Details

  • Validates both code match and expiration time
  • Codes expire exactly 30 minutes after generation
  • Verification success is logged with user ID for security auditing
  • Source: src/routes/users.js:125

Step 3: Reset Password

POST /api/users/reset-password
Completes the password recovery process by setting a new password and clearing the reset code.

Request Body

email
string
required
Email address of the account.
resetCode
string
required
The 6-digit verification code received via email.
newPassword
string
required
New password for the account. Must be at least 6 characters long.

Response

message
string
Success message: “Contraseña actualizada exitosamente”
userId
integer
The user ID of the updated account.
username
string
The username of the updated account.

Code Examples

curl -X POST https://api.mediguide.com/api/users/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "resetCode": "123456",
    "newPassword": "newSecurePassword123"
  }'

Response Example

Success Response (200)
{
  "message": "Contraseña actualizada exitosamente",
  "userId": 42,
  "username": "johndoe"
}

Error Responses

Password Too Short (400)
{
  "error": "La contraseña debe tener al menos 6 caracteres"
}
Invalid Code (401)
{
  "error": "Código de recuperación inválido"
}
Expired Code (401)
{
  "error": "El código de recuperación ha expirado"
}
Server Error (500)
{
  "error": "Error interno del servidor"
}

Implementation Details

  • Password must be at least 6 characters long
  • New password is hashed using bcrypt with 10 salt rounds before storage
  • Reset code and expiry are cleared from database after successful reset
  • Validates both code match and expiration time
  • Password reset is logged with user ID for security auditing
  • Source: src/routes/users.js:156

Security Considerations

  • Code Expiration: All reset codes expire after exactly 30 minutes
  • Email Enumeration Prevention: Generic responses prevent attackers from determining valid email addresses
  • Rate Limiting: Consider implementing rate limiting on these endpoints to prevent abuse
  • HTTPS Only: All password recovery endpoints should only be accessible via HTTPS in production
  • Logging: All verification and reset actions are logged with user IDs for security auditing

Build docs developers (and LLMs) love