package net.moustos.mtgsearch.service; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import net.moustos.mtgsearch.model.User; import net.moustos.mtgsearch.repository.UserRepository; import net.moustos.mtgsearch.security.JwtTokenProvider; import java.util.Optional; /** * Authentication service for user login and registration */ @Service @Transactional public class AuthService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; private final JwtTokenProvider jwtTokenProvider; public AuthService(UserRepository userRepository, PasswordEncoder passwordEncoder, JwtTokenProvider jwtTokenProvider) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; this.jwtTokenProvider = jwtTokenProvider; } /** * Register a new user */ public User register(String username, String email, String password) { if (userRepository.existsByUsername(username)) { throw new IllegalArgumentException("Username already exists"); } if (userRepository.existsByEmail(email)) { throw new IllegalArgumentException("Email already exists"); } User user = User.builder() .username(username) .email(email) .password(passwordEncoder.encode(password)) .active(true) .build(); return userRepository.save(user); } /** * Authenticate user and return JWT token */ public String authenticate(String username, String password) { Optional userOpt = userRepository.findByUsername(username); if (userOpt.isEmpty()) { throw new IllegalArgumentException("Invalid username or password"); } User user = userOpt.get(); if (!user.getActive()) { throw new IllegalArgumentException("User account is inactive"); } if (!passwordEncoder.matches(password, user.getPassword())) { throw new IllegalArgumentException("Invalid username or password"); } return jwtTokenProvider.generateToken(user.getId(), user.getUsername(), user.getEmail()); } /** * Get user by ID */ @Transactional(readOnly = true) public Optional getUserById(Long userId) { return userRepository.findById(userId); } /** * Get user by username */ @Transactional(readOnly = true) public Optional getUserByUsername(String username) { return userRepository.findByUsername(username); } }