hit-server-manager/backend/src/main/java/com/hitcommunications/servermanager/services/AuthService.java

89 lines
3.9 KiB
Java
Raw Normal View History

package com.hitcommunications.servermanager.services;
import com.hitcommunications.servermanager.config.security.JwtService;
import com.hitcommunications.servermanager.config.security.UserPrincipal;
import com.hitcommunications.servermanager.model.Users;
import com.hitcommunications.servermanager.model.dtos.AuthTokens;
import com.hitcommunications.servermanager.model.dtos.LoginRequest;
import com.hitcommunications.servermanager.model.dtos.NewUserDTO;
import com.hitcommunications.servermanager.model.dtos.UserDTO;
import com.hitcommunications.servermanager.mappers.UsersMapper;
import com.hitcommunications.servermanager.repositories.UsersRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.HttpStatus;
import java.sql.Timestamp;
import java.time.Instant;
@Service
@RequiredArgsConstructor
public class AuthService {
private final AuthenticationManager authenticationManager;
private final UsersService usersService;
private final UsersRepository usersRepository;
private final UsersMapper usersMapper;
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
public AuthTokens login(LoginRequest request) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.username(), request.password())
);
UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
Users user = usersRepository.findById(principal.getId())
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found after authentication."));
updateLastLogin(user);
return issueTokens(user, principal);
}
public AuthTokens refresh(String refreshToken) {
if (refreshToken == null || refreshToken.isBlank()) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Refresh token is missing.");
}
try {
String username = jwtService.extractUsername(refreshToken);
var userDetails = userDetailsService.loadUserByUsername(username);
if (!jwtService.isTokenValid(refreshToken, userDetails, JwtService.TokenType.REFRESH)) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid refresh token.");
}
Users user = usersRepository.findByUsername(username)
.or(() -> usersRepository.findByEmail(username))
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found for refresh token."));
return issueTokens(user, UserPrincipal.fromUser(user));
} catch (ResponseStatusException ex) {
throw ex;
} catch (Exception ex) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid refresh token.");
}
}
@Transactional
public UserDTO signup(NewUserDTO createDTO) throws IllegalAccessException {
return usersService.create(createDTO);
}
private AuthTokens issueTokens(Users user, UserPrincipal principal) {
String accessToken = jwtService.generateAccessToken(principal);
String refreshToken = jwtService.generateRefreshToken(principal);
return new AuthTokens(accessToken, refreshToken, usersMapper.toDTO(user));
}
private void updateLastLogin(Users user) {
user.setLastLogin(Timestamp.from(Instant.now()));
usersRepository.save(user);
}
}