modified: serv_nginx/api_bb/.env

modified:   serv_nginx/api_bb/go.mod
	modified:   serv_nginx/api_bb/go.sum
	modified:   serv_nginx/api_bb/internal/database/migrate.go
	modified:   serv_nginx/api_bb/internal/handlers/auth.go
	new file:   serv_nginx/api_bb/internal/handlers/email_handler.go
	modified:   serv_nginx/api_bb/internal/handlers/handlers.go
	modified:   serv_nginx/api_bb/internal/models/user.go
	new file:   serv_nginx/api_bb/internal/repository/email_repository.go
	modified:   serv_nginx/api_bb/internal/repository/user_repository.go
	modified:   serv_nginx/api_bb/internal/routes/routes.go
	new file:   serv_nginx/api_bb/internal/service/email_service.go
	modified:   serv_nginx/api_bb/internal/service/user_service.go
	new file:   serv_nginx/api_bb/pkg/email/email.go
add email sender, vrificator and reset password
This commit is contained in:
2025-10-22 05:16:30 +05:00
parent 64301b9135
commit 1e678c4b7e
14 changed files with 1166 additions and 25 deletions
@@ -0,0 +1,83 @@
// repository/email_repository.go
package repository
import (
"time"
"api_bb/internal/models"
"gorm.io/gorm"
)
type EmailRepository struct {
db *gorm.DB
}
func NewEmailRepository(db *gorm.DB) *EmailRepository {
return &EmailRepository{db: db}
}
func (r *EmailRepository) CreateVerificationToken(verification *models.EmailVerification) error {
return r.db.Create(verification).Error
}
func (r *EmailRepository) GetVerificationToken(token string) (*models.EmailVerification, error) {
var verification models.EmailVerification
err := r.db.Where("token = ? AND used = ? AND expires_at > ?", token, false, time.Now()).
Preload("User").
First(&verification).Error
if err != nil {
return nil, err
}
return &verification, nil
}
func (r *EmailRepository) MarkTokenAsUsed(token string) error {
return r.db.Model(&models.EmailVerification{}).
Where("token = ?", token).
Updates(map[string]interface{}{
"used": true,
"updated_at": time.Now(),
}).Error
}
func (r *EmailRepository) DeleteExpiredTokens() error {
return r.db.Where("expires_at < ?", time.Now()).Delete(&models.EmailVerification{}).Error
}
func (r *EmailRepository) GetUsersWithNewsletter() ([]models.User, error) {
var users []models.User
err := r.db.Where("newsletter = ? AND email_verified = ?", true, true).
Find(&users).Error
return users, err
}
// MarkEmailAsVerified помечает email пользователя как верифицированный
func (r *EmailRepository) MarkEmailAsVerified(userID uint) error {
return r.db.Model(&models.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"email_verified": true,
"updated_at": time.Now(),
}).Error
}
// GetUserByEmail возвращает пользователя по email
func (r *EmailRepository) GetUserByEmail(email string) (*models.User, error) {
var user models.User
err := r.db.Where("email = ?", email).First(&user).Error
if err != nil {
return nil, err
}
return &user, nil
}
// UpdatePassword обновляет пароль пользователя
func (r *EmailRepository) UpdatePassword(userID uint, newPassword string) error {
return r.db.Model(&models.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"password": newPassword,
"updated_at": time.Now(),
}).Error
}
@@ -16,6 +16,9 @@ type UserRepository interface {
UpdateExcludeEmail(userUpdate *models.User) error
UpdateAvatar(userID uint, avatarPath string) error
FindAll() ([]models.User, error)
MarkEmailAsVerified(userID uint) error
UpdatePassword(userID uint, newPassword string) error
GetUserByID(id uint) (*models.User, error)
}
func (r *userRepository) UpdateAvatar(userID uint, avatarPath string) error {
@@ -91,3 +94,33 @@ func (r *userRepository) UpdateExcludeEmail(userUpdate *models.User) error {
return nil
}
// MarkEmailAsVerified помечает email пользователя как верифицированный
func (r userRepository) MarkEmailAsVerified(userID uint) error {
result := r.db.Model(&models.User{}).Where("id = ?", userID).Update("email_verified", true)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("user not found")
}
return nil
}
// UpdatePassword обновляет пароль пользователя
func (r userRepository) UpdatePassword(userID uint, newPassword string) error {
result := r.db.Model(&models.User{}).Where("id = ?", userID).Update("password", newPassword)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return fmt.Errorf("user not found")
}
return nil
}
func (r userRepository) GetUserByID(id uint) (*models.User, error) {
var user models.User
err := r.db.First(&user, id).Error
return &user, err
}