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 }