Eco-It’s password recovery flow gives users a safe way to regain access to their account when they have forgotten their password. Recovery does not require the user to be logged in. A 6-digit code is delivered by email, verified server-side using a SHA-256 hash comparison, and then used to authorise a password reset. The new password is set in plain text and hashed automatically by theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/vanegasjoseignacio2-cyber/Eco-It/llms.txt
Use this file to discover all available pages before exploring further.
User model’s bcrypt pre('save') hook. The entire flow must be completed before the code expires.
Recovery flow
Request a recovery code
Submit the account’s email address. If a matching user is found, the backend generates a 6-digit code, hashes it with SHA-256, and stores the hash alongside an expiry timestamp on the Success response Error response
User document (resetPasswordToken and resetPasswordExpires). The plain-text code is emailed to the user.Endpoint: POST /api/auth/recuperar-passwordThe email address of the account to recover.
200:404 — email not registered:For security, in a production hardening pass you may want to return a generic
200 regardless of whether the email exists, to prevent user-enumeration attacks. The current implementation returns 404 if the email is not found.Verify the code
Submit the email and the 6-digit code from the email. The backend hashes the submitted code and looks for a Success response Error response
User document where resetPasswordToken matches the hash and resetPasswordExpires is still in the future. A 200 response confirms the code is valid and the user may proceed to set a new password.Endpoint: POST /api/auth/recuperar-password/verificarThe account’s email address.
The 6-digit code received by email.
200:400 — invalid or expired code:Set a new password
Submit the email, the verified code, and the new password in a single request. The backend re-validates the code (repeating the hash lookup with the expiry check) to ensure the reset token has not expired between step 2 and step 3. On success, Success response Error response
resetPasswordToken and resetPasswordExpires are cleared from the user document and the new password is saved in plain text — the pre('save') hook hashes it automatically.Endpoint: POST /api/auth/recuperar-password/restablecerThe account’s email address.
The same 6-digit code used in step 2.
The new plain-text password. Must meet the schema minimum of 8 characters.
200:400 — code expired or already used:Resending the code
If the recovery email was not received or the code has expired, users can request a new one without restarting the flow. A 3-minute cooldown applies between resend requests for the same email address: if the current code has more than 12 minutes of its 15-minute lifetime remaining (meaning fewer than 3 minutes have passed since it was issued), the server returns429 with the number of minutes to wait.
Endpoint: POST /api/auth/recuperar-password/reenviar
The account’s email address.
200:
429:
Issuing a new code via the resend endpoint invalidates the previous code immediately. The new
resetPasswordToken hash overwrites the old one on the User document, so any previously received code will fail validation at step 2 or step 3.Frontend flow
The recovery journey maps to three distinct React pages, protected by aRecoveryRoute guard that ensures users cannot jump directly to a later step without completing the earlier ones.
| Page | Route | Purpose |
|---|---|---|
RecuperarPage | /recuperar-password | Collects the email and calls step 1. |
VerificarCode | /recuperar-password/verificar | Collects the 6-digit code and calls step 2. |
| New password form | /recuperar-password/restablecer | Collects the new password and calls step 3. |
RecoveryRoute checks for a recovery session state (set in React Router’s location state after step 1 succeeds). Attempting to navigate directly to /recuperar-password/verificar without the session state redirects back to /recuperar-password.
Rate limiting
All four recovery endpoints —
POST /api/auth/recuperar-password, POST /api/auth/recuperar-password/verificar, POST /api/auth/recuperar-password/reenviar, and POST /api/auth/recuperar-password/restablecer — are protected by authLimiter, which allows a maximum of 15 requests per IP in a 15-minute window. This is 20× more restrictive than the global API limiter (300 requests per window).Code security
Recovery codes are never stored in plain text. The flow uses a SHA-256 hash both in thePendingRegistration (registration) and on the User model (recovery):