package com.sapolar.auth; import com.sapolar.auth.dto.LoginRequest; import com.sapolar.auth.dto.RegisterRequest; import com.sapolar.auth.dto.TokenResponse; import com.sapolar.common.exception.BadRequestException; import com.sapolar.common.exception.DuplicateResourceException; import com.sapolar.common.exception.ResourceNotFoundException; import com.sapolar.user.*; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class AuthService { private final UserRepository userRepository; private final RoleRepository roleRepository; private final PasswordEncoder passwordEncoder; private final JwtTokenProvider jwtTokenProvider; private final AuthenticationManager authenticationManager; @Transactional(readOnly = true) public TokenResponse login(LoginRequest request) { authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()) ); User user = userRepository.findByUsername(request.getUsername()) .orElseThrow(() -> new ResourceNotFoundException("Usuario", 0L)); String accessToken = jwtTokenProvider.generateAccessToken( user.getId(), user.getUsername(), user.getRole().getName()); String refreshToken = jwtTokenProvider.generateRefreshToken( user.getId(), user.getUsername()); return new TokenResponse(accessToken, refreshToken, user.getId(), user.getUsername(), user.getRole().getName()); } @Transactional public TokenResponse register(RegisterRequest request) { if (userRepository.existsByUsername(request.getUsername())) { throw new DuplicateResourceException("El usuario ya existe: " + request.getUsername()); } if (userRepository.existsByEmail(request.getEmail())) { throw new DuplicateResourceException("El email ya está registrado: " + request.getEmail()); } String roleName = request.getRoleName() != null ? request.getRoleName() : "VISUALIZADOR"; Role role = roleRepository.findByName(roleName) .orElseThrow(() -> new BadRequestException("Rol no válido: " + roleName)); User user = new User(); user.setUsername(request.getUsername()); user.setEmail(request.getEmail()); user.setPasswordHash(passwordEncoder.encode(request.getPassword())); user.setFullName(request.getFullName()); user.setPhone(request.getPhone()); user.setRole(role); user.setActive(true); user = userRepository.save(user); String accessToken = jwtTokenProvider.generateAccessToken( user.getId(), user.getUsername(), user.getRole().getName()); String refreshToken = jwtTokenProvider.generateRefreshToken( user.getId(), user.getUsername()); return new TokenResponse(accessToken, refreshToken, user.getId(), user.getUsername(), user.getRole().getName()); } @Transactional(readOnly = true) public TokenResponse refresh(String refreshToken) { if (!jwtTokenProvider.validateToken(refreshToken)) { throw new BadRequestException("Token de refresco inválido o expirado"); } Long userId = jwtTokenProvider.getUserIdFromToken(refreshToken); User user = userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException("Usuario", userId)); String accessToken = jwtTokenProvider.generateAccessToken( user.getId(), user.getUsername(), user.getRole().getName()); String newRefreshToken = jwtTokenProvider.generateRefreshToken( user.getId(), user.getUsername()); return new TokenResponse(accessToken, newRefreshToken, user.getId(), user.getUsername(), user.getRole().getName()); } }