15357fd3c0
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
123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
// service/auth_service.go
|
|
package service
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"api_bb/internal/models"
|
|
"api_bb/internal/repository"
|
|
"api_bb/pkg/logger"
|
|
|
|
"go.uber.org/zap"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type AuthService interface {
|
|
Register(user *models.User) error
|
|
Login(email, password string) (*models.User, string, error)
|
|
}
|
|
|
|
type authService struct {
|
|
userRepo repository.UserRepository
|
|
jwtService JWTService
|
|
logger logger.LoggerInterface
|
|
}
|
|
|
|
func NewAuthService(userRepo repository.UserRepository, jwtService JWTService, log logger.LoggerInterface) AuthService {
|
|
// Создаем логгер с контекстом для сервиса
|
|
serviceLogger := log.With(zap.String("service", "auth"))
|
|
|
|
return &authService{
|
|
userRepo: userRepo,
|
|
jwtService: jwtService,
|
|
logger: serviceLogger,
|
|
}
|
|
}
|
|
|
|
func (s *authService) Register(user *models.User) error {
|
|
s.logger.Info("Registering new user",
|
|
zap.String("email", user.Email),
|
|
)
|
|
|
|
existingUser, err := s.userRepo.FindByEmail(user.Email)
|
|
if err == nil && existingUser != nil {
|
|
s.logger.Warn("Registration failed - email already exists",
|
|
zap.String("email", user.Email),
|
|
)
|
|
return errors.New("user with this email already exists")
|
|
}
|
|
|
|
err = s.userRepo.Create(user)
|
|
if err != nil {
|
|
s.logger.Error("Failed to create user in database",
|
|
zap.String("email", user.Email),
|
|
zap.Error(err),
|
|
)
|
|
return err
|
|
}
|
|
|
|
|
|
s.logger.Info("User registered successfully",
|
|
zap.Uint("user_id", user.ID),
|
|
zap.String("email", user.Email),
|
|
)
|
|
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *authService) Login(email, password string) (*models.User, string, error) {
|
|
s.logger.Info("Login attempt",
|
|
zap.String("email", email),
|
|
zap.Int("password_length", len(password)),
|
|
)
|
|
|
|
user, err := s.userRepo.FindByEmail(email)
|
|
if err != nil {
|
|
s.logger.Warn("Login failed - user not found",
|
|
zap.String("email", email),
|
|
zap.Error(err),
|
|
)
|
|
return nil, "", errors.New("invalid email")
|
|
}
|
|
|
|
s.logger.Debug("User found for login",
|
|
zap.Uint("user_id", user.ID),
|
|
zap.String("stored_hash_prefix", user.Password[:min(10, len(user.Password))]),
|
|
)
|
|
|
|
// Проверяем пароль
|
|
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
|
|
if err != nil {
|
|
s.logger.Warn("Login failed - invalid password",
|
|
zap.Uint("user_id", user.ID),
|
|
zap.String("email", email),
|
|
zap.Error(err),
|
|
)
|
|
return nil, "", errors.New("invalid password")
|
|
}
|
|
|
|
s.logger.Info("Login successful",
|
|
zap.Uint("user_id", user.ID),
|
|
zap.String("email", email),
|
|
)
|
|
|
|
token, err := s.jwtService.GenerateToken(user.ID, user.Email)
|
|
if err != nil {
|
|
s.logger.Error("Failed to generate JWT token",
|
|
zap.Uint("user_id", user.ID),
|
|
zap.Error(err),
|
|
)
|
|
return nil, "", err
|
|
}
|
|
|
|
return user, token, nil
|
|
}
|
|
|
|
func min(a, b int) int {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|