package com.billpaymentservice.bbps.serviceImpl; import java.util.Date; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.billpaymentservice.bbps.config.JwtUtil; import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.UserDetailsDTO; import com.billpaymentservice.bbps.dto.auth.AuthResponse; import com.billpaymentservice.bbps.dto.auth.LoginRequest; import com.billpaymentservice.bbps.dto.auth.OtpSendResponse; import com.billpaymentservice.bbps.dto.auth.RegisterRequest; import com.billpaymentservice.bbps.dto.auth.UserDto; import com.billpaymentservice.bbps.dto.auth.VerifyOtpRequest; import com.billpaymentservice.bbps.dto.response.AuthResponses; import com.billpaymentservice.bbps.entites.UserEntity; import com.billpaymentservice.bbps.entites.UsersDetails; import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.repository.UserRepository; import com.billpaymentservice.bbps.repository.UsersDetailsRepository; import com.billpaymentservice.bbps.service.AuthService; import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.Helper; import com.billpaymentservice.bbps.util.OtpClient; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.JwtException; @Service public class AuthServiceImpl implements AuthService { private static final Logger LOGGER = LoggerFactory.getLogger(AuthServiceImpl.class); private final UserRepository userRepository; private final OtpClient otpClient; private final Helper helper; private final UsersDetailsRepository userRepo; private final JwtUtil jwtUtil; @Autowired public AuthServiceImpl(UserRepository userRepository, OtpClient otpClient, Helper helper, UsersDetailsRepository userRepo, JwtUtil jwtUtil) { this.userRepository = userRepository; this.otpClient = otpClient; this.helper = helper; this.userRepo = userRepo; this.jwtUtil = jwtUtil; } @Override public ResponseModel sendOtp(LoginRequest request) { try { OtpSendResponse resp = otpClient.sendOtp(request.getMobile()); if (resp == null) { return ResponseModel.builder().message("OTP send service returned null").status("Failure") .statusCode(500).data(null).build(); } String status = resp.isSuccess() ? "Success" : "Failure"; int code = resp.isSuccess() ? 200 : 400; return ResponseModel.builder().message(resp.getMessage()).status(status).statusCode(code).data(resp) .build(); } catch (Exception ex) { LOGGER.error("Error in sendOtp: {}", ex.getMessage(), ex); return ResponseModel.builder().message("An unexpected error occurred while sending OTP").status("Failure") .statusCode(500).data(null).build(); } } @Override public ResponseModel verifyOtp(VerifyOtpRequest request) { boolean ok = otpClient.verifyOtp(request.getMobile(), request.getOtp()); LOGGER.info("OTP STATUS {}", ok); if (!ok) { return ResponseModel.builder().message("Invalid OTP").status("Failure").statusCode(401).data(null).build(); } String mobileNo = request.getMobile(); try { Optional byMobileNumber = userRepository.findByMobile(mobileNo); if (byMobileNumber.isPresent()) { UserEntity user = byMobileNumber.get(); String token = jwtUtil.generateToken(user.getMobile()); LOGGER.info("Generated JWT token for mobileNo: " + mobileNo); Object userDetailsDTO = null; if (user != null) { userDetailsDTO = helper.mapUserToUserDetailsDTO(user); } AuthResponses authResp = new AuthResponses(token, "Success", "Login Success", 200, userDetailsDTO, null); return ResponseModel.builder().message("Login Success").status("Success").statusCode(200).data(authResp) .build(); } else { LOGGER.warn("OTP verified successfully, but user not found for mobileNo: {}", mobileNo); String token = jwtUtil.generateTemperaryToken(mobileNo); AuthResponses authResp = new AuthResponses(null, "User Not Found", "OTP verified successfully, but user not found", BBPSConstant.OTP_VERIFIED_USER_NOT_FORUN, null, token); return ResponseModel.builder().message("OTP verified successfully, but user not found") .status("Failure").statusCode(BBPSConstant.OTP_VERIFIED_USER_NOT_FORUN) // Not Found .data(authResp).build(); } } catch (Exception ex) { LOGGER.error("Error occurred during login for mobile no: {} Exception: {}", mobileNo, ex.getMessage(), ex); return ResponseModel.builder().message("Authentication failed: " + ex.getMessage()).status("Failure") .statusCode(500).data(null).build(); } } @Override @Transactional public ResponseModel registerUser(RegisterRequest request) { try { String tokens = request.getRegistrationToken(); Claims claims = jwtUtil.parseToken(tokens); // Parse the JWT token String tokenMobileNo = claims.get("mobileNo", String.class); // Extract the mobile number from the token Date tokenExpiryTime = claims.getExpiration(); // Extract the expiration time from the token String timeGenerated = claims.get("timestamp", String.class); LOGGER.info("Token Mobile Number -:" + tokenMobileNo); LOGGER.info("Time Generated Token -: " + timeGenerated); LOGGER.info("Time Expiry Token -: " + tokenExpiryTime); if (!tokenMobileNo.equals(request.getMobile())) { AuthResponse ar = new AuthResponse(false, "User mobile number does not match", request.getMobile()); return ResponseModel.builder().message(ar.getMessage()).status("Failure").statusCode(400).data(ar) .build(); } Optional existing = userRepository.findByMobile(request.getMobile()); if (existing.isPresent()) { UserEntity u = existing.get(); UserDto dto = new UserDto(u.getUserId(), u.getMobile(), u.getName(), u.getEmail()); AuthResponse ar = new AuthResponse(false, "User already exists", null, dto); return ResponseModel.builder().message(ar.getMessage()).status("Failure").statusCode(409).data(ar) .build(); } UserEntity userEntity = helper.createNewUser(request); userRepository.save(userEntity); String token = jwtUtil.generateToken(userEntity.getMobile()); // UserDto dto = new UserDto(userEntity.getUserId(), userEntity.getMobile(), userEntity.getName(), // userEntity.getEmail()); Object userDetailsDTO = helper.mapUserToUserDetailsDTO(userEntity); AuthResponse ar = new AuthResponse(true, "user registered successfully", token, userDetailsDTO); return ResponseModel.builder().message(ar.getMessage()).status("Success").statusCode(201).data(ar).build(); } catch (ExpiredJwtException e) { LOGGER.error("Token has expired: {}", e.getMessage()); return ResponseModel.builder().message("Token has expired. Please log in again.").status("Failure") .statusCode(401).data(null).build(); } catch (Exception ex) { LOGGER.error("Error in registerUser: {}", ex.getMessage(), ex); return ResponseModel.builder().message("An unexpected error occurred while registering user") .status("Failure").statusCode(500).data(null).build(); } } @Override public ResponseModel authenticateUser(LoginRequest loginRequest) { // LOGGER.info("Processing login for Request: {}", loginRequest); // // try { // String mobileNo = loginRequest.getMobile(); // // Optional byMobileNo = userRepo.findByUserMobNo(mobileNo); // // if (byMobileNo.isPresent()) { // UsersDetails user = (UsersDetails) byMobileNo.get(); // String token = jwtUtil.generateToken(user.getUserMobNo()); // // LOGGER.info("Generated JWT token for mobileNo: " + mobileNo); // // Object userDetailsDTO = null; // // if (user != null) { // userDetailsDTO = UserDetailsDTO.builder().id(user.getId()).userEmailId(user.getUserEmailId()) // .userMobNo(user.getUserMobNo()).userName(user.getUserName()).build(); // } // AuthResponses authResp = new AuthResponses(token, "Success", "Login Done", 200, userDetailsDTO); // return ResponseModel.builder().message("Login Done").status("Success").statusCode(200).data(authResp) // .build(); // } else { // AuthResponses authResp = new AuthResponses("", "User Not Found", "Authentication failed", 401, null); // return ResponseModel.builder().message("User Not Found").status("Failure").statusCode(401) // .data(authResp).build(); // } // // // } catch (Exception ex) { // LOGGER.error("Error occurred during login for mobile no: {} Exception: {}", loginRequest.getMobile(), // ex.getMessage(), ex); // return ResponseModel.builder().message("Authentication failed: " + ex.getMessage()).status("Failure") // .statusCode(500).data(null).build(); // } return null; } @Override public UserEntity findByMobile(String mobile) { return userRepository.findByMobile(mobile).orElse(null); } }