diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java index 7ac7948e..1964bd1c 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java @@ -36,26 +36,35 @@ public class TokenProvider { @PostConstruct public void init() { this.key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); + log.info("JWT Secret Key initialized."); } - public String createToken(Authentication authentication,Boolean rememberMe) { + + public String createToken(Authentication authentication, Boolean rememberMe) { String authorities = authentication.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); - Long now = null; - Date validity=null; - if(Boolean.TRUE.equals(rememberMe)) { - now= DateUtils.addMonths(new Date(), 2).getTime(); + Long now; + Date validity; + + if (Boolean.TRUE.equals(rememberMe)) { + now = DateUtils.addMonths(new Date(), 2).getTime(); validity = new Date(now); - }else { - now=(new Date()).getTime(); + log.info("Creating token with extended validity for 2 months."); + } else { + now = (new Date()).getTime(); validity = new Date(now + (this.tokenValidityInSeconds * 1000)); + log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds); } - return Jwts.builder() + + String token = Jwts.builder() .setSubject(authentication.getName()) .claim("auth", authorities) .signWith(key, SignatureAlgorithm.HS512) .setExpiration(validity) .compact(); + + log.debug("Generated token: {}", token); + return token; } public Authentication getAuthentication(String token) { @@ -64,18 +73,21 @@ public class TokenProvider { .build() .parseClaimsJws(token) .getBody(); - UserDetails principal = new User(claims.getSubject(), "", Collections.emptyList()); - return new UsernamePasswordAuthenticationToken(principal, token, principal.getAuthorities()); + UserDetails principal = new User(claims.getSubject(), "", Collections.emptyList()); + log.info("Authenticated user: {}", claims.getSubject()); + + return new UsernamePasswordAuthenticationToken(principal, token, ClaimsToAuthorities(claims.get("auth"))); } - private Collection ClaimsToAuthorities(Object authClaim) { - return authClaim == null || ((String) authClaim).isEmpty() ? + Collection authorities = authClaim == null || ((String) authClaim).isEmpty() ? Collections.emptyList() : Arrays.stream(((String) authClaim).split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); + log.debug("Converted authorities from claims: {}", authorities); + return authorities; } public boolean validateToken(String authToken) { @@ -84,9 +96,10 @@ public class TokenProvider { .setSigningKey(key) .build() .parseClaimsJws(authToken); + log.info("Token is valid."); return true; } catch (Exception e) { - log.info("Token validation failed: " + e.getMessage()); + log.error("Token validation failed: {}", e.getMessage()); return false; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java b/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java index 3cc3d997..9277b167 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java @@ -3,21 +3,17 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.RegionEntity; -import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.model.request.RegionReq; -import net.gepafin.tendermanagement.model.request.RoleReq; import net.gepafin.tendermanagement.model.response.RegionResponseBean; -import net.gepafin.tendermanagement.model.request.UpdateRegionReq; -import net.gepafin.tendermanagement.model.response.RoleResponseBean; import net.gepafin.tendermanagement.repositories.RegionRepository; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; 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.stereotype.Repository; -import java.math.BigDecimal; -import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -25,14 +21,19 @@ import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; @Repository public class RegionDao { + private final Logger log = LoggerFactory.getLogger(RegionDao.class); + @Autowired - private RegionRepository regionRepository; + private RegionRepository regionRepository; public RegionResponseBean createRegion(RegionReq regionReq) { + log.info("Creating new region with details: {}", regionReq); RegionEntity regionEntity = convertRegionRequestToRegionEntity(regionReq); - regionRepository.save(regionEntity); + regionEntity = regionRepository.save(regionEntity); + log.info("Region created with ID: {}", regionEntity.getId()); return convertRegionEntityToRegionResponse(regionEntity); } + private RegionEntity convertRegionRequestToRegionEntity(RegionReq regionReq) { RegionEntity regionEntity = new RegionEntity(); regionEntity.setCountry(regionReq.getCountry()); @@ -50,7 +51,8 @@ public class RegionDao { regionEntity.setEducationLevel(regionReq.getEducationLevel()); return regionEntity; } - public RegionResponseBean convertRegionEntityToRegionResponse(RegionEntity regionEntity) { + + public RegionResponseBean convertRegionEntityToRegionResponse(RegionEntity regionEntity) { RegionResponseBean regionResponseBean = new RegionResponseBean(); regionResponseBean.setId(regionEntity.getId()); regionResponseBean.setCreatedDate(regionEntity.getCreatedDate()); @@ -72,7 +74,11 @@ public class RegionDao { } public RegionResponseBean updateRegion(Long id, RegionReq regionReq) { + log.info("Updating region with ID: {}", id); RegionEntity existingRegion = getRegionById(id); + log.info("Current region details: {}", existingRegion); + log.info("New region details: {}", regionReq); + setIfUpdated(existingRegion::getRegionName, existingRegion::setRegionName, regionReq.getRegionName()); setIfUpdated(existingRegion::getDescription, existingRegion::setDescription, regionReq.getDescription()); setIfUpdated(existingRegion::getCountry, existingRegion::setCountry, regionReq.getCountry()); @@ -82,28 +88,40 @@ public class RegionDao { setIfUpdated(existingRegion::getAreaSize, existingRegion::setAreaSize, regionReq.getAreaSize()); setIfUpdated(existingRegion::getGdp, existingRegion::setGdp, regionReq.getGdp()); setIfUpdated(existingRegion::getUnemploymentRate, existingRegion::setUnemploymentRate, regionReq.getUnemploymentRate()); - setIfUpdated(existingRegion::getInfrastructureScore, existingRegion::setInfrastructureScore, regionReq.getInfrastructureScore() ); + setIfUpdated(existingRegion::getInfrastructureScore, existingRegion::setInfrastructureScore, regionReq.getInfrastructureScore()); setIfUpdated(existingRegion::getEducationLevel, existingRegion::setEducationLevel, regionReq.getEducationLevel()); setIfUpdated(existingRegion::getHealthcareAccess, existingRegion::setHealthcareAccess, regionReq.getHealthcareAccess()); setIfUpdated(existingRegion::getEnvironmentalScore, existingRegion::setEnvironmentalScore, regionReq.getEnvironmentalScore()); - regionRepository.save(existingRegion); + + existingRegion = regionRepository.save(existingRegion); + + log.info("Region updated with ID: {}", existingRegion.getId()); return Utils.convertObject(existingRegion, RegionResponseBean.class); } - public RegionEntity getRegionById(Long id) { - return regionRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); - } - public void deleteById(Long id) { + public RegionEntity getRegionById(Long id) { + log.info("Fetching region with ID: {}", id); + RegionEntity regionEntity = regionRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); + log.info("Region found: {}", regionEntity); + return regionEntity; + } + + public void deleteById(Long id) { + log.info("Deleting region with ID: {}", id); regionRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); regionRepository.deleteById(id); + log.info("Region deleted with ID: {}", id); } - public List getAllRegions() - { - return regionRepository.findAll() + + public List getAllRegions() { + log.info("Fetching all regions"); + List regions = regionRepository.findAll() .stream() .map(regionEntity -> Utils.convertObject(regionEntity, RegionResponseBean.class)) .collect(Collectors.toList()); + log.info("Total regions found: {}", regions.size()); + return regions; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java index fe25a923..e7f4c5f9 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java @@ -11,6 +11,8 @@ import net.gepafin.tendermanagement.service.RegionService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; 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.stereotype.Component; @@ -21,10 +23,11 @@ import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; @Component public class RoleDao { + private final Logger log = LoggerFactory.getLogger(RoleDao.class); @Autowired private RoleRepository roleRepository; - + @Autowired private RegionService regionService; @@ -32,55 +35,76 @@ public class RoleDao { private RegionDao regionDao; public RoleResponseBean createRole(RoleReq roleReq) { + log.info("Creating new role with details: {}", roleReq); RoleEntity roleEntity = convertRoleRequestToRoleEntity(roleReq); roleEntity = roleRepository.save(roleEntity); + log.info("Role created with ID: {}", roleEntity.getId()); return convertRoleEntityToRoleResponse(roleEntity); } + private RoleEntity convertRoleRequestToRoleEntity(RoleReq roleReq) { RoleEntity roleEntity = new RoleEntity(); roleEntity.setRoleName(roleReq.getRoleName()); roleEntity.setPermissions(roleReq.getPermissions()); - roleEntity.setDescription(roleEntity.getDescription()); + roleEntity.setDescription(roleReq.getDescription()); roleEntity.setRegion(regionService.getRegionById(roleReq.getRegionId())); return roleEntity; } + public RoleResponseBean convertRoleEntityToRoleResponse(RoleEntity roleEntity) { - RoleResponseBean roleResponseBean=new RoleResponseBean(); - roleResponseBean.setId(roleEntity.getId()); - roleResponseBean.setCreatedDate(roleEntity.getCreatedDate()); - roleResponseBean.setUpdatedDate(roleEntity.getUpdatedDate()); - roleResponseBean.setRoleName(roleEntity.getRoleName()); - roleResponseBean.setDescription(roleEntity.getDescription()); - roleResponseBean.setPermissions(roleEntity.getPermissions()); - RegionResponseBean regionResponseBean = regionDao.convertRegionEntityToRegionResponse(roleEntity.getRegion()); - roleResponseBean.setRegion(regionResponseBean); + RoleResponseBean roleResponseBean = new RoleResponseBean(); + roleResponseBean.setId(roleEntity.getId()); + roleResponseBean.setCreatedDate(roleEntity.getCreatedDate()); + roleResponseBean.setUpdatedDate(roleEntity.getUpdatedDate()); + roleResponseBean.setRoleName(roleEntity.getRoleName()); + roleResponseBean.setDescription(roleEntity.getDescription()); + roleResponseBean.setPermissions(roleEntity.getPermissions()); + RegionResponseBean regionResponseBean = regionDao.convertRegionEntityToRegionResponse(roleEntity.getRegion()); + roleResponseBean.setRegion(regionResponseBean); return roleResponseBean; } - public RoleResponseBean updateRole(Long id, RoleReq roleReq) { - RoleEntity existingUserRole = getRoleById(id); - setIfUpdated(existingUserRole::getRoleName, existingUserRole::setRoleName, roleReq.getRoleName()); - setIfUpdated(existingUserRole::getDescription, existingUserRole::setDescription, roleReq.getDescription()); - setIfUpdated(existingUserRole::getPermissions, existingUserRole::setPermissions, roleReq.getPermissions()); - roleRepository.save(existingUserRole); - return Utils.convertObject(existingUserRole, RoleResponseBean.class); + public RoleResponseBean updateRole(Long id, RoleReq roleReq) { + log.info("Updating role with ID: {}", id); + RoleEntity existingRole = getRoleById(id); + + // Log changes before update + log.info("Current role details: {}", existingRole); + log.info("New role details: {}", roleReq); + + setIfUpdated(existingRole::getRoleName, existingRole::setRoleName, roleReq.getRoleName()); + setIfUpdated(existingRole::getDescription, existingRole::setDescription, roleReq.getDescription()); + setIfUpdated(existingRole::getPermissions, existingRole::setPermissions, roleReq.getPermissions()); + + existingRole = roleRepository.save(existingRole); + + log.info("Role updated with ID: {}", existingRole.getId()); + return Utils.convertObject(existingRole, RoleResponseBean.class); } public RoleEntity getRoleById(Long id) { - return roleRepository.findById(id) + log.info("Fetching role with ID: {}", id); + RoleEntity roleEntity = roleRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ROLE_NOT_FOUND))); + log.info("Role found: {}", roleEntity); + return roleEntity; } public void deleteById(Long id) { + log.info("Deleting role with ID: {}", id); roleRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.ROLE_NOT_FOUND))); + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ROLE_NOT_FOUND))); roleRepository.deleteById(id); + log.info("Role deleted with ID: {}", id); } public List getAllRoles() { - return roleRepository.findAll() + log.info("Fetching all roles"); + List roles = roleRepository.findAll() .stream() .map(roleEntity -> Utils.convertObject(roleEntity, RoleResponseBean.class)) .collect(Collectors.toList()); + log.info("Total roles found: {}", roles.size()); + return roles; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index eecdd4e0..af0e19f4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -18,45 +18,61 @@ import net.gepafin.tendermanagement.service.impl.AuthenticationService; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; 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.crypto.password.PasswordEncoder; import org.springframework.stereotype.Repository; import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; + @Repository public class UserDao { + private final Logger log = LoggerFactory.getLogger(UserDao.class); + @Autowired private UserRepository userRepository; + @Autowired private AuthenticationService authService; + @Autowired private RoleService roleService; @Autowired private PasswordEncoder passwordEncoder; - + @Autowired private RoleDao roleDao; public UserResponseBean createUser(UserReq userReq) { + log.info("Creating user with email: {}", userReq.getEmail()); if (userRepository.existsByEmail(userReq.getEmail())) { + log.error("User creation failed: Email {} already exists", userReq.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); } if (!userReq.getPassword().equals(userReq.getConfPassword())) { + log.error("User creation failed: Passwords do not match for email {}", userReq.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } if (userReq.getPassword().length() < 8) { + log.error("User creation failed: Password length is less than 8 characters for email {}", userReq.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_MIN_LEN)); } UserEntity userEntity = convertUserRequestToUserEntity(userReq); userEntity = userRepository.save(userEntity); + log.info("User created with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); } public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { + log.info("Updating user with ID: {}", userId); UserEntity userEntity = userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); + log.info("Current user details: {}", userEntity); + log.info("New user details: {}", userReq); + setIfUpdated(userEntity::getStatus, userEntity::setStatus, userReq.getStatus()); setIfUpdated(userEntity::getFirstName, userEntity::setFirstName, userReq.getFirstName()); setIfUpdated(userEntity::getLastName, userEntity::setLastName, userReq.getLastName()); @@ -68,6 +84,7 @@ public class UserDao { setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); } userEntity = userRepository.save(userEntity); + log.info("User updated with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); } @@ -90,7 +107,6 @@ public class UserDao { userResponseBean.setId(userEntity.getId()); userResponseBean.setCreatedDate(userEntity.getCreatedDate()); userResponseBean.setUpdatedDate(userEntity.getUpdatedDate()); - userResponseBean.setId(userEntity.getId()); userResponseBean.setEmail(userEntity.getEmail()); userResponseBean.setFirstName(userEntity.getFirstName()); userResponseBean.setLastName(userEntity.getLastName()); @@ -107,19 +123,25 @@ public class UserDao { } public UserResponseBean getUserById(Long id) { + log.info("Fetching user with ID: {}", id); UserEntity userEntity = userRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + log.info("User found: {}", userEntity); return convertUserEntityToUserResponse(userEntity); } public void deleteUser(Long id) { + log.info("Deleting user with ID: {}", id); userRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); userRepository.deleteById(id); + log.info("User deleted with ID: {}", id); } - public JWTToken login(LoginReq loginReq) { - return authService.login(loginReq); + log.info("User login attempt for email: {}", loginReq.getEmail()); + JWTToken jwtToken = authService.login(loginReq); + log.info("Login successful for email: {}", loginReq.getEmail()); + return jwtToken; } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index 1b5137ce..022f3775 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -12,6 +12,8 @@ import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.repositories.UserRepository; 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; @@ -20,18 +22,20 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import java.util.Collections; - @Service public class AuthenticationService { + private final Logger log = LoggerFactory.getLogger(AuthenticationService.class); + private final TokenProvider tokenProvider; private final AuthenticationManager authenticationManager; @Autowired - private UserRepository userRepository; + private UserRepository userRepository; + @Autowired private PasswordEncoder passwordEncoder; + @Autowired private RoleDao roleDao; @@ -42,19 +46,26 @@ public class AuthenticationService { } public JWTToken login(LoginReq loginReq) { - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginReq.getEmail(),loginReq.getPassword()); - Authentication authentication = this.authenticationManager.authenticate(authenticationToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - String token = tokenProvider.createToken(authentication,loginReq.getRememberMe()); - UserEntity user = userRepository.findByEmail(loginReq.getEmail()); - if (user == null) { - throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); - } - RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); - return new JWTToken(token, new LoginResponse(user.getId(),user.getEmail(), - user.getFirstName(),user.getLastName(),roleResponseBean, user.getPhoneNumber(), user.getAddress(), user.getOrganization(), user.getCountry(),user.getStatus() - ,user.getCity(),user.getLastLogin(),user.getCreatedDate(),user.getUpdatedDate())); - } - } + 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()); + String token = tokenProvider.createToken(authentication, loginReq.getRememberMe()); + log.info("JWT token generated for email: {}", loginReq.getEmail()); + UserEntity user = userRepository.findByEmail(loginReq.getEmail()); + if (user == null) { + log.error("User not found for email: {}", loginReq.getEmail()); + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); + } + RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); + JWTToken jwtToken = new JWTToken(token, new LoginResponse(user.getId(), user.getEmail(), user.getFirstName(), + user.getLastName(), roleResponseBean, user.getPhoneNumber(), user.getAddress(), user.getOrganization(), + user.getCountry(), user.getStatus(), user.getCity(), user.getLastLogin(), user.getCreatedDate(), + user.getUpdatedDate())); + log.info("Login successful for email: {}", loginReq.getEmail()); + return jwtToken; + } +}