package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.dao.RoleDao; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.response.LoginResponse; import net.gepafin.tendermanagement.model.response.RoleResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @Service public class AuthenticationService { private final Logger log = LoggerFactory.getLogger(AuthenticationService.class); private final TokenProvider tokenProvider; private final AuthenticationManager authenticationManager; @Autowired private UserRepository userRepository; @Autowired private RoleDao roleDao; @Autowired public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) { this.tokenProvider = tokenProvider; this.authenticationManager = authenticationManager; } public JWTToken login(LoginReq loginReq) { log.info("Attempting login for email: {}", loginReq.getEmail()); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loginReq.getEmail(), loginReq.getPassword()); Authentication authentication = this.authenticationManager.authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); log.info("Authentication successful for email: {}", loginReq.getEmail()); UserEntity user = userRepository.findByEmailIgnoreCase(loginReq.getEmail()).orElseThrow(()-> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) { throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); } user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); userRepository.save(user); String token = tokenProvider.createToken(authentication, loginReq.getRememberMe(), user); log.info("JWT token generated for email: {}", loginReq.getEmail()); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); LoginResponse loginResponse = getLoginResponse(user, roleResponseBean); JWTToken jwtToken = new JWTToken(token, loginResponse); log.info("Login successful for email: {}", loginReq.getEmail()); return jwtToken; } private static LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) { LoginResponse loginResponse = new LoginResponse(); loginResponse.setId(user.getId()); loginResponse.setEmail(user.getEmail()); loginResponse.setFirstName(user.getFirstName()); loginResponse.setLastName(user.getLastName()); loginResponse.setRole(roleResponseBean); loginResponse.setPhoneNumber(user.getPhoneNumber()); loginResponse.setAddress(user.getAddress()); loginResponse.setOrganization(user.getOrganization()); loginResponse.setCountry(user.getCountry()); loginResponse.setStatus(user.getStatus()); loginResponse.setCity(user.getCity()); loginResponse.setLastLogin(user.getLastLogin()); loginResponse.setCreatedDate(user.getCreatedDate()); loginResponse.setUpdatedDate(user.getUpdatedDate()); return loginResponse; } public void logout(HttpServletRequest request, HttpServletResponse response) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { String token = tokenProvider.extractTokenFromRequest(request); tokenProvider.invalidateToken(token); new SecurityContextLogoutHandler().logout(request, response, auth); } SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.clearContext(); } }