diff --git a/resources/views/auth/login.html b/resources/views/auth/login.html index a86d57d..2284d34 100755 --- a/resources/views/auth/login.html +++ b/resources/views/auth/login.html @@ -71,7 +71,7 @@
- + ¿Olvidaste tu contraseña?
diff --git a/resources/views/auth/password-reset.html b/resources/views/auth/password-reset.html index a4cdc8a..96553dd 100755 --- a/resources/views/auth/password-reset.html +++ b/resources/views/auth/password-reset.html @@ -1,50 +1,114 @@ -
-
-

¡Restablece tu contraseña!

-
-
- - +
+ +
+
+ + +
- -
- - -
- -
- - -
- - - +

Nueva contraseña

+

Elige una contraseña segura para tu cuenta

-
- \ No newline at end of file + + + {{if .error}} +
+ + + + {{.error}} +
+ {{end}} + +
+ + +
+ +
+
+ + + +
+ + +
+
+ + +
+ +
+
+ + + +
+ + +
+
+ + +
+ +
+ + + + +
+
diff --git a/resources/views/auth/request-password-reset.html b/resources/views/auth/request-password-reset.html index ce8aa40..1bb4107 100755 --- a/resources/views/auth/request-password-reset.html +++ b/resources/views/auth/request-password-reset.html @@ -1,11 +1,100 @@ -

Reset my password!

-
-
- - - - +
+ +
+
+ + + +
+

Recuperar contraseña

+

Te enviaremos un enlace a tu correo

- -{{.Login.Email}} \ No newline at end of file + +
+
+ + + +
+

¡Revisa tu correo!

+

Si el correo está registrado, recibirás instrucciones para restablecer tu contraseña en los próximos minutos.

+ Volver al inicio de sesión +
+ + +
+ +
+ + + + +
+ +
+
+ +
+
+ + + +
+ +
+
+ + + + +
+
+
diff --git a/rest/controllers/register_controller.go b/rest/controllers/register_controller.go index 4422e32..f378f52 100755 --- a/rest/controllers/register_controller.go +++ b/rest/controllers/register_controller.go @@ -80,25 +80,26 @@ func ReenvioEmail(c *fiber.Ctx) error { // Función para manejar la solicitud de restablecimiento de contraseña func RequestPasswordResetPost(c *fiber.Ctx) error { - usuario := c.FormValue("nombre_usuario") - fmt.Println("Usuario recibido:", usuario) - - user, err := models.GetUserByUsuario(usuario) - if err != nil || user == nil { + email := strings.TrimSpace(c.FormValue("email")) + if email == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, - "message": "Usuario inactivo o no existente", + "message": "El correo electrónico es requerido.", }) } - usuario_email := user.Email - log.Println("Sending password reset email to:", usuario_email) - - go services.SendPasswordResetEmail(usuario_email, services.GetPublicURL()) + // Intentar enviar el correo solo si el usuario existe — mismo mensaje en ambos casos por seguridad + user, err := models.GetUserByEmail(email) + if err == nil && user != nil && user.Email != "" { + log.Println("[Reset] Enviando enlace de recuperación a:", email) + go services.SendPasswordResetEmail(user.Email, services.GetPublicURL()) + } else { + log.Println("[Reset] Correo no encontrado (no se revela al cliente):", email) + } return c.JSON(fiber.Map{ "success": true, - "message": "We've sent an email to reset your password to your registered email address", + "message": "Si el correo está registrado, recibirás instrucciones en los próximos minutos.", }) } @@ -207,53 +208,56 @@ func PasswordReset(c *fiber.Ctx) error { } func PasswordResetPost(c *fiber.Ctx) error { - // Recuperar el nombre de usuario y la nueva contraseña del formulario - nombreUsuario := c.FormValue("nombre_usuario") - password := c.FormValue("password") + // El email fue validado y extraído del token por el middleware ValidatePasswordResetPost + emailLocal := c.Locals("email") + if emailLocal == nil { + return c.Status(fiber.StatusBadRequest).Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "Token inválido. Solicita un nuevo enlace.", + }, "layouts/landing") + } + email := fmt.Sprintf("%v", emailLocal) - // Validar que ambos campos estén presentes - if nombreUsuario == "" || password == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ - "message": "Los campos nombre_usuario y password son obligatorios.", - "error": true, - }) + password := c.FormValue("password") + cPassword := c.FormValue("c_password") + + if password == "" || len(password) < 6 { + return c.Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "La contraseña debe tener al menos 6 caracteres.", + }, "layouts/landing") + } + if password != cPassword { + return c.Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "Las contraseñas no coinciden.", + }, "layouts/landing") } - // Imprimir los datos recibidos (opcional para depuración) - fmt.Printf("Datos recibidos: nombre_usuario=%s, password=%s\n", nombreUsuario, password) - - // Buscar al usuario en la base de datos por nombre de usuario - user, err := models.GetUserByUsuario(nombreUsuario) + user, err := models.GetUserByEmail(email) if err != nil || user == nil { - return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ - "message": "Usuario no encontrado.", - "error": true, - }) + return c.Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "No se encontró una cuenta asociada a este enlace.", + }, "layouts/landing") } hash := config.Hash{} - - // Encripta la nueva contraseña hashedPassword, err := hash.Create(password) if err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ - "message": "Error al encriptar la contraseña", - "error": true, - }) + return c.Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "Error al procesar la contraseña. Intenta de nuevo.", + }, "layouts/landing") } - // Asigna la contraseña encriptada al modelo - password = hashedPassword - // Actualizar la contraseña del usuario - err = models.UpdateUserPassword(user.ID, password) - if err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ - "message": "Error al actualizar la contraseña.", - "error": true, - }) + if err := models.UpdateUserPassword(user.ID, hashedPassword); err != nil { + return c.Render("auth/password-reset", fiber.Map{ + "Token": c.Params("token"), + "error": "No se pudo actualizar la contraseña. Intenta de nuevo.", + }, "layouts/landing") } - // Redirigir al usuario al formulario de inicio de sesión después del éxito return c.Redirect("/login") } diff --git a/rest/middlewares/password_reset.go b/rest/middlewares/password_reset.go index 3338d01..b1e8f22 100755 --- a/rest/middlewares/password_reset.go +++ b/rest/middlewares/password_reset.go @@ -47,7 +47,7 @@ func _validatePasswordReset(c *fiber.Ctx, t string) error { } now := time.Now().Unix() diff := now - tokenTS - if diff > (5 * 60) { + if diff > (60 * 60) { return errors.New("Password Reset Token has expired!") } else if diff < 0 { return errors.New("Invalid Password Reset Token")