refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
aovantsev
2025-10-10 19:56:06 +03:00
parent f081c9d947
commit 73ed514a34
30 changed files with 1728 additions and 1020 deletions

View File

@@ -0,0 +1,141 @@
package auth
import (
"context"
"counter/internal/domain/entities"
"counter/internal/domain/repositories"
"counter/internal/infrastructure/security"
)
// AuthService handles authentication business logic
type AuthService struct {
userRepo repositories.UserRepository
passwordService security.PasswordService
jwtService security.JWTService
}
// NewAuthService creates a new authentication service
func NewAuthService(
userRepo repositories.UserRepository,
passwordService security.PasswordService,
jwtService security.JWTService,
) *AuthService {
return &AuthService{
userRepo: userRepo,
passwordService: passwordService,
jwtService: jwtService,
}
}
// RegisterRequest represents a user registration request
type RegisterRequest struct {
Username string `json:"username" binding:"required,min=3,max=50"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=6"`
}
// LoginRequest represents a user login request
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// AuthResponse represents an authentication response
type AuthResponse struct {
Token string `json:"token"`
User *entities.User `json:"user"`
}
// Register registers a new user
func (s *AuthService) Register(ctx context.Context, req *RegisterRequest) (*AuthResponse, error) {
// Check if username already exists
_, err := s.userRepo.FindByUsername(ctx, req.Username)
if err == nil {
return nil, entities.ErrUserAlreadyExists
}
if err != entities.ErrUserNotFound {
return nil, err
}
// Check if email already exists
_, err = s.userRepo.FindByEmail(ctx, req.Email)
if err == nil {
return nil, entities.ErrUserAlreadyExists
}
if err != entities.ErrUserNotFound {
return nil, err
}
// Hash password
hashedPassword, err := s.passwordService.HashPassword(req.Password)
if err != nil {
return nil, err
}
// Create user
user := &entities.User{
Username: req.Username,
Email: req.Email,
Password: hashedPassword,
}
if err := s.userRepo.Create(ctx, user); err != nil {
return nil, err
}
// Generate token
token, err := s.jwtService.GenerateToken(user.ID, user.Username)
if err != nil {
return nil, err
}
// Clear password from response
user.ClearPassword()
return &AuthResponse{
Token: token,
User: user,
}, nil
}
// Login authenticates a user
func (s *AuthService) Login(ctx context.Context, req *LoginRequest) (*AuthResponse, error) {
// Find user
user, err := s.userRepo.FindByUsername(ctx, req.Username)
if err != nil {
return nil, entities.ErrInvalidCredentials
}
// Check password
if !s.passwordService.CheckPasswordHash(req.Password, user.Password) {
return nil, entities.ErrInvalidCredentials
}
// Generate token
token, err := s.jwtService.GenerateToken(user.ID, user.Username)
if err != nil {
return nil, err
}
// Clear password from response
user.ClearPassword()
return &AuthResponse{
Token: token,
User: user,
}, nil
}
// GetCurrentUser retrieves the current authenticated user
func (s *AuthService) GetCurrentUser(ctx context.Context, userID int) (*entities.User, error) {
user, err := s.userRepo.FindByID(ctx, userID)
if err != nil {
return nil, err
}
// Clear password from response
user.ClearPassword()
return user, nil
}