codeword/internal/controller/recovery/recovery_controller.go
2023-12-29 14:30:20 +03:00

82 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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