codeword/internal/controller/recovery/recovery_controller.go

82 lines
3.1 KiB
Go
Raw Normal View History

2023-12-29 11:30:20 +00:00
package controller
import (
"codeword/internal/services"
"fmt"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"time"
)
type RecoveryController struct {
2023-12-29 18:02:50 +00:00
logger *zap.Logger
service *services.RecoveryService
2023-12-29 11:30:20 +00:00
}
func NewRecoveryController(logger *zap.Logger, service *services.RecoveryService) *RecoveryController {
return &RecoveryController{
2023-12-29 18:02:50 +00:00
logger: logger,
service: service,
2023-12-29 11:30:20 +00:00
}
}
// HandleRecoveryRequest обрабатывает запрос на восстановление пароля
func (r *RecoveryController) HandleRecoveryRequest(c *fiber.Ctx) error {
email := c.FormValue("email")
2023-12-29 18:02:50 +00:00
key, err := r.service.GenerateKey()
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to generate key", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
fmt.Println(key)
2023-12-29 18:02:50 +00:00
user, err := r.service.FindUserByEmail(email)
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to find user by email", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
}
fmt.Println(user)
// сохраняем в бд
2023-12-29 18:02:50 +00:00
signature, err := r.service.StoreRecoveryRecord("user")
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to store recovery record", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
// тут что-то на подобии канала или что-то подобное так как отправка выполнятеся в воркере,
//это пока временное решение для написания структуры кода и проверки отправки, далее перепишу
// под горутины
2023-12-29 18:02:50 +00:00
err = r.service.SendRecoveryEmail(email, signature)
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to send recovery email", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{"message": "Recovery email sent successfully"})
}
// HandleRecoveryLink обрабатывает ссылку восстановления и обменивает ее на токены
func (r *RecoveryController) HandleRecoveryLink(c *fiber.Ctx) error {
signature := c.Params("sign")
// тут получается
2023-12-29 18:02:50 +00:00
record, err := r.service.GetRecoveryRecord(signature)
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to get recovery record", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
// проверка на более чем 15 минут
if time.Since(record.CreatedAt) > 15*time.Minute {
2023-12-29 18:02:50 +00:00
r.logger.Error("Recovery link expired", zap.String("signature", signature))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Recovery link expired"})
}
2023-12-29 18:02:50 +00:00
tokens, err := r.service.ExchangeForTokens(record.UserID)
2023-12-29 11:30:20 +00:00
if err != nil {
2023-12-29 18:02:50 +00:00
r.logger.Error("Failed to exchange recovery link for tokens", zap.Error(err))
2023-12-29 11:30:20 +00:00
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"})
}
return c.Status(fiber.StatusOK).JSON(tokens)
}