Files
tp/main_dc/BB/api_bb/internal/handlers/email_handler.go
T
valitovgaziz 15357fd3c0 create and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarbacreate and moove into new directories for BegushiyBashkir and
yalarba
2025-10-24 05:22:44 +05:00

224 lines
7.0 KiB
Go

// handlers/email_handler.go
package handlers
import (
"net/http"
"api_bb/internal/models"
"api_bb/internal/service"
"api_bb/pkg/logger"
"api_bb/pkg/middleware"
"api_bb/pkg/utils"
"go.uber.org/zap"
)
type EmailHandler struct {
logger logger.LoggerInterface
emailService *service.EmailService
}
func NewEmailHandler(emailService *service.EmailService) *EmailHandler {
return &EmailHandler{
logger: logger.NewWrapper(logger.Get().With(zap.String("handler", "email"))),
emailService: emailService,
}
}
// VerifyEmail подтверждает email пользователя
func (h *EmailHandler) VerifyEmail(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling email verification request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
token := r.URL.Query().Get("token")
if token == "" {
h.logger.Warn("email verification failed - token is required")
utils.RespondWithError(w, http.StatusBadRequest, "Токен обязателен")
return
}
if err := h.emailService.VerifyEmail(token); err != nil {
h.logger.Error("email verification failed, expired",
zap.Error(err),
zap.String("token", token),
)
utils.RespondWithError(w, http.StatusBadRequest, "Неверный или просроченный токен")
return
}
h.logger.Info("email successfully verified",
zap.String("token", token),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]string{
"message": "Email успешно подтвержден",
})
}
// RequestPasswordReset запрашивает сброс пароля
func (h *EmailHandler) RequestPasswordReset(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling password reset request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
var req models.PasswordResetRequest
if err := utils.DecodeJSONBody(w, r, &req); err != nil {
h.logger.Warn("password reset request failed - invalid request format",
zap.Error(err),
)
utils.RespondWithError(w, http.StatusBadRequest, "Неверный формат запроса")
return
}
if err := h.emailService.SendPasswordResetEmail(req.Email); err != nil {
h.logger.Error("password reset request failed",
zap.Error(err),
zap.String("email", req.Email),
)
// Для безопасности всегда возвращаем успех
}
h.logger.Info("password reset request processed",
zap.String("email", req.Email),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]string{
"message": "Если email зарегистрирован, инструкции по восстановлению пароля будут отправлены",
})
}
// ConfirmPasswordReset подтверждает сброс пароля
func (h *EmailHandler) ConfirmPasswordReset(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling password reset confirmation request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
var req models.PasswordResetConfirm
if err := utils.DecodeJSONBody(w, r, &req); err != nil {
h.logger.Warn("password reset confirmation failed - invalid request format",
zap.Error(err),
)
utils.RespondWithError(w, http.StatusBadRequest, "Неверный формат запроса")
return
}
if err := h.emailService.ResetPassword(req.Token, req.Password); err != nil {
h.logger.Error("password reset confirmation failed",
zap.Error(err),
zap.String("token", req.Token),
)
utils.RespondWithError(w, http.StatusBadRequest, "Неверный или просроченный токен")
return
}
h.logger.Info("password successfully reset",
zap.String("token", req.Token),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]string{
"message": "Пароль успешно изменен",
})
}
type NewsletterRequest struct {
Subject string `json:"subject" validate:"required"`
Content string `json:"content" validate:"required"`
}
// SendNewsletter отправляет рассылку новостей
func (h *EmailHandler) SendNewsletter(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling newsletter sending request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
var req NewsletterRequest
if err := utils.DecodeJSONBody(w, r, &req); err != nil {
h.logger.Warn("newsletter sending failed - invalid request format",
zap.Error(err),
)
utils.RespondWithError(w, http.StatusBadRequest, "Неверный формат запроса")
return
}
if err := h.emailService.SendNewsletterToSubscribers(req.Subject, req.Content); err != nil {
h.logger.Error("newsletter sending failed",
zap.Error(err),
zap.String("subject", req.Subject),
)
utils.RespondWithError(w, http.StatusInternalServerError, "Не удалось отправить рассылку")
return
}
h.logger.Info("newsletter sent successfully",
zap.String("subject", req.Subject),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]string{
"message": "Рассылка отправлена подписчикам",
})
}
// ResendVerification повторно отправляет email верификации
func (h *EmailHandler) ResendVerification(w http.ResponseWriter, r *http.Request) {
h.logger.Info("handling resend verification request",
zap.String("method", r.Method),
zap.String("path", r.URL.Path),
zap.String("remote_addr", r.RemoteAddr),
)
user, ok := middleware.GetUserFromContext(r.Context())
if !ok {
h.logger.Warn("resend verification failed - authentication required")
utils.RespondWithError(w, http.StatusUnauthorized, "Пользователь не авторизован")
return
}
// Получаем пользователя
userData, err := h.emailService.GetUserByID(user.ID)
if err != nil {
h.logger.Warn("resend verification failed - user not found",
zap.Uint("user_id", user.ID),
zap.Error(err),
)
utils.RespondWithError(w, http.StatusNotFound, "Пользователь не найден")
return
}
if userData.EmailVerified {
h.logger.Warn("resend verification failed - email already verified",
zap.Uint("user_id", user.ID),
zap.String("email", userData.Email),
)
utils.RespondWithError(w, http.StatusBadRequest, "Email уже подтвержден")
return
}
if err := h.emailService.SendVerificationEmail(userData.ID, userData.Email, userData.FirstName); err != nil {
h.logger.Error("resend verification failed",
zap.Error(err),
zap.Uint("user_id", user.ID),
zap.String("email", userData.Email),
)
utils.RespondWithError(w, http.StatusInternalServerError, "Не удалось отправить email подтверждения")
return
}
h.logger.Info("verification email resent successfully",
zap.Uint("user_id", user.ID),
zap.String("email", userData.Email),
)
utils.RespondWithJSON(w, http.StatusOK, map[string]string{
"message": "Email подтверждения отправлен повторно",
})
}