package com.faf223.expensetrackerfaf.service; import com.faf223.expensetrackerfaf.config.JwtService; import com.faf223.expensetrackerfaf.controller.auth.AuthenticationRequest; import com.faf223.expensetrackerfaf.controller.auth.AuthenticationResponse; import com.faf223.expensetrackerfaf.controller.auth.RegisterRequest; import com.faf223.expensetrackerfaf.controller.auth.TokenRefreshRequest; import com.faf223.expensetrackerfaf.model.Credential; import com.faf223.expensetrackerfaf.model.User; import com.faf223.expensetrackerfaf.repository.CredentialRepository; import com.faf223.expensetrackerfaf.repository.UserRepository; import com.faf223.expensetrackerfaf.security.PersonDetails; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.Optional; @Service @RequiredArgsConstructor public class AuthenticationService { private final UserRepository userRepository; private final CredentialRepository credentialRepository; private final PasswordEncoder passwordEncoder; private final JwtService jwtService; private final AuthenticationManager authenticationManager; public AuthenticationResponse register(RegisterRequest request) { User user = User.builder() .firstName(request.getFirstname()) .lastName(request.getLastname()) .username(request.getUsername()) .build(); userRepository.save(user); Credential credential = new Credential(user, request.getEmail(), passwordEncoder.encode(request.getPassword())); credentialRepository.save(credential); UserDetails userDetails = new PersonDetails(credential); String jwtToken = jwtService.generateToken(userDetails); String refreshToken = jwtService.generateToken(userDetails); return AuthenticationResponse.builder() .accessToken(jwtToken) .refreshToken(refreshToken) .build(); } public AuthenticationResponse authenticate(AuthenticationRequest request) { authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword())); Credential credential = credentialRepository.findByEmail(request.getEmail()).orElseThrow((() -> new UsernameNotFoundException("User not found"))); UserDetails userDetails = new PersonDetails(credential); String jwtToken = jwtService.generateToken(userDetails); String refreshToken = jwtService.generateToken(userDetails); return AuthenticationResponse.builder() .accessToken(jwtToken) .refreshToken(refreshToken) .build(); } public AuthenticationResponse refreshAccessToken(TokenRefreshRequest refreshRequest) { String refreshToken = refreshRequest.getRefreshToken(); Optional credential = credentialRepository.findByEmail(jwtService.extractUsername(refreshToken)); if (credential.isPresent()) { UserDetails userDetails = new PersonDetails(credential.get()); String jwtToken = jwtService.generateToken(userDetails); return AuthenticationResponse.builder() .accessToken(jwtToken) .refreshToken(refreshToken) // Return the same refresh token .build(); }else { throw new RuntimeException("Invalid or expired refresh token"); } } }