112 lines
3.0 KiB
Go
112 lines
3.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"tailly_back_v2/internal/domain"
|
|
"tailly_back_v2/internal/repository"
|
|
"tailly_back_v2/pkg/auth"
|
|
"time"
|
|
)
|
|
|
|
// Интерфейс сервиса аутентификации
|
|
type AuthService interface {
|
|
Register(ctx context.Context, input RegisterInput) (*domain.User, error)
|
|
Login(ctx context.Context, email, password string) (*domain.Tokens, error)
|
|
RefreshTokens(ctx context.Context, refreshToken string) (*domain.Tokens, error)
|
|
}
|
|
|
|
// Реализация сервиса аутентификации
|
|
type authService struct {
|
|
userRepo repository.UserRepository
|
|
tokenAuth auth.TokenAuth
|
|
}
|
|
|
|
// Конструктор сервиса
|
|
func NewAuthService(userRepo repository.UserRepository, tokenAuth auth.TokenAuth) AuthService {
|
|
return &authService{
|
|
userRepo: userRepo,
|
|
tokenAuth: tokenAuth,
|
|
}
|
|
}
|
|
|
|
// Входные данные для регистрации
|
|
type RegisterInput struct {
|
|
Username string
|
|
Email string
|
|
Password string
|
|
}
|
|
|
|
// Регистрация нового пользователя
|
|
func (s *authService) Register(ctx context.Context, input RegisterInput) (*domain.User, error) {
|
|
// Проверка существования пользователя
|
|
_, err := s.userRepo.GetByEmail(ctx, input.Email)
|
|
if err == nil {
|
|
return nil, errors.New("user with this email already exists")
|
|
} else if err != repository.ErrUserNotFound {
|
|
return nil, err
|
|
}
|
|
|
|
// Хеширование пароля
|
|
hashedPassword, err := auth.HashPassword(input.Password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Создание пользователя
|
|
user := &domain.User{
|
|
Username: input.Username,
|
|
Email: input.Email,
|
|
Password: hashedPassword,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if err := s.userRepo.Create(ctx, user); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// Вход в систему
|
|
func (s *authService) Login(ctx context.Context, email, password string) (*domain.Tokens, error) {
|
|
user, err := s.userRepo.GetByEmail(ctx, email)
|
|
if err != nil {
|
|
if err == repository.ErrUserNotFound {
|
|
return nil, errors.New("invalid credentials")
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
// Проверка пароля
|
|
if !auth.CheckPasswordHash(password, user.Password) {
|
|
return nil, errors.New("invalid credentials")
|
|
}
|
|
|
|
// Генерация токенов
|
|
tokens, err := s.tokenAuth.GenerateTokens(user.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return tokens, nil
|
|
}
|
|
|
|
// Обновление токенов
|
|
func (s *authService) RefreshTokens(ctx context.Context, refreshToken string) (*domain.Tokens, error) {
|
|
userID, err := s.tokenAuth.ValidateRefreshToken(refreshToken)
|
|
if err != nil {
|
|
return nil, errors.New("invalid refresh token")
|
|
}
|
|
|
|
// Проверка существования пользователя
|
|
_, err = s.userRepo.GetByID(ctx, userID)
|
|
if err != nil {
|
|
return nil, errors.New("user not found")
|
|
}
|
|
|
|
// Генерация новых токенов
|
|
return s.tokenAuth.GenerateTokens(userID)
|
|
}
|