From 9f0fbb02e4493b6995315f34ed243ed7129e0aaf Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 10 Mar 2025 16:27:11 +0530 Subject: [PATCH 001/318] Beneficiary consent --- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 1 + .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +++ .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index 431a267a..846e5c51 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -59,6 +59,7 @@ public class CommonIdentityDTO { private Integer educationId; private String education; private Boolean emergencyRegistration = false; + private Boolean isConsent; private Integer healthCareWorkerId; private String healthCareWorker; private String fatherName; diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index aee6b8f7..696da9b1 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -77,6 +77,9 @@ public class BeneficiaryModel implements Comparable { // private List outboundCallRequests; // private List beneficiaryCalls; // private List feedbacks; + @Expose + private Boolean isConsent=false; + @Expose private String beneficiaryID; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 1d829d17..8af08922 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -163,13 +163,14 @@ private int updateDemographics(BeneficiaryDemographicsModel i_BenDemographics) { @Override public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servletRequest) throws Exception { - // logger.info("benificiaryDetails: " + beneficiaryModel); + logger.info("benificiaryDetails: " + beneficiaryModel); CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); + identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO .setBenFamilyDTOs(identityMapper.benPhoneMapListToBenFamilyDTOList(beneficiaryModel.getBenPhoneMaps())); String request = new Gson().toJson(identityDTO); From a94ad60568d0069a2dcc7b00ede255aeffd2cfee Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 10 Mar 2025 17:31:49 +0530 Subject: [PATCH 002/318] Beneficiary consent --- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 2 ++ .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +++ .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index 431a267a..8e364eb3 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -54,6 +54,8 @@ public class CommonIdentityDTO { private Integer beneficiaryRegId; private Integer communityId; private String community; + private Boolean isConsent=false; + private Timestamp dob; private Integer ageAtMarriage; private Integer educationId; diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index aee6b8f7..209472ef 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -87,6 +87,9 @@ public class BeneficiaryModel implements Comparable { private TitleModel m_title; @Expose private String firstName; + @Expose + private Boolean isConsent=false; + @Expose private String middleName; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 1d829d17..4ab722e7 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -163,11 +163,12 @@ private int updateDemographics(BeneficiaryDemographicsModel i_BenDemographics) { @Override public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servletRequest) throws Exception { - // logger.info("benificiaryDetails: " + beneficiaryModel); + logger.info("benificiaryDetails: " + beneficiaryModel); CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); + identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); identityDTO From 01abcbda8003b76986644c63d928baa0a0974efe Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:05:36 +0530 Subject: [PATCH 003/318] Beneficiary consent --- .../java/com/iemr/common/controller/otp/OTPGateway.java | 9 +++++++-- .../iemr/common/model/beneficiary/BeneficiaryModel.java | 1 + .../beneficiary/RegisterBenificiaryServiceImpl.java | 3 ++- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java index 42371a88..f74caa63 100644 --- a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java +++ b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java @@ -55,6 +55,7 @@ public class OTPGateway { @Operation(summary = "Send OTP") @RequestMapping(value = "/sendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -62,7 +63,8 @@ public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody Stri OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.sendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); @@ -102,6 +104,7 @@ public String validateOTP( @Operation(summary = "Resend OTP") @RequestMapping(value = "/resendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -109,7 +112,9 @@ public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody St OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.resendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index 696da9b1..a437ec20 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -80,6 +80,7 @@ public class BeneficiaryModel implements Comparable { @Expose private Boolean isConsent=false; + @Expose private String beneficiaryID; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 8af08922..0b52ce26 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -37,7 +37,6 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.iemr.common.data.beneficiary.Beneficiary; import com.iemr.common.data.mctshistory.MctsOutboundCallDetail; @@ -77,6 +76,8 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired Validator validator; + + @Autowired OutboundHistoryRepository outboundHistoryRepository; diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 0c12c3a6..5341e678 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -35,6 +35,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); + // Log cookies for debugging Cookie[] cookies = request.getCookies(); if (cookies != null) { From 0f0113c8a93d804f59964d93f61d0960a41a6c1b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:06:32 +0530 Subject: [PATCH 004/318] Beneficiary consent --- .../utils/http/HTTPRequestInterceptor.java | 260 +++++++++--------- 1 file changed, 131 insertions(+), 129 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index a31b2a2b..bfa07031 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -1,24 +1,24 @@ /* -* AMRIT – Accessible Medical Records via Integrated Technology -* Integrated EHR (Electronic Health Records) Solution -* -* Copyright (C) "Piramal Swasthya Management and Research Institute" -* -* This file is part of AMRIT. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see https://www.gnu.org/licenses/. -*/ + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.utils.http; @@ -38,125 +38,127 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { - private Validator validator; + private Validator validator; - Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); - @Autowired - public void setValidator(Validator validator) { - this.validator = validator; - } + @Autowired + public void setValidator(Validator validator) { + this.validator = validator; + } - private SessionObject sessionObject; + private SessionObject sessionObject; - @Autowired - public void setSessionObject(SessionObject sessionObject) { - this.sessionObject = sessionObject; - } + @Autowired + public void setSessionObject(SessionObject sessionObject) { + this.sessionObject = sessionObject; + } - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { - boolean status = true; - logger.info("In info preHandle we are Intercepting the Request"); - logger.debug("In preHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); - String authorization = null; - String preAuth = request.getHeader("Authorization"); - if(null != preAuth && preAuth.contains("Bearer ")) - authorization=preAuth.replace("Bearer ", ""); - else - authorization = preAuth; - logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization - + " || method :: " + request.getMethod()); - if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { - try { - String[] requestURIParts = request.getRequestURI().split("/"); - String requestAPI = requestURIParts[requestURIParts.length - 1]; - switch (requestAPI) { - case "userAuthenticate": - case "superUserAuthenticate": - case "userAuthenticateNew": - case "userAuthenticateV1": - case "forgetPassword": - case "setForgetPassword": - case "changePassword": - case "saveUserSecurityQuesAns": - case "doAgentLogout": - case "userLogout": - case "swagger-ui.html": - case "index.html": - case "index.css": - case "swagger-initializer.js": - case "swagger-config": - case "swagger-ui-bundle.js": - case "swagger-ui.css": - case "ui": - case "swagger-ui-standalone-preset.js": - case "favicon-32x32.png": - case "favicon-16x16.png": - case "swagger-resources": - case "api-docs": - case "updateBenCallIdsInPhoneBlock": - case "userAuthenticateByEncryption": + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { + boolean status = true; + logger.info("In info preHandle we are Intercepting the Request"); + logger.debug("In preHandle we are Intercepting the Request"); + // String authorization = request.getHeader("Authorization"); + String authorization = null; + String preAuth = request.getHeader("Authorization"); + if (null != preAuth && preAuth.contains("Bearer ")) + authorization = preAuth.replace("Bearer ", ""); + else + authorization = preAuth; + logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization + + " || method :: " + request.getMethod()); + if (!request.getMethod().equalsIgnoreCase("OPTIONS")) { + try { + String[] requestURIParts = request.getRequestURI().split("/"); + String requestAPI = requestURIParts[requestURIParts.length - 1]; - case "sendOTP": - case "validateOTP": - case "resendOTP": - case "validateSecurityQuestionAndAnswer": - case "logOutUserFromConcurrentSession": + switch (requestAPI) { + case "create": + case "userAuthenticate": + case "superUserAuthenticate": + case "userAuthenticateNew": + case "userAuthenticateV1": + case "forgetPassword": + case "setForgetPassword": + case "changePassword": + case "saveUserSecurityQuesAns": + case "doAgentLogout": + case "userLogout": + case "swagger-ui.html": + case "index.html": + case "index.css": + case "swagger-initializer.js": + case "swagger-config": + case "swagger-ui-bundle.js": + case "swagger-ui.css": + case "ui": + case "swagger-ui-standalone-preset.js": + case "favicon-32x32.png": + case "favicon-16x16.png": + case "swagger-resources": + case "api-docs": + case "updateBenCallIdsInPhoneBlock": + case "userAuthenticateByEncryption": + case "sendOTP": + case "validateOTP": + case "resendOTP": + case "validateSecurityQuestionAndAnswer": + case "logOutUserFromConcurrentSession": - break; - case "error": - status = false; - break; - default: - String remoteAddress = request.getHeader("X-FORWARDED-FOR"); - if (remoteAddress == null || remoteAddress.trim().length() == 0) { - remoteAddress = request.getRemoteAddr(); - } - validator.checkKeyExists(authorization, remoteAddress); - break; - } - } catch (Exception e) { - OutputResponse output = new OutputResponse(); - output.setError(e); - response.getOutputStream().print(output.toString()); - response.setContentType(MediaType.APPLICATION_JSON); - response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "*"); - status = false; - } - } - return status; - } + break; + case "error": + status = false; + break; + default: + String remoteAddress = request.getHeader("X-FORWARDED-FOR"); + if (remoteAddress == null || remoteAddress.trim().length() == 0) { + remoteAddress = request.getRemoteAddr(); + } + validator.checkKeyExists(authorization, remoteAddress); + break; + } + } catch (Exception e) { + OutputResponse output = new OutputResponse(); + output.setError(e); + response.getOutputStream().print(output.toString()); + response.setContentType(MediaType.APPLICATION_JSON); + response.setContentLength(output.toString().length()); + response.setHeader("Access-Control-Allow-Origin", "*"); + status = false; + } + } + return status; + } - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) - throws Exception { - try { - logger.debug("In postHandle we are Intercepting the Request"); - // String authorization = request.getHeader("Authorization"); - String authorization = null; - String postAuth = request.getHeader("Authorization"); - if(null != postAuth && postAuth.contains("Bearer ")) - authorization=postAuth.replace("Bearer ", ""); - else - authorization = postAuth; - logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - if (authorization != null) { - sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); - } - } catch (Exception e) { - logger.debug("postHandle failed with error " + e.getMessage()); - } - } + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) + throws Exception { +// try { +// logger.debug("In postHandle we are Intercepting the Request"); +// // String authorization = request.getHeader("Authorization"); +// String authorization = null; +// String postAuth = request.getHeader("Authorization"); +// if (null != postAuth && postAuth.contains("Bearer ")) +// authorization = postAuth.replace("Bearer ", ""); +// else +// authorization = postAuth; +// logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); +// if (authorization != null) { +// sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); +// } +// } catch (Exception e) { +// logger.debug("postHandle failed with error " + e.getMessage()); +// } + } - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) - throws Exception { - logger.debug("In afterCompletion Request Completed"); - } + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) + throws Exception { + logger.debug("In afterCompletion Request Completed"); + } } \ No newline at end of file From a5b595ed10a52d3a50468eff4c0c2b1568b18646 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:24:30 +0530 Subject: [PATCH 005/318] Beneficiary consent --- .../iemr/common/service/notification/NotificationService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/service/notification/NotificationService.java b/src/main/java/com/iemr/common/service/notification/NotificationService.java index a3c85387..6fa8ee8d 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationService.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationService.java @@ -55,4 +55,5 @@ String createEmergencyContacts(String request) String updateEmergencyContacts(String request) throws JSONException, NoSuchAlgorithmException, IOException, IEMRException, Exception; + } From a363c332a051a958a4f2e739b6b993a30b11509f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:25:20 +0530 Subject: [PATCH 006/318] Beneficiary consent --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f29e4dca..0e81958f 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,6 @@ hibernate-jpa-2.0-api 1.0.1.Final - org.springframework.boot spring-boot-starter-cache @@ -497,7 +496,7 @@ - commonapi-v3.0.0 + commonapi-v1.0 org.apache.maven.plugins From 72715a79bbd00227e01ffec736c6c32a609e46de Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 14:21:06 +0530 Subject: [PATCH 007/318] firebase setup --- pom.xml | 8 +++- .../com/iemr/common/CommonApplication.java | 20 ++++++++++ .../FirebaseNotificationController.java | 25 +++++++++++++ .../notification/NotificationMessage.java | 14 +++++++ .../FirebaseNotificationService.java | 37 +++++++++++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java create mode 100644 src/main/java/com/iemr/common/model/notification/NotificationMessage.java create mode 100644 src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java diff --git a/pom.xml b/pom.xml index db199065..8e41c424 100644 --- a/pom.xml +++ b/pom.xml @@ -107,6 +107,12 @@ + + + com.google.firebase + firebase-admin + 9.4.3 + org.springframework.boot spring-boot-starter-data-jpa @@ -497,7 +503,7 @@ - commonapi-v3.0.0 + commonapi-v1.0 org.apache.maven.plugins diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 83078018..cd140056 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -21,11 +21,16 @@ */ package com.iemr.common; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; +import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; @@ -36,6 +41,8 @@ import com.iemr.common.data.users.User; import com.iemr.common.utils.IEMRApplBeans; +import java.io.IOException; + @SpringBootApplication @EnableScheduling public class CommonApplication extends SpringBootServletInitializer { @@ -73,4 +80,17 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } + @Bean + FirebaseMessaging firebaseMessaging() throws IOException { + GoogleCredentials googleCredentials = GoogleCredentials.fromStream( + new ClassPathResource("Place your admin json").getInputStream() + + ); + FirebaseOptions firebaseOptions = FirebaseOptions.builder().setCredentials(googleCredentials).build(); + FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions); + return FirebaseMessaging.getInstance(firebaseApp); + + + } + } diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java new file mode 100644 index 00000000..22f438ca --- /dev/null +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -0,0 +1,25 @@ +package com.iemr.common.controller.firebaseNotification; + +import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.service.firebaseNotification.FirebaseNotificationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value= "/firebaseNotification") +public class FirebaseNotificationController { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + FirebaseNotificationService firebaseNotificationService; + + @CrossOrigin + @RequestMapping(value = "sendNotification",method = RequestMethod.POST) + public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ + return firebaseNotificationService.sendNotification(notificationMessage); + } + + +} diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java new file mode 100644 index 00000000..2838eca3 --- /dev/null +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -0,0 +1,14 @@ +package com.iemr.common.model.notification; + +import lombok.Data; + +import java.util.Map; + +@Data +public class NotificationMessage { + private String appType; + private String topic; + private String title; + private String body; + private Map data; +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java new file mode 100644 index 00000000..642bd6fa --- /dev/null +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -0,0 +1,37 @@ +package com.iemr.common.service.firebaseNotification; + +import com.google.firebase.FirebaseException; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import com.iemr.common.model.notification.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FirebaseNotificationService { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + FirebaseMessaging firebaseMessaging; + + public String sendNotification(NotificationMessage notificationMessage) { + + Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); + + Message message = Message.builder().setTopic(notificationMessage.getTopic()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + + + try { + String response = FirebaseMessaging.getInstance().send(message); + + return response; + } catch (FirebaseException e) { + return "Error sending notification"; + + } + } + +} From 121928c71ac4635d34de301c9c152bd135b2f19a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 15:23:54 +0530 Subject: [PATCH 008/318] firebase setup --- src/main/java/com/iemr/common/CommonApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index cd140056..7b709768 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -94,3 +94,4 @@ FirebaseMessaging firebaseMessaging() throws IOException { } } + From 396359d637bbd4f7f1ae528c2ff942b0ac1a9185 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 16:15:05 +0530 Subject: [PATCH 009/318] firebase setup --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e41c424..454fd02a 100644 --- a/pom.xml +++ b/pom.xml @@ -503,7 +503,7 @@ - commonapi-v1.0 + commonapi-v3.0.0 org.apache.maven.plugins From 0e24515a15014282ad7aade9ff1d9e1151ed9ca2 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 18:32:07 +0530 Subject: [PATCH 010/318] firebase setup --- .../firebaseNotification/FirebaseNotificationController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 22f438ca..18601d22 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -8,14 +8,13 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification") +@RequestMapping(value= "/firebaseNotification",headers = "Authorization") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired FirebaseNotificationService firebaseNotificationService; - @CrossOrigin @RequestMapping(value = "sendNotification",method = RequestMethod.POST) public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ return firebaseNotificationService.sendNotification(notificationMessage); From 70a425605d87cddacc876a361a307ceb86d5e3ec Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 14 Apr 2025 14:48:33 +0530 Subject: [PATCH 011/318] firebase setup --- .../com/iemr/common/CommonApplication.java | 12 ---- .../firebase/FirebaseMessagingConfig.java | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 7b709768..ea0adb97 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -80,18 +80,6 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - @Bean - FirebaseMessaging firebaseMessaging() throws IOException { - GoogleCredentials googleCredentials = GoogleCredentials.fromStream( - new ClassPathResource("Place your admin json").getInputStream() - - ); - FirebaseOptions firebaseOptions = FirebaseOptions.builder().setCredentials(googleCredentials).build(); - FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions); - return FirebaseMessaging.getInstance(firebaseApp); - - - } } diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java new file mode 100644 index 00000000..438ca4f9 --- /dev/null +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -0,0 +1,57 @@ +package com.iemr.common.config.firebase; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Base64; + +@Configuration +public class FirebaseMessagingConfig { + + @Value("${firebase.enabled:false}") + private boolean firebaseEnabled; + + @Value("${firebase.credential-file:}") + private String firebaseCredentialFile; + + @Value("${firebase.credential-base64:}") + private String firebaseCredentialBase64; + + @Bean + public FirebaseMessaging firebaseMessaging() throws IOException { + if (!firebaseEnabled) { + throw new IllegalStateException("Firebase is disabled"); + } + + GoogleCredentials credentials; + + if (!firebaseCredentialBase64.isBlank()) { + byte[] decoded = Base64.getDecoder().decode(firebaseCredentialBase64); + credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(decoded)); + } else if (!firebaseCredentialFile.isBlank()) { + credentials = GoogleCredentials.fromStream( + new ClassPathResource(firebaseCredentialFile).getInputStream() + ); + } else { + throw new IllegalStateException("No Firebase credentials provided"); + } + + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(credentials) + .build(); + + FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() + ? FirebaseApp.initializeApp(options) + : FirebaseApp.getInstance(); + + return FirebaseMessaging.getInstance(firebaseApp); + } +} From 8df1a0fb68d596676c6c4772fe2a44bf317ea9bf Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:22:00 +0530 Subject: [PATCH 012/318] firebase setup --- src/main/environment/common_ci.properties | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 1f82e9ea..0e498ac8 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -34,6 +34,13 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=false cron-scheduler-sms=0 0/1 * * * ? * +// Firebase Configuration +firebase.enabled= @env.FIREBASE_ENABLE@ +# if using file +firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +# for CI/CD +credential-base64 =@env.CREDENTIAL_BASE^$@ + #### Email Configuration send-email=@env.SEND_EMAIL@ spring.mail.host=@env.MAIL_HOST@ From 7222cbd725898cd680365d3ed1d1b676e34e8760 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:25:40 +0530 Subject: [PATCH 013/318] Firebase Configuration in ci --- src/main/environment/common_ci.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 0e498ac8..478cd4e4 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -34,8 +34,8 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=false cron-scheduler-sms=0 0/1 * * * ? * -// Firebase Configuration -firebase.enabled= @env.FIREBASE_ENABLE@ ++ # Firebase Configuration +firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ # for CI/CD From ede033903ea402a6e3c1c918d66219985a7e80bd Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:27:01 +0530 Subject: [PATCH 014/318] Firebase Configuration in ci --- src/main/environment/common_ci.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 478cd4e4..a9a8426f 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -34,12 +34,12 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=false cron-scheduler-sms=0 0/1 * * * ? * -+ # Firebase Configuration +# Firebase Configuration firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ # for CI/CD -credential-base64 =@env.CREDENTIAL_BASE^$@ +firebase.credential-base64=@env.CREDENTIAL_BASE64@ #### Email Configuration send-email=@env.SEND_EMAIL@ From e3a177e65d022e461a47d379075c712f30947f4f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 2 May 2025 12:44:26 +0530 Subject: [PATCH 015/318] firebase notification setup --- .../com/iemr/common/model/notification/NotificationMessage.java | 1 + .../firebaseNotification/FirebaseNotificationService.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index 2838eca3..eed0c171 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -7,6 +7,7 @@ @Data public class NotificationMessage { private String appType; + private String token; private String topic; private String title; private String body; diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 642bd6fa..e41ca94f 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -21,7 +21,7 @@ public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); - Message message = Message.builder().setTopic(notificationMessage.getTopic()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + Message message = Message.builder().setToken(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); try { From ea4747026f7f3e7db919e31c9ba2ea695915eff9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 13 Jun 2025 15:07:53 +0530 Subject: [PATCH 016/318] Beneficiary consent --- .../BeneficiaryConsentController.java | 100 +++++++++ .../BeneficiaryConsentRequest.java | 12 + .../BeneficiaryOTPHandler.java | 14 ++ .../BeneficiaryOTPHandlerImpl.java | 207 ++++++++++++++++++ 4 files changed, 333 insertions(+) create mode 100644 src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java create mode 100644 src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java create mode 100644 src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java create mode 100644 src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java new file mode 100644 index 00000000..60c7bdee --- /dev/null +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -0,0 +1,100 @@ +package com.iemr.common.controller.beneficiaryConsent; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; +import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.utils.mapper.InputMapper; +import com.iemr.common.utils.response.OutputResponse; +import io.lettuce.core.dynamic.annotation.Param; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.ws.rs.core.MediaType; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +public class BeneficiaryConsentController { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private BeneficiaryOTPHandler beneficiaryOTPHandler; + + @Operation(summary = "Send Consent") + @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); + + String success = beneficiaryOTPHandler.sendOTP(obj); // method name unchanged if internal logic still uses 'OTP' + logger.info(success.toString()); + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Validate Consent") + @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"Integer\"}") @RequestBody String requestOBJ) { + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj); + if (responseOBJ != null) + response.setResponse(responseOBJ.toString()); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in validating Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Resend Consent") + @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + String success = beneficiaryOTPHandler.resendOTP(obj); + logger.info(success.toString()); + + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in re-sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + +} + + diff --git a/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java new file mode 100644 index 00000000..ac629a3c --- /dev/null +++ b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java @@ -0,0 +1,12 @@ +package com.iemr.common.data.beneficiaryConsent; + +import lombok.Data; + +@Data +public class BeneficiaryConsentRequest { + private String mobNo; + private int otp; + private String userName; + private String designation; + +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java new file mode 100644 index 00000000..234640a8 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java @@ -0,0 +1,14 @@ +package com.iemr.common.service.beneficiaryOTPHandler; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import org.json.JSONObject; + +public interface BeneficiaryOTPHandler { + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception; + + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception; + + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception; + +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java new file mode 100644 index 00000000..9fa73005 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -0,0 +1,207 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.service.beneficiaryOTPHandler; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.primitives.Ints; +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.data.sms.SMSTemplate; +import com.iemr.common.data.sms.SMSType; +import com.iemr.common.repository.sms.SMSTemplateRepository; +import com.iemr.common.repository.sms.SMSTypeRepository; +import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.service.users.IEMRAdminUserServiceImpl; +import com.iemr.common.utils.config.ConfigProperties; +import com.iemr.common.utils.http.HttpUtils; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.*; +import java.util.concurrent.TimeUnit; + +@Service +public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { + + @Autowired + HttpUtils httpUtils; + @Autowired + private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + @Autowired + SMSTemplateRepository smsTemplateRepository; + private LoadingCache otpCache; + + @Autowired + SMSTypeRepository smsTypeRepository; + + private static final Integer EXPIRE_MIN = 5; + private static final String SMS_GATEWAY_URL = ConfigProperties.getPropertyByName("sms-gateway-url"); + + // Constructor for new object creation + public BeneficiaryOTPHandlerImpl() { + otpCache = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_MIN, TimeUnit.MINUTES) + .build(new CacheLoader() { + public String load(String key) { + return "0"; + } + }); + } + + /*** + * @param obj + * @return success if OTP sent successfully + */ + @Override + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + /*** + * @param obj + * @return OTP verification success or failure + * + */ + @Override + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { + String cachedOTP = otpCache.get(obj.getMobNo()); + String inputOTPEncrypted = getEncryptedOTP(obj.getOtp()); + + if (cachedOTP.equalsIgnoreCase(inputOTPEncrypted)) { + JSONObject responseObj = new JSONObject(); + responseObj.put("userName", obj.getMobNo()); + responseObj.put("userID", obj.getMobNo()); + + JSONObject responseOBJ = iEMRAdminUserServiceImpl.generateKeyPostOTPValidation(responseObj); + + return responseOBJ; + } else { + throw new Exception("Please enter valid OTP"); + } + + } + + /*** + * @param obj + * @return success if OTP re-sent successfully + */ + @Override + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + // generate 6 digit random no # + public int generateOTP(String authKey) throws Exception { + String generatedPassword = null; + Random random = SecureRandom.getInstanceStrong(); + int otp = 100000 + random.nextInt(900000); + + generatedPassword = getEncryptedOTP(otp); + + if (otpCache != null) + otpCache.put(authKey, generatedPassword); + else { + BeneficiaryOTPHandlerImpl obj = new BeneficiaryOTPHandlerImpl(); + obj.otpCache.put(authKey, generatedPassword); + } + return otp; + } + + // SHA-256 encoding logic implemented + private String getEncryptedOTP(int otp) throws Exception { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] bytes = md.digest(Ints.toByteArray(otp)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + + return sb.toString(); + } + + // send SMS to beneficiary + + + public String sendSMS(int otp, BeneficiaryConsentRequest obj) { + + final RestTemplate restTemplate = new RestTemplate(); + String sendSMSURL = ConfigProperties.getPropertyByName("send-message-url"); + + String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL + "/" + sendSMSURL; + + + try { + + +// String message = "Dear Citizen, your OTP for login is " +otp+". Use it within 15 minutes. Do not share this code. Regards PSMRIAM."; + String message = "Hello! Your OTP for providing consent for registration on AMRIT is " + otp + ". This OTP is valid for 10 minutes. Kindly share it only with " + obj.getUserName() + " " + obj.getDesignation() + " to complete the process. PSMRI"; + + // Build payload + Map payload = new HashMap<>(); + payload.put("customerId", ConfigProperties.getPropertyByName("sms-username")); + payload.put("destinationAddress", obj.getMobNo()); + payload.put("message", message); + payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", ConfigProperties.getPropertyByName("dltTemplateId")); + payload.put("entityId",ConfigProperties.getPropertyByName("entityId") ); + payload.put("otp", true); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = ConfigProperties.getPropertyByName("sms-username") + ":" + ConfigProperties.getPropertyByName("sms-password"); + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> request = new HttpEntity<>(payload, headers); + + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + + // Return response + return response.getBody(); + + } catch (Exception e) { + e.printStackTrace(); + return "Error sending SMS: " + e.getMessage(); + } + } + +} From bab8d0a365a92dee755316b0ebec77ee4dc00416 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 13:03:00 +0530 Subject: [PATCH 017/318] Firebase update userToken --- .../FirebaseNotificationController.java | 13 +++++ .../common/data/userToken/UserTokenData.java | 22 ++++++++ .../notification/NotificationMessage.java | 1 - .../common/model/notification/UserToken.java | 9 ++++ .../FirebaseNotificationService.java | 53 +++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iemr/common/data/userToken/UserTokenData.java create mode 100644 src/main/java/com/iemr/common/model/notification/UserToken.java diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 18601d22..3e39fe21 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -1,7 +1,9 @@ package com.iemr.common.controller.firebaseNotification; import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.model.notification.UserToken; import com.iemr.common.service.firebaseNotification.FirebaseNotificationService; +import com.iemr.common.utils.exception.IEMRException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -20,5 +22,16 @@ public String sendNotificationByToken(@RequestBody NotificationMessage notificat return firebaseNotificationService.sendNotification(notificationMessage); } + @RequestMapping(value = "updateToken",method = RequestMethod.POST) + public String updateToken(@RequestBody UserToken userToken){ + return firebaseNotificationService.updateToken(userToken); + } + + @RequestMapping(value = "getToken",method = RequestMethod.GET,headers = "Authorization") + public String getUserToken() throws IEMRException { + + return firebaseNotificationService.getUserToken(); + } + } diff --git a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java new file mode 100644 index 00000000..f27d74e4 --- /dev/null +++ b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java @@ -0,0 +1,22 @@ +package com.iemr.common.data.userToken; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +import java.sql.Timestamp; + +@Entity +@Table(name = "user_tokens", schema = "db_iemr") +@Data +public class UserTokenData { + @Id + @Column(name = "user_id") + Integer userId; + @Column(name = "token") + String token; + @Column(name = "updated_at") + Timestamp updatedAt; +} diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index eed0c171..c81f68c4 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -8,7 +8,6 @@ public class NotificationMessage { private String appType; private String token; - private String topic; private String title; private String body; private Map data; diff --git a/src/main/java/com/iemr/common/model/notification/UserToken.java b/src/main/java/com/iemr/common/model/notification/UserToken.java new file mode 100644 index 00000000..d68d6c5e --- /dev/null +++ b/src/main/java/com/iemr/common/model/notification/UserToken.java @@ -0,0 +1,9 @@ +package com.iemr.common.model.notification; + +import lombok.Data; + +@Data +public class UserToken { + Integer userId; + String token; +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index e41ca94f..0fe37b5a 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -4,11 +4,23 @@ import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Notification; +import com.iemr.common.data.userToken.UserTokenData; import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.model.notification.UserToken; +import com.iemr.common.repo.userToken.UserTokenRepo; +import com.iemr.common.utils.CookieUtil; +import com.iemr.common.utils.JwtUtil; +import com.iemr.common.utils.exception.IEMRException; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.sql.Timestamp; +import java.util.Optional; @Service public class FirebaseNotificationService { @@ -17,6 +29,16 @@ public class FirebaseNotificationService { @Autowired FirebaseMessaging firebaseMessaging; + @Autowired + private UserTokenRepo userTokenRepo; + + @Autowired + private CookieUtil cookieUtil; + + @Autowired + private JwtUtil jwtUtil; + + public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); @@ -34,4 +56,35 @@ public String sendNotification(NotificationMessage notificationMessage) { } } + public String updateToken(UserToken userToken) { + Optional existingTokenData = userTokenRepo.findById(userToken.getUserId()); + + UserTokenData userTokenData; + + if (existingTokenData.isPresent()) { + // User token exist karta hai => update karna hai + userTokenData = existingTokenData.get(); + userTokenData.setToken(userToken.getToken()); + userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + } else { + // User token nahi mila => naya insert karna hai + userTokenData = new UserTokenData(); + userTokenData.setUserId(userToken.getUserId()); + userTokenData.setToken(userToken.getToken()); + userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + } + + userTokenRepo.save(userTokenData); + return "Save Successfully"; + } + + public String getUserToken() throws IEMRException { + HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) + .getRequest(); + String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader); + return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB + .map(UserTokenData::getToken) // mil gaya to token nikalo + .orElse(null); // nah + } + } From 8f8cc6f0d62a1099eb1efe7e75ee334f099095a3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 13:04:41 +0530 Subject: [PATCH 018/318] Firebase update userToken --- .../FirebaseNotificationController.java | 24 ++++++++++++++ .../common/data/userToken/UserTokenData.java | 24 ++++++++++++++ .../notification/NotificationMessage.java | 24 ++++++++++++++ .../common/model/notification/UserToken.java | 24 ++++++++++++++ .../common/repo/userToken/UserTokenRepo.java | 31 +++++++++++++++++++ .../FirebaseNotificationService.java | 24 ++++++++++++++ 6 files changed, 151 insertions(+) create mode 100644 src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 3e39fe21..89fb01a9 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.controller.firebaseNotification; import com.iemr.common.model.notification.NotificationMessage; diff --git a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java index f27d74e4..0646972e 100644 --- a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java +++ b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.data.userToken; import jakarta.persistence.Column; diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index c81f68c4..58343034 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.model.notification; import lombok.Data; diff --git a/src/main/java/com/iemr/common/model/notification/UserToken.java b/src/main/java/com/iemr/common/model/notification/UserToken.java index d68d6c5e..3ea36588 100644 --- a/src/main/java/com/iemr/common/model/notification/UserToken.java +++ b/src/main/java/com/iemr/common/model/notification/UserToken.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.model.notification; import lombok.Data; diff --git a/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java b/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java new file mode 100644 index 00000000..817f26f0 --- /dev/null +++ b/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java @@ -0,0 +1,31 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ +package com.iemr.common.repo.userToken; + +import com.iemr.common.data.userToken.UserTokenData; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserTokenRepo extends JpaRepository { +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 0fe37b5a..7705fb9e 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.service.firebaseNotification; import com.google.firebase.FirebaseException; From f6ca2b92ec6ef6f92a67747eeb7aa5e1bdd09c71 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 18:33:51 +0530 Subject: [PATCH 019/318] Add firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 56e2a2fe..ff2cde29 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -178,4 +178,11 @@ captcha.secret-key=${CAPTCHA_SECRET_KEY} captcha.verify-url=${CAPTCHA_VERIFY_URL} captcha.enable-captcha=${ENABLE_CAPTCHA} -cors.allowed-origins=${CORS_ALLOWED_ORIGINS} \ No newline at end of file +cors.allowed-origins=${CORS_ALLOWED_ORIGINS} + +# Firebase Configuration +firebase.enabled=@env.FIREBASE_ENABLE@ +# if using file +firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +# for CI/CD +firebase.credential-base64=@env.CREDENTIAL_BASE64@ \ No newline at end of file From 825c2c2697c1ac5438a844517f5b25c19c6f49b7 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 20:06:02 +0530 Subject: [PATCH 020/318] Add firebase variables in common_docker.properties --- .../firebaseNotification/FirebaseNotificationService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 7705fb9e..ea0cc005 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -86,12 +86,10 @@ public String updateToken(UserToken userToken) { UserTokenData userTokenData; if (existingTokenData.isPresent()) { - // User token exist karta hai => update karna hai userTokenData = existingTokenData.get(); userTokenData.setToken(userToken.getToken()); userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); } else { - // User token nahi mila => naya insert karna hai userTokenData = new UserTokenData(); userTokenData.setUserId(userToken.getUserId()); userTokenData.setToken(userToken.getToken()); @@ -107,8 +105,8 @@ public String getUserToken() throws IEMRException { .getRequest(); String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader); return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB - .map(UserTokenData::getToken) // mil gaya to token nikalo - .orElse(null); // nah + .map(UserTokenData::getToken) + .orElse(null); // } } From 02c5a8921247246cb1708b8f0d40e2f059c91547 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 10:43:43 +0530 Subject: [PATCH 021/318] update firebase variables in common_docker.properties --- .../java/com/iemr/common/utils/JwtUtil.java | 238 +++++++----------- 1 file changed, 90 insertions(+), 148 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index dc29018c..0ea70bda 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -1,164 +1,106 @@ package com.iemr.common.utils; -import io.jsonwebtoken.*; -import io.jsonwebtoken.security.Keys; +import java.util.Date; +import java.util.UUID; +import java.util.function.Function; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; + import javax.crypto.SecretKey; -import java.util.Date; -import java.util.UUID; -import java.util.function.Function; @Component public class JwtUtil { - @Value("${jwt.secret}") - private String SECRET_KEY; - - @Value("${jwt.access.expiration}") - private long ACCESS_EXPIRATION_TIME; - - @Value("${jwt.refresh.expiration}") - private long REFRESH_EXPIRATION_TIME; - - @Autowired - private TokenDenylist tokenDenylist; - - private SecretKey getSigningKey() { - if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { - throw new IllegalStateException("JWT secret key is not set in application.properties"); - } - return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); - } - - /** - * Generate an access token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT access token - */ - public String generateToken(String username, String userId) { - return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); - } - - /** - * Generate a refresh token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT refresh token - */ - public String generateRefreshToken(String username, String userId) { - return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); - } - - /** - * Build a JWT token with the specified parameters. - * - * @param username the username of the user - * @param userId the user ID - * @param tokenType the type of the token (access or refresh) - * @param expiration the expiration time of the token in milliseconds - * @return the generated JWT token - */ - private String buildToken(String username, String userId, String tokenType, long expiration) { - return Jwts.builder() - .subject(username) - .claim("userId", userId) - .claim("token_type", tokenType) - .id(UUID.randomUUID().toString()) - .issuedAt(new Date()) - .expiration(new Date(System.currentTimeMillis() + expiration)) - .signWith(getSigningKey()) - .compact(); - } - - /** - * Validate the JWT token, checking if it is expired and if it's blacklisted - * @param token the JWT token - * @return Claims if valid, null if invalid (expired or denylisted) - */ - public Claims validateToken(String token) { - try { - Claims claims = Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); - String jti = claims.getId(); - - // Check if token is denylisted (only if jti exists) - if (jti != null && tokenDenylist.isTokenDenylisted(jti)) { - return null; - } - - return claims; - } catch (ExpiredJwtException ex) { - - return null; // Token is expired, so return null - } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { - return null; // Return null for any other JWT-related issue (invalid format, bad signature, etc.) - } - } - - /** - * Extract claims from the token - * @param token the JWT token - * @return all claims from the token - */ - public Claims getAllClaimsFromToken(String token) { - return Jwts.parser() + @Value("${jwt.secret}") + private String SECRET_KEY; + + @Value("${jwt.access.expiration}") + private long ACCESS_EXPIRATION_TIME; + + @Value("${jwt.refresh.expiration}") + private long REFRESH_EXPIRATION_TIME; + + private SecretKey getSigningKey() { + if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { + throw new IllegalStateException("JWT secret key is not set in application.properties"); + } + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + + public String generateToken(String username, String userId) { + return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); + } + + public String generateRefreshToken(String username, String userId) { + return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); + } + + private String buildToken(String username, String userId, String tokenType, long expiration) { + return Jwts.builder() + .subject(username) + .claim("userId", userId) + .claim("token_type", tokenType) + .id(UUID.randomUUID().toString()) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + expiration)) + .signWith(getSigningKey()) + .compact(); + } + + public Claims validateToken(String token) { + try { + return Jwts.parser() + .verifyWith(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload(); + + } catch (ExpiredJwtException ex) { + // Handle expired token specifically if needed + } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { + // Log specific error types + } + return null; + } + + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + public Claims getAllClaimsFromToken(String token) { + return Jwts.parser() .verifyWith(getSigningKey()) .build() .parseSignedClaims(token) .getPayload(); + } + + + public long getRefreshTokenExpiration() { + return REFRESH_EXPIRATION_TIME; + } + + // Additional helper methods + public String getJtiFromToken(String token) { + return getAllClaimsFromToken(token).getId(); + } + + public String getUsernameFromToken(String token) { + return getAllClaimsFromToken(token).getSubject(); + } + + public String extractUserId(String token) { + return getAllClaimsFromToken(token).getId(); - } - - /** - * Extract a specific claim from the token using a function - * @param token the JWT token - * @param claimsResolver the function to extract the claim - * @param the type of the claim - * @return the extracted claim - */ - public T getClaimFromToken(String token, Function claimsResolver) { - final Claims claims = getAllClaimsFromToken(token); - return claimsResolver.apply(claims); - } - - /** - * Get the JWT ID (JTI) from the token - * @param token the JWT token - * @return the JWT ID - */ - public String getJtiFromToken(String token) { - return getAllClaimsFromToken(token).getId(); - } - - /** - * Get the username from the token - * @param token the JWT token - * @return the username - */ - public String getUsernameFromToken(String token) { - return getAllClaimsFromToken(token).getSubject(); - } - - /** - * Get the user ID from the token - * @param token the JWT token - * @return the user ID - */ - public String getUserIdFromToken(String token) { - return getAllClaimsFromToken(token).get("userId", String.class); - } - - /** - * Get the expiration time of the refresh token - * @return the expiration time in milliseconds - */ - public long getRefreshTokenExpiration() { - return REFRESH_EXPIRATION_TIME; - } -} + } +} \ No newline at end of file From 6e9d25316441c43445b14c864811efd969d195ac Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 11:05:35 +0530 Subject: [PATCH 022/318] update firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index ff2cde29..999252c0 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -181,8 +181,8 @@ captcha.enable-captcha=${ENABLE_CAPTCHA} cors.allowed-origins=${CORS_ALLOWED_ORIGINS} # Firebase Configuration -firebase.enabled=@env.FIREBASE_ENABLE@ +firebase.enabled= ${FIREBASE_ENABLE} # if using file -firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +firebase.credential-file= ${FIREBASE_CREDENTIAL} # for CI/CD -firebase.credential-base64=@env.CREDENTIAL_BASE64@ \ No newline at end of file +firebase.credential-base64= ${CREDENTIAL_BASE64} \ No newline at end of file From cbe0d55c12b43ff104185c57af10614e6d7d0791 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 11:07:04 +0530 Subject: [PATCH 023/318] update firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 999252c0..7fc32ba3 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -181,8 +181,8 @@ captcha.enable-captcha=${ENABLE_CAPTCHA} cors.allowed-origins=${CORS_ALLOWED_ORIGINS} # Firebase Configuration -firebase.enabled= ${FIREBASE_ENABLE} +firebase.enabled=${FIREBASE_ENABLE} # if using file -firebase.credential-file= ${FIREBASE_CREDENTIAL} +firebase.credential-file=${FIREBASE_CREDENTIAL} # for CI/CD -firebase.credential-base64= ${CREDENTIAL_BASE64} \ No newline at end of file +firebase.credential-base64=${CREDENTIAL_BASE64} \ No newline at end of file From 37aadb58a4a9d76ef61a6286add9b37ac008eb5b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Sat, 21 Jun 2025 11:17:38 +0530 Subject: [PATCH 024/318] fixed code --- .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index 8b00263a..a6bd9eca 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -91,8 +91,7 @@ public class BeneficiaryModel implements Comparable { private TitleModel m_title; @Expose private String firstName; - @Expose - private Boolean isConsent=false; + @Expose private String middleName; From 599ed6e45351d39c8a6c1c766e882f07f896a6ae Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Sat, 21 Jun 2025 11:29:03 +0530 Subject: [PATCH 025/318] fixed code --- .../beneficiaryConsent/BeneficiaryConsentController.java | 4 ++-- .../com/iemr/common/controller/users/IEMRAdminController.java | 2 +- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index 60c7bdee..3b89f63e 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -54,7 +54,7 @@ public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"In OutputResponse response = new OutputResponse(); try { - OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj); if (responseOBJ != null) @@ -77,7 +77,7 @@ public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBod OutputResponse response = new OutputResponse(); try { - OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); String success = beneficiaryOTPHandler.resendOTP(obj); logger.info(success.toString()); diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 81acd8ca..4a1af2a2 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -567,7 +567,7 @@ public String getLoginResponse(HttpServletRequest request) { } // Extract user ID from the JWT token - String userId = jwtUtil.getUserIdFromToken(jwtToken); + String userId = jwtUtil.extractUserId(jwtToken); // Get user details and prepare response User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index c057b58d..8e364eb3 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -61,7 +61,6 @@ public class CommonIdentityDTO { private Integer educationId; private String education; private Boolean emergencyRegistration = false; - private Boolean isConsent; private Integer healthCareWorkerId; private String healthCareWorker; private String fatherName; From 4970f1e2f4a1dd4d370f2401c56cf71a5b731ece Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 11:57:37 +0530 Subject: [PATCH 026/318] Fixed security hotspot --- .../BeneficiaryConsentController.java | 25 ++++++++++++++++--- .../BeneficiaryOTPHandlerImpl.java | 1 - 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index 3b89f63e..e8e55034 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -1,9 +1,28 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.controller.beneficiaryConsent; import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; -import com.iemr.common.data.otp.OTPRequestParsor; import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; -import com.iemr.common.service.otp.OTPHandler; import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.response.OutputResponse; import io.lettuce.core.dynamic.annotation.Param; @@ -26,7 +45,6 @@ public class BeneficiaryConsentController { @Operation(summary = "Send Consent") @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { - logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -41,7 +59,6 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody response.setError(500, "failure"); } catch (Exception e) { - logger.error("error in sending Consent : " + e); response.setError(500, "error : " + e); } return response.toString(); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 9fa73005..6f791a87 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -199,7 +199,6 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { return response.getBody(); } catch (Exception e) { - e.printStackTrace(); return "Error sending SMS: " + e.getMessage(); } } From 41b327b5a29ffdb6d0851f38dc3976ea7de0088e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 17:41:23 +0530 Subject: [PATCH 027/318] Fixed security hotspot --- .../BeneficiaryConsentController.java | 9 +++--- .../BeneficiaryOTPHandlerImpl.java | 31 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index e8e55034..e917204c 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -35,7 +35,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +@RequestMapping(value = { "/beneficiaryConsent" },headers ="Authorization" ) +@RestController public class BeneficiaryConsentController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @@ -53,10 +56,8 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String success = beneficiaryOTPHandler.sendOTP(obj); // method name unchanged if internal logic still uses 'OTP' logger.info(success.toString()); - if (success.contains("otp")) - response.setResponse(success); - else - response.setError(500, "failure"); + response.setResponse(success); + } catch (Exception e) { response.setError(500, "error : " + e); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 6f791a87..17027667 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -87,8 +87,7 @@ public String load(String key) { @Override public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { int otp = generateOTP(obj.getMobNo()); - sendSMS(otp, obj); - return "success"; + return sendSMS(otp, obj); } /*** @@ -122,8 +121,7 @@ public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { @Override public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { int otp = generateOTP(obj.getMobNo()); - sendSMS(otp, obj); - return "success"; + return sendSMS(otp, obj); } // generate 6 digit random no # @@ -161,16 +159,17 @@ private String getEncryptedOTP(int otp) throws Exception { public String sendSMS(int otp, BeneficiaryConsentRequest obj) { final RestTemplate restTemplate = new RestTemplate(); - String sendSMSURL = ConfigProperties.getPropertyByName("send-message-url"); - String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL + "/" + sendSMSURL; + String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); + SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); + String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL; try { - - -// String message = "Dear Citizen, your OTP for login is " +otp+". Use it within 15 minutes. Do not share this code. Regards PSMRIAM."; - String message = "Hello! Your OTP for providing consent for registration on AMRIT is " + otp + ". This OTP is valid for 10 minutes. Kindly share it only with " + obj.getUserName() + " " + obj.getDesignation() + " to complete the process. PSMRI"; + String message = template.getSmsTemplate() + .replace("$$OTP$$",String.valueOf(otp)) + .replace("$$UserName$$", obj.getUserName()) + .replace("$$Designation$$", obj.getDesignation()); // Build payload Map payload = new HashMap<>(); @@ -179,8 +178,8 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("message", message); payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", ConfigProperties.getPropertyByName("dltTemplateId")); - payload.put("entityId",ConfigProperties.getPropertyByName("entityId") ); + payload.put("dltTemplateId", dltTemplateId); + payload.put("entityId",ConfigProperties.getPropertyByName("sms-entityid") ); payload.put("otp", true); // Set headers HttpHeaders headers = new HttpHeaders(); @@ -194,9 +193,13 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { // Call API ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + logger.info("sms-response:"+response.getBody()); + if(response.getStatusCode().value()==200){ + return "OTP sent successfully on register mobile number"; + }else { + return "Fail"; - // Return response - return response.getBody(); + } } catch (Exception e) { return "Error sending SMS: " + e.getMessage(); From 983dfd10849b090c1038b1f234eed5705db52188 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 18:19:09 +0530 Subject: [PATCH 028/318] Remove firebase base64 variable --- src/main/environment/common_ci.properties | 2 -- src/main/environment/common_docker.properties | 2 -- .../common/config/firebase/FirebaseMessagingConfig.java | 7 +------ 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 9eac3447..50be0c7f 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -44,8 +44,6 @@ cron-scheduler-sms=0 0/1 * * * ? * firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ -# for CI/CD -firebase.credential-base64=@env.CREDENTIAL_BASE64@ #### Email Configuration send-email=@env.SEND_EMAIL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 7fc32ba3..8989ac1d 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -184,5 +184,3 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS} firebase.enabled=${FIREBASE_ENABLE} # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} -# for CI/CD -firebase.credential-base64=${CREDENTIAL_BASE64} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 438ca4f9..250558bb 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -22,8 +22,6 @@ public class FirebaseMessagingConfig { @Value("${firebase.credential-file:}") private String firebaseCredentialFile; - @Value("${firebase.credential-base64:}") - private String firebaseCredentialBase64; @Bean public FirebaseMessaging firebaseMessaging() throws IOException { @@ -33,10 +31,7 @@ public FirebaseMessaging firebaseMessaging() throws IOException { GoogleCredentials credentials; - if (!firebaseCredentialBase64.isBlank()) { - byte[] decoded = Base64.getDecoder().decode(firebaseCredentialBase64); - credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(decoded)); - } else if (!firebaseCredentialFile.isBlank()) { + if (!firebaseCredentialFile.isBlank()) { credentials = GoogleCredentials.fromStream( new ClassPathResource(firebaseCredentialFile).getInputStream() ); From bc777cbeb07541a4462e2250ae3551c1c015b2ba Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 18:39:49 +0530 Subject: [PATCH 029/318] Remove firebase base64 variable --- src/main/environment/common_docker.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 8989ac1d..e490991b 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -184,3 +184,4 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS} firebase.enabled=${FIREBASE_ENABLE} # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} + From 8683835c2e68f136756517c518b185de1558c07e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 19:14:36 +0530 Subject: [PATCH 030/318] fix firebase file access issue --- .../config/firebase/FirebaseMessagingConfig.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 250558bb..9a0c88a0 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -10,6 +10,7 @@ import org.springframework.core.io.ClassPathResource; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.util.Base64; @@ -29,16 +30,12 @@ public FirebaseMessaging firebaseMessaging() throws IOException { throw new IllegalStateException("Firebase is disabled"); } - GoogleCredentials credentials; - - if (!firebaseCredentialFile.isBlank()) { - credentials = GoogleCredentials.fromStream( - new ClassPathResource(firebaseCredentialFile).getInputStream() - ); - } else { - throw new IllegalStateException("No Firebase credentials provided"); + if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { + throw new IllegalStateException("No Firebase credentials path provided"); } + GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(firebaseCredentialFile)); + FirebaseOptions options = FirebaseOptions.builder() .setCredentials(credentials) .build(); From f66cf54903a84ddd2328c57bc92e3d722caa6a7e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 19:16:06 +0530 Subject: [PATCH 031/318] fix firebase file access issue --- .../com/iemr/common/config/firebase/FirebaseMessagingConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 9a0c88a0..ebb98b59 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -46,4 +46,5 @@ public FirebaseMessaging firebaseMessaging() throws IOException { return FirebaseMessaging.getInstance(firebaseApp); } + } From cb001e39b346b3fea8d75dfe519091c57732376a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:10:04 +0530 Subject: [PATCH 032/318] dynamic form --- .../dynamicForm/DynamicFormController.java | 30 ++++++++++++++++ .../common/data/dynamic_from/FormEntity.java | 25 +++++++++++++ .../data/dynamic_from/ModuleEntity.java | 23 ++++++++++++ .../common/dto/dynamicForm/FormFieldDTO.java | 23 ++++++++++++ .../dto/dynamicForm/FormTypeEntityDTO.java | 18 ++++++++++ .../dto/dynamicForm/ModuleEntityDTO.java | 12 +++++++ .../dynamic_form/FormTypeRepository.java | 8 +++++ .../dynamic_form/ModuleRepository.java | 10 ++++++ .../service/dynamicForm/FormTypeService.java | 35 +++++++++++++++++++ .../service/dynamicForm/ModuleService.java | 26 ++++++++++++++ 10 files changed, 210 insertions(+) create mode 100644 src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java new file mode 100644 index 00000000..f15ad2c0 --- /dev/null +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -0,0 +1,30 @@ +package com.iemr.common.controller.dynamicForm; + +import com.iemr.common.data.dynamic_from.FormEntity; +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; +import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; +import com.iemr.common.service.dynamicForm.FormTypeService; +import com.iemr.common.service.dynamicForm.ModuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequestMapping(value = "masterFrom") +@RestController +public class DynamicFormController { + @Autowired ModuleService moduleService; + @Autowired + private FormTypeService formTypeService; + + @PostMapping("/modules") + public ResponseEntity createModule(@RequestBody ModuleEntityDTO module) { + return ResponseEntity.ok(moduleService.save(module)); + } + + @PostMapping("/modules/{moduleId}/form-types") + public ResponseEntity createFormType(@PathVariable Long moduleId, @RequestBody FormTypeEntityDTO formType) { + return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); + } + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java new file mode 100644 index 00000000..0b81e148 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -0,0 +1,25 @@ +package com.iemr.common.data.dynamic_from; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.persistence.*; +import lombok.Data; + +@Data +@Entity +@Table(name = "form_types",schema = "db_imer") +public class FormEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "Id") + private Long id; + + @Column(name = "form_name",columnDefinition = "TEXT") + private String formName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "module_id") + private ModuleEntity module; + + @Column(name = "fields",columnDefinition = "TEXT") + private String fields ; +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java new file mode 100644 index 00000000..4d699a7e --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java @@ -0,0 +1,23 @@ +package com.iemr.common.data.dynamic_from; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.persistence.*; +import lombok.Data; + +import java.util.List; +@Data +@Entity +@Table(name = "m_modules",schema = "db_iemr") +public class ModuleEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "Id") + private Long id; + + @Column(name = "module_name",columnDefinition = "TEXT") + private String moduleName; + + @OneToMany(mappedBy = "module", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List formTypes; + +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java new file mode 100644 index 00000000..27a6ee93 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java @@ -0,0 +1,23 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FormFieldDTO { + private String name; + private String label; + private String type; + private boolean required; + private String inputType; + private String fileType; + private String buttonAction; + private String visibleIfField; + private String visibleIfValue; + private Map validations; + private List> options; + + // Getters and Setters +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java new file mode 100644 index 00000000..ff31dfd5 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java @@ -0,0 +1,18 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class FormTypeEntityDTO { + + private Long id; + + private String formName; + + private ModuleEntityDTO module; + + private List fields; + +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java new file mode 100644 index 00000000..03cfc834 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java @@ -0,0 +1,12 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; +@Data +public class ModuleEntityDTO { + private Long id; + private String moduleName; + +} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java new file mode 100644 index 00000000..b3b731fe --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java @@ -0,0 +1,8 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormEntity; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FormTypeRepository extends CrudRepository {} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java new file mode 100644 index 00000000..e4eb221e --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java @@ -0,0 +1,10 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.ModuleEntity; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ModuleRepository extends CrudRepository { + +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java new file mode 100644 index 00000000..38068cdc --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java @@ -0,0 +1,35 @@ +package com.iemr.common.service.dynamicForm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iemr.common.data.dynamic_from.FormEntity; +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; +import com.iemr.common.repository.dynamic_form.FormTypeRepository; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FormTypeService { + @Autowired + ModuleRepository moduleRepo; + @Autowired + FormTypeRepository formTypeRepo; + @Autowired + ObjectMapper objectMapper; + + public FormEntity createFormType(Long moduleId, FormTypeEntityDTO formTypeDTO) { + ModuleEntity module = moduleRepo.findById(moduleId).orElseThrow(); + FormEntity formType = new FormEntity(); + formType.setFormName(formTypeDTO.getFormName()); + formType.setModule(module); + try { + String fieldsJson = objectMapper.writeValueAsString(formTypeDTO.getFields()); + formType.setFields(fieldsJson); + } catch (JsonProcessingException e) { + throw new RuntimeException("Failed to serialize form fields", e); + } + return formTypeRepo.save(formType); + } +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java new file mode 100644 index 00000000..644d2c59 --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java @@ -0,0 +1,26 @@ +package com.iemr.common.service.dynamicForm; + +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class ModuleService { + @Autowired + ModuleRepository repo; + + public ModuleEntity save(ModuleEntityDTO module) { + ModuleEntity moduleEntity = new ModuleEntity(); + moduleEntity.setModuleName(module.getModuleName()); + return repo.save(moduleEntity); + } + + public Optional findById(Long id) { + return repo.findById(id); + } +} + From 9e395b5c20ad973a4dbdea742b670abcef593f84 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:10:54 +0530 Subject: [PATCH 033/318] dynamic form --- src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java index 0b81e148..6f4445a6 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -22,4 +22,5 @@ public class FormEntity { @Column(name = "fields",columnDefinition = "TEXT") private String fields ; + } From 9c112569ff1d5c5cb82f6fbfc30f5a80468c5b44 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:18:08 +0530 Subject: [PATCH 034/318] dynamic form --- src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java index 6f4445a6..578111f5 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -23,4 +23,5 @@ public class FormEntity { @Column(name = "fields",columnDefinition = "TEXT") private String fields ; + } From d1cc9d59a43f45c778be3060c0218202a6accbdd Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 1 Jul 2025 10:19:04 +0530 Subject: [PATCH 035/318] dynamic form --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index f15ad2c0..9a924872 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -27,4 +27,5 @@ public ResponseEntity createFormType(@PathVariable Long moduleId, @R return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); } + } From 768b3f783e8e50d5bab36323fdce00981926cc6c Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Tue, 1 Jul 2025 17:26:57 +0530 Subject: [PATCH 036/318] fix: AMM-1677 - rendering only grievances who have consent --- .../com/iemr/common/dto/grivance/GrievanceWorklistDTO.java | 6 ++++-- .../service/grievance/GrievanceHandlingServiceImpl.java | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/dto/grivance/GrievanceWorklistDTO.java b/src/main/java/com/iemr/common/dto/grivance/GrievanceWorklistDTO.java index b8184162..6364b7f6 100644 --- a/src/main/java/com/iemr/common/dto/grivance/GrievanceWorklistDTO.java +++ b/src/main/java/com/iemr/common/dto/grivance/GrievanceWorklistDTO.java @@ -39,13 +39,14 @@ public class GrievanceWorklistDTO implements Serializable { private String age; private Boolean retryNeeded; private Integer callCounter; - private Timestamp lastCall; + private Timestamp lastCall; + private Boolean beneficiaryConsent; public GrievanceWorklistDTO(String complaintID,Long grievanceId, String subjectOfComplaint, String complaint, Long beneficiaryRegID, Integer providerServiceMapID,String primaryNumber,String severety,String state, Integer userId, Boolean deleted, String createdBy, Timestamp createdDate, Timestamp lastModDate, Boolean isCompleted,String firstName, String lastName, String gender, String district, Long beneficiaryID, String age, - Boolean retryNeeded, Integer callCounter, Timestamp lastCall) { + Boolean retryNeeded, Integer callCounter, Timestamp lastCall, Boolean beneficiaryConsent) { super(); this.complaintID = complaintID; this.grievanceId = grievanceId; @@ -71,6 +72,7 @@ public GrievanceWorklistDTO(String complaintID,Long grievanceId, String subjectO this.retryNeeded = retryNeeded; this.callCounter = callCounter; this.lastCall = lastCall; + this.beneficiaryConsent = beneficiaryConsent; } diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java index 68e8e76e..ed643417 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceHandlingServiceImpl.java @@ -296,7 +296,7 @@ public List getFormattedGrievanceData(String request) thro // Loop through the worklist data and format the response for (Object[] row : worklistData) { - if (row == null || row.length < 22) + if (row == null || row.length < 24) { logger.warn("invalid row data received"); continue; @@ -334,7 +334,8 @@ public List getFormattedGrievanceData(String request) thro ageFormatted, (Boolean) row[21], // retryNeeded (Integer) row[22], // callCounter - (Timestamp) row[13] //lastCall + (Timestamp) row[13], // lastCall + (Boolean) row[23] //beneficiaryConsent ); From dab6926d6fe7960420546c003d320002e48482e8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 3 Jul 2025 21:23:36 +0530 Subject: [PATCH 037/318] IDENTITY_BASE_URL fix --- .../IdentityBeneficiaryServiceImpl.java | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 697322c6..9056eb45 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -26,15 +26,11 @@ import java.util.HashSet; import java.util.List; +import com.google.gson.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import com.iemr.common.dto.identity.BeneficiariesDTO; import com.iemr.common.dto.identity.BeneficiariesPartialDTO; import com.iemr.common.dto.identity.IdentityEditDTO; @@ -399,23 +395,40 @@ public List getBeneficiaryListByGovId(String identity, String @Override public String getIdentityResponse(String request, String auth, Boolean is1097) throws IEMRException { - String result; HashMap header = new HashMap<>(); if (auth != null) { header.put("Authorization", auth); } - result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), request, header); - OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); - if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { - throw new IEMRException(identityResponse.getErrorMessage()); + String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); + + logger.info("Calling URL: {}", apiUrl); + logger.info("Request Payload: {}", request); + + result = httpUtils.post(apiUrl, request, header); + + if (result == null || result.isEmpty()) { + logger.error("Empty response from Identity API"); + throw new IEMRException("No response received from Identity API"); + } + + try { + OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); + if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { + throw new IEMRException(identityResponse.getErrorMessage()); + } + } catch (JsonSyntaxException e) { + logger.error("JSON parsing error: {}", e.getMessage()); + throw new IEMRException("Invalid response format from Identity API"); } + return result; } + public Integer editIdentityEditDTO(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { JsonParser parser = new JsonParser(); From 8242ff9daeae3d9e489b2f0b75928215a03a5111 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 3 Jul 2025 21:33:17 +0530 Subject: [PATCH 038/318] IDENTITY_BASE_URL fix --- src/main/resources/application.properties | 214 +++++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 813637b0..180ad75d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -115,7 +115,9 @@ identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenR identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= identity-api-url-getByBenId =IDENTITY_BASE_URL/id/getByBenId?benId= identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= -identity-api-url-benCreate =IDENTITY_BASE_URL/id/create +IDENTITY_API_URL=https://amritdemo.piramalswasthya.org +identity-api-url-benCreate=${IDENTITY_API_URL}/id/create +#identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity @@ -173,3 +175,213 @@ failedLoginAttempt=5 jwt.access.expiration=86400000 jwt.refresh.expiration=604800000 +# local env +server.port=8083 +# DB Connections +spring.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_iemr +spring.datasource.username=root +spring.datasource.password=BizDev@24BB +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +encDbUserName=zFlYsp9Z0s+lRvLM15A3g/Ba0w8VGs/1usuW7EsGF3k= +encDbPass=JGGAGn5wTlrbTLUHY+5BzfBa0w8VGs/1usuW7EsGF3k= + +secondary.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_reporting +secondary.datasource.username=root +secondary.datasource.password=BizDev@24BB +secondary.datasource.driver-class-name=com.mysql.jdbc.Driver +firebase.enabled = true +firebase.credential-file =firebase_cred.json + + + +## KM Configuration +km-base-protocol=http +km-username=okmAdmin +km-password=admin +km-base-url=http://localhost:8084/OpenKM +km-base-path=localhost:8084/OpenKM +km-root-path=/okm:personal/users/ +km-guest-user=guest +km-guest-password=guest + +# CTI Config +cti-server-ip=10.208.122.99 +cti-logger_base_url=http://10.208.122.99/logger +sms-gateway-url = + +# Identity Config +identity-api-url = http://localhost:8094/ +#Verify whether 1097 and identity are same? +identity-1097-api-url = http://localhost:8095/ +##Generate Benificiary Config +genben-api=http://localhost:8092/ + +#### SMS Configuration +send-sms=false +sendSMSUrl = http://localhost:8080/sms/sendSMS +source-address=AIDSHL +sms-username= +sms-password= +send-message-url= + +###SMS Scheduler configurations +start-sms-scheduler=false +cron-scheduler-sms=0 0/1 * * * ? * + +#### Email Configuration +send-email=false +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username= +spring.mail.password= +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true + +###Email Scheduler configurations +start-email-scheduler=true +cron-scheduler-email=0 0/1 * * * ? * + +##-------------------------------###cti data sync Scheduler configurations------------------------------------------------------ + +start-ctidatasync-scheduler=false +cron-scheduler-ctidatasync=0 0 2 */2 * ? + +##-------------------------------###cti data check with call detail report Scheduler------------------------------------------------------ + +#Runs at everyday 12:10AM +start-ctidatacheck-scheduler=true +cron-scheduler-ctidatacheck=0 10 00 * * * + +##---------------------------------#### Registration schedular for Avni------------------------------------------------------------------------------ + +start-avni-scheduler=false +cron-avni-registration=0 0/1 * * * ? * + +##------------------------------------------------#### Everwell Regsitration Scheduler--------------------------------------------------------------- + +start-registration-scheduler=false +cron-scheduler-registration=0 34 19 * * ? * + +##----------------------------------------------------#everwell data sync----------------------------------------------------------- + +start-everwelldatasync-scheduler=false +cron-scheduler-everwelldatasync=0 0/5 * * * ? * + +##-----------------------------------------------#NHM data dashboard schedular---------------------------------------------------------------- +# run at everyday 12:01AM +start-nhmdashboard-scheduler=true +cron-scheduler-nhmdashboard=0 1 * * * ? * +##----------------------------------------------------#grievance data sync----------------------------------------------------------- + +start-grievancedatasync-scheduler=false +cron-scheduler-grievancedatasync=0 0/2 * * * ? + +### Redis IP +spring.redis.host=localhost + +##--------------------------------------------------------------------------------------------------------------- +###CTI data sync schedular +cz-duration=40 +##--------------------------------------------------------------------------------------------------------------- +## prescription template +TMprescriptionTemplate=TMPrescription +##--------------------------------------------------------------------------------------------------------------- +##duration for everwell calender +everwellCalendarDuration=15 +##--------------------------------------------------------------------------------------------------------------- +##lonic variables +lonicPageSize=10 +##--------------------------------------------------------------------------------------------------------------- +#snomedcti +snomedCTPageSize=10 +##--------------------------------------------------------------------------------------------------------------- +#call retry count +callRetryConfiguration=3 +##--------------------------------------------------------------------------------------------------------------- +#avni registration Duration +avniRegistrationLimit=7 + +#--------------------------NHM Agent Real Time Data---------------------------- +nhm.agent.real.time.data.url= http://175.101.1.83/apps/utility/alive_api.php +nhm.agent.real.time.data.cron.scheduler=0 */2 * ? * * +nhm.agent.real.time.data.cron.flag=true + +carestream_socket_ip = 192.168.43.39 +carestream_socket_port = 1235 + +## everwell variables +everwellUserName = +everwellPassword = +amritUserName = +amritPassword = + +## everwell API call +everwellAddSupportAction = https://beta-hub.everwell.org/Api/Patients/AddSupportAction +everwellEditDoses = https://beta-hub.everwell.org/Api/Patients/EditManualDoses +everwellEditMissedDoses = https://beta-hub.everwell.org/Api/Patients/EditMissedDoses +everwellGetPatientAdherenceUrl = https://beta-hub.everwell.org/Api/Patients/CurrentMonthMissedAdherence?Page= +everwellEditSecondaryPhoneNo = https://beta-hub.everwell.org/Api/Patients/EditPhoneNumber +everwell1097userAuthenticate = http://localhost:8083/user/userAuthenticate +everwelluserAuthenticate = https://beta-hub.everwell.org/token +everwellRegisterBenficiary = http://localhost:8083/beneficiary/create + + +## LungAssessment credentials +lungAssessmentEmail = +lungAssessmentPassword = + + +## SWASSA APIs +lungAssessmentAdminLogin = http://swaasa.sandbox.swaasa.ai/api/adminLogin +lungAssessmentValidateCough = http://swaasa.sandbox.swaasa.ai/api/verifycough +lungAssessmentStartAssesment = http://swaasa.sandbox.swaasa.ai/api/assessment +lungAssessmentGetAssesment = http://swaasa.sandbox.swaasa.ai/api/getAssessment + +#E- Sanjeevani user authenticate creds +eSanjeevani.url: https://preprod.esanjeevaniopd.xyz/uat/aus/api/ThirdPartyAuth/providerLogin +eSanjeevani.userName: +eSanjeevani.password: +eSanjeevani.salt: 123456 +eSanjeevani.source: 11001 +eSanjeevani.registerPatient: https://preprod.esanjeevaniopd.xyz/uat/ps/api/v1/Patient +eSanjeevani.routeUrl: https://uat.esanjeevani.in/user/signin + +biometric.discover.url = http://127.0.0.1:port/ +biometric.deviceInfo.url = http://127.0.0.1:port/rd/info +biometric.capture.url = http://127.0.0.1:port/rd/capture +eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward + +eausadhaAuthorization= +spring.main.allow-bean-definition-overriding=true +spring.main.allow-circular-references=true +jwt.secret=my-32-character-ultra-secure-and-ultra-long-secret + + +fileBasePath =/Doc +##grievance API call +updateGrievanceDetails = /grsbepro/igemr1097/public/api/v1/state-wise/grievance-list?page=PageNumber¤tpage=1 +updateGrievanceTransactionDetails=/grsbepro/igemr1097/public/api/v1/grievance_details/ + +## grievance variables +grievanceUserName = +grievancePassword = + +grievanceUserAuthenticate = +grievanceDataSyncDuration = + +springdoc.api-docs.enabled=true +springdoc.swagger-ui.enabled=true + +isProduction=false +grievanceAllocationRetryConfiguration=3 + +logging.path=logs/ +logging.file.name=logs/common-api.log + +captcha.secret-key= +captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify +captcha.enable-captcha=true + +cors.allowed-origins=http://localhost:* + From f49b34bdc1a1801e3c6c9bc38e5b76285170274a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 3 Jul 2025 21:34:21 +0530 Subject: [PATCH 039/318] IDENTITY_BASE_URL fix --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 180ad75d..05f0b921 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -118,6 +118,7 @@ identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= IDENTITY_API_URL=https://amritdemo.piramalswasthya.org identity-api-url-benCreate=${IDENTITY_API_URL}/id/create #identity-api-url-benCreate =IDENTITY_BASE_URL/id/create + identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity From 5cfac3f2aeb4dd86b7a178cf68d5f3bb4d4f4a7d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 06:45:12 +0530 Subject: [PATCH 040/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 4 ++-- src/main/resources/application.properties | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 9056eb45..48d5aef7 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -401,9 +401,9 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } + String baseUrl = is1097 ? identity1097BaseURL : identityBaseURL; + String apiUrl = baseUrl + ConfigProperties.getPropertyByName("identity-api-url-benCreate"); - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 180ad75d..07983569 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -115,9 +115,7 @@ identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenR identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= identity-api-url-getByBenId =IDENTITY_BASE_URL/id/getByBenId?benId= identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= -IDENTITY_API_URL=https://amritdemo.piramalswasthya.org -identity-api-url-benCreate=${IDENTITY_API_URL}/id/create -#identity-api-url-benCreate =IDENTITY_BASE_URL/id/create +identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity From f14beb2e24cd413d863baf05d0e84ec6da34c71b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 06:58:48 +0530 Subject: [PATCH 041/318] IDENTITY_BASE_URL fix --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 48d5aef7..5c27c251 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -52,7 +52,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); - private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; + private static final String IDENTITY_BASE_URL = "https://amritdemo.piramalswasthya.org"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); @@ -80,7 +80,7 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String } result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( - IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); + IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : "https://amritdemo.piramalswasthya.org")), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse != null && identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { throw new IEMRException(identityResponse.getErrorMessage()); @@ -401,9 +401,9 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } - String baseUrl = is1097 ? identity1097BaseURL : identityBaseURL; - String apiUrl = baseUrl + ConfigProperties.getPropertyByName("identity-api-url-benCreate"); + String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); From 61c13a175da4a67df1974c9f211b4233bd93f6ab Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:00:34 +0530 Subject: [PATCH 042/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 5c27c251..c3bc662d 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -79,6 +79,7 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String header.put("Authorization", auth); } + result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : "https://amritdemo.piramalswasthya.org")), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); From c49557685a9a885ec469ceea422162cb95d9f27b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:07:54 +0530 Subject: [PATCH 043/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 5c27c251..a31c71ab 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -52,7 +52,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); - private static final String IDENTITY_BASE_URL = "https://amritdemo.piramalswasthya.org"; + private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); @@ -79,8 +79,9 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String header.put("Authorization", auth); } + result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( - IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : "https://amritdemo.piramalswasthya.org")), benIdList.toString(), header); + IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse != null && identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { throw new IEMRException(identityResponse.getErrorMessage()); From f89737a4a33def82aa61eb1759c7bde36dea7cf9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:12:45 +0530 Subject: [PATCH 044/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..9056eb45 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -79,7 +79,6 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String header.put("Authorization", auth); } - result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); From bff3dab07f37600974cf24b92b5989b6b14ff1a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:24:16 +0530 Subject: [PATCH 045/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/environment/common_docker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 3569b7f3..817cf696 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -25,7 +25,7 @@ cti-server-ip=${CTI_SERVER_IP} cti-logger_base_url=${CTI_SERVER_LOGGER_BASE}/logger # Identity Config -identity-api-url = ${IDENTITY_API_URL} +identity-api-url = ${IDENTITY_API_BASE_URL} identity-1097-api-url = ${IDENTITY_1097_API_URL} #### SMS Configuration From c8bc5de92fcca37f6bdb7f1f801b09db6533df21 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 08:33:08 +0530 Subject: [PATCH 046/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..930e4615 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -403,12 +403,12 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t header.put("Authorization", auth); } - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); +// String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") +// .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); + String apiUrl = "https://amritdemo.piramalswasthya.org/id/create"; logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); - result = httpUtils.post(apiUrl, request, header); if (result == null || result.isEmpty()) { From 21fb98044de536bd38841814a2ec2bd21989c9c0 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 08:40:14 +0530 Subject: [PATCH 047/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..8f1455dd 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -405,7 +405,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); - logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); From b71ef0c50c80e84eac1c92379147ba83865e19a3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 14:48:58 +0530 Subject: [PATCH 048/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0a3d57cc..a26b8bbb 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -175,22 +175,7 @@ jwt.access.expiration=86400000 jwt.refresh.expiration=604800000 # local env -server.port=8083 -# DB Connections -spring.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_iemr -spring.datasource.username=root -spring.datasource.password=BizDev@24BB -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -encDbUserName=zFlYsp9Z0s+lRvLM15A3g/Ba0w8VGs/1usuW7EsGF3k= -encDbPass=JGGAGn5wTlrbTLUHY+5BzfBa0w8VGs/1usuW7EsGF3k= - -secondary.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_reporting -secondary.datasource.username=root -secondary.datasource.password=BizDev@24BB -secondary.datasource.driver-class-name=com.mysql.jdbc.Driver -firebase.enabled = true -firebase.credential-file =firebase_cred.json + From 82d64083c9eaad92255d2a3fe6bd1da57817b1ea Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Fri, 4 Jul 2025 15:44:54 +0530 Subject: [PATCH 049/318] fix: AMM-1701 callcounter issue fix --- .../grievance/GrievanceDataSyncImpl.java | 59 +++++++++++-------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java index 5a05b94f..35c9b57b 100644 --- a/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java +++ b/src/main/java/com/iemr/common/service/grievance/GrievanceDataSyncImpl.java @@ -579,41 +579,48 @@ public String completeGrievanceCall(String request) throws Exception { // Logic for reattempt based on call group type and call type boolean isRetryNeeded = grievanceCallStatus.getRetryNeeded(); - if ((null != grievanceCallStatus.getComplaintResolution() - && grievanceCallStatus.getComplaintResolution().equalsIgnoreCase("Resolved")) || (callGroupType.equalsIgnoreCase("Valid") && (callType.equalsIgnoreCase("Valid") || callType.equals("Test Call")))) { + boolean isResolved = grievanceCallStatus.getComplaintResolution() != null + && grievanceCallStatus.getComplaintResolution().equalsIgnoreCase("Resolved"); + boolean isValidGroup = callGroupType.equalsIgnoreCase("Valid") + && (callType.equalsIgnoreCase("Valid") || callType.equals("Test Call")); + boolean isInvalidGroup = callGroupType.equalsIgnoreCase("Invalid") + && (callType.equalsIgnoreCase("Wrong Number") || callType.equalsIgnoreCase("Invalid Call")); + + if (isResolved) { + // 1) Any resolved call → complete, no retry isRetryNeeded = false; updateCount = grievanceDataRepo.updateCompletedStatusInCall(true, false, complaintID, userID, beneficiaryRegID); - } - else if (callGroupType.equalsIgnoreCase("Invalid") && (callType.equalsIgnoreCase("Wrong Number") || callType.equalsIgnoreCase("Invalid Call"))) { + + } else if (isValidGroup) { + // 2) Valid but not resolved → leave open, retry allowed + isRetryNeeded = true; + updateCount = grievanceDataRepo.updateCompletedStatusInCall(false, true, complaintID, userID, beneficiaryRegID); + + } else if (isInvalidGroup) { + // 3) Invalid calls → complete, no retry isRetryNeeded = false; - updateCount = grievanceDataRepo.updateCompletedStatusInCall(true, isRetryNeeded, complaintID, userID, - beneficiaryRegID); - }else { + updateCount = grievanceDataRepo.updateCompletedStatusInCall(true, false, complaintID, userID, beneficiaryRegID); + + } else { + // 4) All other cases (e.g. unreachable) → leave open, retry allowed isRetryNeeded = true; - updateCount = grievanceDataRepo.updateCompletedStatusInCall(false, isRetryNeeded, complaintID, - userID, beneficiaryRegID); + updateCount = grievanceDataRepo.updateCompletedStatusInCall(false, true, complaintID, userID, beneficiaryRegID); } - // Check if max attempts (3) are reached + + //Call counter update if (isRetryNeeded && grievanceCallStatus.getCallCounter() < grievanceAllocationRetryConfiguration) { grievanceCallStatus.setCallCounter(grievanceCallStatus.getCallCounter() + 1); - updateCallCounter = grievanceDataRepo.updateCallCounter(grievanceCallStatus.getCallCounter(), - isRetryNeeded, grievanceCallRequest.getComplaintID(), - grievanceCallRequest.getBeneficiaryRegID(), - grievanceCallRequest.getUserID()); - if (updateCallCounter > 0) - response = "Successfully closing call"; - else { - response = "failure in closing call"; - } - } else if (grievanceCallStatus.getCallCounter() == grievanceAllocationRetryConfiguration) { - // Max attempts reached, no further reattempt + updateCallCounter = grievanceDataRepo.updateCallCounter( + grievanceCallStatus.getCallCounter(), true, complaintID, beneficiaryRegID, userID); + response = (updateCallCounter > 0) ? "Successfully closing call" : "failure in closing call"; + + } else if (grievanceCallStatus.getCallCounter() >= grievanceAllocationRetryConfiguration) { + // Max attempts reached → treated as “complete” isRetryNeeded = false; - // isCompleted = true; - updateCount = grievanceDataRepo.updateCompletedStatusInCall(isCompleted, isRetryNeeded, complaintID, - userID, beneficiaryRegID); - response = "max_attempts_reached"; // Indicate that max attempts are reached + updateCount = grievanceDataRepo.updateCompletedStatusInCall(true, false, complaintID, userID, beneficiaryRegID); + response = "max_attempts_reached"; - }else if(updateCount > 0) { + } else if (updateCount > 0) { response = "Successfully closing call"; } From 786e31ec38cbebe9ad9b0a85448380c2176ad544 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 16:32:29 +0530 Subject: [PATCH 050/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 5 +++-- src/main/resources/application.properties | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..39cc4cfd 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -403,8 +403,9 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t header.put("Authorization", auth); } - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); +// String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") +// .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); + String apiUrl ="https://amritdemo.piramalswasthya.org/identity-api/id/create"; logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a26b8bbb..af7947d2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -116,7 +116,6 @@ identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= identity-api-url-getByBenId =IDENTITY_BASE_URL/id/getByBenId?benId= identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= identity-api-url-benCreate =IDENTITY_BASE_URL/id/create -#identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity From ee67c570e3b9c9be7b7e795b3d83d32f7c55f873 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 16:45:08 +0530 Subject: [PATCH 051/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 39cc4cfd..a31c71ab 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -403,9 +403,8 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t header.put("Authorization", auth); } -// String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") -// .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); - String apiUrl ="https://amritdemo.piramalswasthya.org/identity-api/id/create"; + String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); From c935f373ff564934ffc021e45a94a8c71ebb964d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 16:46:06 +0530 Subject: [PATCH 052/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..a6332e92 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -402,7 +402,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); From af2abc7ef32010557d87670035c128e2a016ed75 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 11:40:18 +0530 Subject: [PATCH 053/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a6332e92..6b402866 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -29,6 +29,7 @@ import com.google.gson.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.iemr.common.dto.identity.BeneficiariesDTO; @@ -50,8 +51,12 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); - private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); + @Value("${identity-api-ur}") + private String identityBaseURL; + + @Value("${identity-1097-api-url}") + private String identity1097BaseURL; + private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); From 6c0a72fc11c2347e0e11560884b0bbc9a4b0cd7e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 13:10:32 +0530 Subject: [PATCH 054/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index af7947d2..6c40d0e6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -368,3 +368,17 @@ captcha.enable-captcha=true cors.allowed-origins=http://localhost:* +# DB Connections +spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr +spring.datasource.username= +spring.datasource.password=YesBank@123# + +spring.datasource.driver-class-name=com.mysql.jdbc.Driver + +secondary.datasource.username= +secondary.datasource.password= +secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting +secondary.datasource.driver-class-name=com.mysql.jdbc.Driver + +identity-api-ur= +firebase.enabled=true From e4ea5c3638c4f38e01e0ebfeec3e57e711743f4a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:16:48 +0530 Subject: [PATCH 055/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6c40d0e6..597cfde2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -380,5 +380,4 @@ secondary.datasource.password= secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver -identity-api-ur= firebase.enabled=true From 6cc87492fda1a5982f42b9ad9264c5587c7da142 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:23:14 +0530 Subject: [PATCH 056/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 6b402866..365840bc 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -51,7 +51,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - @Value("${identity-api-ur}") + @Value("${identity-api-url}") private String identityBaseURL; @Value("${identity-1097-api-url}") From b554799b7db8298f4b9111eead5ef802e4287384 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:24:14 +0530 Subject: [PATCH 057/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 365840bc..e1fdfb59 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -53,7 +53,6 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); @Value("${identity-api-url}") private String identityBaseURL; - @Value("${identity-1097-api-url}") private String identity1097BaseURL; From c8a4f05c54da9b147fdc20203afab593ead0a98d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 15:46:31 +0530 Subject: [PATCH 058/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../IdentityBeneficiaryServiceImpl.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index e1fdfb59..09eb8126 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -58,16 +58,13 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; - private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); - private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); - // public IdentityBeneficiaryServiceImpl() - // { - // - //// if (urlRequest == null) - //// { - //// urlRequest = ConfigProperties.getPropertyByName("identity-api-url"); - //// } - // } + @Value("${genben-api}") + private static String BEN_GEN ; + + + @Value("${generateBeneficiaryIDs-api-url}") + private static String BEN_GEN_API_URL ; + @Override // public List getBeneficiaryListByIDs() {// search by regID From ae0971459f0546e57768652fbfcf56c64c2b8994 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:06:29 +0530 Subject: [PATCH 059/318] dynamic from feature --- .../dynamicForm/DynamicFormController.java | 96 ++++++++-- .../data/dynamic_from/FormDefinition.java | 30 +++ .../common/data/dynamic_from/FormEntity.java | 27 --- .../common/data/dynamic_from/FormField.java | 59 ++++++ .../common/data/dynamic_from/FormModule.java | 23 +++ .../data/dynamic_from/ModuleEntity.java | 23 --- .../iemr/common/dto/dynamicForm/FieldDTO.java | 25 +++ .../dto/dynamicForm/FieldResponseDTO.java | 24 +++ .../iemr/common/dto/dynamicForm/FormDTO.java | 10 + .../common/dto/dynamicForm/FormFieldDTO.java | 23 --- .../dto/dynamicForm/FormResponseDTO.java | 13 ++ .../dto/dynamicForm/FormTypeEntityDTO.java | 18 -- .../dynamicForm/GroupedFieldResponseDTO.java | 11 ++ .../common/dto/dynamicForm/ModuleDTO.java | 8 + .../dto/dynamicForm/ModuleEntityDTO.java | 12 -- .../dynamic_form/FieldRepository.java | 12 ++ .../dynamic_form/FormRepository.java | 14 ++ .../dynamic_form/FormTypeRepository.java | 8 - .../dynamic_form/ModuleRepository.java | 4 +- .../dynamicForm/FormMasterService.java | 22 +++ .../dynamicForm/FormMasterServiceImpl.java | 177 ++++++++++++++++++ .../service/dynamicForm/FormTypeService.java | 35 ---- .../service/dynamicForm/ModuleService.java | 26 --- .../exception/GlobalExceptionHandler.java | 36 ++++ .../common/utils/response/ApiResponse.java | 31 +++ 25 files changed, 578 insertions(+), 189 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java delete mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormField.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormModule.java delete mode 100644 src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java delete mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java delete mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java delete mode 100644 src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java create mode 100644 src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/iemr/common/utils/response/ApiResponse.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index f15ad2c0..a67dcadd 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -1,30 +1,96 @@ package com.iemr.common.controller.dynamicForm; -import com.iemr.common.data.dynamic_from.FormEntity; -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; -import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; -import com.iemr.common.service.dynamicForm.FormTypeService; -import com.iemr.common.service.dynamicForm.ModuleService; +import com.iemr.common.dto.dynamicForm.FieldDTO; +import com.iemr.common.dto.dynamicForm.FormDTO; +import com.iemr.common.dto.dynamicForm.ModuleDTO; +import com.iemr.common.service.dynamicForm.FormMasterService; +import com.iemr.common.utils.response.ApiResponse; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -@RequestMapping(value = "masterFrom") +import java.util.List; + +@RequestMapping(value = "dynamicForm",headers = "Authorization") @RestController public class DynamicFormController { - @Autowired ModuleService moduleService; @Autowired - private FormTypeService formTypeService; + private FormMasterService formMasterService; + + @PostMapping(value = "createModule",headers = "Authorization") + public ResponseEntity> createModule(@Valid @RequestBody ModuleDTO moduleDTO) { + try { + Object result = formMasterService.createModule(moduleDTO); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Module created successfully", HttpStatus.OK.value(), result)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error("Invalid module data: " + e.getMessage(), HttpStatus.BAD_REQUEST.value(), null)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create module", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } + + @PostMapping(value = "createForm",headers = "Authorization") + public ResponseEntity> createForm(@Valid @RequestBody FormDTO dto) { + try { + Object result = formMasterService.createForm(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Form created successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create form", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } + + @PostMapping(value = "createFields",headers = "Authorization") + public ResponseEntity> createField(@Valid @RequestBody List dto) { + try { + Object result = formMasterService.createField(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Fields created successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create fields", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } - @PostMapping("/modules") - public ResponseEntity createModule(@RequestBody ModuleEntityDTO module) { - return ResponseEntity.ok(moduleService.save(module)); + @PostMapping(value = "field/update",headers = "Authorization") + public ResponseEntity> updateField(@Valid @RequestBody FieldDTO dto) { + try { + Object result = formMasterService.updateField(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Field updated successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to update field", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } } - @PostMapping("/modules/{moduleId}/form-types") - public ResponseEntity createFormType(@PathVariable Long moduleId, @RequestBody FormTypeEntityDTO formType) { - return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); + @DeleteMapping(value = "delete/{fieldId}/field",headers = "Authorization") + public ResponseEntity> deleteField(@PathVariable Long fieldId) { + try { + formMasterService.deleteField(fieldId); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Field deleted successfully", HttpStatus.OK.value(), null)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to delete field", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } } + @GetMapping(value = "form/{formId}/fields",headers = "Authorization") + public ResponseEntity> getStructuredForm(@PathVariable String formId) { + try { + Object result = formMasterService.getStructuredFormByFormId(formId); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } } diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java b/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java new file mode 100644 index 00000000..9e62b6d9 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java @@ -0,0 +1,30 @@ +package com.iemr.common.data.dynamic_from; +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; +@Entity +@Data +@Table(name = "form_master") +public class FormDefinition { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "form_id") + private String formId; + + @Column(name = "form_name") + private String formName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "module_id") + private FormModule module; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + @Column(name = "version") + private Integer version; + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java deleted file mode 100644 index 578111f5..00000000 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.iemr.common.data.dynamic_from; - -import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.*; -import lombok.Data; - -@Data -@Entity -@Table(name = "form_types",schema = "db_imer") -public class FormEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "Id") - private Long id; - - @Column(name = "form_name",columnDefinition = "TEXT") - private String formName; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "module_id") - private ModuleEntity module; - - @Column(name = "fields",columnDefinition = "TEXT") - private String fields ; - - -} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java new file mode 100644 index 00000000..39785ae9 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java @@ -0,0 +1,59 @@ +package com.iemr.common.data.dynamic_from; +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@Entity +@Data +@Table(name = "form_fields") +public class FormField { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "form_id", referencedColumnName = "form_id") + private FormDefinition form; + + @Column(name = "section_title") + private String sectionTitle; + + @Column(name = "field_id") + private String fieldId; + + @Column(name = "label") + private String label; + + @Column(name = "type") + private String type; + + @Column(name = "is_required") + private Boolean isRequired; + + @Column(name = "is_visible") + private Boolean isVisible; + + @Column(name = "default_value") + private String defaultValue; + + @Column(name = "placeholder") + private String placeholder; + + @Column(name = "options", columnDefinition = "json") + private String options; + + @Column(name = "validation", columnDefinition = "json") + private String validation; // includes error messages now + + @Column(name = "conditional", columnDefinition = "json") + private String conditional; + + @Column(name = "sequence") + private Integer sequence; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java b/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java new file mode 100644 index 00000000..ba5d0170 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java @@ -0,0 +1,23 @@ +package com.iemr.common.data.dynamic_from; + +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@Entity +@Data +@Table(name = "form_module") +public class FormModule { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "module_name") + private String moduleName; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java deleted file mode 100644 index 4d699a7e..00000000 --- a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iemr.common.data.dynamic_from; - -import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.*; -import lombok.Data; - -import java.util.List; -@Data -@Entity -@Table(name = "m_modules",schema = "db_iemr") -public class ModuleEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "Id") - private Long id; - - @Column(name = "module_name",columnDefinition = "TEXT") - private String moduleName; - - @OneToMany(mappedBy = "module", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List formTypes; - -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java new file mode 100644 index 00000000..894f03c2 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java @@ -0,0 +1,25 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FieldDTO { + private Long id; + private String formId; + private String sectionTitle; + private String fieldId; + private String label; + private String type; + private Boolean isVisible; + private Boolean isRequired; + private String defaultValue; + private String placeholder; + private Integer sequence; + private String options; // ⬅️ changed from String to List + private String validation; // ⬅️ changed from String to Map + private String conditional; // ⬅️ changed from String to Map +} + diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java new file mode 100644 index 00000000..3415d91a --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -0,0 +1,24 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FieldResponseDTO { + private Long id; + private String formId; + private String sectionTitle; + private String fieldId; + private String label; + private Boolean visible; + private String type; + private Boolean isRequired; + private String defaultValue; + private String placeholder; + private Integer sequence; + private List options; + private Map validation; + private Map conditional; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java new file mode 100644 index 00000000..24788cac --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java @@ -0,0 +1,10 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +@Data +public class FormDTO { + private String formId; + private String formName; + private Long moduleId; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java deleted file mode 100644 index 27a6ee93..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.List; -import java.util.Map; - -@Data -public class FormFieldDTO { - private String name; - private String label; - private String type; - private boolean required; - private String inputType; - private String fileType; - private String buttonAction; - private String visibleIfField; - private String visibleIfValue; - private Map validations; - private List> options; - - // Getters and Setters -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java new file mode 100644 index 00000000..26563927 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java @@ -0,0 +1,13 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class FormResponseDTO { + private Integer version; + private String formId; + private String formName; + private List sections; +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java deleted file mode 100644 index ff31dfd5..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.List; - -@Data -public class FormTypeEntityDTO { - - private Long id; - - private String formName; - - private ModuleEntityDTO module; - - private List fields; - -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java new file mode 100644 index 00000000..840c5097 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java @@ -0,0 +1,11 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class GroupedFieldResponseDTO { + private String sectionTitle; + private List fields; +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java new file mode 100644 index 00000000..3f4240c4 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java @@ -0,0 +1,8 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +@Data +public class ModuleDTO { + private String moduleName; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java deleted file mode 100644 index 03cfc834..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; -@Data -public class ModuleEntityDTO { - private Long id; - private String moduleName; - -} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java new file mode 100644 index 00000000..4aea5698 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java @@ -0,0 +1,12 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormField; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface FieldRepository extends JpaRepository { + List findByForm_FormIdOrderBySequenceAsc(String formId); +} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java new file mode 100644 index 00000000..50331dd2 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java @@ -0,0 +1,14 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormDefinition; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface FormRepository extends JpaRepository { + Optional findByFormId(String formId); + List findByModule_Id(Long moduleId); +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java deleted file mode 100644 index b3b731fe..00000000 --- a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.iemr.common.repository.dynamic_form; - -import com.iemr.common.data.dynamic_from.FormEntity; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface FormTypeRepository extends CrudRepository {} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java index e4eb221e..bafbfbea 100644 --- a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java +++ b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java @@ -1,10 +1,10 @@ package com.iemr.common.repository.dynamic_form; -import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.data.dynamic_from.FormModule; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository -public interface ModuleRepository extends CrudRepository { +public interface ModuleRepository extends CrudRepository { } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java new file mode 100644 index 00000000..c603cd65 --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java @@ -0,0 +1,22 @@ +package com.iemr.common.service.dynamicForm; + +import com.iemr.common.data.dynamic_from.FormDefinition; +import com.iemr.common.data.dynamic_from.FormField; +import com.iemr.common.data.dynamic_from.FormModule; +import com.iemr.common.dto.dynamicForm.FieldDTO; +import com.iemr.common.dto.dynamicForm.FormDTO; +import com.iemr.common.dto.dynamicForm.FormResponseDTO; +import com.iemr.common.dto.dynamicForm.ModuleDTO; + +import java.util.List; + +public interface FormMasterService { + FormModule createModule(ModuleDTO dto); + FormDefinition createForm(FormDTO dto); + List createField(List dto); + FormField updateField(FieldDTO dto); + + FormResponseDTO getStructuredFormByFormId(String formId); + + void deleteField(Long fieldId); +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java new file mode 100644 index 00000000..893c1c8a --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -0,0 +1,177 @@ +package com.iemr.common.service.dynamicForm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iemr.common.data.dynamic_from.FormDefinition; +import com.iemr.common.data.dynamic_from.FormField; +import com.iemr.common.data.dynamic_from.FormModule; +import com.iemr.common.dto.dynamicForm.*; +import com.iemr.common.repository.dynamic_form.FieldRepository; +import com.iemr.common.repository.dynamic_form.FormRepository; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class FormMasterServiceImpl implements FormMasterService { + + @Autowired + private ModuleRepository moduleRepo; + @Autowired private FormRepository formRepo; + @Autowired private FieldRepository fieldRepo; + + @Override + public FormModule createModule(ModuleDTO dto) { + FormModule module = new FormModule(); + module.setModuleName(dto.getModuleName()); + return moduleRepo.save(module); + } + + @Override + public FormDefinition createForm(FormDTO dto) { + FormModule module = moduleRepo.findById(dto.getModuleId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid module ID")); + + FormDefinition form = new FormDefinition(); + form.setFormId(dto.getFormId()); + form.setFormName(dto.getFormName()); + form.setModule(module); + return formRepo.save(form); + } + + @Override + public List createField(List dtoList) { + List savedFields = new ArrayList<>(); + + for (FieldDTO dto : dtoList) { + FormDefinition form = formRepo.findByFormId(dto.getFormId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + + FormField field = new FormField(); + field.setForm(form); + field.setSectionTitle(dto.getSectionTitle()); + field.setFieldId(dto.getFieldId()); + field.setLabel(dto.getLabel()); + field.setType(dto.getType()); + field.setIsVisible(dto.getIsVisible()); + field.setIsRequired(dto.getIsRequired()); + field.setDefaultValue(dto.getDefaultValue()); + field.setPlaceholder(dto.getPlaceholder()); + field.setOptions(dto.getOptions()); + field.setValidation(dto.getValidation()); + field.setConditional(dto.getConditional()); + field.setSequence(dto.getSequence()); + + savedFields.add(fieldRepo.save(field)); + } + + return savedFields; + } + + @Override + public FormField updateField(FieldDTO dto) { + FormField field = fieldRepo.findById(dto.getId()) + .orElseThrow(() -> new IllegalArgumentException("Field not found: " + dto.getId())); + field.setId(dto.getId()); + field.setSectionTitle(dto.getSectionTitle()); + field.setLabel(dto.getLabel()); + field.setType(dto.getType()); + field.setIsVisible(dto.getIsVisible()); + field.setIsRequired(dto.getIsRequired()); + field.setDefaultValue(dto.getDefaultValue()); + field.setPlaceholder(dto.getPlaceholder()); + field.setSequence(dto.getSequence()); + field.setOptions(dto.getOptions()); + field.setValidation(dto.getValidation()); + field.setConditional(dto.getConditional()); + + + return fieldRepo.save(field); + } + + @Override + public FormResponseDTO getStructuredFormByFormId(String formId) { + FormDefinition form = formRepo.findByFormId(formId) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + ObjectMapper objectMapper = new ObjectMapper(); + + List fieldDtos = fields.stream() + .map(field -> { + FieldResponseDTO dto = new FieldResponseDTO(); + dto.setId(field.getId()); + dto.setVisible(field.getIsVisible()); + dto.setFormId(field.getForm().getFormId()); + dto.setSectionTitle(field.getSectionTitle()); + dto.setFieldId(field.getFieldId()); + dto.setLabel(field.getLabel()); + dto.setType(field.getType()); + dto.setIsRequired(field.getIsRequired()); + dto.setDefaultValue(field.getDefaultValue()); + dto.setPlaceholder(field.getPlaceholder()); + dto.setSequence(field.getSequence()); + + try { + // Handle options + if (field.getOptions() != null && !field.getOptions().isBlank()) { + List options = objectMapper.readValue(field.getOptions(), new TypeReference<>() {}); + dto.setOptions(options.isEmpty() ? null : options); + } else { + dto.setOptions(null); + } + + // Handle validation + if (field.getValidation() != null && !field.getValidation().isBlank()) { + Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() {}); + dto.setValidation(validation.isEmpty() ? null : validation); + } else { + dto.setValidation(null); + } + + // Handle conditional + if (field.getConditional() != null && !field.getConditional().isBlank()) { + Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() {}); + dto.setConditional(conditional.isEmpty() ? null : conditional); + } else { + dto.setConditional(null); + } + } catch (JsonProcessingException e) { + System.err.println("JSON Parsing Error in field: " + field.getFieldId()); + e.printStackTrace(); + throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); + } + + return dto; + }) + .sorted(Comparator.comparing(FieldResponseDTO::getId)) + .collect(Collectors.toList()); + + + GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); + singleSection.setSectionTitle("HBNC Form Fields"); // your custom section title + singleSection.setFields(fieldDtos); + + FormResponseDTO response = new FormResponseDTO(); + response.setVersion(form.getVersion()); + response.setFormId(form.getFormId()); + response.setFormName(form.getFormName()); + response.setSections(List.of(singleSection)); + + return response; + } + + + @Override + public void deleteField(Long fieldId) { + fieldRepo.deleteById(fieldId); + } + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java deleted file mode 100644 index 38068cdc..00000000 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.iemr.common.service.dynamicForm; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.iemr.common.data.dynamic_from.FormEntity; -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; -import com.iemr.common.repository.dynamic_form.FormTypeRepository; -import com.iemr.common.repository.dynamic_form.ModuleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class FormTypeService { - @Autowired - ModuleRepository moduleRepo; - @Autowired - FormTypeRepository formTypeRepo; - @Autowired - ObjectMapper objectMapper; - - public FormEntity createFormType(Long moduleId, FormTypeEntityDTO formTypeDTO) { - ModuleEntity module = moduleRepo.findById(moduleId).orElseThrow(); - FormEntity formType = new FormEntity(); - formType.setFormName(formTypeDTO.getFormName()); - formType.setModule(module); - try { - String fieldsJson = objectMapper.writeValueAsString(formTypeDTO.getFields()); - formType.setFields(fieldsJson); - } catch (JsonProcessingException e) { - throw new RuntimeException("Failed to serialize form fields", e); - } - return formTypeRepo.save(formType); - } -} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java deleted file mode 100644 index 644d2c59..00000000 --- a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.iemr.common.service.dynamicForm; - -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; -import com.iemr.common.repository.dynamic_form.ModuleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Optional; - -@Service -public class ModuleService { - @Autowired - ModuleRepository repo; - - public ModuleEntity save(ModuleEntityDTO module) { - ModuleEntity moduleEntity = new ModuleEntity(); - moduleEntity.setModuleName(module.getModuleName()); - return repo.save(moduleEntity); - } - - public Optional findById(Long id) { - return repo.findById(id); - } -} - diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java new file mode 100644 index 00000000..90a06c79 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -0,0 +1,36 @@ +package com.iemr.common.utils.exception; + +import com.iemr.common.utils.response.ApiResponse; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.stream.Collectors; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleException(Exception ex) { + ex.printStackTrace(); // Log for debugging + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(),null)); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationException(MethodArgumentNotValidException ex) { + String errorMessage = ex.getBindingResult().getFieldErrors().stream() + .map(error -> error.getField() + ": " + error.getDefaultMessage()) + .collect(Collectors.joining(", ")); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error("Validation Error: " + errorMessage, HttpStatus.BAD_REQUEST.value(),null)); + } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgException(IllegalArgumentException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error(ex.getMessage(), HttpStatus.BAD_REQUEST.value(),null)); + } +} diff --git a/src/main/java/com/iemr/common/utils/response/ApiResponse.java b/src/main/java/com/iemr/common/utils/response/ApiResponse.java new file mode 100644 index 00000000..928a2a25 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/response/ApiResponse.java @@ -0,0 +1,31 @@ +package com.iemr.common.utils.response; + +import lombok.Data; + +@Data +public class ApiResponse { + private boolean success; + private String message; + private Integer statusCode; + + private T data; + + public ApiResponse() {} + + public ApiResponse(boolean success, String message, Integer statusCode,T data) { + this.success = success; + this.message = message; + this.data = data; + this.statusCode = statusCode; + } + + public static ApiResponse success(String message,Integer statusCode, T data) { + return new ApiResponse<>(true, message,statusCode, data); + } + + public static ApiResponse error(String message,Integer statusCode, T data) { + return new ApiResponse<>(false, message, statusCode,data); + } + + // getters and setters +} From 515f27ca449df8d8ec1a7256ac95c97b9bcde9d7 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:25:10 +0530 Subject: [PATCH 060/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index a67dcadd..065cdb14 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,4 +93,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } + } From 27cf841f7216d0b3efb7de7dbacb13642578f3ae Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:25:25 +0530 Subject: [PATCH 061/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 065cdb14..a67dcadd 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,5 +93,4 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } - } From 0e7b33b0e08c535cd7a90cded578b1dd6eaf04ed Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:26:35 +0530 Subject: [PATCH 062/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index a67dcadd..065cdb14 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,4 +93,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } + } From a72334e3076550b72b234303f1912f81fce572bd Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:13:37 +0530 Subject: [PATCH 063/318] Update BeneficiaryOTPHandlerImpl.java --- .../BeneficiaryOTPHandlerImpl.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 17027667..47dbed68 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -39,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -67,8 +68,21 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Autowired SMSTypeRepository smsTypeRepository; + @Value("${sms-username}") + private String smsUserName; + + @Value("${sms-password}") + private String smsPassword; + + @Value("${sms-entityid}") + private String smsEntityId; + + @Value("${source-address}") + private String smsSourceAddress; + @Value("${send-message-url}") + private String SMS_GATEWAY_URL; + private static final Integer EXPIRE_MIN = 5; - private static final String SMS_GATEWAY_URL = ConfigProperties.getPropertyByName("sms-gateway-url"); // Constructor for new object creation public BeneficiaryOTPHandlerImpl() { @@ -163,32 +177,34 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); - String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL; + String sendSMSAPI = SMS_GATEWAY_URL; + logger.info("sms template"+template); try { - String message = template.getSmsTemplate() - .replace("$$OTP$$",String.valueOf(otp)) - .replace("$$UserName$$", obj.getUserName()) - .replace("$$Designation$$", obj.getDesignation()); + String message = "Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha ,Asha to complete the process. PSMRI"; +// String message = template.getSmsTemplate() +// .replace("$$OTP$$",String.valueOf(otp)) +// .replace("$$UserName$$", obj.getUserName()) +// .replace("$$Designation$$", obj.getDesignation()); // Build payload Map payload = new HashMap<>(); - payload.put("customerId", ConfigProperties.getPropertyByName("sms-username")); + payload.put("customerId",smsUserName); payload.put("destinationAddress", obj.getMobNo()); payload.put("message", message); - payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); + payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); payload.put("dltTemplateId", dltTemplateId); - payload.put("entityId",ConfigProperties.getPropertyByName("sms-entityid") ); + payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers HttpHeaders headers = new HttpHeaders(); - String auth = ConfigProperties.getPropertyByName("sms-username") + ":" + ConfigProperties.getPropertyByName("sms-password"); + String auth = smsUserName + ":" + smsPassword; headers.add("Authorization", "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); headers.setContentType(MediaType.APPLICATION_JSON); - + logger.info("payload: "+payload); HttpEntity> request = new HttpEntity<>(payload, headers); // Call API From 680a73219172d694a9a9b0e1c871b6a58d9ea2ef Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:21:52 +0530 Subject: [PATCH 064/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 47dbed68..b4d3cf18 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -181,7 +181,7 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { logger.info("sms template"+template); try { - String message = "Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha ,Asha to complete the process. PSMRI"; + String message ="Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha to complete the process. Regards PSMRI"; // String message = template.getSmsTemplate() // .replace("$$OTP$$",String.valueOf(otp)) // .replace("$$UserName$$", obj.getUserName()) From ad1965634e4f484b485325ce36866e2984be222d Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:31:11 +0530 Subject: [PATCH 065/318] Update application.properties --- src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 597cfde2..644994e1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -370,8 +370,8 @@ cors.allowed-origins=http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr -spring.datasource.username= -spring.datasource.password=YesBank@123# +spring.datasource.username= +spring.datasource.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver From 61717553351c6ed0bb15c702158d1b1ef41aa7b8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:32:40 +0530 Subject: [PATCH 066/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index b4d3cf18..a21d066a 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -194,7 +194,7 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", dltTemplateId); + payload.put("dltTemplateId", "1007730329175402034"); payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers From 0be53edc55959a91b09a2fb154da94056b1058dc Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 21:56:17 +0530 Subject: [PATCH 067/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index a21d066a..ef83e448 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -71,14 +71,14 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword; + // @Value("${sms-password}") + private String smsPassword ="]Kt9GAp8}$S*@"; @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") - private String smsSourceAddress; + // @Value("${source-address}") + private String smsSourceAddress = "PSMRAM"; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 8e186e6522cc4c5001506fb6d1cf6ad0e920b6ab Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:03:09 +0530 Subject: [PATCH 068/318] Update JwtUserIdValidationFilter.java --- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 27fbf771..c296f387 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -155,12 +155,15 @@ private boolean isMobileClient(String userAgent) { } private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") + return path.equals(contextPath + "/user/userAuthenticate") || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") || path.startsWith(contextPath + "/user/userAuthenticateV1") || path.startsWith(contextPath + "/user/forgetPassword") || path.startsWith(contextPath + "/user/setForgetPassword") From 121c33fe070665a91182f0290807508d7b1a808a Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 4 Aug 2025 16:51:31 +0530 Subject: [PATCH 069/318] Update CommonIdentityMapperDecorator.java --- .../mapper/CommonIdentityMapperDecorator.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java b/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java index 5e8034af..1480f306 100644 --- a/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java +++ b/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java @@ -168,8 +168,17 @@ public CommonIdentityDTO beneficiaryModelCommonIdentityDTO(BeneficiaryModel bene Short maritalStatusID = beneficiary.getMaritalStatusID(); if (maritalStatusID != null) { commonIdentityDTO.setMaritalStatusId(maritalStatusID.intValue()); - commonIdentityDTO.setMaritalStatus( - maritalStatusMapper.maritalStatusByIDToResponse(maritalStatusID.intValue()).getStatus()); + var model = maritalStatusMapper.maritalStatusByIDToResponse(maritalStatusID.intValue()); + if (model != null) { + commonIdentityDTO.setMaritalStatus(model.getStatus()); + } else { + // Option 1: Return null + commonIdentityDTO.setMaritalStatus(null); + // Option 2: Or set a default + // commonIdentityDTO.setMaritalStatus("Unknown"); + // Option 3: Or log a warning + // logger.warn("Invalid maritalStatusID: {}", maritalStatusID); + } } commonIdentityDTO.setMaritalStatus(beneficiary.getMaritalStatusName()); commonIdentityDTO.setGender(beneficiary.getGenderName()); From f8d543e1fb9111b207cf59579028ac25b8427255 Mon Sep 17 00:00:00 2001 From: ravishanigarapu <133210792+ravishanigarapu@users.noreply.github.com> Date: Thu, 7 Aug 2025 10:30:30 +0530 Subject: [PATCH 070/318] Added Jwttoken as header while calling Identity-API (#274) * removed issanjeevani variable * Jwttoken added in Header for Identity-API calls * Coderabbit comments addressed --- .../iemr/common/utils/RestTemplateUtil.java | 84 +++++++++++++------ .../com/iemr/common/utils/http/HttpUtils.java | 35 +++----- 2 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java index 447ba80f..c8299fe7 100644 --- a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java +++ b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java @@ -10,14 +10,17 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import com.iemr.common.constant.Constants; + import jakarta.servlet.http.HttpServletRequest; public class RestTemplateUtil { private final static Logger logger = LoggerFactory.getLogger(RestTemplateUtil.class); - + public static HttpEntity createRequestEntity(Object body, String authorization) { - - ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()); + + ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder + .getRequestAttributes()); if (servletRequestAttributes == null) { MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8"); @@ -25,29 +28,58 @@ public static HttpEntity createRequestEntity(Object body, String authori return new HttpEntity<>(body, headers); } HttpServletRequest requestHeader = servletRequestAttributes.getRequest(); - String jwtTokenFromCookie = null; + + String jwtTokenFromCookie = extractJwttoken(requestHeader); + + MultiValueMap headers = new LinkedMultiValueMap<>(); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8"); + if (null != UserAgentContext.getUserAgent()) { + headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent()); + } + headers.add(HttpHeaders.AUTHORIZATION, authorization); + if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { + headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + } + if (null != jwtTokenFromCookie) { + headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie); + } + + return new HttpEntity<>(body, headers); + } + + private static String extractJwttoken(HttpServletRequest requestHeader) { + String jwtTokenFromCookie = null; try { jwtTokenFromCookie = CookieUtil.getJwtTokenFromCookie(requestHeader); - + } catch (Exception e) { - logger.error("Error while getting jwtToken from Cookie" + e.getMessage() ); - } - - MultiValueMap headers = new LinkedMultiValueMap<>(); - headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8"); - if(null != UserAgentContext.getUserAgent()) { - logger.info("Common-API getting User-Agent as : "+UserAgentContext.getUserAgent()); - headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent()); - } - headers.add(HttpHeaders.AUTHORIZATION, authorization); - if(null != requestHeader.getHeader("JwtToken")) { - headers.add("JwtToken",requestHeader.getHeader("JwtToken")); - } - if(null != jwtTokenFromCookie) { - headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie); - } - - return new HttpEntity<>(body, headers); - } - -} \ No newline at end of file + logger.error("Error while getting jwtToken from Cookie" + e.getMessage()); + } + return jwtTokenFromCookie; + } + + public static void getJwttokenFromHeaders(HttpHeaders headers) { + ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder + .getRequestAttributes()); + if (servletRequestAttributes == null) { + return; + } + HttpServletRequest requestHeader = servletRequestAttributes.getRequest(); + String jwtTokenFromCookie = extractJwttoken(requestHeader); + if (!headers.containsKey(HttpHeaders.CONTENT_TYPE)) { + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8"); + } + if (null != UserAgentContext.getUserAgent()) { + if (!headers.containsKey(HttpHeaders.USER_AGENT)) { + headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent()); + } + } + if (null != jwtTokenFromCookie) { + headers.add(HttpHeaders.COOKIE, Constants.JWT_TOKEN + "=" + jwtTokenFromCookie); + } else if (null != requestHeader.getHeader(Constants.JWT_TOKEN)) { + headers.add(Constants.JWT_TOKEN, requestHeader.getHeader(Constants.JWT_TOKEN)); + } + + } + +} diff --git a/src/main/java/com/iemr/common/utils/http/HttpUtils.java b/src/main/java/com/iemr/common/utils/http/HttpUtils.java index 0f308619..4f49e662 100644 --- a/src/main/java/com/iemr/common/utils/http/HttpUtils.java +++ b/src/main/java/com/iemr/common/utils/http/HttpUtils.java @@ -40,6 +40,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; +import com.iemr.common.utils.RestTemplateUtil; import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataMultiPart; @@ -54,9 +55,6 @@ public class HttpUtils { // @Autowired private HttpStatus status; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - // @Autowired(required = true) - // @Qualifier("hibernateCriteriaBuilder") public HttpUtils() { if (rest == null) { rest = new RestTemplate(); @@ -64,33 +62,22 @@ public HttpUtils() { headers.add("Content-Type", "application/json"); } } - // public HttpUtils() { - // if (rest == null) { - // rest = new RestTemplate(); - // headers = new HttpHeaders(); - // headers.add("Content-Type", "application/json"); - // } - // } - - // @Bean - // public HttpUtils httpUtils() { - // return new HttpUtils(); - // } - + public String get(String uri) { String body; - HttpEntity requestEntity = new HttpEntity("", headers); + HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.add("Content-Type", "application/json"); + RestTemplateUtil.getJwttokenFromHeaders(requestHeaders); + HttpEntity requestEntity = new HttpEntity("", requestHeaders); ResponseEntity responseEntity = rest.exchange(uri, HttpMethod.GET, requestEntity, String.class); setStatus((HttpStatus) responseEntity.getStatusCode()); - // if (status == HttpStatus.OK){ body = responseEntity.getBody(); - // }else{ - // responseEntity - // } + return body; } public ResponseEntity getV1(String uri) throws URISyntaxException, MalformedURLException { + RestTemplateUtil.getJwttokenFromHeaders(headers); HttpEntity requestEntity = new HttpEntity("", headers); ResponseEntity responseEntity = rest.exchange(uri, HttpMethod.GET, requestEntity, String.class); return responseEntity; @@ -107,6 +94,7 @@ public String get(String uri, HashMap header) { } else { headers.add("Content-Type", MediaType.APPLICATION_JSON); } + RestTemplateUtil.getJwttokenFromHeaders(headers); HttpEntity requestEntity = new HttpEntity("", headers); ResponseEntity responseEntity = rest.exchange(uri, HttpMethod.GET, requestEntity, String.class); setStatus((HttpStatus) responseEntity.getStatusCode()); @@ -116,6 +104,7 @@ public String get(String uri, HashMap header) { public String post(String uri, String json) { String body; + RestTemplateUtil.getJwttokenFromHeaders(headers); HttpEntity requestEntity = new HttpEntity(json, headers); ResponseEntity responseEntity = rest.exchange(uri, HttpMethod.POST, requestEntity, String.class); setStatus((HttpStatus) responseEntity.getStatusCode()); @@ -129,9 +118,7 @@ public String post(String uri, String data, HashMap header) { if (header.containsKey(headers.AUTHORIZATION)) { headers.add(headers.AUTHORIZATION, header.get(headers.AUTHORIZATION).toString()); } - - // headers.add("Content-Type", MediaType.APPLICATION_JSON); - + RestTemplateUtil.getJwttokenFromHeaders(headers); headers.add("Content-Type", MediaType.APPLICATION_JSON + ";charset=utf-8"); ResponseEntity responseEntity = new ResponseEntity(HttpStatus.BAD_REQUEST); HttpEntity requestEntity; From 2dfb40d8e03799bedb40126b7d8d1a6dc5f0e5a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:47:15 +0530 Subject: [PATCH 071/318] Update JwtUserIdValidationFilter.java --- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index c296f387..671df832 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -161,9 +161,10 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/firebaseNotification/sendNotification") || path.startsWith(contextPath + "/user/userAuthenticateV1") || path.startsWith(contextPath + "/user/forgetPassword") || path.startsWith(contextPath + "/user/setForgetPassword") From 6f86bb7bdaa046a2ef55e53ef35b511ca88bd2b0 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:48:04 +0530 Subject: [PATCH 072/318] Update FirebaseNotificationController.java --- .../firebaseNotification/FirebaseNotificationController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 89fb01a9..1fe15720 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification",headers = "Authorization") +@RequestMapping(value= "/firebaseNotification") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From 75633a07198a7b164945f0b9bbc1ab72353520a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:03:40 +0530 Subject: [PATCH 073/318] Update FirebaseNotificationService.java --- .../firebaseNotification/FirebaseNotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index ea0cc005..7c76c9ee 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -67,7 +67,7 @@ public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); - Message message = Message.builder().setToken(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + Message message = Message.builder().setTopic(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); try { From d29eccbfa8dbb105cac9650686d1fd8cff9cb325 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:15:55 +0530 Subject: [PATCH 074/318] Update BeneficiaryConsentController.java --- .../beneficiaryConsent/BeneficiaryConsentController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index e917204c..77492d89 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -@RequestMapping(value = { "/beneficiaryConsent" },headers ="Authorization" ) +@RequestMapping(value = { "/beneficiaryConsent" }) @RestController public class BeneficiaryConsentController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @@ -46,7 +46,7 @@ public class BeneficiaryConsentController { private BeneficiaryOTPHandler beneficiaryOTPHandler; @Operation(summary = "Send Consent") - @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { OutputResponse response = new OutputResponse(); @@ -66,7 +66,7 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody } @Operation(summary = "Validate Consent") - @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"Integer\"}") @RequestBody String requestOBJ) { OutputResponse response = new OutputResponse(); @@ -88,7 +88,7 @@ public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"In } @Operation(summary = "Resend Consent") - @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { logger.info(requestOBJ.toString()); From 08450e6a7340ec0d66312f29e48f3cf2bc75bf84 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 12:10:23 +0530 Subject: [PATCH 075/318] welcome sms --- .../RegisterBenificiaryServiceImpl.java | 23 +++++- .../BeneficiaryCallServiceImpl.java | 7 +- .../WelcomeBenificarySmsService.java | 9 +++ .../WelcomeBenificarySmsServiceImpl.java | 79 +++++++++++++++++++ 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsService.java create mode 100644 src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 9e8dcb0d..bffda4c0 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -30,6 +30,8 @@ import java.util.ArrayList; import java.util.List; +import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService; +import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsServiceImpl; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,6 +75,9 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired IdentityBenEditMapper identityBenEditMapper; + @Autowired + private WelcomeBenificarySmsService welcomeBenificarySmsService; + @Autowired Validator validator; @@ -167,16 +172,25 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet logger.info("benificiaryDetails: " + beneficiaryModel); CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); + setSaveDemographicDetails(identityDTO,beneficiaryModel); - // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); +// identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); + identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); + identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); + identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); + identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); + identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); + identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); + + identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); - identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO .setBenFamilyDTOs(identityMapper.benPhoneMapListToBenFamilyDTOList(beneficiaryModel.getBenPhoneMaps())); String request = new Gson().toJson(identityDTO); + if (beneficiaryModel.getIs1097() == null) beneficiaryModel.setIs1097(false); @@ -196,10 +210,15 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } + if(identityDTO.getContact().getEmergencyContactNum()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(identityDTO.getContact().getEmergencyContactNum(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + } } return OutputMapper.gson().toJson(beneficiary); } + + private void setSaveDemographicDetails(CommonIdentityDTO identityDTO, BeneficiaryModel beneficiaryModel) { if(null != beneficiaryModel.getI_bendemographics()) { identityDTO.setCommunity(beneficiaryModel.getI_bendemographics().getCommunityName()); diff --git a/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java b/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java index 1a9474ff..c28d41cb 100644 --- a/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java +++ b/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java @@ -1684,8 +1684,11 @@ public List getBeneficiaryListFromMapper(List payload = new HashMap<>(); + payload.put("customerId",smsUserName); + payload.put("destinationAddress", contactNo); + payload.put("message", message); + payload.put("sourceAddress", smsSourceAddress); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", dltTemplateId); + payload.put("entityId",smsEntityId ); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = smsUserName + ":" + smsPassword; + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + + headers.setContentType(MediaType.APPLICATION_JSON); + logger.info("payload: "+payload); + HttpEntity> request = new HttpEntity<>(payload, headers); + + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + logger.info("sms-response:"+response.getBody()); + if(response.getStatusCode().value()==200){ + return "OTP sent successfully on register mobile number"; + }else { + return "Fail"; + + } + + } catch (Exception e) { + return "Error sending SMS: " + e.getMessage().toString(); + } + + } +} From d13e32a1366430b4b8d64cc08402e2493d5e8f8f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:02:31 +0530 Subject: [PATCH 076/318] fix issue --- .../beneficiary/RegisterBenificiaryServiceImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index bffda4c0..e76be425 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -176,12 +176,12 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); - identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); - identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); - identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); - identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); - identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); - identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); +// identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); +// identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); +// identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); +// identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); +// identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); +// identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); From 32c5f68c2f8c34149827aed4ab30c0d11bae9647 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:18:21 +0530 Subject: [PATCH 077/318] fix issue --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 644994e1..208c3c33 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,3 +381,4 @@ secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true +START_GRIEVANCEDATASYNC_SCHEDULER = \ No newline at end of file From 61f16263525039aa7a6466a5a48a9e30dd9b72ef Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 13 Aug 2025 14:25:55 +0530 Subject: [PATCH 078/318] Update application.properties --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 208c3c33..644994e1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,4 +381,3 @@ secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true -START_GRIEVANCEDATASYNC_SCHEDULER = \ No newline at end of file From c1b6e83690488c8cf36bb703c2d122d68dd6d74e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:45:33 +0530 Subject: [PATCH 079/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 208c3c33..888c7836 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,4 +381,4 @@ secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true -START_GRIEVANCEDATASYNC_SCHEDULER = \ No newline at end of file +video-call-url = From 160071bb27c3686e77cc3e51598fd760c14f2dd3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:52:44 +0530 Subject: [PATCH 080/318] fix issue --- .../common/config/quartz/ScheduleForGrievanceDataSync.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index f016de3d..e64f604f 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag; + //@Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag = true; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From 33e0f69986bc9a1c5c4a137711ea58bbfa3880f0 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:01:15 +0530 Subject: [PATCH 081/318] fix issue --- .../controller/nhmdashboard/NHMDetailCallReportScheduler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 5fd3e281..3ce4b913 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag; +// @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag = true; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") From cb7bdd70f85d8a6da04055ddcc5a384daca194eb Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:23:09 +0530 Subject: [PATCH 082/318] fix issue --- .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index e76be425..dbba5ac3 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -210,8 +210,8 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } - if(identityDTO.getContact().getEmergencyContactNum()!=null){ - welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(identityDTO.getContact().getEmergencyContactNum(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + if(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); } } return OutputMapper.gson().toJson(beneficiary); From 2ed19b052e61c0405ae79c3c2e297089ee07735f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:24:07 +0530 Subject: [PATCH 083/318] fix issue --- .../beneficiary/RegisterBenificiaryServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index dbba5ac3..7d87a9fb 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -210,9 +210,12 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } - if(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo()!=null){ - welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + if(beneficiary!=null){ + if(beneficiary.getBenPhoneMaps().get(0).getPhoneNo()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiary.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + } } + } return OutputMapper.gson().toJson(beneficiary); } From 1ad9c81d9b0bf84be69fb90548f5a5c7b6232eef Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 16:43:53 +0530 Subject: [PATCH 084/318] fix issue --- .../service/welcomeSms/WelcomeBenificarySmsServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 8bc8da51..9a4e9602 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -26,8 +26,8 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") - private String smsSourceAddress; +// @Value("${source-address}") + private String smsSourceAddress ="PSMRAM"; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 8f5a94756a5ace7d2bfcc25f2e27610c40413872 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 18 Aug 2025 16:07:53 +0530 Subject: [PATCH 085/318] Update JwtUserIdValidationFilter.java --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 671df832..ebc73ff0 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -160,6 +160,7 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") + || path.startsWith(contextPath + "/beneficiary/create") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") From 357f28f020be7dfc64c67483b991039491297f79 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:20:28 +0530 Subject: [PATCH 086/318] Update WelcomeBenificarySmsServiceImpl.java --- .../service/welcomeSms/WelcomeBenificarySmsServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 9a4e9602..50e2353f 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -20,8 +20,8 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword; + // @Value("${sms-password}") + private String smsPassword = "]Kt9GAp8}$S*@"; @Value("${sms-entityid}") private String smsEntityId; From 0f7628dd287012d06ab3e7fcb1acdc4828ac3ec3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:07:07 +0530 Subject: [PATCH 087/318] Update application.properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 888c7836..dc3ae9d1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -364,7 +364,7 @@ logging.file.name=logs/common-api.log captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify -captcha.enable-captcha=true +captcha.enable-captcha=false cors.allowed-origins=http://localhost:* From 997bee34ac9a233fc90497d777ba9144e00614cb Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:20:01 +0530 Subject: [PATCH 088/318] Update IEMRAdminController.java --- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index e1b20d66..ed3760bc 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - @Value("${captcha.enable-captcha}") - private boolean enableCaptcha; + // @Value("${captcha.enable-captcha}") + private boolean enableCaptcha = false; @Autowired private CaptchaValidationService captchaValidatorService; From 7d80955ef6d128d451e59a150366d13770764571 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 14:51:28 +0530 Subject: [PATCH 089/318] fix issue --- .../utils/JwtUserIdValidationFilter.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 671df832..e759ed85 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -154,26 +154,27 @@ private boolean isMobileClient(String userAgent) { return userAgent.contains("okhttp"); // iOS (custom clients) } - private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") - || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") - || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") - || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") - || path.startsWith(contextPath + "/user/superUserAuthenticate") - || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") - || path.startsWith(contextPath + "/firebaseNotification/sendNotification") - || path.startsWith(contextPath + "/user/userAuthenticateV1") - || path.startsWith(contextPath + "/user/forgetPassword") - || path.startsWith(contextPath + "/user/setForgetPassword") - || path.startsWith(contextPath + "/user/changePassword") - || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") - || path.startsWith(contextPath + "/user/userLogout") - || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") - || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); - } + private boolean shouldSkipAuthentication(String path, String contextPath) { + return path.equals(contextPath + "/user/userAuthenticate") + || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") + || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") + || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") + || path.startsWith(contextPath + "/user/superUserAuthenticate") + || path.startsWith(contextPath + "/user/user/userAuthenticateNew") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/dynamicForm") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/firebaseNotification/sendNotification") + || path.startsWith(contextPath + "/user/userAuthenticateV1") + || path.startsWith(contextPath + "/user/forgetPassword") + || path.startsWith(contextPath + "/user/setForgetPassword") + || path.startsWith(contextPath + "/user/changePassword") + || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") + || path.startsWith(contextPath + "/user/userLogout") + || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") + || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + } private String getJwtTokenFromCookies(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); From 6d40fd07218f9361a2b4d553d156e69e3c8b400e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 14:52:51 +0530 Subject: [PATCH 090/318] fix issue --- .../utils/JwtUserIdValidationFilter.java | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index b20d9b21..b5c4a7f9 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -164,6 +164,7 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") || path.startsWith(contextPath + "/dynamicForm") + || path.startsWith(contextPath + "/beneficiary/create") || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") || path.startsWith(contextPath + "/firebaseNotification/sendNotification") || path.startsWith(contextPath + "/user/userAuthenticateV1") @@ -175,27 +176,7 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); } - private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") - || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") - || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") - || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") - || path.startsWith(contextPath + "/user/superUserAuthenticate") - || path.startsWith(contextPath + "/beneficiary/create") - || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") - || path.startsWith(contextPath + "/firebaseNotification/sendNotification") - || path.startsWith(contextPath + "/user/userAuthenticateV1") - || path.startsWith(contextPath + "/user/forgetPassword") - || path.startsWith(contextPath + "/user/setForgetPassword") - || path.startsWith(contextPath + "/user/changePassword") - || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") - || path.startsWith(contextPath + "/user/userLogout") - || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") - || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); - } + private String getJwtTokenFromCookies(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); From bf151099783dbee7b4717ec18a51e213cca38357 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 14:59:51 +0530 Subject: [PATCH 091/318] fix issue --- .../common/controller/dynamicForm/DynamicFormController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index d1d14735..ffd86660 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -82,7 +82,7 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } } - @GetMapping(value = "form/{formId}/fields",headers = "Authorization") + @GetMapping(value = "form/{formId}/fields") public ResponseEntity> getStructuredForm(@PathVariable String formId) { try { Object result = formMasterService.getStructuredFormByFormId(formId); From 32a2b4fdb2fec2605aacd40beff245a5ca7f19d8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 15:00:48 +0530 Subject: [PATCH 092/318] fix issue --- .../common/controller/dynamicForm/DynamicFormController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index ffd86660..a5f72bbf 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -13,7 +13,7 @@ import java.util.List; -@RequestMapping(value = "dynamicForm",headers = "Authorization") +@RequestMapping(value = "dynamicForm") @RestController public class DynamicFormController { @Autowired From f8a16f43770e0779439f07d2d3910574bdc8f0e8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 16:20:38 +0530 Subject: [PATCH 093/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index dc3ae9d1..7544a6ea 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://localhost:* +cors.allowed-origins=http://localhost:*,http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From d8881d4023e329f88a180669eada43c203eb42cf Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 17:57:44 +0530 Subject: [PATCH 094/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 7544a6ea..bcdab642 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://localhost:*,http://devbox.bizbrolly.com:4901 +cors.allowed-origins=http://devbox.bizbrolly.com:4901:*,http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From fb1f504f8c512f538fd2bbb475884002ea3aa189 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 18:09:13 +0530 Subject: [PATCH 095/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index bcdab642..df59362f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:4901:*,http://localhost:* +cors.allowed-origins=http://devbox.bizbrolly.com:*,http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 27eac5b2f4fed2592f019cbfe6ea574cefcd190e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 18:38:25 +0530 Subject: [PATCH 096/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index df59362f..308d67cf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:*,http://localhost:* +cors.allowed-origins=http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 7eb4e5ddbe7c74bae850bf74a233f723e527d952 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 19:00:37 +0530 Subject: [PATCH 097/318] fix issue --- .../iemr/common/utils/http/HTTPRequestInterceptor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 23b0af62..be8d564c 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -38,6 +38,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + +import java.util.Arrays; +import java.util.List; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { @@ -125,18 +129,22 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons break; } } catch (Exception e) { + String origin = request.getHeader("Origin"); + OutputResponse output = new OutputResponse(); output.setError(e); response.getOutputStream().print(output.toString()); response.setContentType(MediaType.APPLICATION_JSON); response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Origin", "http://devbox.bizbrolly.com:4901"); status = false; } } return status; } + + @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) throws Exception { From c2e67a71234cfbc6760e7ee8cc64b2ffbfaee5e8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 19:07:30 +0530 Subject: [PATCH 098/318] fix issue --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- src/main/resources/application.properties | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 2e226b79..84f5e865 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Override diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 9f6efb13..379eb180 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Bean diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 308d67cf..5c522ef9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,8 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:4901 +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From ae01abc3bd5d1758b33f31679e2caf1a050a02c8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 21:43:27 +0530 Subject: [PATCH 099/318] fix issue --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index b5c4a7f9..f2ebbfdd 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -163,6 +163,8 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/user/userAuthenticateNew") || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/bulkRegistration") + || path.startsWith(contextPath + "/download-error-sheet") || path.startsWith(contextPath + "/dynamicForm") || path.startsWith(contextPath + "/beneficiary/create") || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") From ee87acba7a8d0dcd789e345e5f839db00320f4af Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 15:34:50 +0530 Subject: [PATCH 100/318] changed the pom correction --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ab4de84..3a0191c9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.4.0 + 3.6.0 war Common-API From 7d3008614069706b7dd1cb3276a0daebde012180 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 17:51:15 +0530 Subject: [PATCH 101/318] fix: allowed file format for upload --- .../KMFileManagerServiceImpl.java | 114 ++++++++++++------ src/main/resources/application.properties | 4 + 2 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java index 7a24c6da..1446787d 100644 --- a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java +++ b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java @@ -34,12 +34,14 @@ import java.util.Objects; import java.util.Set; +import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; @@ -84,6 +86,9 @@ public void setSubCategoryRepository(SubCategoryRepository subCategoryRepository private InputMapper inputMapper = new InputMapper(); + @Value("${allowed.file.extensions}") + private String allowedFileExtensions; + @Override public String getKMFileLists(String request) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); @@ -131,43 +136,78 @@ private ArrayList addKMFile(Iterable kmFileManager ArrayList savedFileManagers = new ArrayList(); FileOutputStream newFile = null; FileInputStream fis = null; - try - { - for (KMFileManager kmFileManager : kmFileManagers) { - if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null - && kmFileManager.getFileContent() != null) { - kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "").replace("$", "") - .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") - .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") - .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") - .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") - .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") - .replace("=", "").replace("\"", "").replace("'", "")); - String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); - newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); - newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); - newFile.flush(); - newFile.close(); - fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); - String checksum = DigestUtils.md5DigestAsHex(fis); - fis.close(); - logger.info("File is " + kmFileManager.getFileName()); - logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); - logger.info("File checksum is " + checksum); - logger.info("File checksum length is " + checksum.length()); - kmFileManager.setFileCheckSum(checksum); - kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); - String version = getFileVersion(kmFileManager); - kmFileManager.setVersionNo(version); - String documentPath = kmFileManager.getProviderServiceMapID() + "/"; - if (kmFileManager.getCategoryID() != null) { - documentPath += kmFileManager.getCategoryID() + "/"; - } - if (kmFileManager.getSubCategoryID() != null) { - documentPath += kmFileManager.getSubCategoryID() + "/"; - } - if (kmFileManager.getVanID() != null) - documentPath += kmFileManager.getVanID() + "/"; + try { + for (KMFileManager kmFileManager : kmFileManagers) { + if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null + && kmFileManager.getFileContent() != null) { + + if (allowedFileExtensions == null || allowedFileExtensions.trim().isEmpty()) { + throw new IllegalStateException( + "Environment variable 'allowed.file.extensions' is not configured or is empty"); + } + List allowedExtensions = Arrays.asList(allowedFileExtensions.split(",")); + logger.info("Allowed extensions: " + allowedExtensions); + + + // Extract extension from fileName + String extensionFromName = FilenameUtils.getExtension(kmFileManager.getFileName()); + logger.info("extensionFromName " + extensionFromName); + + // Normalize payload fileExtension (remove dot if present) + String extensionFromPayload = kmFileManager.getFileExtension(); + logger.info("extensionPayload " + extensionFromPayload); + + if (extensionFromPayload != null && extensionFromPayload.startsWith(".")) { + extensionFromPayload = extensionFromPayload.substring(1); + } + + // Validate extensions + if (extensionFromName == null || extensionFromPayload == null) { + throw new IOException("File extension missing"); + } + + if (!extensionFromName.equalsIgnoreCase(extensionFromPayload)) { + throw new IOException( + "File extension mismatch: " + extensionFromName + " vs " + extensionFromPayload); + } + + if (!allowedExtensions.contains(extensionFromName.toLowerCase())) { + throw new IOException("File extension not allowed: " + extensionFromName); + } + + kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "") + .replace("$", "") + .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") + .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") + .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") + .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") + .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") + .replace("=", "").replace("\"", "").replace("'", "")); + String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); + newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); + newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); + newFile.flush(); + newFile.close(); + fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); + String checksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + logger.info("File is " + kmFileManager.getFileName()); + logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); + logger.info("File checksum is " + checksum); + logger.info("File checksum length is " + checksum.length()); + kmFileManager.setFileCheckSum(checksum); + kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); + String version = getFileVersion(kmFileManager); + kmFileManager.setVersionNo(version); + String documentPath = kmFileManager.getProviderServiceMapID() + "/"; + if (kmFileManager.getCategoryID() != null) { + documentPath += kmFileManager.getCategoryID() + "/"; + } + if (kmFileManager.getSubCategoryID() != null) { + documentPath += kmFileManager.getSubCategoryID() + "/"; + } + if (kmFileManager.getVanID() != null) + documentPath += kmFileManager.getVanID() + "/"; documentPath += version + "/"; documentPath += kmFileManager.getFileName(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5c522ef9..c8f58b89 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -383,3 +383,7 @@ secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true video-call-url = + +allowable-file-extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt + + From 45399c2482662a22fab74d3ad04a896b125c899d Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 18:27:26 +0530 Subject: [PATCH 102/318] fix: changed application properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c8f58b89..7a8fbea3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -384,6 +384,6 @@ secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true video-call-url = -allowable-file-extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt +allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt From e305d5d35142812d5c89d6fa0eb8f27ed8c4221c Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 19:00:40 +0530 Subject: [PATCH 103/318] fix: removed firebase enabled --- src/main/environment/common_ci.properties | 2 +- src/main/environment/common_docker.properties | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 5f6fda30..d6c2ae73 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -41,7 +41,7 @@ start-sms-scheduler=true cron-scheduler-sms=0 0/1 * * * ? * # Firebase Configuration -firebase.enabled=@env.FIREBASE_ENABLE@ +# firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 240aa80c..55141d4f 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -185,9 +185,9 @@ captcha.enable-captcha=${ENABLE_CAPTCHA} cors.allowed-origins=${CORS_ALLOWED_ORIGINS} -# Firebase Configuration -firebase.enabled=${FIREBASE_ENABLE} -# if using file +# # Firebase Configuration +# firebase.enabled=${FIREBASE_ENABLE} +# # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} From b9fd2268c511c4af1d8ccdf048f2ade44088e14f Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 19:37:17 +0530 Subject: [PATCH 104/318] fix: added firebase enabled --- src/main/environment/common_ci.properties | 2 +- src/main/environment/common_docker.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index d6c2ae73..5f6fda30 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -41,7 +41,7 @@ start-sms-scheduler=true cron-scheduler-sms=0 0/1 * * * ? * # Firebase Configuration -# firebase.enabled=@env.FIREBASE_ENABLE@ +firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 55141d4f..9e5dc01c 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -186,7 +186,7 @@ captcha.enable-captcha=${ENABLE_CAPTCHA} cors.allowed-origins=${CORS_ALLOWED_ORIGINS} # # Firebase Configuration -# firebase.enabled=${FIREBASE_ENABLE} +firebase.enabled=${FIREBASE_ENABLE} # # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} From 84a75fa86cad97d3e131c59ed5a9c40c68196a20 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 27 Aug 2025 17:48:14 +0530 Subject: [PATCH 105/318] fix firebase issue --- .../firebase/FirebaseMessagingConfig.java | 39 +++++++++++++------ .../FirebaseNotificationService.java | 6 ++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index ebb98b59..ebb697ec 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -4,7 +4,10 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @@ -16,6 +19,7 @@ @Configuration public class FirebaseMessagingConfig { + private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); @Value("${firebase.enabled:false}") private boolean firebaseEnabled; @@ -25,26 +29,37 @@ public class FirebaseMessagingConfig { @Bean + @ConditionalOnProperty(name = "firebase.enabled", havingValue = "true") public FirebaseMessaging firebaseMessaging() throws IOException { if (!firebaseEnabled) { - throw new IllegalStateException("Firebase is disabled"); + logger.error("⚠️ Firebase disabled by config"); + return null; } - if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { - throw new IllegalStateException("No Firebase credentials path provided"); - } + try { + if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { + logger.error("⚠️ No Firebase credentials path provided"); + return null; // don't throw, app will still start + } + + GoogleCredentials credentials = GoogleCredentials.fromStream( + new ClassPathResource(firebaseCredentialFile).getInputStream() + ); + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(credentials) + .build(); - GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(firebaseCredentialFile)); + FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() + ? FirebaseApp.initializeApp(options) + : FirebaseApp.getInstance(); - FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(credentials) - .build(); + return FirebaseMessaging.getInstance(firebaseApp); - FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() - ? FirebaseApp.initializeApp(options) - : FirebaseApp.getInstance(); + } catch (Exception e) { + logger.error("⚠️ Firebase init failed: " + e.getMessage()); + return null; // keep app running + } - return FirebaseMessaging.getInstance(firebaseApp); } } diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 7c76c9ee..d59a63f0 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -50,7 +50,7 @@ public class FirebaseNotificationService { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Autowired + @Autowired(required = false) FirebaseMessaging firebaseMessaging; @Autowired @@ -64,6 +64,10 @@ public class FirebaseNotificationService { public String sendNotification(NotificationMessage notificationMessage) { + if (firebaseMessaging == null) { + logger.error("⚠️ Firebase is not configured, skipping notification"); + return null; + } Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); From 6b3d22e0e32563043a1b9adfe2a6c78c5c871a91 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 10:42:40 +0530 Subject: [PATCH 106/318] fix sms issue --- .../repository/sms/SMSTemplateRepository.java | 3 ++ .../BeneficiaryOTPHandlerImpl.java | 34 +++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java index e5d741f0..7e898710 100644 --- a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java +++ b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java @@ -22,6 +22,7 @@ package com.iemr.common.repository.sms; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -56,6 +57,8 @@ public List getSMSTemplateByProviderServiceMapIDAndSMSTypeID( @Query("select smsTemplate.dltTemplateId from SMSTemplate smsTemplate where smsTemplate.smsTemplateID = :smsTemplateID and smsTemplate.deleted <> true") public String findDLTTemplateID(@Param("smsTemplateID") Integer smsTemplateID ); + + public Optional findBySmsTemplateName(String smsTemplateName); SMSTemplate findBySmsTemplateID(Integer smsTemplateID); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index ef83e448..9b17bdaa 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -67,18 +67,24 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Autowired SMSTypeRepository smsTypeRepository; + @Value("${sms-template-name}") + private String smsTemplateName ; + private String smsTemplate; @Value("${sms-username}") private String smsUserName; - // @Value("${sms-password}") - private String smsPassword ="]Kt9GAp8}$S*@"; + @Value("${sms-password}") + private String smsPassword ; + + @Value("${sms-message-type}") + private String smsMessageType; @Value("${sms-entityid}") private String smsEntityId; - // @Value("${source-address}") - private String smsSourceAddress = "PSMRAM"; + @Value("${source-address}") + private String smsSourceAddress ; @Value("${send-message-url}") private String SMS_GATEWAY_URL; @@ -174,18 +180,18 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { final RestTemplate restTemplate = new RestTemplate(); - String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); - SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); + Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + if(smsTemplateData.isPresent()){ + smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); + + } String sendSMSAPI = SMS_GATEWAY_URL; - logger.info("sms template"+template); + logger.info("sms template"+smsTemplate); try { - String message ="Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha to complete the process. Regards PSMRI"; -// String message = template.getSmsTemplate() -// .replace("$$OTP$$",String.valueOf(otp)) -// .replace("$$UserName$$", obj.getUserName()) -// .replace("$$Designation$$", obj.getDesignation()); + String message = smsTemplate + .replace("$$OTP$$",String.valueOf(otp)); // Build payload Map payload = new HashMap<>(); @@ -193,8 +199,8 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("destinationAddress", obj.getMobNo()); payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); - payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", "1007730329175402034"); + payload.put("messageType", smsMessageType); + payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers From 355eafeb0cbdb41afac46b5fbac183f7358b541b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 10:44:00 +0530 Subject: [PATCH 107/318] fix sms issue --- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 30d75168..d75ee3a0 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -163,14 +163,6 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/bulkRegistration") - || path.startsWith(contextPath + "/download-error-sheet") - || path.startsWith(contextPath + "/dynamicForm") - || path.startsWith(contextPath + "/beneficiary/create") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") - || path.startsWith(contextPath + "/firebaseNotification/sendNotification") || path.startsWith(contextPath + "/user/userAuthenticateV1") || path.startsWith(contextPath + "/user/forgetPassword") || path.startsWith(contextPath + "/user/setForgetPassword") From c1caeaeffb2ea46faf78d7f8d316f28d30e77368 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:41:14 +0530 Subject: [PATCH 108/318] fix sms issue --- src/main/resources/application.properties | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5c522ef9..6e750ac6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -374,12 +374,14 @@ spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr spring.datasource.username= spring.datasource.password= -spring.datasource.driver-class-name=com.mysql.jdbc.Driver secondary.datasource.username= secondary.datasource.password= secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver -firebase.enabled=true video-call-url = + +##sms details for beneficiary otp cosent +sms-template-name = otp_consent + From ff53e6610a26b5a31e08685864c529e68adb8aab Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:48:15 +0530 Subject: [PATCH 109/318] fix firebase code issue --- .../FirebaseNotificationController.java | 6 +++--- .../firebaseNotification/FirebaseNotificationService.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 1fe15720..3bb10cfc 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -34,19 +34,19 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification") +@RequestMapping(value= "/firebaseNotification",headers = "Authorization") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired FirebaseNotificationService firebaseNotificationService; - @RequestMapping(value = "sendNotification",method = RequestMethod.POST) + @RequestMapping(value = "sendNotification",method = RequestMethod.POST,headers = "Authorization") public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ return firebaseNotificationService.sendNotification(notificationMessage); } - @RequestMapping(value = "updateToken",method = RequestMethod.POST) + @RequestMapping(value = "updateToken",method = RequestMethod.POST,headers = "Authorization") public String updateToken(@RequestBody UserToken userToken){ return firebaseNotificationService.updateToken(userToken); } diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index d59a63f0..b97ac4de 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -62,6 +62,8 @@ public class FirebaseNotificationService { @Autowired private JwtUtil jwtUtil; + private Message message; + public String sendNotification(NotificationMessage notificationMessage) { if (firebaseMessaging == null) { From 9df05422d0b47e920d8189f24ff347314df8ac2b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:54:07 +0530 Subject: [PATCH 110/318] fix code issue --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- .../config/quartz/ScheduleForGrievanceDataSync.java | 4 ++-- .../nhmdashboard/NHMDetailCallReportScheduler.java | 4 ++-- .../common/controller/users/IEMRAdminController.java | 10 ++-------- .../iemr/common/utils/http/HTTPRequestInterceptor.java | 4 +--- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 84f5e865..2e226b79 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Override diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index e64f604f..c9284574 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - //@Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag = true; + @Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag ; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 3ce4b913..c63d5aa2 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); -// @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag = true; + @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag ; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index ed3760bc..87fa007a 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - // @Value("${captcha.enable-captcha}") - private boolean enableCaptcha = false; + @Value("${captcha.enable-captcha}") + private boolean enableCaptcha ; @Autowired private CaptchaValidationService captchaValidatorService; @@ -257,34 +257,28 @@ public ResponseEntity refreshToken(@RequestBody Map request) logger.warn("Token validation failed: invalid token provided."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - Claims claims = jwtUtil.getAllClaimsFromToken(refreshToken); - // Verify token type if (!"refresh".equals(claims.get("token_type", String.class))) { logger.warn("Token validation failed: incorrect token type in refresh request."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - // Check revocation using JTI String jti = claims.getId(); if (!redisTemplate.hasKey("refresh:" + jti)) { logger.warn("Token validation failed: refresh token is revoked or not found in store."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - // Get user details // Get user details String userId = claims.get("userId", String.class); User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); - // Validate that the user still exists and is active if (user == null) { logger.warn("Token validation failed: user not found for userId in token."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - if (user.getM_status() == null || !"Active".equalsIgnoreCase(user.getM_status().getStatus())) { logger.warn("Token validation failed: user account is inactive or not in 'Active' status."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index be8d564c..fe738905 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -129,14 +129,12 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons break; } } catch (Exception e) { - String origin = request.getHeader("Origin"); - OutputResponse output = new OutputResponse(); output.setError(e); response.getOutputStream().print(output.toString()); response.setContentType(MediaType.APPLICATION_JSON); response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "http://devbox.bizbrolly.com:4901"); + response.setHeader("Access-Control-Allow-Origin", "*"); status = false; } } From c2b1a44869c4a16b1797032e803eb8abae31ae0e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:14:59 +0530 Subject: [PATCH 111/318] fix code issue --- .../common/config/quartz/ScheduleForGrievanceDataSync.java | 2 +- .../controller/nhmdashboard/NHMDetailCallReportScheduler.java | 2 +- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index c9284574..f016de3d 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -15,7 +15,7 @@ public class ScheduleForGrievanceDataSync { @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag ; + private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index c63d5aa2..5fd3e281 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -39,7 +39,7 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag ; + private boolean startCtiDataCheckFlag; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 87fa007a..ffc6fad4 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - @Value("${captcha.enable-captcha}") - private boolean enableCaptcha ; + @Value("${captcha.enable-captcha}") + private boolean enableCaptcha; @Autowired private CaptchaValidationService captchaValidatorService; From eccc11632242cc23daa20c0c56c465d987df50f3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:17:06 +0530 Subject: [PATCH 112/318] fix code issue --- .../java/com/iemr/common/utils/http/HTTPRequestInterceptor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index fe738905..3f0268d1 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -141,8 +141,6 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons return status; } - - @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) throws Exception { From abfc4e4ae370ca3849509775822dc0d22f467bcc Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:18:41 +0530 Subject: [PATCH 113/318] fix code issue --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6e750ac6..6c06ee88 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,8 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 -cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From ace7340ce86a7ed7fb69897724391a433fee962b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:24:04 +0530 Subject: [PATCH 114/318] fix code issue --- .../welcomeSms/WelcomeBenificarySmsServiceImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 50e2353f..f154b8fa 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -20,14 +20,14 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-username}") private String smsUserName; - // @Value("${sms-password}") - private String smsPassword = "]Kt9GAp8}$S*@"; + @Value("${sms-password}") + private String smsPassword ; @Value("${sms-entityid}") private String smsEntityId; -// @Value("${source-address}") - private String smsSourceAddress ="PSMRAM"; + @Value("${source-address}") + private String smsSourceAddress; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 86042b92e2bd2a06ef2981025ba0d7207ac5c70d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:31:01 +0530 Subject: [PATCH 115/318] fix code issue --- .../WelcomeBenificarySmsServiceImpl.java | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index f154b8fa..fe5a4b72 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -1,8 +1,12 @@ package com.iemr.common.service.welcomeSms; +import com.google.common.cache.LoadingCache; import com.iemr.common.data.sms.SMSTemplate; +import com.iemr.common.repository.sms.SMSTemplateRepository; +import com.iemr.common.repository.sms.SMSTypeRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -14,14 +18,16 @@ import java.util.Base64; import java.util.HashMap; import java.util.Map; +import java.util.Optional; + @Service -public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsService{ +public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsService { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword ; + @Value("${sms-password}") + private String smsPassword; @Value("${sms-entityid}") private String smsEntityId; @@ -29,28 +35,45 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${source-address}") private String smsSourceAddress; @Value("${send-message-url}") - private String SMS_GATEWAY_URL; + private String SMS_GATEWAY_URL; + + @Autowired + SMSTemplateRepository smsTemplateRepository; + + @Autowired + SMSTypeRepository smsTypeRepository; + + private String smsTemplateName = "welcome_sms"; + + private String smsTemplate; @Override - public String sendWelcomeSMStoBenificiary(String contactNo,String beneficiaryName,String beneficiaryId) { + public String sendWelcomeSMStoBenificiary(String contactNo, String beneficiaryName, String beneficiaryId) { final RestTemplate restTemplate = new RestTemplate(); - String dltTemplateId = "1007006798022225953"; + Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + if (smsTemplateData.isPresent()) { + smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); + + } + + logger.info("sms template" + smsTemplate); + String sendSMSAPI = SMS_GATEWAY_URL; try { - String message = "Dear "+beneficiaryName+", your unique Beneficiary ID is "+beneficiaryId+". Thank you for registering. Regards PSMRI"; + String message = smsTemplate.replace("$$BENE_NAME$$", beneficiaryName).replace("$$BEN_ID$$", beneficiaryId); // Build payload Map payload = new HashMap<>(); - payload.put("customerId",smsUserName); + payload.put("customerId", smsUserName); payload.put("destinationAddress", contactNo); payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", dltTemplateId); - payload.put("entityId",smsEntityId ); + payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); + payload.put("entityId", smsEntityId); // Set headers HttpHeaders headers = new HttpHeaders(); String auth = smsUserName + ":" + smsPassword; @@ -58,15 +81,15 @@ public String sendWelcomeSMStoBenificiary(String contactNo,String beneficiaryNa "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); headers.setContentType(MediaType.APPLICATION_JSON); - logger.info("payload: "+payload); + logger.info("payload: " + payload); HttpEntity> request = new HttpEntity<>(payload, headers); // Call API ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); - logger.info("sms-response:"+response.getBody()); - if(response.getStatusCode().value()==200){ - return "OTP sent successfully on register mobile number"; - }else { + logger.info("sms-response:" + response.getBody()); + if (response.getStatusCode().value() == 200) { + return "OTP sent successfully on register mobile number"; + } else { return "Fail"; } From 555e2747c7c3fcb563f2634cf8a2ea7768e05014 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:36:23 +0530 Subject: [PATCH 116/318] fix code issue --- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 379eb180..9f6efb13 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Bean diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index d75ee3a0..414f4b9e 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -171,6 +171,7 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/userLogout") || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + } From 17bad73096b785d6a5a64fea365f48036d3c07cb Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:41:35 +0530 Subject: [PATCH 117/318] fix code issue --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 1 - .../com/iemr/common/utils/exception/GlobalExceptionHandler.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 893c1c8a..19864742 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -145,7 +145,6 @@ public FormResponseDTO getStructuredFormByFormId(String formId) { } } catch (JsonProcessingException e) { System.err.println("JSON Parsing Error in field: " + field.getFieldId()); - e.printStackTrace(); throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); } diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java index 90a06c79..632e90d2 100644 --- a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -14,7 +14,6 @@ public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity> handleException(Exception ex) { - ex.printStackTrace(); // Log for debugging return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(),null)); } From 9f2ebd67ddf1de3bcc3c798d04b8691b73c346fc Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:56:06 +0530 Subject: [PATCH 118/318] fix code issue --- .../quartz/ScheduleForGrievanceDataSync.java | 2 +- .../notification/NotificationService.java | 1 - .../utils/JwtUserIdValidationFilter.java | 32 +++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index f016de3d..ba840321 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,7 +14,7 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler}") + @Value("${start-grievancedatasync-scheduler:false}") private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/service/notification/NotificationService.java b/src/main/java/com/iemr/common/service/notification/NotificationService.java index 6fa8ee8d..a3c85387 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationService.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationService.java @@ -55,5 +55,4 @@ String createEmergencyContacts(String request) String updateEmergencyContacts(String request) throws JSONException, NoSuchAlgorithmException, IOException, IEMRException, Exception; - } diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 414f4b9e..98215dfd 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -156,23 +156,23 @@ private boolean isMobileClient(String userAgent) { return userAgent.contains("okhttp") || userAgent.contains("java/"); // iOS (custom clients) } - private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") - || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") - || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") - || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") - || path.startsWith(contextPath + "/user/superUserAuthenticate") - || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/user/userAuthenticateV1") - || path.startsWith(contextPath + "/user/forgetPassword") - || path.startsWith(contextPath + "/user/setForgetPassword") - || path.startsWith(contextPath + "/user/changePassword") - || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") - || path.startsWith(contextPath + "/user/userLogout") - || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") - || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + private boolean shouldSkipAuthentication(String path, String contextPath) { + return path.equals(contextPath + "/user/userAuthenticate") + || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") + || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") + || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") + || path.startsWith(contextPath + "/user/superUserAuthenticate") + || path.startsWith(contextPath + "/user/user/userAuthenticateNew") + || path.startsWith(contextPath + "/user/userAuthenticateV1") + || path.startsWith(contextPath + "/user/forgetPassword") + || path.startsWith(contextPath + "/user/setForgetPassword") + || path.startsWith(contextPath + "/user/changePassword") + || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") + || path.startsWith(contextPath + "/user/userLogout") + || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") + || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); - } + } private String getJwtTokenFromCookies(HttpServletRequest request) { From edb61377277e448959e2a9be3250577bed08bf28 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:00:09 +0530 Subject: [PATCH 119/318] fix code issue --- .../java/com/iemr/common/utils/http/HTTPRequestInterceptor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 3f0268d1..a116f3a7 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -39,8 +39,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.util.Arrays; -import java.util.List; @Configuration @Component From 3dd65221f2b912187b1a3ba5d079dd3517494f5a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:03:24 +0530 Subject: [PATCH 120/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index c4800782..2a5068f6 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -83,6 +83,5 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - } From 3aa039e896c4ece60cceaa00163b66622cb68afd Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:04:14 +0530 Subject: [PATCH 121/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 2a5068f6..feeb18c8 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -85,3 +85,4 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor } + From 16194a1b6f479cb2fc4ab878f3aa664854c7cdea Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:04:52 +0530 Subject: [PATCH 122/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index feeb18c8..a66b6d9a 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -82,7 +82,4 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - } - - From aaf41c9a18457f0ae4bd94548e9bbfe268a213dc Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:05:23 +0530 Subject: [PATCH 123/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index a66b6d9a..442a9ffe 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -44,8 +44,6 @@ import com.iemr.common.data.users.User; import com.iemr.common.utils.IEMRApplBeans; -import java.io.IOException; - @SpringBootApplication @EnableScheduling public class CommonApplication extends SpringBootServletInitializer { From 4771ce62afe67f771fa5a3ddb31cf13a6e911578 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:06:18 +0530 Subject: [PATCH 124/318] fix code issue --- .../iemr/common/config/quartz/ScheduleForGrievanceDataSync.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index ba840321..f016de3d 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,7 +14,7 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler:false}") + @Value("${start-grievancedatasync-scheduler}") private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From 089035d57abeef9e806a004bbe7d58bb2e6a341a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 2 Sep 2025 11:37:12 +0530 Subject: [PATCH 125/318] fix code issue --- src/main/environment/common_ci.properties | 1 + src/main/environment/common_docker.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 5f6fda30..cbd6c2d7 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -32,6 +32,7 @@ identity-1097-api-url = @env.IDENTITY_1097_API_URL@ send-sms=@env.SEND_SMS@ sendSMSUrl = @env.SEND_SMS_URL@ source-address=@env.SMS_SOURCE_ADDRESS@ +sms_consent_source-address=@env.SMS_CONSENT_SOURCE_ADDRESS@ sms-username=@env.SMS_USERNAME@ sms-password=@env.SMS_PASSWORD@ send-message-url=@env.SMS_MESSAGE_URL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 240aa80c..2d3fb8a1 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -32,6 +32,7 @@ identity-1097-api-url = ${IDENTITY_1097_API_URL} send-sms=${SEND_SMS} sendSMSUrl = ${SEND_SMS_URL} source-address=${SMS_SOURCE_ADDRESS} +sms-consent-source-address=${SMS_CONSENT_SOURCE_ADDRESS} sms-username=${SMS_USERNAME} sms-password=${SMS_PASSWORD} send-message-url=${SMS_MESSAGE_URL} From f75892e3ae7db59b2e510c6cae679336e685c2e4 Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Tue, 2 Sep 2025 12:07:43 +0530 Subject: [PATCH 126/318] VAPT: File Upload Validation and Security Hardening (#285) * fix: allowed file format for upload * fix: changed application properties * fix: removed firebase enabled * fix: added firebase enabled --- src/main/environment/common_docker.properties | 4 +- .../KMFileManagerServiceImpl.java | 114 ++++++++++++------ src/main/resources/application.properties | 3 + 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 2d3fb8a1..b7f7c605 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -186,9 +186,9 @@ captcha.enable-captcha=${ENABLE_CAPTCHA} cors.allowed-origins=${CORS_ALLOWED_ORIGINS} -# Firebase Configuration +# # Firebase Configuration firebase.enabled=${FIREBASE_ENABLE} -# if using file +# # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} diff --git a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java index 7a24c6da..1446787d 100644 --- a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java +++ b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java @@ -34,12 +34,14 @@ import java.util.Objects; import java.util.Set; +import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; @@ -84,6 +86,9 @@ public void setSubCategoryRepository(SubCategoryRepository subCategoryRepository private InputMapper inputMapper = new InputMapper(); + @Value("${allowed.file.extensions}") + private String allowedFileExtensions; + @Override public String getKMFileLists(String request) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); @@ -131,43 +136,78 @@ private ArrayList addKMFile(Iterable kmFileManager ArrayList savedFileManagers = new ArrayList(); FileOutputStream newFile = null; FileInputStream fis = null; - try - { - for (KMFileManager kmFileManager : kmFileManagers) { - if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null - && kmFileManager.getFileContent() != null) { - kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "").replace("$", "") - .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") - .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") - .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") - .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") - .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") - .replace("=", "").replace("\"", "").replace("'", "")); - String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); - newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); - newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); - newFile.flush(); - newFile.close(); - fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); - String checksum = DigestUtils.md5DigestAsHex(fis); - fis.close(); - logger.info("File is " + kmFileManager.getFileName()); - logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); - logger.info("File checksum is " + checksum); - logger.info("File checksum length is " + checksum.length()); - kmFileManager.setFileCheckSum(checksum); - kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); - String version = getFileVersion(kmFileManager); - kmFileManager.setVersionNo(version); - String documentPath = kmFileManager.getProviderServiceMapID() + "/"; - if (kmFileManager.getCategoryID() != null) { - documentPath += kmFileManager.getCategoryID() + "/"; - } - if (kmFileManager.getSubCategoryID() != null) { - documentPath += kmFileManager.getSubCategoryID() + "/"; - } - if (kmFileManager.getVanID() != null) - documentPath += kmFileManager.getVanID() + "/"; + try { + for (KMFileManager kmFileManager : kmFileManagers) { + if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null + && kmFileManager.getFileContent() != null) { + + if (allowedFileExtensions == null || allowedFileExtensions.trim().isEmpty()) { + throw new IllegalStateException( + "Environment variable 'allowed.file.extensions' is not configured or is empty"); + } + List allowedExtensions = Arrays.asList(allowedFileExtensions.split(",")); + logger.info("Allowed extensions: " + allowedExtensions); + + + // Extract extension from fileName + String extensionFromName = FilenameUtils.getExtension(kmFileManager.getFileName()); + logger.info("extensionFromName " + extensionFromName); + + // Normalize payload fileExtension (remove dot if present) + String extensionFromPayload = kmFileManager.getFileExtension(); + logger.info("extensionPayload " + extensionFromPayload); + + if (extensionFromPayload != null && extensionFromPayload.startsWith(".")) { + extensionFromPayload = extensionFromPayload.substring(1); + } + + // Validate extensions + if (extensionFromName == null || extensionFromPayload == null) { + throw new IOException("File extension missing"); + } + + if (!extensionFromName.equalsIgnoreCase(extensionFromPayload)) { + throw new IOException( + "File extension mismatch: " + extensionFromName + " vs " + extensionFromPayload); + } + + if (!allowedExtensions.contains(extensionFromName.toLowerCase())) { + throw new IOException("File extension not allowed: " + extensionFromName); + } + + kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "") + .replace("$", "") + .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") + .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") + .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") + .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") + .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") + .replace("=", "").replace("\"", "").replace("'", "")); + String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); + newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); + newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); + newFile.flush(); + newFile.close(); + fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); + String checksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + logger.info("File is " + kmFileManager.getFileName()); + logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); + logger.info("File checksum is " + checksum); + logger.info("File checksum length is " + checksum.length()); + kmFileManager.setFileCheckSum(checksum); + kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); + String version = getFileVersion(kmFileManager); + kmFileManager.setVersionNo(version); + String documentPath = kmFileManager.getProviderServiceMapID() + "/"; + if (kmFileManager.getCategoryID() != null) { + documentPath += kmFileManager.getCategoryID() + "/"; + } + if (kmFileManager.getSubCategoryID() != null) { + documentPath += kmFileManager.getSubCategoryID() + "/"; + } + if (kmFileManager.getVanID() != null) + documentPath += kmFileManager.getVanID() + "/"; documentPath += version + "/"; documentPath += kmFileManager.getFileName(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6c06ee88..65fc3d97 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,6 +381,9 @@ secondary.datasource.driver-class-name=com.mysql.jdbc.Driver video-call-url = +allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt + ##sms details for beneficiary otp cosent sms-template-name = otp_consent + From fa648d2572b0dc62e34a7f34c49512923e7c11a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 2 Sep 2025 18:11:30 +0530 Subject: [PATCH 127/318] Update application.properties --- src/main/resources/application.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 65fc3d97..929729d2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -338,8 +338,6 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true -jwt.secret=my-32-character-ultra-secure-and-ultra-long-secret - fileBasePath =/Doc ##grievance API call From 79cc8b1e3eac3fd8438f85969c8a22fad652b440 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 10 Mar 2025 16:27:11 +0530 Subject: [PATCH 128/318] Beneficiary consent --- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 1 + .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +++ .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index 431a267a..846e5c51 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -59,6 +59,7 @@ public class CommonIdentityDTO { private Integer educationId; private String education; private Boolean emergencyRegistration = false; + private Boolean isConsent; private Integer healthCareWorkerId; private String healthCareWorker; private String fatherName; diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index dfb76d00..f13e82c4 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -78,6 +78,9 @@ public class BeneficiaryModel implements Comparable { // private List outboundCallRequests; // private List beneficiaryCalls; // private List feedbacks; + @Expose + private Boolean isConsent=false; + @Expose private String beneficiaryID; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 7f6f6266..eb35507f 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -170,13 +170,14 @@ private int updateDemographics(BeneficiaryDemographicsModel i_BenDemographics) { @Override public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servletRequest) throws Exception { - // logger.info("benificiaryDetails: " + beneficiaryModel); + logger.info("benificiaryDetails: " + beneficiaryModel); CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); + identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO .setBenFamilyDTOs(identityMapper.benPhoneMapListToBenFamilyDTOList(beneficiaryModel.getBenPhoneMaps())); String request = new Gson().toJson(identityDTO); From ab64879a4c63c9d51ef44913c1249333da2c5914 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:05:36 +0530 Subject: [PATCH 129/318] Beneficiary consent --- .../java/com/iemr/common/controller/otp/OTPGateway.java | 9 +++++++-- .../iemr/common/model/beneficiary/BeneficiaryModel.java | 1 + .../beneficiary/RegisterBenificiaryServiceImpl.java | 2 ++ .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java index 777503b8..57c1762b 100644 --- a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java +++ b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java @@ -53,6 +53,7 @@ public class OTPGateway { @Operation(summary = "Send OTP") @RequestMapping(value = "/sendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -60,7 +61,8 @@ public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody Stri OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.sendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); @@ -98,6 +100,7 @@ public String validateOTP( @Operation(summary = "Resend OTP") @RequestMapping(value = "/resendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -105,7 +108,9 @@ public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody St OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.resendOTP(obj); - if (success.equalsIgnoreCase("success")) + logger.info(success.toString()); + + if (success.contains("otp")) response.setResponse(success); else response.setError(5000, "failure"); diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index f13e82c4..ed7c9cad 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -81,6 +81,7 @@ public class BeneficiaryModel implements Comparable { @Expose private Boolean isConsent=false; + @Expose private String beneficiaryID; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index eb35507f..5bce93de 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -76,6 +76,8 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired Validator validator; + + @Autowired OutboundHistoryRepository outboundHistoryRepository; diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 13eaea2f..94b86799 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -59,6 +59,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); + // Log cookies for debugging Cookie[] cookies = request.getCookies(); if (cookies != null) { From 88b042ad0f69babf5568e604d8043b62e52f6da6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 10 Apr 2025 11:24:30 +0530 Subject: [PATCH 130/318] Beneficiary consent --- .../iemr/common/service/notification/NotificationService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/service/notification/NotificationService.java b/src/main/java/com/iemr/common/service/notification/NotificationService.java index a3c85387..6fa8ee8d 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationService.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationService.java @@ -55,4 +55,5 @@ String createEmergencyContacts(String request) String updateEmergencyContacts(String request) throws JSONException, NoSuchAlgorithmException, IOException, IEMRException, Exception; + } From 50416d647d87a6ae482854acd90ff610d19fee4f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 13 Jun 2025 15:07:53 +0530 Subject: [PATCH 131/318] Beneficiary consent --- .../BeneficiaryConsentController.java | 100 +++++++++ .../BeneficiaryConsentRequest.java | 12 + .../BeneficiaryOTPHandler.java | 14 ++ .../BeneficiaryOTPHandlerImpl.java | 207 ++++++++++++++++++ 4 files changed, 333 insertions(+) create mode 100644 src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java create mode 100644 src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java create mode 100644 src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java create mode 100644 src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java new file mode 100644 index 00000000..60c7bdee --- /dev/null +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -0,0 +1,100 @@ +package com.iemr.common.controller.beneficiaryConsent; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; +import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.utils.mapper.InputMapper; +import com.iemr.common.utils.response.OutputResponse; +import io.lettuce.core.dynamic.annotation.Param; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.ws.rs.core.MediaType; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +public class BeneficiaryConsentController { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private BeneficiaryOTPHandler beneficiaryOTPHandler; + + @Operation(summary = "Send Consent") + @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); + + String success = beneficiaryOTPHandler.sendOTP(obj); // method name unchanged if internal logic still uses 'OTP' + logger.info(success.toString()); + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Validate Consent") + @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"Integer\"}") @RequestBody String requestOBJ) { + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj); + if (responseOBJ != null) + response.setResponse(responseOBJ.toString()); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in validating Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + @Operation(summary = "Resend Consent") + @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { + logger.info(requestOBJ.toString()); + + OutputResponse response = new OutputResponse(); + + try { + OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + + String success = beneficiaryOTPHandler.resendOTP(obj); + logger.info(success.toString()); + + if (success.contains("otp")) + response.setResponse(success); + else + response.setError(500, "failure"); + + } catch (Exception e) { + logger.error("error in re-sending Consent : " + e); + response.setError(500, "error : " + e); + } + return response.toString(); + } + + +} + + diff --git a/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java new file mode 100644 index 00000000..ac629a3c --- /dev/null +++ b/src/main/java/com/iemr/common/data/beneficiaryConsent/BeneficiaryConsentRequest.java @@ -0,0 +1,12 @@ +package com.iemr.common.data.beneficiaryConsent; + +import lombok.Data; + +@Data +public class BeneficiaryConsentRequest { + private String mobNo; + private int otp; + private String userName; + private String designation; + +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java new file mode 100644 index 00000000..234640a8 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandler.java @@ -0,0 +1,14 @@ +package com.iemr.common.service.beneficiaryOTPHandler; + +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import org.json.JSONObject; + +public interface BeneficiaryOTPHandler { + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception; + + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception; + + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception; + +} diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java new file mode 100644 index 00000000..9fa73005 --- /dev/null +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -0,0 +1,207 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.service.beneficiaryOTPHandler; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.primitives.Ints; +import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; +import com.iemr.common.data.otp.OTPRequestParsor; +import com.iemr.common.data.sms.SMSTemplate; +import com.iemr.common.data.sms.SMSType; +import com.iemr.common.repository.sms.SMSTemplateRepository; +import com.iemr.common.repository.sms.SMSTypeRepository; +import com.iemr.common.service.otp.OTPHandler; +import com.iemr.common.service.users.IEMRAdminUserServiceImpl; +import com.iemr.common.utils.config.ConfigProperties; +import com.iemr.common.utils.http.HttpUtils; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.*; +import java.util.concurrent.TimeUnit; + +@Service +public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { + + @Autowired + HttpUtils httpUtils; + @Autowired + private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + @Autowired + SMSTemplateRepository smsTemplateRepository; + private LoadingCache otpCache; + + @Autowired + SMSTypeRepository smsTypeRepository; + + private static final Integer EXPIRE_MIN = 5; + private static final String SMS_GATEWAY_URL = ConfigProperties.getPropertyByName("sms-gateway-url"); + + // Constructor for new object creation + public BeneficiaryOTPHandlerImpl() { + otpCache = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_MIN, TimeUnit.MINUTES) + .build(new CacheLoader() { + public String load(String key) { + return "0"; + } + }); + } + + /*** + * @param obj + * @return success if OTP sent successfully + */ + @Override + public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + /*** + * @param obj + * @return OTP verification success or failure + * + */ + @Override + public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { + String cachedOTP = otpCache.get(obj.getMobNo()); + String inputOTPEncrypted = getEncryptedOTP(obj.getOtp()); + + if (cachedOTP.equalsIgnoreCase(inputOTPEncrypted)) { + JSONObject responseObj = new JSONObject(); + responseObj.put("userName", obj.getMobNo()); + responseObj.put("userID", obj.getMobNo()); + + JSONObject responseOBJ = iEMRAdminUserServiceImpl.generateKeyPostOTPValidation(responseObj); + + return responseOBJ; + } else { + throw new Exception("Please enter valid OTP"); + } + + } + + /*** + * @param obj + * @return success if OTP re-sent successfully + */ + @Override + public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { + int otp = generateOTP(obj.getMobNo()); + sendSMS(otp, obj); + return "success"; + } + + // generate 6 digit random no # + public int generateOTP(String authKey) throws Exception { + String generatedPassword = null; + Random random = SecureRandom.getInstanceStrong(); + int otp = 100000 + random.nextInt(900000); + + generatedPassword = getEncryptedOTP(otp); + + if (otpCache != null) + otpCache.put(authKey, generatedPassword); + else { + BeneficiaryOTPHandlerImpl obj = new BeneficiaryOTPHandlerImpl(); + obj.otpCache.put(authKey, generatedPassword); + } + return otp; + } + + // SHA-256 encoding logic implemented + private String getEncryptedOTP(int otp) throws Exception { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] bytes = md.digest(Ints.toByteArray(otp)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + + return sb.toString(); + } + + // send SMS to beneficiary + + + public String sendSMS(int otp, BeneficiaryConsentRequest obj) { + + final RestTemplate restTemplate = new RestTemplate(); + String sendSMSURL = ConfigProperties.getPropertyByName("send-message-url"); + + String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL + "/" + sendSMSURL; + + + try { + + +// String message = "Dear Citizen, your OTP for login is " +otp+". Use it within 15 minutes. Do not share this code. Regards PSMRIAM."; + String message = "Hello! Your OTP for providing consent for registration on AMRIT is " + otp + ". This OTP is valid for 10 minutes. Kindly share it only with " + obj.getUserName() + " " + obj.getDesignation() + " to complete the process. PSMRI"; + + // Build payload + Map payload = new HashMap<>(); + payload.put("customerId", ConfigProperties.getPropertyByName("sms-username")); + payload.put("destinationAddress", obj.getMobNo()); + payload.put("message", message); + payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", ConfigProperties.getPropertyByName("dltTemplateId")); + payload.put("entityId",ConfigProperties.getPropertyByName("entityId") ); + payload.put("otp", true); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = ConfigProperties.getPropertyByName("sms-username") + ":" + ConfigProperties.getPropertyByName("sms-password"); + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> request = new HttpEntity<>(payload, headers); + + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + + // Return response + return response.getBody(); + + } catch (Exception e) { + e.printStackTrace(); + return "Error sending SMS: " + e.getMessage(); + } + } + +} From afdf9f0e2e830de5bf61ca5581efe9103f719b3e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 10 Mar 2025 17:31:49 +0530 Subject: [PATCH 132/318] Beneficiary consent --- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 2 ++ .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +++ .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 1 + 3 files changed, 6 insertions(+) diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index 846e5c51..c057b58d 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -54,6 +54,8 @@ public class CommonIdentityDTO { private Integer beneficiaryRegId; private Integer communityId; private String community; + private Boolean isConsent=false; + private Timestamp dob; private Integer ageAtMarriage; private Integer educationId; diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index ed7c9cad..39a7233b 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -92,6 +92,9 @@ public class BeneficiaryModel implements Comparable { private TitleModel m_title; @Expose private String firstName; + @Expose + private Boolean isConsent=false; + @Expose private String middleName; @Expose diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 5bce93de..9baa24c1 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -177,6 +177,7 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); + identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); From 0d22d68974758fa10a7966233ab6be0c060d3b12 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 14:21:06 +0530 Subject: [PATCH 133/318] firebase setup --- .../com/iemr/common/CommonApplication.java | 20 ++++++++++ .../FirebaseNotificationController.java | 25 +++++++++++++ .../notification/NotificationMessage.java | 14 +++++++ .../FirebaseNotificationService.java | 37 +++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java create mode 100644 src/main/java/com/iemr/common/model/notification/NotificationMessage.java create mode 100644 src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index b9b797b2..cd9ebded 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -21,11 +21,16 @@ */ package com.iemr.common; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; +import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; @@ -39,6 +44,8 @@ import com.iemr.common.data.users.User; import com.iemr.common.utils.IEMRApplBeans; +import java.io.IOException; + @SpringBootApplication @EnableScheduling public class CommonApplication extends SpringBootServletInitializer { @@ -76,4 +83,17 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } + @Bean + FirebaseMessaging firebaseMessaging() throws IOException { + GoogleCredentials googleCredentials = GoogleCredentials.fromStream( + new ClassPathResource("Place your admin json").getInputStream() + + ); + FirebaseOptions firebaseOptions = FirebaseOptions.builder().setCredentials(googleCredentials).build(); + FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions); + return FirebaseMessaging.getInstance(firebaseApp); + + + } + } diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java new file mode 100644 index 00000000..22f438ca --- /dev/null +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -0,0 +1,25 @@ +package com.iemr.common.controller.firebaseNotification; + +import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.service.firebaseNotification.FirebaseNotificationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value= "/firebaseNotification") +public class FirebaseNotificationController { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + FirebaseNotificationService firebaseNotificationService; + + @CrossOrigin + @RequestMapping(value = "sendNotification",method = RequestMethod.POST) + public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ + return firebaseNotificationService.sendNotification(notificationMessage); + } + + +} diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java new file mode 100644 index 00000000..2838eca3 --- /dev/null +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -0,0 +1,14 @@ +package com.iemr.common.model.notification; + +import lombok.Data; + +import java.util.Map; + +@Data +public class NotificationMessage { + private String appType; + private String topic; + private String title; + private String body; + private Map data; +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java new file mode 100644 index 00000000..642bd6fa --- /dev/null +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -0,0 +1,37 @@ +package com.iemr.common.service.firebaseNotification; + +import com.google.firebase.FirebaseException; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import com.iemr.common.model.notification.NotificationMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FirebaseNotificationService { + final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + FirebaseMessaging firebaseMessaging; + + public String sendNotification(NotificationMessage notificationMessage) { + + Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); + + Message message = Message.builder().setTopic(notificationMessage.getTopic()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + + + try { + String response = FirebaseMessaging.getInstance().send(message); + + return response; + } catch (FirebaseException e) { + return "Error sending notification"; + + } + } + +} From ad11e103509370d4cad06e6de0e3f744e892908e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 15:23:54 +0530 Subject: [PATCH 134/318] firebase setup --- src/main/java/com/iemr/common/CommonApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index cd9ebded..360821e7 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -97,3 +97,4 @@ FirebaseMessaging firebaseMessaging() throws IOException { } } + From 2f281b014006340f96f40105130d177807fd05d5 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 11 Apr 2025 18:32:07 +0530 Subject: [PATCH 135/318] firebase setup --- .../firebaseNotification/FirebaseNotificationController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 22f438ca..18601d22 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -8,14 +8,13 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification") +@RequestMapping(value= "/firebaseNotification",headers = "Authorization") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired FirebaseNotificationService firebaseNotificationService; - @CrossOrigin @RequestMapping(value = "sendNotification",method = RequestMethod.POST) public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ return firebaseNotificationService.sendNotification(notificationMessage); From f8d2784f27f99df2085999c4c0e77d5be90d8d80 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 14 Apr 2025 14:48:33 +0530 Subject: [PATCH 136/318] firebase setup --- .../com/iemr/common/CommonApplication.java | 12 ---- .../firebase/FirebaseMessagingConfig.java | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 360821e7..c4800782 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -83,18 +83,6 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - @Bean - FirebaseMessaging firebaseMessaging() throws IOException { - GoogleCredentials googleCredentials = GoogleCredentials.fromStream( - new ClassPathResource("Place your admin json").getInputStream() - - ); - FirebaseOptions firebaseOptions = FirebaseOptions.builder().setCredentials(googleCredentials).build(); - FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions); - return FirebaseMessaging.getInstance(firebaseApp); - - - } } diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java new file mode 100644 index 00000000..438ca4f9 --- /dev/null +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -0,0 +1,57 @@ +package com.iemr.common.config.firebase; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Base64; + +@Configuration +public class FirebaseMessagingConfig { + + @Value("${firebase.enabled:false}") + private boolean firebaseEnabled; + + @Value("${firebase.credential-file:}") + private String firebaseCredentialFile; + + @Value("${firebase.credential-base64:}") + private String firebaseCredentialBase64; + + @Bean + public FirebaseMessaging firebaseMessaging() throws IOException { + if (!firebaseEnabled) { + throw new IllegalStateException("Firebase is disabled"); + } + + GoogleCredentials credentials; + + if (!firebaseCredentialBase64.isBlank()) { + byte[] decoded = Base64.getDecoder().decode(firebaseCredentialBase64); + credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(decoded)); + } else if (!firebaseCredentialFile.isBlank()) { + credentials = GoogleCredentials.fromStream( + new ClassPathResource(firebaseCredentialFile).getInputStream() + ); + } else { + throw new IllegalStateException("No Firebase credentials provided"); + } + + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(credentials) + .build(); + + FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() + ? FirebaseApp.initializeApp(options) + : FirebaseApp.getInstance(); + + return FirebaseMessaging.getInstance(firebaseApp); + } +} From d113d36109ceb4367451b6fdb48cf170fca5aaf0 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:22:00 +0530 Subject: [PATCH 137/318] firebase setup --- src/main/environment/common_ci.properties | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index a5e66660..def8144b 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -40,6 +40,13 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=true cron-scheduler-sms=0 0/1 * * * ? * +// Firebase Configuration +firebase.enabled= @env.FIREBASE_ENABLE@ +# if using file +firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +# for CI/CD +credential-base64 =@env.CREDENTIAL_BASE^$@ + #### Email Configuration send-email=@env.SEND_EMAIL@ spring.mail.host=@env.MAIL_HOST@ From acd9ee114527a554baa834f62aa45f8c5d0159ad Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:25:40 +0530 Subject: [PATCH 138/318] Firebase Configuration in ci --- src/main/environment/common_ci.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index def8144b..c3c8a1a8 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -40,8 +40,8 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=true cron-scheduler-sms=0 0/1 * * * ? * -// Firebase Configuration -firebase.enabled= @env.FIREBASE_ENABLE@ ++ # Firebase Configuration +firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ # for CI/CD From 77b823fb3e52a704465d6481b43d4b6781917810 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 17 Apr 2025 14:27:01 +0530 Subject: [PATCH 139/318] Firebase Configuration in ci --- src/main/environment/common_ci.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index c3c8a1a8..bb1a8b1c 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -40,12 +40,12 @@ send-message-url=@env.SMS_MESSAGE_URL@ start-sms-scheduler=true cron-scheduler-sms=0 0/1 * * * ? * -+ # Firebase Configuration +# Firebase Configuration firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ # for CI/CD -credential-base64 =@env.CREDENTIAL_BASE^$@ +firebase.credential-base64=@env.CREDENTIAL_BASE64@ #### Email Configuration send-email=@env.SEND_EMAIL@ From 2ab86e174819010987de92de3984ec7f57f9100c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 2 May 2025 12:44:26 +0530 Subject: [PATCH 140/318] firebase notification setup --- .../com/iemr/common/model/notification/NotificationMessage.java | 1 + .../firebaseNotification/FirebaseNotificationService.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index 2838eca3..eed0c171 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -7,6 +7,7 @@ @Data public class NotificationMessage { private String appType; + private String token; private String topic; private String title; private String body; diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 642bd6fa..e41ca94f 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -21,7 +21,7 @@ public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); - Message message = Message.builder().setTopic(notificationMessage.getTopic()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + Message message = Message.builder().setToken(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); try { From 3551a00bb50509b219784b1ab2cbfbe73bbbb2ac Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 13:03:00 +0530 Subject: [PATCH 141/318] Firebase update userToken --- .../FirebaseNotificationController.java | 13 +++++ .../common/data/userToken/UserTokenData.java | 22 ++++++++ .../notification/NotificationMessage.java | 1 - .../common/model/notification/UserToken.java | 9 ++++ .../FirebaseNotificationService.java | 53 +++++++++++++++++++ 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iemr/common/data/userToken/UserTokenData.java create mode 100644 src/main/java/com/iemr/common/model/notification/UserToken.java diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 18601d22..3e39fe21 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -1,7 +1,9 @@ package com.iemr.common.controller.firebaseNotification; import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.model.notification.UserToken; import com.iemr.common.service.firebaseNotification.FirebaseNotificationService; +import com.iemr.common.utils.exception.IEMRException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -20,5 +22,16 @@ public String sendNotificationByToken(@RequestBody NotificationMessage notificat return firebaseNotificationService.sendNotification(notificationMessage); } + @RequestMapping(value = "updateToken",method = RequestMethod.POST) + public String updateToken(@RequestBody UserToken userToken){ + return firebaseNotificationService.updateToken(userToken); + } + + @RequestMapping(value = "getToken",method = RequestMethod.GET,headers = "Authorization") + public String getUserToken() throws IEMRException { + + return firebaseNotificationService.getUserToken(); + } + } diff --git a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java new file mode 100644 index 00000000..f27d74e4 --- /dev/null +++ b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java @@ -0,0 +1,22 @@ +package com.iemr.common.data.userToken; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +import java.sql.Timestamp; + +@Entity +@Table(name = "user_tokens", schema = "db_iemr") +@Data +public class UserTokenData { + @Id + @Column(name = "user_id") + Integer userId; + @Column(name = "token") + String token; + @Column(name = "updated_at") + Timestamp updatedAt; +} diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index eed0c171..c81f68c4 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -8,7 +8,6 @@ public class NotificationMessage { private String appType; private String token; - private String topic; private String title; private String body; private Map data; diff --git a/src/main/java/com/iemr/common/model/notification/UserToken.java b/src/main/java/com/iemr/common/model/notification/UserToken.java new file mode 100644 index 00000000..d68d6c5e --- /dev/null +++ b/src/main/java/com/iemr/common/model/notification/UserToken.java @@ -0,0 +1,9 @@ +package com.iemr.common.model.notification; + +import lombok.Data; + +@Data +public class UserToken { + Integer userId; + String token; +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index e41ca94f..0fe37b5a 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -4,11 +4,23 @@ import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Notification; +import com.iemr.common.data.userToken.UserTokenData; import com.iemr.common.model.notification.NotificationMessage; +import com.iemr.common.model.notification.UserToken; +import com.iemr.common.repo.userToken.UserTokenRepo; +import com.iemr.common.utils.CookieUtil; +import com.iemr.common.utils.JwtUtil; +import com.iemr.common.utils.exception.IEMRException; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.sql.Timestamp; +import java.util.Optional; @Service public class FirebaseNotificationService { @@ -17,6 +29,16 @@ public class FirebaseNotificationService { @Autowired FirebaseMessaging firebaseMessaging; + @Autowired + private UserTokenRepo userTokenRepo; + + @Autowired + private CookieUtil cookieUtil; + + @Autowired + private JwtUtil jwtUtil; + + public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); @@ -34,4 +56,35 @@ public String sendNotification(NotificationMessage notificationMessage) { } } + public String updateToken(UserToken userToken) { + Optional existingTokenData = userTokenRepo.findById(userToken.getUserId()); + + UserTokenData userTokenData; + + if (existingTokenData.isPresent()) { + // User token exist karta hai => update karna hai + userTokenData = existingTokenData.get(); + userTokenData.setToken(userToken.getToken()); + userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + } else { + // User token nahi mila => naya insert karna hai + userTokenData = new UserTokenData(); + userTokenData.setUserId(userToken.getUserId()); + userTokenData.setToken(userToken.getToken()); + userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); + } + + userTokenRepo.save(userTokenData); + return "Save Successfully"; + } + + public String getUserToken() throws IEMRException { + HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) + .getRequest(); + String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader); + return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB + .map(UserTokenData::getToken) // mil gaya to token nikalo + .orElse(null); // nah + } + } From bddf0dc16c41a01800462661f64d086437b46c2b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 13:04:41 +0530 Subject: [PATCH 142/318] Firebase update userToken --- .../FirebaseNotificationController.java | 24 ++++++++++++++ .../common/data/userToken/UserTokenData.java | 24 ++++++++++++++ .../notification/NotificationMessage.java | 24 ++++++++++++++ .../common/model/notification/UserToken.java | 24 ++++++++++++++ .../common/repo/userToken/UserTokenRepo.java | 31 +++++++++++++++++++ .../FirebaseNotificationService.java | 24 ++++++++++++++ 6 files changed, 151 insertions(+) create mode 100644 src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 3e39fe21..89fb01a9 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.controller.firebaseNotification; import com.iemr.common.model.notification.NotificationMessage; diff --git a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java index f27d74e4..0646972e 100644 --- a/src/main/java/com/iemr/common/data/userToken/UserTokenData.java +++ b/src/main/java/com/iemr/common/data/userToken/UserTokenData.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.data.userToken; import jakarta.persistence.Column; diff --git a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java index c81f68c4..58343034 100644 --- a/src/main/java/com/iemr/common/model/notification/NotificationMessage.java +++ b/src/main/java/com/iemr/common/model/notification/NotificationMessage.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.model.notification; import lombok.Data; diff --git a/src/main/java/com/iemr/common/model/notification/UserToken.java b/src/main/java/com/iemr/common/model/notification/UserToken.java index d68d6c5e..3ea36588 100644 --- a/src/main/java/com/iemr/common/model/notification/UserToken.java +++ b/src/main/java/com/iemr/common/model/notification/UserToken.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.model.notification; import lombok.Data; diff --git a/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java b/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java new file mode 100644 index 00000000..817f26f0 --- /dev/null +++ b/src/main/java/com/iemr/common/repo/userToken/UserTokenRepo.java @@ -0,0 +1,31 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ +package com.iemr.common.repo.userToken; + +import com.iemr.common.data.userToken.UserTokenData; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserTokenRepo extends JpaRepository { +} diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 0fe37b5a..7705fb9e 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -1,3 +1,27 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ package com.iemr.common.service.firebaseNotification; import com.google.firebase.FirebaseException; From affd611c4e76c2172c17831285e7a33085b6a433 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 18:33:51 +0530 Subject: [PATCH 143/318] Add firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 41881886..1e8be6c2 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -187,4 +187,11 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS} video-call-url=${VIDEO_CALL_URL} jibri.output.path={JIBRI_OUTPUT_PATH} -video.recording.path={VIDEO_RECORDING_PATH} \ No newline at end of file +video.recording.path={VIDEO_RECORDING_PATH} + +# Firebase Configuration +firebase.enabled=@env.FIREBASE_ENABLE@ +# if using file +firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +# for CI/CD +firebase.credential-base64=@env.CREDENTIAL_BASE64@ \ No newline at end of file From 13031c49d2de649fa044b31560942fd06c5a1344 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 19 Jun 2025 20:06:02 +0530 Subject: [PATCH 144/318] Add firebase variables in common_docker.properties --- .../firebaseNotification/FirebaseNotificationService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 7705fb9e..ea0cc005 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -86,12 +86,10 @@ public String updateToken(UserToken userToken) { UserTokenData userTokenData; if (existingTokenData.isPresent()) { - // User token exist karta hai => update karna hai userTokenData = existingTokenData.get(); userTokenData.setToken(userToken.getToken()); userTokenData.setUpdatedAt(new Timestamp(System.currentTimeMillis())); } else { - // User token nahi mila => naya insert karna hai userTokenData = new UserTokenData(); userTokenData.setUserId(userToken.getUserId()); userTokenData.setToken(userToken.getToken()); @@ -107,8 +105,8 @@ public String getUserToken() throws IEMRException { .getRequest(); String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader); return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB - .map(UserTokenData::getToken) // mil gaya to token nikalo - .orElse(null); // nah + .map(UserTokenData::getToken) + .orElse(null); // } } From 433ffeccc253196748ffbaa104ee3e7ddf6c606d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 10:43:43 +0530 Subject: [PATCH 145/318] update firebase variables in common_docker.properties --- .../java/com/iemr/common/utils/JwtUtil.java | 238 +++++++----------- 1 file changed, 90 insertions(+), 148 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index dc29018c..0ea70bda 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -1,164 +1,106 @@ package com.iemr.common.utils; -import io.jsonwebtoken.*; -import io.jsonwebtoken.security.Keys; +import java.util.Date; +import java.util.UUID; +import java.util.function.Function; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; + import javax.crypto.SecretKey; -import java.util.Date; -import java.util.UUID; -import java.util.function.Function; @Component public class JwtUtil { - @Value("${jwt.secret}") - private String SECRET_KEY; - - @Value("${jwt.access.expiration}") - private long ACCESS_EXPIRATION_TIME; - - @Value("${jwt.refresh.expiration}") - private long REFRESH_EXPIRATION_TIME; - - @Autowired - private TokenDenylist tokenDenylist; - - private SecretKey getSigningKey() { - if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { - throw new IllegalStateException("JWT secret key is not set in application.properties"); - } - return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); - } - - /** - * Generate an access token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT access token - */ - public String generateToken(String username, String userId) { - return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); - } - - /** - * Generate a refresh token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT refresh token - */ - public String generateRefreshToken(String username, String userId) { - return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); - } - - /** - * Build a JWT token with the specified parameters. - * - * @param username the username of the user - * @param userId the user ID - * @param tokenType the type of the token (access or refresh) - * @param expiration the expiration time of the token in milliseconds - * @return the generated JWT token - */ - private String buildToken(String username, String userId, String tokenType, long expiration) { - return Jwts.builder() - .subject(username) - .claim("userId", userId) - .claim("token_type", tokenType) - .id(UUID.randomUUID().toString()) - .issuedAt(new Date()) - .expiration(new Date(System.currentTimeMillis() + expiration)) - .signWith(getSigningKey()) - .compact(); - } - - /** - * Validate the JWT token, checking if it is expired and if it's blacklisted - * @param token the JWT token - * @return Claims if valid, null if invalid (expired or denylisted) - */ - public Claims validateToken(String token) { - try { - Claims claims = Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); - String jti = claims.getId(); - - // Check if token is denylisted (only if jti exists) - if (jti != null && tokenDenylist.isTokenDenylisted(jti)) { - return null; - } - - return claims; - } catch (ExpiredJwtException ex) { - - return null; // Token is expired, so return null - } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { - return null; // Return null for any other JWT-related issue (invalid format, bad signature, etc.) - } - } - - /** - * Extract claims from the token - * @param token the JWT token - * @return all claims from the token - */ - public Claims getAllClaimsFromToken(String token) { - return Jwts.parser() + @Value("${jwt.secret}") + private String SECRET_KEY; + + @Value("${jwt.access.expiration}") + private long ACCESS_EXPIRATION_TIME; + + @Value("${jwt.refresh.expiration}") + private long REFRESH_EXPIRATION_TIME; + + private SecretKey getSigningKey() { + if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { + throw new IllegalStateException("JWT secret key is not set in application.properties"); + } + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + + public String generateToken(String username, String userId) { + return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); + } + + public String generateRefreshToken(String username, String userId) { + return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); + } + + private String buildToken(String username, String userId, String tokenType, long expiration) { + return Jwts.builder() + .subject(username) + .claim("userId", userId) + .claim("token_type", tokenType) + .id(UUID.randomUUID().toString()) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + expiration)) + .signWith(getSigningKey()) + .compact(); + } + + public Claims validateToken(String token) { + try { + return Jwts.parser() + .verifyWith(getSigningKey()) + .build() + .parseSignedClaims(token) + .getPayload(); + + } catch (ExpiredJwtException ex) { + // Handle expired token specifically if needed + } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { + // Log specific error types + } + return null; + } + + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + public Claims getAllClaimsFromToken(String token) { + return Jwts.parser() .verifyWith(getSigningKey()) .build() .parseSignedClaims(token) .getPayload(); + } + + + public long getRefreshTokenExpiration() { + return REFRESH_EXPIRATION_TIME; + } + + // Additional helper methods + public String getJtiFromToken(String token) { + return getAllClaimsFromToken(token).getId(); + } + + public String getUsernameFromToken(String token) { + return getAllClaimsFromToken(token).getSubject(); + } + + public String extractUserId(String token) { + return getAllClaimsFromToken(token).getId(); - } - - /** - * Extract a specific claim from the token using a function - * @param token the JWT token - * @param claimsResolver the function to extract the claim - * @param the type of the claim - * @return the extracted claim - */ - public T getClaimFromToken(String token, Function claimsResolver) { - final Claims claims = getAllClaimsFromToken(token); - return claimsResolver.apply(claims); - } - - /** - * Get the JWT ID (JTI) from the token - * @param token the JWT token - * @return the JWT ID - */ - public String getJtiFromToken(String token) { - return getAllClaimsFromToken(token).getId(); - } - - /** - * Get the username from the token - * @param token the JWT token - * @return the username - */ - public String getUsernameFromToken(String token) { - return getAllClaimsFromToken(token).getSubject(); - } - - /** - * Get the user ID from the token - * @param token the JWT token - * @return the user ID - */ - public String getUserIdFromToken(String token) { - return getAllClaimsFromToken(token).get("userId", String.class); - } - - /** - * Get the expiration time of the refresh token - * @return the expiration time in milliseconds - */ - public long getRefreshTokenExpiration() { - return REFRESH_EXPIRATION_TIME; - } -} + } +} \ No newline at end of file From af65376c272b19a751661785393f5f38267f5227 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 11:05:35 +0530 Subject: [PATCH 146/318] update firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 1e8be6c2..556fe048 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -190,8 +190,8 @@ jibri.output.path={JIBRI_OUTPUT_PATH} video.recording.path={VIDEO_RECORDING_PATH} # Firebase Configuration -firebase.enabled=@env.FIREBASE_ENABLE@ +firebase.enabled= ${FIREBASE_ENABLE} # if using file -firebase.credential-file=@env.FIREBASE_CREDENTIAL@ +firebase.credential-file= ${FIREBASE_CREDENTIAL} # for CI/CD -firebase.credential-base64=@env.CREDENTIAL_BASE64@ \ No newline at end of file +firebase.credential-base64= ${CREDENTIAL_BASE64} \ No newline at end of file From d4d6cbfac4a292c5e65dbe02eef059dcd85d920b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 20 Jun 2025 11:07:04 +0530 Subject: [PATCH 147/318] update firebase variables in common_docker.properties --- src/main/environment/common_docker.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 556fe048..2b999cb0 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -190,8 +190,8 @@ jibri.output.path={JIBRI_OUTPUT_PATH} video.recording.path={VIDEO_RECORDING_PATH} # Firebase Configuration -firebase.enabled= ${FIREBASE_ENABLE} +firebase.enabled=${FIREBASE_ENABLE} # if using file -firebase.credential-file= ${FIREBASE_CREDENTIAL} +firebase.credential-file=${FIREBASE_CREDENTIAL} # for CI/CD -firebase.credential-base64= ${CREDENTIAL_BASE64} \ No newline at end of file +firebase.credential-base64=${CREDENTIAL_BASE64} \ No newline at end of file From 1441f990075ac017881cb502bcf52d5b2881221e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Sat, 21 Jun 2025 11:17:38 +0530 Subject: [PATCH 148/318] fixed code --- .../com/iemr/common/model/beneficiary/BeneficiaryModel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index 39a7233b..184a5637 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -92,8 +92,7 @@ public class BeneficiaryModel implements Comparable { private TitleModel m_title; @Expose private String firstName; - @Expose - private Boolean isConsent=false; + @Expose private String middleName; From 4376a8a7b440734777671a24ca44b5e6f7454cee Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Sat, 21 Jun 2025 11:29:03 +0530 Subject: [PATCH 149/318] fixed code --- .../beneficiaryConsent/BeneficiaryConsentController.java | 4 ++-- .../com/iemr/common/controller/users/IEMRAdminController.java | 2 +- .../java/com/iemr/common/dto/identity/CommonIdentityDTO.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index 60c7bdee..3b89f63e 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -54,7 +54,7 @@ public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"In OutputResponse response = new OutputResponse(); try { - OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); JSONObject responseOBJ = beneficiaryOTPHandler.validateOTP(obj); if (responseOBJ != null) @@ -77,7 +77,7 @@ public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBod OutputResponse response = new OutputResponse(); try { - OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); + BeneficiaryConsentRequest obj = InputMapper.gson().fromJson(requestOBJ, BeneficiaryConsentRequest.class); String success = beneficiaryOTPHandler.resendOTP(obj); logger.info(success.toString()); diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 28c7e4b9..e1b20d66 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -581,7 +581,7 @@ public String getLoginResponse(HttpServletRequest request) { } // Extract user ID from the JWT token - String userId = jwtUtil.getUserIdFromToken(jwtToken); + String userId = jwtUtil.extractUserId(jwtToken); // Get user details and prepare response User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); diff --git a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java index c057b58d..8e364eb3 100644 --- a/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java +++ b/src/main/java/com/iemr/common/dto/identity/CommonIdentityDTO.java @@ -61,7 +61,6 @@ public class CommonIdentityDTO { private Integer educationId; private String education; private Boolean emergencyRegistration = false; - private Boolean isConsent; private Integer healthCareWorkerId; private String healthCareWorker; private String fatherName; From 807f0436c030e6dd8bb4699551a6e46150e7048e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 11:57:37 +0530 Subject: [PATCH 150/318] Fixed security hotspot --- .../BeneficiaryConsentController.java | 25 ++++++++++++++++--- .../BeneficiaryOTPHandlerImpl.java | 1 - 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index 3b89f63e..e8e55034 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -1,9 +1,28 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.controller.beneficiaryConsent; import com.iemr.common.data.beneficiaryConsent.BeneficiaryConsentRequest; -import com.iemr.common.data.otp.OTPRequestParsor; import com.iemr.common.service.beneficiaryOTPHandler.BeneficiaryOTPHandler; -import com.iemr.common.service.otp.OTPHandler; import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.response.OutputResponse; import io.lettuce.core.dynamic.annotation.Param; @@ -26,7 +45,6 @@ public class BeneficiaryConsentController { @Operation(summary = "Send Consent") @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { - logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -41,7 +59,6 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody response.setError(500, "failure"); } catch (Exception e) { - logger.error("error in sending Consent : " + e); response.setError(500, "error : " + e); } return response.toString(); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 9fa73005..6f791a87 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -199,7 +199,6 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { return response.getBody(); } catch (Exception e) { - e.printStackTrace(); return "Error sending SMS: " + e.getMessage(); } } From 2f728d3d3ef9a89ac9602e0b27c826127ccfc936 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 17:41:23 +0530 Subject: [PATCH 151/318] Fixed security hotspot --- .../BeneficiaryConsentController.java | 9 +++--- .../BeneficiaryOTPHandlerImpl.java | 31 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index e8e55034..e917204c 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -35,7 +35,10 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +@RequestMapping(value = { "/beneficiaryConsent" },headers ="Authorization" ) +@RestController public class BeneficiaryConsentController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @@ -53,10 +56,8 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String success = beneficiaryOTPHandler.sendOTP(obj); // method name unchanged if internal logic still uses 'OTP' logger.info(success.toString()); - if (success.contains("otp")) - response.setResponse(success); - else - response.setError(500, "failure"); + response.setResponse(success); + } catch (Exception e) { response.setError(500, "error : " + e); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 6f791a87..17027667 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -87,8 +87,7 @@ public String load(String key) { @Override public String sendOTP(BeneficiaryConsentRequest obj) throws Exception { int otp = generateOTP(obj.getMobNo()); - sendSMS(otp, obj); - return "success"; + return sendSMS(otp, obj); } /*** @@ -122,8 +121,7 @@ public JSONObject validateOTP(BeneficiaryConsentRequest obj) throws Exception { @Override public String resendOTP(BeneficiaryConsentRequest obj) throws Exception { int otp = generateOTP(obj.getMobNo()); - sendSMS(otp, obj); - return "success"; + return sendSMS(otp, obj); } // generate 6 digit random no # @@ -161,16 +159,17 @@ private String getEncryptedOTP(int otp) throws Exception { public String sendSMS(int otp, BeneficiaryConsentRequest obj) { final RestTemplate restTemplate = new RestTemplate(); - String sendSMSURL = ConfigProperties.getPropertyByName("send-message-url"); - String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL + "/" + sendSMSURL; + String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); + SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); + String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL; try { - - -// String message = "Dear Citizen, your OTP for login is " +otp+". Use it within 15 minutes. Do not share this code. Regards PSMRIAM."; - String message = "Hello! Your OTP for providing consent for registration on AMRIT is " + otp + ". This OTP is valid for 10 minutes. Kindly share it only with " + obj.getUserName() + " " + obj.getDesignation() + " to complete the process. PSMRI"; + String message = template.getSmsTemplate() + .replace("$$OTP$$",String.valueOf(otp)) + .replace("$$UserName$$", obj.getUserName()) + .replace("$$Designation$$", obj.getDesignation()); // Build payload Map payload = new HashMap<>(); @@ -179,8 +178,8 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("message", message); payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", ConfigProperties.getPropertyByName("dltTemplateId")); - payload.put("entityId",ConfigProperties.getPropertyByName("entityId") ); + payload.put("dltTemplateId", dltTemplateId); + payload.put("entityId",ConfigProperties.getPropertyByName("sms-entityid") ); payload.put("otp", true); // Set headers HttpHeaders headers = new HttpHeaders(); @@ -194,9 +193,13 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { // Call API ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + logger.info("sms-response:"+response.getBody()); + if(response.getStatusCode().value()==200){ + return "OTP sent successfully on register mobile number"; + }else { + return "Fail"; - // Return response - return response.getBody(); + } } catch (Exception e) { return "Error sending SMS: " + e.getMessage(); From 2c8277fbf518f902d692bc6355c18b5318a5dd83 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 18:19:09 +0530 Subject: [PATCH 152/318] Remove firebase base64 variable --- src/main/environment/common_ci.properties | 2 -- src/main/environment/common_docker.properties | 2 -- .../common/config/firebase/FirebaseMessagingConfig.java | 7 +------ 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index bb1a8b1c..5f6fda30 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -44,8 +44,6 @@ cron-scheduler-sms=0 0/1 * * * ? * firebase.enabled=@env.FIREBASE_ENABLE@ # if using file firebase.credential-file=@env.FIREBASE_CREDENTIAL@ -# for CI/CD -firebase.credential-base64=@env.CREDENTIAL_BASE64@ #### Email Configuration send-email=@env.SEND_EMAIL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 2b999cb0..efe99a89 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -193,5 +193,3 @@ video.recording.path={VIDEO_RECORDING_PATH} firebase.enabled=${FIREBASE_ENABLE} # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} -# for CI/CD -firebase.credential-base64=${CREDENTIAL_BASE64} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 438ca4f9..250558bb 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -22,8 +22,6 @@ public class FirebaseMessagingConfig { @Value("${firebase.credential-file:}") private String firebaseCredentialFile; - @Value("${firebase.credential-base64:}") - private String firebaseCredentialBase64; @Bean public FirebaseMessaging firebaseMessaging() throws IOException { @@ -33,10 +31,7 @@ public FirebaseMessaging firebaseMessaging() throws IOException { GoogleCredentials credentials; - if (!firebaseCredentialBase64.isBlank()) { - byte[] decoded = Base64.getDecoder().decode(firebaseCredentialBase64); - credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(decoded)); - } else if (!firebaseCredentialFile.isBlank()) { + if (!firebaseCredentialFile.isBlank()) { credentials = GoogleCredentials.fromStream( new ClassPathResource(firebaseCredentialFile).getInputStream() ); From 157a6e6b1856326917c51f57e4421ffafa5f778d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 18:39:49 +0530 Subject: [PATCH 153/318] Remove firebase base64 variable --- src/main/environment/common_docker.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index efe99a89..f3f7ebfd 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -193,3 +193,4 @@ video.recording.path={VIDEO_RECORDING_PATH} firebase.enabled=${FIREBASE_ENABLE} # if using file firebase.credential-file=${FIREBASE_CREDENTIAL} + From c88d2c12688abb7fadeb2a41e91f706a37280b1d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 19:14:36 +0530 Subject: [PATCH 154/318] fix firebase file access issue --- .../config/firebase/FirebaseMessagingConfig.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 250558bb..9a0c88a0 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -10,6 +10,7 @@ import org.springframework.core.io.ClassPathResource; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.util.Base64; @@ -29,16 +30,12 @@ public FirebaseMessaging firebaseMessaging() throws IOException { throw new IllegalStateException("Firebase is disabled"); } - GoogleCredentials credentials; - - if (!firebaseCredentialFile.isBlank()) { - credentials = GoogleCredentials.fromStream( - new ClassPathResource(firebaseCredentialFile).getInputStream() - ); - } else { - throw new IllegalStateException("No Firebase credentials provided"); + if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { + throw new IllegalStateException("No Firebase credentials path provided"); } + GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(firebaseCredentialFile)); + FirebaseOptions options = FirebaseOptions.builder() .setCredentials(credentials) .build(); From 1e900a33d21c5711b9153b2163c2240783611c0c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 23 Jun 2025 19:16:06 +0530 Subject: [PATCH 155/318] fix firebase file access issue --- .../com/iemr/common/config/firebase/FirebaseMessagingConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index 9a0c88a0..ebb98b59 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -46,4 +46,5 @@ public FirebaseMessaging firebaseMessaging() throws IOException { return FirebaseMessaging.getInstance(firebaseApp); } + } From 845c1389122ccf26c23dfe729693286e45a1cc9a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:10:04 +0530 Subject: [PATCH 156/318] dynamic form --- .../dynamicForm/DynamicFormController.java | 30 ++++++++++++++++ .../common/data/dynamic_from/FormEntity.java | 25 +++++++++++++ .../data/dynamic_from/ModuleEntity.java | 23 ++++++++++++ .../common/dto/dynamicForm/FormFieldDTO.java | 23 ++++++++++++ .../dto/dynamicForm/FormTypeEntityDTO.java | 18 ++++++++++ .../dto/dynamicForm/ModuleEntityDTO.java | 12 +++++++ .../dynamic_form/FormTypeRepository.java | 8 +++++ .../dynamic_form/ModuleRepository.java | 10 ++++++ .../service/dynamicForm/FormTypeService.java | 35 +++++++++++++++++++ .../service/dynamicForm/ModuleService.java | 26 ++++++++++++++ 10 files changed, 210 insertions(+) create mode 100644 src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java new file mode 100644 index 00000000..f15ad2c0 --- /dev/null +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -0,0 +1,30 @@ +package com.iemr.common.controller.dynamicForm; + +import com.iemr.common.data.dynamic_from.FormEntity; +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; +import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; +import com.iemr.common.service.dynamicForm.FormTypeService; +import com.iemr.common.service.dynamicForm.ModuleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequestMapping(value = "masterFrom") +@RestController +public class DynamicFormController { + @Autowired ModuleService moduleService; + @Autowired + private FormTypeService formTypeService; + + @PostMapping("/modules") + public ResponseEntity createModule(@RequestBody ModuleEntityDTO module) { + return ResponseEntity.ok(moduleService.save(module)); + } + + @PostMapping("/modules/{moduleId}/form-types") + public ResponseEntity createFormType(@PathVariable Long moduleId, @RequestBody FormTypeEntityDTO formType) { + return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); + } + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java new file mode 100644 index 00000000..0b81e148 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -0,0 +1,25 @@ +package com.iemr.common.data.dynamic_from; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.persistence.*; +import lombok.Data; + +@Data +@Entity +@Table(name = "form_types",schema = "db_imer") +public class FormEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "Id") + private Long id; + + @Column(name = "form_name",columnDefinition = "TEXT") + private String formName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "module_id") + private ModuleEntity module; + + @Column(name = "fields",columnDefinition = "TEXT") + private String fields ; +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java new file mode 100644 index 00000000..4d699a7e --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java @@ -0,0 +1,23 @@ +package com.iemr.common.data.dynamic_from; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.persistence.*; +import lombok.Data; + +import java.util.List; +@Data +@Entity +@Table(name = "m_modules",schema = "db_iemr") +public class ModuleEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "Id") + private Long id; + + @Column(name = "module_name",columnDefinition = "TEXT") + private String moduleName; + + @OneToMany(mappedBy = "module", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List formTypes; + +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java new file mode 100644 index 00000000..27a6ee93 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java @@ -0,0 +1,23 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FormFieldDTO { + private String name; + private String label; + private String type; + private boolean required; + private String inputType; + private String fileType; + private String buttonAction; + private String visibleIfField; + private String visibleIfValue; + private Map validations; + private List> options; + + // Getters and Setters +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java new file mode 100644 index 00000000..ff31dfd5 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java @@ -0,0 +1,18 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class FormTypeEntityDTO { + + private Long id; + + private String formName; + + private ModuleEntityDTO module; + + private List fields; + +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java new file mode 100644 index 00000000..03cfc834 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java @@ -0,0 +1,12 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; +@Data +public class ModuleEntityDTO { + private Long id; + private String moduleName; + +} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java new file mode 100644 index 00000000..b3b731fe --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java @@ -0,0 +1,8 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormEntity; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FormTypeRepository extends CrudRepository {} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java new file mode 100644 index 00000000..e4eb221e --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java @@ -0,0 +1,10 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.ModuleEntity; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ModuleRepository extends CrudRepository { + +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java new file mode 100644 index 00000000..38068cdc --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java @@ -0,0 +1,35 @@ +package com.iemr.common.service.dynamicForm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iemr.common.data.dynamic_from.FormEntity; +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; +import com.iemr.common.repository.dynamic_form.FormTypeRepository; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FormTypeService { + @Autowired + ModuleRepository moduleRepo; + @Autowired + FormTypeRepository formTypeRepo; + @Autowired + ObjectMapper objectMapper; + + public FormEntity createFormType(Long moduleId, FormTypeEntityDTO formTypeDTO) { + ModuleEntity module = moduleRepo.findById(moduleId).orElseThrow(); + FormEntity formType = new FormEntity(); + formType.setFormName(formTypeDTO.getFormName()); + formType.setModule(module); + try { + String fieldsJson = objectMapper.writeValueAsString(formTypeDTO.getFields()); + formType.setFields(fieldsJson); + } catch (JsonProcessingException e) { + throw new RuntimeException("Failed to serialize form fields", e); + } + return formTypeRepo.save(formType); + } +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java new file mode 100644 index 00000000..644d2c59 --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java @@ -0,0 +1,26 @@ +package com.iemr.common.service.dynamicForm; + +import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class ModuleService { + @Autowired + ModuleRepository repo; + + public ModuleEntity save(ModuleEntityDTO module) { + ModuleEntity moduleEntity = new ModuleEntity(); + moduleEntity.setModuleName(module.getModuleName()); + return repo.save(moduleEntity); + } + + public Optional findById(Long id) { + return repo.findById(id); + } +} + From d6abd658e48b556d3ddc8aff558e6d3df6ec0f91 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:10:54 +0530 Subject: [PATCH 157/318] dynamic form --- src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java index 0b81e148..6f4445a6 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -22,4 +22,5 @@ public class FormEntity { @Column(name = "fields",columnDefinition = "TEXT") private String fields ; + } From 9a743da14e6e541ee00d8fd91e0bcac77fa54aa1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 30 Jun 2025 15:18:08 +0530 Subject: [PATCH 158/318] dynamic form --- src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java index 6f4445a6..578111f5 100644 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java @@ -23,4 +23,5 @@ public class FormEntity { @Column(name = "fields",columnDefinition = "TEXT") private String fields ; + } From 6c1417d682fcb9aea3cb8c1958ffb5bcb06d57c9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 1 Jul 2025 10:19:04 +0530 Subject: [PATCH 159/318] dynamic form --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index f15ad2c0..9a924872 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -27,4 +27,5 @@ public ResponseEntity createFormType(@PathVariable Long moduleId, @R return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); } + } From cd9417a685b83c6674ae87d446d8fa27968b1980 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 3 Jul 2025 21:23:36 +0530 Subject: [PATCH 160/318] IDENTITY_BASE_URL fix --- .../IdentityBeneficiaryServiceImpl.java | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 697322c6..9056eb45 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -26,15 +26,11 @@ import java.util.HashSet; import java.util.List; +import com.google.gson.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import com.iemr.common.dto.identity.BeneficiariesDTO; import com.iemr.common.dto.identity.BeneficiariesPartialDTO; import com.iemr.common.dto.identity.IdentityEditDTO; @@ -399,23 +395,40 @@ public List getBeneficiaryListByGovId(String identity, String @Override public String getIdentityResponse(String request, String auth, Boolean is1097) throws IEMRException { - String result; HashMap header = new HashMap<>(); if (auth != null) { header.put("Authorization", auth); } - result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), request, header); - OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); - if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { - throw new IEMRException(identityResponse.getErrorMessage()); + String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); + + logger.info("Calling URL: {}", apiUrl); + logger.info("Request Payload: {}", request); + + result = httpUtils.post(apiUrl, request, header); + + if (result == null || result.isEmpty()) { + logger.error("Empty response from Identity API"); + throw new IEMRException("No response received from Identity API"); + } + + try { + OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); + if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { + throw new IEMRException(identityResponse.getErrorMessage()); + } + } catch (JsonSyntaxException e) { + logger.error("JSON parsing error: {}", e.getMessage()); + throw new IEMRException("Invalid response format from Identity API"); } + return result; } + public Integer editIdentityEditDTO(IdentityEditDTO identityEditDTO, String auth, Boolean is1097) throws IEMRException { JsonParser parser = new JsonParser(); From 8bf6d0c2ce214c9f98b3744d60768d0763b8224b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 3 Jul 2025 21:33:17 +0530 Subject: [PATCH 161/318] IDENTITY_BASE_URL fix --- src/main/resources/application.properties | 214 +++++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 813637b0..180ad75d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -115,7 +115,9 @@ identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenR identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= identity-api-url-getByBenId =IDENTITY_BASE_URL/id/getByBenId?benId= identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= -identity-api-url-benCreate =IDENTITY_BASE_URL/id/create +IDENTITY_API_URL=https://amritdemo.piramalswasthya.org +identity-api-url-benCreate=${IDENTITY_API_URL}/id/create +#identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity @@ -173,3 +175,213 @@ failedLoginAttempt=5 jwt.access.expiration=86400000 jwt.refresh.expiration=604800000 +# local env +server.port=8083 +# DB Connections +spring.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_iemr +spring.datasource.username=root +spring.datasource.password=BizDev@24BB +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +encDbUserName=zFlYsp9Z0s+lRvLM15A3g/Ba0w8VGs/1usuW7EsGF3k= +encDbPass=JGGAGn5wTlrbTLUHY+5BzfBa0w8VGs/1usuW7EsGF3k= + +secondary.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_reporting +secondary.datasource.username=root +secondary.datasource.password=BizDev@24BB +secondary.datasource.driver-class-name=com.mysql.jdbc.Driver +firebase.enabled = true +firebase.credential-file =firebase_cred.json + + + +## KM Configuration +km-base-protocol=http +km-username=okmAdmin +km-password=admin +km-base-url=http://localhost:8084/OpenKM +km-base-path=localhost:8084/OpenKM +km-root-path=/okm:personal/users/ +km-guest-user=guest +km-guest-password=guest + +# CTI Config +cti-server-ip=10.208.122.99 +cti-logger_base_url=http://10.208.122.99/logger +sms-gateway-url = + +# Identity Config +identity-api-url = http://localhost:8094/ +#Verify whether 1097 and identity are same? +identity-1097-api-url = http://localhost:8095/ +##Generate Benificiary Config +genben-api=http://localhost:8092/ + +#### SMS Configuration +send-sms=false +sendSMSUrl = http://localhost:8080/sms/sendSMS +source-address=AIDSHL +sms-username= +sms-password= +send-message-url= + +###SMS Scheduler configurations +start-sms-scheduler=false +cron-scheduler-sms=0 0/1 * * * ? * + +#### Email Configuration +send-email=false +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username= +spring.mail.password= +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true + +###Email Scheduler configurations +start-email-scheduler=true +cron-scheduler-email=0 0/1 * * * ? * + +##-------------------------------###cti data sync Scheduler configurations------------------------------------------------------ + +start-ctidatasync-scheduler=false +cron-scheduler-ctidatasync=0 0 2 */2 * ? + +##-------------------------------###cti data check with call detail report Scheduler------------------------------------------------------ + +#Runs at everyday 12:10AM +start-ctidatacheck-scheduler=true +cron-scheduler-ctidatacheck=0 10 00 * * * + +##---------------------------------#### Registration schedular for Avni------------------------------------------------------------------------------ + +start-avni-scheduler=false +cron-avni-registration=0 0/1 * * * ? * + +##------------------------------------------------#### Everwell Regsitration Scheduler--------------------------------------------------------------- + +start-registration-scheduler=false +cron-scheduler-registration=0 34 19 * * ? * + +##----------------------------------------------------#everwell data sync----------------------------------------------------------- + +start-everwelldatasync-scheduler=false +cron-scheduler-everwelldatasync=0 0/5 * * * ? * + +##-----------------------------------------------#NHM data dashboard schedular---------------------------------------------------------------- +# run at everyday 12:01AM +start-nhmdashboard-scheduler=true +cron-scheduler-nhmdashboard=0 1 * * * ? * +##----------------------------------------------------#grievance data sync----------------------------------------------------------- + +start-grievancedatasync-scheduler=false +cron-scheduler-grievancedatasync=0 0/2 * * * ? + +### Redis IP +spring.redis.host=localhost + +##--------------------------------------------------------------------------------------------------------------- +###CTI data sync schedular +cz-duration=40 +##--------------------------------------------------------------------------------------------------------------- +## prescription template +TMprescriptionTemplate=TMPrescription +##--------------------------------------------------------------------------------------------------------------- +##duration for everwell calender +everwellCalendarDuration=15 +##--------------------------------------------------------------------------------------------------------------- +##lonic variables +lonicPageSize=10 +##--------------------------------------------------------------------------------------------------------------- +#snomedcti +snomedCTPageSize=10 +##--------------------------------------------------------------------------------------------------------------- +#call retry count +callRetryConfiguration=3 +##--------------------------------------------------------------------------------------------------------------- +#avni registration Duration +avniRegistrationLimit=7 + +#--------------------------NHM Agent Real Time Data---------------------------- +nhm.agent.real.time.data.url= http://175.101.1.83/apps/utility/alive_api.php +nhm.agent.real.time.data.cron.scheduler=0 */2 * ? * * +nhm.agent.real.time.data.cron.flag=true + +carestream_socket_ip = 192.168.43.39 +carestream_socket_port = 1235 + +## everwell variables +everwellUserName = +everwellPassword = +amritUserName = +amritPassword = + +## everwell API call +everwellAddSupportAction = https://beta-hub.everwell.org/Api/Patients/AddSupportAction +everwellEditDoses = https://beta-hub.everwell.org/Api/Patients/EditManualDoses +everwellEditMissedDoses = https://beta-hub.everwell.org/Api/Patients/EditMissedDoses +everwellGetPatientAdherenceUrl = https://beta-hub.everwell.org/Api/Patients/CurrentMonthMissedAdherence?Page= +everwellEditSecondaryPhoneNo = https://beta-hub.everwell.org/Api/Patients/EditPhoneNumber +everwell1097userAuthenticate = http://localhost:8083/user/userAuthenticate +everwelluserAuthenticate = https://beta-hub.everwell.org/token +everwellRegisterBenficiary = http://localhost:8083/beneficiary/create + + +## LungAssessment credentials +lungAssessmentEmail = +lungAssessmentPassword = + + +## SWASSA APIs +lungAssessmentAdminLogin = http://swaasa.sandbox.swaasa.ai/api/adminLogin +lungAssessmentValidateCough = http://swaasa.sandbox.swaasa.ai/api/verifycough +lungAssessmentStartAssesment = http://swaasa.sandbox.swaasa.ai/api/assessment +lungAssessmentGetAssesment = http://swaasa.sandbox.swaasa.ai/api/getAssessment + +#E- Sanjeevani user authenticate creds +eSanjeevani.url: https://preprod.esanjeevaniopd.xyz/uat/aus/api/ThirdPartyAuth/providerLogin +eSanjeevani.userName: +eSanjeevani.password: +eSanjeevani.salt: 123456 +eSanjeevani.source: 11001 +eSanjeevani.registerPatient: https://preprod.esanjeevaniopd.xyz/uat/ps/api/v1/Patient +eSanjeevani.routeUrl: https://uat.esanjeevani.in/user/signin + +biometric.discover.url = http://127.0.0.1:port/ +biometric.deviceInfo.url = http://127.0.0.1:port/rd/info +biometric.capture.url = http://127.0.0.1:port/rd/capture +eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward + +eausadhaAuthorization= +spring.main.allow-bean-definition-overriding=true +spring.main.allow-circular-references=true +jwt.secret=my-32-character-ultra-secure-and-ultra-long-secret + + +fileBasePath =/Doc +##grievance API call +updateGrievanceDetails = /grsbepro/igemr1097/public/api/v1/state-wise/grievance-list?page=PageNumber¤tpage=1 +updateGrievanceTransactionDetails=/grsbepro/igemr1097/public/api/v1/grievance_details/ + +## grievance variables +grievanceUserName = +grievancePassword = + +grievanceUserAuthenticate = +grievanceDataSyncDuration = + +springdoc.api-docs.enabled=true +springdoc.swagger-ui.enabled=true + +isProduction=false +grievanceAllocationRetryConfiguration=3 + +logging.path=logs/ +logging.file.name=logs/common-api.log + +captcha.secret-key= +captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify +captcha.enable-captcha=true + +cors.allowed-origins=http://localhost:* + From 52660af5877e230eefda557fe3c7eed20e1613ed Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 06:45:12 +0530 Subject: [PATCH 162/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 4 ++-- src/main/resources/application.properties | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 9056eb45..48d5aef7 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -401,9 +401,9 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } + String baseUrl = is1097 ? identity1097BaseURL : identityBaseURL; + String apiUrl = baseUrl + ConfigProperties.getPropertyByName("identity-api-url-benCreate"); - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 180ad75d..07983569 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -115,9 +115,7 @@ identity-api-url-getByPartialBenRegIdList =IDENTITY_BASE_URL/id/getByPartialBenR identity-api-url-getByPhoneNum =IDENTITY_BASE_URL/id/getByPhoneNum?phoneNum= identity-api-url-getByBenId =IDENTITY_BASE_URL/id/getByBenId?benId= identity-api-url-getByBenRegId =IDENTITY_BASE_URL/id/getByBenRegId?benRegId= -IDENTITY_API_URL=https://amritdemo.piramalswasthya.org -identity-api-url-benCreate=${IDENTITY_API_URL}/id/create -#identity-api-url-benCreate =IDENTITY_BASE_URL/id/create +identity-api-url-benCreate =IDENTITY_BASE_URL/id/create identity-api-url-benEdit =IDENTITY_BASE_URL/id/edit identity-api-url-benEditEducationCommunity=IDENTITY_BASE_URL/id/editEducationOrCommunity From 7d21b14813813426ffb699e0d5fe1d383d511576 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 06:58:48 +0530 Subject: [PATCH 163/318] IDENTITY_BASE_URL fix --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 48d5aef7..5c27c251 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -52,7 +52,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); - private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; + private static final String IDENTITY_BASE_URL = "https://amritdemo.piramalswasthya.org"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); @@ -80,7 +80,7 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String } result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( - IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); + IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : "https://amritdemo.piramalswasthya.org")), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse != null && identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { throw new IEMRException(identityResponse.getErrorMessage()); @@ -401,9 +401,9 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } - String baseUrl = is1097 ? identity1097BaseURL : identityBaseURL; - String apiUrl = baseUrl + ConfigProperties.getPropertyByName("identity-api-url-benCreate"); + String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); From 1a07e5691530bbb2109598613c57824526a115b6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:07:54 +0530 Subject: [PATCH 164/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 5c27c251..a31c71ab 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -52,7 +52,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); - private static final String IDENTITY_BASE_URL = "https://amritdemo.piramalswasthya.org"; + private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); @@ -79,8 +79,9 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String header.put("Authorization", auth); } + result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( - IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : "https://amritdemo.piramalswasthya.org")), benIdList.toString(), header); + IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse != null && identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { throw new IEMRException(identityResponse.getErrorMessage()); From 272db98f0ad2b421736be7adf399f23865e2009c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 08:40:14 +0530 Subject: [PATCH 165/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a31c71ab..8f1455dd 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -405,7 +405,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); - logger.info("Calling URL: {}", apiUrl); logger.info("Request Payload: {}", request); From 78531fa3a997323031208f9abb7fdbe2f74bb8cf Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:12:45 +0530 Subject: [PATCH 166/318] IDENTITY_BASE_URL fix --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 8f1455dd..ee3c15eb 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -79,7 +79,6 @@ public List getBeneficiaryListByIDs(HashSet benIdList, String header.put("Authorization", auth); } - result = httpUtils.post(ConfigProperties.getPropertyByName("identity-api-url-getByBenRegIdList").replace( IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)), benIdList.toString(), header); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); From a66ac6f4059757fcea087c3b952a1cbed112c69b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 07:24:16 +0530 Subject: [PATCH 167/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/environment/common_docker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index f3f7ebfd..fd69c7e4 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -25,7 +25,7 @@ cti-server-ip=${CTI_SERVER_IP} cti-logger_base_url=${CTI_SERVER_LOGGER_BASE}/logger # Identity Config -identity-api-url = ${IDENTITY_API_URL} +identity-api-url = ${IDENTITY_API_BASE_URL} identity-1097-api-url = ${IDENTITY_1097_API_URL} #### SMS Configuration From 534665dec1a52db9d8bbc6c662546da8b1d91819 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 14:48:58 +0530 Subject: [PATCH 168/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 07983569..af7947d2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -174,22 +174,7 @@ jwt.access.expiration=86400000 jwt.refresh.expiration=604800000 # local env -server.port=8083 -# DB Connections -spring.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_iemr -spring.datasource.username=root -spring.datasource.password=BizDev@24BB -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -encDbUserName=zFlYsp9Z0s+lRvLM15A3g/Ba0w8VGs/1usuW7EsGF3k= -encDbPass=JGGAGn5wTlrbTLUHY+5BzfBa0w8VGs/1usuW7EsGF3k= - -secondary.datasource.url=jdbc:mysql://devbox.bizbrolly.com:3306/db_reporting -secondary.datasource.username=root -secondary.datasource.password=BizDev@24BB -secondary.datasource.driver-class-name=com.mysql.jdbc.Driver -firebase.enabled = true -firebase.credential-file =firebase_cred.json + From d176d64919991daa373af75dfdbd16873726f236 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 4 Jul 2025 16:46:06 +0530 Subject: [PATCH 169/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index ee3c15eb..ef7f7cd2 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -401,7 +401,6 @@ public String getIdentityResponse(String request, String auth, Boolean is1097) t if (auth != null) { header.put("Authorization", auth); } - String apiUrl = ConfigProperties.getPropertyByName("identity-api-url-benCreate") .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL)); logger.info("Calling URL: {}", apiUrl); From 634b9e210832e0b95bb2a3355b84544fe2aea7a2 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 11:40:18 +0530 Subject: [PATCH 170/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index ef7f7cd2..a0f0e11b 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -29,6 +29,7 @@ import com.google.gson.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.iemr.common.dto.identity.BeneficiariesDTO; @@ -50,8 +51,12 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); - private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); + @Value("${identity-api-ur}") + private String identityBaseURL; + + @Value("${identity-1097-api-url}") + private String identity1097BaseURL; + private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); From c25aa3f5a82fc23a24a8474faecc731fd9abca7a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 13:10:32 +0530 Subject: [PATCH 171/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index af7947d2..6c40d0e6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -368,3 +368,17 @@ captcha.enable-captcha=true cors.allowed-origins=http://localhost:* +# DB Connections +spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr +spring.datasource.username= +spring.datasource.password=YesBank@123# + +spring.datasource.driver-class-name=com.mysql.jdbc.Driver + +secondary.datasource.username= +secondary.datasource.password= +secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting +secondary.datasource.driver-class-name=com.mysql.jdbc.Driver + +identity-api-ur= +firebase.enabled=true From 697ba3652bfdf8518edbfdd54eef81a735fbc169 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:16:48 +0530 Subject: [PATCH 172/318] fix IDENTITY_API_BASE_URL variable in docker file --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6c40d0e6..597cfde2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -380,5 +380,4 @@ secondary.datasource.password= secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver -identity-api-ur= firebase.enabled=true From e2dab17300a8c623eee1c1ed40999260d4a9f82b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:23:14 +0530 Subject: [PATCH 173/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a0f0e11b..b3e11ba6 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -51,7 +51,7 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - @Value("${identity-api-ur}") + @Value("${identity-api-url}") private String identityBaseURL; @Value("${identity-1097-api-url}") From d3c6f2f28e40ac532d3a731ad7ef8f8bc6095508 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 14:24:14 +0530 Subject: [PATCH 174/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../service/beneficiary/IdentityBeneficiaryServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index b3e11ba6..0f759bb0 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -53,7 +53,6 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private InputMapper inputMapper = new InputMapper(); @Value("${identity-api-url}") private String identityBaseURL; - @Value("${identity-1097-api-url}") private String identity1097BaseURL; From e6e992bc2e61bcdb39b8da00b53792dd8c14a92d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 7 Jul 2025 15:46:31 +0530 Subject: [PATCH 175/318] fix IDENTITY_API_BASE_URL variable in docker file --- .../IdentityBeneficiaryServiceImpl.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 0f759bb0..c31a927f 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -58,16 +58,13 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; - private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); - private static final String BEN_GEN_API_URL = ConfigProperties.getPropertyByName("generateBeneficiaryIDs-api-url"); - // public IdentityBeneficiaryServiceImpl() - // { - // - //// if (urlRequest == null) - //// { - //// urlRequest = ConfigProperties.getPropertyByName("identity-api-url"); - //// } - // } + @Value("${genben-api}") + private static String BEN_GEN ; + + + @Value("${generateBeneficiaryIDs-api-url}") + private static String BEN_GEN_API_URL ; + @Override // public List getBeneficiaryListByIDs() {// search by regID From 1b5b9b98be8b6e1930e57165e870bbb5928568ba Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:13:37 +0530 Subject: [PATCH 176/318] Update BeneficiaryOTPHandlerImpl.java --- .../BeneficiaryOTPHandlerImpl.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 17027667..47dbed68 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -39,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -67,8 +68,21 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Autowired SMSTypeRepository smsTypeRepository; + @Value("${sms-username}") + private String smsUserName; + + @Value("${sms-password}") + private String smsPassword; + + @Value("${sms-entityid}") + private String smsEntityId; + + @Value("${source-address}") + private String smsSourceAddress; + @Value("${send-message-url}") + private String SMS_GATEWAY_URL; + private static final Integer EXPIRE_MIN = 5; - private static final String SMS_GATEWAY_URL = ConfigProperties.getPropertyByName("sms-gateway-url"); // Constructor for new object creation public BeneficiaryOTPHandlerImpl() { @@ -163,32 +177,34 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); - String sendSMSAPI = BeneficiaryOTPHandlerImpl.SMS_GATEWAY_URL; + String sendSMSAPI = SMS_GATEWAY_URL; + logger.info("sms template"+template); try { - String message = template.getSmsTemplate() - .replace("$$OTP$$",String.valueOf(otp)) - .replace("$$UserName$$", obj.getUserName()) - .replace("$$Designation$$", obj.getDesignation()); + String message = "Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha ,Asha to complete the process. PSMRI"; +// String message = template.getSmsTemplate() +// .replace("$$OTP$$",String.valueOf(otp)) +// .replace("$$UserName$$", obj.getUserName()) +// .replace("$$Designation$$", obj.getDesignation()); // Build payload Map payload = new HashMap<>(); - payload.put("customerId", ConfigProperties.getPropertyByName("sms-username")); + payload.put("customerId",smsUserName); payload.put("destinationAddress", obj.getMobNo()); payload.put("message", message); - payload.put("sourceAddress", ConfigProperties.getPropertyByName("source-address")); + payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); payload.put("dltTemplateId", dltTemplateId); - payload.put("entityId",ConfigProperties.getPropertyByName("sms-entityid") ); + payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers HttpHeaders headers = new HttpHeaders(); - String auth = ConfigProperties.getPropertyByName("sms-username") + ":" + ConfigProperties.getPropertyByName("sms-password"); + String auth = smsUserName + ":" + smsPassword; headers.add("Authorization", "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); headers.setContentType(MediaType.APPLICATION_JSON); - + logger.info("payload: "+payload); HttpEntity> request = new HttpEntity<>(payload, headers); // Call API From 15b705502eb5050f42cd096ac9905100f11968da Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:21:52 +0530 Subject: [PATCH 177/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 47dbed68..b4d3cf18 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -181,7 +181,7 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { logger.info("sms template"+template); try { - String message = "Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha ,Asha to complete the process. PSMRI"; + String message ="Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha to complete the process. Regards PSMRI"; // String message = template.getSmsTemplate() // .replace("$$OTP$$",String.valueOf(otp)) // .replace("$$UserName$$", obj.getUserName()) From 61ae6afde4f65e9e166ee83698b2c0d42af1ff0e Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:31:11 +0530 Subject: [PATCH 178/318] Update application.properties --- src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 597cfde2..644994e1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -370,8 +370,8 @@ cors.allowed-origins=http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr -spring.datasource.username= -spring.datasource.password=YesBank@123# +spring.datasource.username= +spring.datasource.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver From 8680ecb356c3b02ada5b0029e7ee3422e54cbee3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:32:40 +0530 Subject: [PATCH 179/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index b4d3cf18..a21d066a 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -194,7 +194,7 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", dltTemplateId); + payload.put("dltTemplateId", "1007730329175402034"); payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers From e7c6b04f7bf4caba6851f0442ddb5987f936ba5d Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Fri, 18 Jul 2025 21:56:17 +0530 Subject: [PATCH 180/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index a21d066a..ef83e448 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -71,14 +71,14 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword; + // @Value("${sms-password}") + private String smsPassword ="]Kt9GAp8}$S*@"; @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") - private String smsSourceAddress; + // @Value("${source-address}") + private String smsSourceAddress = "PSMRAM"; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 376e7046e527887762c3e5c3e804cc8716860d82 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:03:09 +0530 Subject: [PATCH 181/318] Update JwtUserIdValidationFilter.java --- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 94b86799..6d329979 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -157,12 +157,15 @@ private boolean isMobileClient(String userAgent) { } private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") + return path.equals(contextPath + "/user/userAuthenticate") || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") || path.startsWith(contextPath + "/user/userAuthenticateV1") || path.startsWith(contextPath + "/user/forgetPassword") || path.startsWith(contextPath + "/user/setForgetPassword") From 795c427fdd7ac4210481ac8ed9ee47294f00f600 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 4 Aug 2025 16:51:31 +0530 Subject: [PATCH 182/318] Update CommonIdentityMapperDecorator.java --- .../mapper/CommonIdentityMapperDecorator.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java b/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java index 5e8034af..1480f306 100644 --- a/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java +++ b/src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java @@ -168,8 +168,17 @@ public CommonIdentityDTO beneficiaryModelCommonIdentityDTO(BeneficiaryModel bene Short maritalStatusID = beneficiary.getMaritalStatusID(); if (maritalStatusID != null) { commonIdentityDTO.setMaritalStatusId(maritalStatusID.intValue()); - commonIdentityDTO.setMaritalStatus( - maritalStatusMapper.maritalStatusByIDToResponse(maritalStatusID.intValue()).getStatus()); + var model = maritalStatusMapper.maritalStatusByIDToResponse(maritalStatusID.intValue()); + if (model != null) { + commonIdentityDTO.setMaritalStatus(model.getStatus()); + } else { + // Option 1: Return null + commonIdentityDTO.setMaritalStatus(null); + // Option 2: Or set a default + // commonIdentityDTO.setMaritalStatus("Unknown"); + // Option 3: Or log a warning + // logger.warn("Invalid maritalStatusID: {}", maritalStatusID); + } } commonIdentityDTO.setMaritalStatus(beneficiary.getMaritalStatusName()); commonIdentityDTO.setGender(beneficiary.getGenderName()); From ebd595e7052c2b6739046858c2588d16fbb5b15b Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:47:15 +0530 Subject: [PATCH 183/318] Update JwtUserIdValidationFilter.java --- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 6d329979..d027ea74 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -163,9 +163,10 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") || path.startsWith(contextPath + "/user/superUserAuthenticate") || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/firebaseNotification/sendNotification") || path.startsWith(contextPath + "/user/userAuthenticateV1") || path.startsWith(contextPath + "/user/forgetPassword") || path.startsWith(contextPath + "/user/setForgetPassword") From 3e9d00e8354235dad1fda6700d75f6777ef6019b Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 16:48:04 +0530 Subject: [PATCH 184/318] Update FirebaseNotificationController.java --- .../firebaseNotification/FirebaseNotificationController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 89fb01a9..1fe15720 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification",headers = "Authorization") +@RequestMapping(value= "/firebaseNotification") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From 82434e1a291a0021cd54df4bf899b3a08bbc38a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:03:40 +0530 Subject: [PATCH 185/318] Update FirebaseNotificationService.java --- .../firebaseNotification/FirebaseNotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index ea0cc005..7c76c9ee 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -67,7 +67,7 @@ public String sendNotification(NotificationMessage notificationMessage) { Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); - Message message = Message.builder().setToken(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); + Message message = Message.builder().setTopic(notificationMessage.getToken()).setNotification(notification).putAllData(notificationMessage.getData()).build(); try { From 34bd50d241bf30973ceb4b19f7973209fb073a2f Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:15:55 +0530 Subject: [PATCH 186/318] Update BeneficiaryConsentController.java --- .../beneficiaryConsent/BeneficiaryConsentController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java index e917204c..77492d89 100644 --- a/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java +++ b/src/main/java/com/iemr/common/controller/beneficiaryConsent/BeneficiaryConsentController.java @@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -@RequestMapping(value = { "/beneficiaryConsent" },headers ="Authorization" ) +@RequestMapping(value = { "/beneficiaryConsent" }) @RestController public class BeneficiaryConsentController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @@ -46,7 +46,7 @@ public class BeneficiaryConsentController { private BeneficiaryOTPHandler beneficiaryOTPHandler; @Operation(summary = "Send Consent") - @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/sendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { OutputResponse response = new OutputResponse(); @@ -66,7 +66,7 @@ public String sendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody } @Operation(summary = "Validate Consent") - @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/validateConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"Integer\"}") @RequestBody String requestOBJ) { OutputResponse response = new OutputResponse(); @@ -88,7 +88,7 @@ public String validateConsent(@Param(value = "{\"mobNo\":\"String\",\"otp\":\"In } @Operation(summary = "Resend Consent") - @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") + @RequestMapping(value = "/resendConsent", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON) public String resendConsent(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { logger.info(requestOBJ.toString()); From dff88e6842ba0f06c5a654d1f64ca70d3ffd473c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:06:29 +0530 Subject: [PATCH 187/318] dynamic from feature --- .../dynamicForm/DynamicFormController.java | 95 ++++++++-- .../data/dynamic_from/FormDefinition.java | 30 +++ .../common/data/dynamic_from/FormEntity.java | 27 --- .../common/data/dynamic_from/FormField.java | 59 ++++++ .../common/data/dynamic_from/FormModule.java | 23 +++ .../data/dynamic_from/ModuleEntity.java | 23 --- .../iemr/common/dto/dynamicForm/FieldDTO.java | 25 +++ .../dto/dynamicForm/FieldResponseDTO.java | 24 +++ .../iemr/common/dto/dynamicForm/FormDTO.java | 10 + .../common/dto/dynamicForm/FormFieldDTO.java | 23 --- .../dto/dynamicForm/FormResponseDTO.java | 13 ++ .../dto/dynamicForm/FormTypeEntityDTO.java | 18 -- .../dynamicForm/GroupedFieldResponseDTO.java | 11 ++ .../common/dto/dynamicForm/ModuleDTO.java | 8 + .../dto/dynamicForm/ModuleEntityDTO.java | 12 -- .../dynamic_form/FieldRepository.java | 12 ++ .../dynamic_form/FormRepository.java | 14 ++ .../dynamic_form/FormTypeRepository.java | 8 - .../dynamic_form/ModuleRepository.java | 4 +- .../dynamicForm/FormMasterService.java | 22 +++ .../dynamicForm/FormMasterServiceImpl.java | 177 ++++++++++++++++++ .../service/dynamicForm/FormTypeService.java | 35 ---- .../service/dynamicForm/ModuleService.java | 26 --- .../exception/GlobalExceptionHandler.java | 36 ++++ .../common/utils/response/ApiResponse.java | 31 +++ 25 files changed, 577 insertions(+), 189 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java delete mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormField.java create mode 100644 src/main/java/com/iemr/common/data/dynamic_from/FormModule.java delete mode 100644 src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java create mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java delete mode 100644 src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java create mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java delete mode 100644 src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java create mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java delete mode 100644 src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java delete mode 100644 src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java create mode 100644 src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/iemr/common/utils/response/ApiResponse.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 9a924872..a67dcadd 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -1,31 +1,96 @@ package com.iemr.common.controller.dynamicForm; -import com.iemr.common.data.dynamic_from.FormEntity; -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; -import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; -import com.iemr.common.service.dynamicForm.FormTypeService; -import com.iemr.common.service.dynamicForm.ModuleService; +import com.iemr.common.dto.dynamicForm.FieldDTO; +import com.iemr.common.dto.dynamicForm.FormDTO; +import com.iemr.common.dto.dynamicForm.ModuleDTO; +import com.iemr.common.service.dynamicForm.FormMasterService; +import com.iemr.common.utils.response.ApiResponse; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -@RequestMapping(value = "masterFrom") +import java.util.List; + +@RequestMapping(value = "dynamicForm",headers = "Authorization") @RestController public class DynamicFormController { - @Autowired ModuleService moduleService; @Autowired - private FormTypeService formTypeService; + private FormMasterService formMasterService; + + @PostMapping(value = "createModule",headers = "Authorization") + public ResponseEntity> createModule(@Valid @RequestBody ModuleDTO moduleDTO) { + try { + Object result = formMasterService.createModule(moduleDTO); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Module created successfully", HttpStatus.OK.value(), result)); + } catch (IllegalArgumentException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error("Invalid module data: " + e.getMessage(), HttpStatus.BAD_REQUEST.value(), null)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create module", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } - @PostMapping("/modules") - public ResponseEntity createModule(@RequestBody ModuleEntityDTO module) { - return ResponseEntity.ok(moduleService.save(module)); + @PostMapping(value = "createForm",headers = "Authorization") + public ResponseEntity> createForm(@Valid @RequestBody FormDTO dto) { + try { + Object result = formMasterService.createForm(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Form created successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create form", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } } - @PostMapping("/modules/{moduleId}/form-types") - public ResponseEntity createFormType(@PathVariable Long moduleId, @RequestBody FormTypeEntityDTO formType) { - return ResponseEntity.ok(formTypeService.createFormType(moduleId, formType)); + @PostMapping(value = "createFields",headers = "Authorization") + public ResponseEntity> createField(@Valid @RequestBody List dto) { + try { + Object result = formMasterService.createField(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Fields created successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to create fields", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } } + @PostMapping(value = "field/update",headers = "Authorization") + public ResponseEntity> updateField(@Valid @RequestBody FieldDTO dto) { + try { + Object result = formMasterService.updateField(dto); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Field updated successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to update field", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } + @DeleteMapping(value = "delete/{fieldId}/field",headers = "Authorization") + public ResponseEntity> deleteField(@PathVariable Long fieldId) { + try { + formMasterService.deleteField(fieldId); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Field deleted successfully", HttpStatus.OK.value(), null)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to delete field", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } + + @GetMapping(value = "form/{formId}/fields",headers = "Authorization") + public ResponseEntity> getStructuredForm(@PathVariable String formId) { + try { + Object result = formMasterService.getStructuredFormByFormId(formId); + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + } + } } diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java b/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java new file mode 100644 index 00000000..9e62b6d9 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormDefinition.java @@ -0,0 +1,30 @@ +package com.iemr.common.data.dynamic_from; +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; +@Entity +@Data +@Table(name = "form_master") +public class FormDefinition { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "form_id") + private String formId; + + @Column(name = "form_name") + private String formName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "module_id") + private FormModule module; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + @Column(name = "version") + private Integer version; + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java deleted file mode 100644 index 578111f5..00000000 --- a/src/main/java/com/iemr/common/data/dynamic_from/FormEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.iemr.common.data.dynamic_from; - -import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.*; -import lombok.Data; - -@Data -@Entity -@Table(name = "form_types",schema = "db_imer") -public class FormEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "Id") - private Long id; - - @Column(name = "form_name",columnDefinition = "TEXT") - private String formName; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "module_id") - private ModuleEntity module; - - @Column(name = "fields",columnDefinition = "TEXT") - private String fields ; - - -} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormField.java b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java new file mode 100644 index 00000000..39785ae9 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormField.java @@ -0,0 +1,59 @@ +package com.iemr.common.data.dynamic_from; +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@Entity +@Data +@Table(name = "form_fields") +public class FormField { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "form_id", referencedColumnName = "form_id") + private FormDefinition form; + + @Column(name = "section_title") + private String sectionTitle; + + @Column(name = "field_id") + private String fieldId; + + @Column(name = "label") + private String label; + + @Column(name = "type") + private String type; + + @Column(name = "is_required") + private Boolean isRequired; + + @Column(name = "is_visible") + private Boolean isVisible; + + @Column(name = "default_value") + private String defaultValue; + + @Column(name = "placeholder") + private String placeholder; + + @Column(name = "options", columnDefinition = "json") + private String options; + + @Column(name = "validation", columnDefinition = "json") + private String validation; // includes error messages now + + @Column(name = "conditional", columnDefinition = "json") + private String conditional; + + @Column(name = "sequence") + private Integer sequence; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java b/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java new file mode 100644 index 00000000..ba5d0170 --- /dev/null +++ b/src/main/java/com/iemr/common/data/dynamic_from/FormModule.java @@ -0,0 +1,23 @@ +package com.iemr.common.data.dynamic_from; + +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@Entity +@Data +@Table(name = "form_module") +public class FormModule { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "module_name") + private String moduleName; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + +} diff --git a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java b/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java deleted file mode 100644 index 4d699a7e..00000000 --- a/src/main/java/com/iemr/common/data/dynamic_from/ModuleEntity.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iemr.common.data.dynamic_from; - -import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.*; -import lombok.Data; - -import java.util.List; -@Data -@Entity -@Table(name = "m_modules",schema = "db_iemr") -public class ModuleEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "Id") - private Long id; - - @Column(name = "module_name",columnDefinition = "TEXT") - private String moduleName; - - @OneToMany(mappedBy = "module", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private List formTypes; - -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java new file mode 100644 index 00000000..894f03c2 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldDTO.java @@ -0,0 +1,25 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FieldDTO { + private Long id; + private String formId; + private String sectionTitle; + private String fieldId; + private String label; + private String type; + private Boolean isVisible; + private Boolean isRequired; + private String defaultValue; + private String placeholder; + private Integer sequence; + private String options; // ⬅️ changed from String to List + private String validation; // ⬅️ changed from String to Map + private String conditional; // ⬅️ changed from String to Map +} + diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java new file mode 100644 index 00000000..3415d91a --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FieldResponseDTO.java @@ -0,0 +1,24 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FieldResponseDTO { + private Long id; + private String formId; + private String sectionTitle; + private String fieldId; + private String label; + private Boolean visible; + private String type; + private Boolean isRequired; + private String defaultValue; + private String placeholder; + private Integer sequence; + private List options; + private Map validation; + private Map conditional; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java new file mode 100644 index 00000000..24788cac --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormDTO.java @@ -0,0 +1,10 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +@Data +public class FormDTO { + private String formId; + private String formName; + private Long moduleId; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java deleted file mode 100644 index 27a6ee93..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FormFieldDTO.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.List; -import java.util.Map; - -@Data -public class FormFieldDTO { - private String name; - private String label; - private String type; - private boolean required; - private String inputType; - private String fileType; - private String buttonAction; - private String visibleIfField; - private String visibleIfValue; - private Map validations; - private List> options; - - // Getters and Setters -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java new file mode 100644 index 00000000..26563927 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/FormResponseDTO.java @@ -0,0 +1,13 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class FormResponseDTO { + private Integer version; + private String formId; + private String formName; + private List sections; +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java deleted file mode 100644 index ff31dfd5..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/FormTypeEntityDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.List; - -@Data -public class FormTypeEntityDTO { - - private Long id; - - private String formName; - - private ModuleEntityDTO module; - - private List fields; - -} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java new file mode 100644 index 00000000..840c5097 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/GroupedFieldResponseDTO.java @@ -0,0 +1,11 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +import java.util.List; + +@Data +public class GroupedFieldResponseDTO { + private String sectionTitle; + private List fields; +} diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java new file mode 100644 index 00000000..3f4240c4 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleDTO.java @@ -0,0 +1,8 @@ +package com.iemr.common.dto.dynamicForm; + +import lombok.Data; + +@Data +public class ModuleDTO { + private String moduleName; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java b/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java deleted file mode 100644 index 03cfc834..00000000 --- a/src/main/java/com/iemr/common/dto/dynamicForm/ModuleEntityDTO.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.iemr.common.dto.dynamicForm; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; -@Data -public class ModuleEntityDTO { - private Long id; - private String moduleName; - -} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java new file mode 100644 index 00000000..4aea5698 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FieldRepository.java @@ -0,0 +1,12 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormField; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface FieldRepository extends JpaRepository { + List findByForm_FormIdOrderBySequenceAsc(String formId); +} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java new file mode 100644 index 00000000..50331dd2 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/dynamic_form/FormRepository.java @@ -0,0 +1,14 @@ +package com.iemr.common.repository.dynamic_form; + +import com.iemr.common.data.dynamic_from.FormDefinition; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface FormRepository extends JpaRepository { + Optional findByFormId(String formId); + List findByModule_Id(Long moduleId); +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java deleted file mode 100644 index b3b731fe..00000000 --- a/src/main/java/com/iemr/common/repository/dynamic_form/FormTypeRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.iemr.common.repository.dynamic_form; - -import com.iemr.common.data.dynamic_from.FormEntity; -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface FormTypeRepository extends CrudRepository {} diff --git a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java index e4eb221e..bafbfbea 100644 --- a/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java +++ b/src/main/java/com/iemr/common/repository/dynamic_form/ModuleRepository.java @@ -1,10 +1,10 @@ package com.iemr.common.repository.dynamic_form; -import com.iemr.common.data.dynamic_from.ModuleEntity; +import com.iemr.common.data.dynamic_from.FormModule; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository -public interface ModuleRepository extends CrudRepository { +public interface ModuleRepository extends CrudRepository { } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java new file mode 100644 index 00000000..c603cd65 --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java @@ -0,0 +1,22 @@ +package com.iemr.common.service.dynamicForm; + +import com.iemr.common.data.dynamic_from.FormDefinition; +import com.iemr.common.data.dynamic_from.FormField; +import com.iemr.common.data.dynamic_from.FormModule; +import com.iemr.common.dto.dynamicForm.FieldDTO; +import com.iemr.common.dto.dynamicForm.FormDTO; +import com.iemr.common.dto.dynamicForm.FormResponseDTO; +import com.iemr.common.dto.dynamicForm.ModuleDTO; + +import java.util.List; + +public interface FormMasterService { + FormModule createModule(ModuleDTO dto); + FormDefinition createForm(FormDTO dto); + List createField(List dto); + FormField updateField(FieldDTO dto); + + FormResponseDTO getStructuredFormByFormId(String formId); + + void deleteField(Long fieldId); +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java new file mode 100644 index 00000000..893c1c8a --- /dev/null +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -0,0 +1,177 @@ +package com.iemr.common.service.dynamicForm; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iemr.common.data.dynamic_from.FormDefinition; +import com.iemr.common.data.dynamic_from.FormField; +import com.iemr.common.data.dynamic_from.FormModule; +import com.iemr.common.dto.dynamicForm.*; +import com.iemr.common.repository.dynamic_form.FieldRepository; +import com.iemr.common.repository.dynamic_form.FormRepository; +import com.iemr.common.repository.dynamic_form.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class FormMasterServiceImpl implements FormMasterService { + + @Autowired + private ModuleRepository moduleRepo; + @Autowired private FormRepository formRepo; + @Autowired private FieldRepository fieldRepo; + + @Override + public FormModule createModule(ModuleDTO dto) { + FormModule module = new FormModule(); + module.setModuleName(dto.getModuleName()); + return moduleRepo.save(module); + } + + @Override + public FormDefinition createForm(FormDTO dto) { + FormModule module = moduleRepo.findById(dto.getModuleId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid module ID")); + + FormDefinition form = new FormDefinition(); + form.setFormId(dto.getFormId()); + form.setFormName(dto.getFormName()); + form.setModule(module); + return formRepo.save(form); + } + + @Override + public List createField(List dtoList) { + List savedFields = new ArrayList<>(); + + for (FieldDTO dto : dtoList) { + FormDefinition form = formRepo.findByFormId(dto.getFormId()) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + + FormField field = new FormField(); + field.setForm(form); + field.setSectionTitle(dto.getSectionTitle()); + field.setFieldId(dto.getFieldId()); + field.setLabel(dto.getLabel()); + field.setType(dto.getType()); + field.setIsVisible(dto.getIsVisible()); + field.setIsRequired(dto.getIsRequired()); + field.setDefaultValue(dto.getDefaultValue()); + field.setPlaceholder(dto.getPlaceholder()); + field.setOptions(dto.getOptions()); + field.setValidation(dto.getValidation()); + field.setConditional(dto.getConditional()); + field.setSequence(dto.getSequence()); + + savedFields.add(fieldRepo.save(field)); + } + + return savedFields; + } + + @Override + public FormField updateField(FieldDTO dto) { + FormField field = fieldRepo.findById(dto.getId()) + .orElseThrow(() -> new IllegalArgumentException("Field not found: " + dto.getId())); + field.setId(dto.getId()); + field.setSectionTitle(dto.getSectionTitle()); + field.setLabel(dto.getLabel()); + field.setType(dto.getType()); + field.setIsVisible(dto.getIsVisible()); + field.setIsRequired(dto.getIsRequired()); + field.setDefaultValue(dto.getDefaultValue()); + field.setPlaceholder(dto.getPlaceholder()); + field.setSequence(dto.getSequence()); + field.setOptions(dto.getOptions()); + field.setValidation(dto.getValidation()); + field.setConditional(dto.getConditional()); + + + return fieldRepo.save(field); + } + + @Override + public FormResponseDTO getStructuredFormByFormId(String formId) { + FormDefinition form = formRepo.findByFormId(formId) + .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); + + List fields = fieldRepo.findByForm_FormIdOrderBySequenceAsc(formId); + ObjectMapper objectMapper = new ObjectMapper(); + + List fieldDtos = fields.stream() + .map(field -> { + FieldResponseDTO dto = new FieldResponseDTO(); + dto.setId(field.getId()); + dto.setVisible(field.getIsVisible()); + dto.setFormId(field.getForm().getFormId()); + dto.setSectionTitle(field.getSectionTitle()); + dto.setFieldId(field.getFieldId()); + dto.setLabel(field.getLabel()); + dto.setType(field.getType()); + dto.setIsRequired(field.getIsRequired()); + dto.setDefaultValue(field.getDefaultValue()); + dto.setPlaceholder(field.getPlaceholder()); + dto.setSequence(field.getSequence()); + + try { + // Handle options + if (field.getOptions() != null && !field.getOptions().isBlank()) { + List options = objectMapper.readValue(field.getOptions(), new TypeReference<>() {}); + dto.setOptions(options.isEmpty() ? null : options); + } else { + dto.setOptions(null); + } + + // Handle validation + if (field.getValidation() != null && !field.getValidation().isBlank()) { + Map validation = objectMapper.readValue(field.getValidation(), new TypeReference<>() {}); + dto.setValidation(validation.isEmpty() ? null : validation); + } else { + dto.setValidation(null); + } + + // Handle conditional + if (field.getConditional() != null && !field.getConditional().isBlank()) { + Map conditional = objectMapper.readValue(field.getConditional(), new TypeReference<>() {}); + dto.setConditional(conditional.isEmpty() ? null : conditional); + } else { + dto.setConditional(null); + } + } catch (JsonProcessingException e) { + System.err.println("JSON Parsing Error in field: " + field.getFieldId()); + e.printStackTrace(); + throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); + } + + return dto; + }) + .sorted(Comparator.comparing(FieldResponseDTO::getId)) + .collect(Collectors.toList()); + + + GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); + singleSection.setSectionTitle("HBNC Form Fields"); // your custom section title + singleSection.setFields(fieldDtos); + + FormResponseDTO response = new FormResponseDTO(); + response.setVersion(form.getVersion()); + response.setFormId(form.getFormId()); + response.setFormName(form.getFormName()); + response.setSections(List.of(singleSection)); + + return response; + } + + + @Override + public void deleteField(Long fieldId) { + fieldRepo.deleteById(fieldId); + } + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java deleted file mode 100644 index 38068cdc..00000000 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormTypeService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.iemr.common.service.dynamicForm; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.iemr.common.data.dynamic_from.FormEntity; -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.FormTypeEntityDTO; -import com.iemr.common.repository.dynamic_form.FormTypeRepository; -import com.iemr.common.repository.dynamic_form.ModuleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class FormTypeService { - @Autowired - ModuleRepository moduleRepo; - @Autowired - FormTypeRepository formTypeRepo; - @Autowired - ObjectMapper objectMapper; - - public FormEntity createFormType(Long moduleId, FormTypeEntityDTO formTypeDTO) { - ModuleEntity module = moduleRepo.findById(moduleId).orElseThrow(); - FormEntity formType = new FormEntity(); - formType.setFormName(formTypeDTO.getFormName()); - formType.setModule(module); - try { - String fieldsJson = objectMapper.writeValueAsString(formTypeDTO.getFields()); - formType.setFields(fieldsJson); - } catch (JsonProcessingException e) { - throw new RuntimeException("Failed to serialize form fields", e); - } - return formTypeRepo.save(formType); - } -} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java b/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java deleted file mode 100644 index 644d2c59..00000000 --- a/src/main/java/com/iemr/common/service/dynamicForm/ModuleService.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.iemr.common.service.dynamicForm; - -import com.iemr.common.data.dynamic_from.ModuleEntity; -import com.iemr.common.dto.dynamicForm.ModuleEntityDTO; -import com.iemr.common.repository.dynamic_form.ModuleRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Optional; - -@Service -public class ModuleService { - @Autowired - ModuleRepository repo; - - public ModuleEntity save(ModuleEntityDTO module) { - ModuleEntity moduleEntity = new ModuleEntity(); - moduleEntity.setModuleName(module.getModuleName()); - return repo.save(moduleEntity); - } - - public Optional findById(Long id) { - return repo.findById(id); - } -} - diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java new file mode 100644 index 00000000..90a06c79 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -0,0 +1,36 @@ +package com.iemr.common.utils.exception; + +import com.iemr.common.utils.response.ApiResponse; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.stream.Collectors; + +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(Exception.class) + public ResponseEntity> handleException(Exception ex) { + ex.printStackTrace(); // Log for debugging + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(),null)); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationException(MethodArgumentNotValidException ex) { + String errorMessage = ex.getBindingResult().getFieldErrors().stream() + .map(error -> error.getField() + ": " + error.getDefaultMessage()) + .collect(Collectors.joining(", ")); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error("Validation Error: " + errorMessage, HttpStatus.BAD_REQUEST.value(),null)); + } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgException(IllegalArgumentException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ApiResponse.error(ex.getMessage(), HttpStatus.BAD_REQUEST.value(),null)); + } +} diff --git a/src/main/java/com/iemr/common/utils/response/ApiResponse.java b/src/main/java/com/iemr/common/utils/response/ApiResponse.java new file mode 100644 index 00000000..928a2a25 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/response/ApiResponse.java @@ -0,0 +1,31 @@ +package com.iemr.common.utils.response; + +import lombok.Data; + +@Data +public class ApiResponse { + private boolean success; + private String message; + private Integer statusCode; + + private T data; + + public ApiResponse() {} + + public ApiResponse(boolean success, String message, Integer statusCode,T data) { + this.success = success; + this.message = message; + this.data = data; + this.statusCode = statusCode; + } + + public static ApiResponse success(String message,Integer statusCode, T data) { + return new ApiResponse<>(true, message,statusCode, data); + } + + public static ApiResponse error(String message,Integer statusCode, T data) { + return new ApiResponse<>(false, message, statusCode,data); + } + + // getters and setters +} From 544193975dc24491bc45eafc3908e498159be7d9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:25:10 +0530 Subject: [PATCH 188/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index a67dcadd..065cdb14 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,4 +93,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } + } From 616dbfc75cd106fa7881e97b3157d89cac3e9ac8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:25:25 +0530 Subject: [PATCH 189/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 065cdb14..a67dcadd 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,5 +93,4 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } - } From bae3a68acec9610729ddbc2ea8aa0fd62be7a859 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 16 Jul 2025 10:26:35 +0530 Subject: [PATCH 190/318] dynamic from feature --- .../common/controller/dynamicForm/DynamicFormController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index a67dcadd..065cdb14 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -93,4 +93,5 @@ public ResponseEntity> getStructuredForm(@PathVariable String for .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } + } From ad459c27cbef00c4bba557ebd0b5dd244ecf79c6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 12:10:23 +0530 Subject: [PATCH 191/318] welcome sms --- .../RegisterBenificiaryServiceImpl.java | 23 +++++- .../BeneficiaryCallServiceImpl.java | 7 +- .../WelcomeBenificarySmsService.java | 9 +++ .../WelcomeBenificarySmsServiceImpl.java | 79 +++++++++++++++++++ 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsService.java create mode 100644 src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 9baa24c1..8bef307b 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -30,6 +30,8 @@ import java.util.ArrayList; import java.util.List; +import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService; +import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsServiceImpl; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,6 +75,9 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired IdentityBenEditMapper identityBenEditMapper; + @Autowired + private WelcomeBenificarySmsService welcomeBenificarySmsService; + @Autowired Validator validator; @@ -175,16 +180,25 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet logger.info("benificiaryDetails: " + beneficiaryModel); CommonIdentityDTO identityDTO = identityMapper.beneficiaryModelCommonIdentityDTO(beneficiaryModel); + setSaveDemographicDetails(identityDTO,beneficiaryModel); - // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); +// identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); + identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); + identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); + identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); + identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); + identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); + identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); + + identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); - identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); identityDTO .setBenFamilyDTOs(identityMapper.benPhoneMapListToBenFamilyDTOList(beneficiaryModel.getBenPhoneMaps())); String request = new Gson().toJson(identityDTO); + if (beneficiaryModel.getIs1097() == null) beneficiaryModel.setIs1097(false); @@ -204,10 +218,15 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } + if(identityDTO.getContact().getEmergencyContactNum()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(identityDTO.getContact().getEmergencyContactNum(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + } } return OutputMapper.gson().toJson(beneficiary); } + + private void setSaveDemographicDetails(CommonIdentityDTO identityDTO, BeneficiaryModel beneficiaryModel) { if(null != beneficiaryModel.getI_bendemographics()) { identityDTO.setCommunity(beneficiaryModel.getI_bendemographics().getCommunityName()); diff --git a/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java b/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java index 1a9474ff..c28d41cb 100644 --- a/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java +++ b/src/main/java/com/iemr/common/service/callhandling/BeneficiaryCallServiceImpl.java @@ -1684,8 +1684,11 @@ public List getBeneficiaryListFromMapper(List payload = new HashMap<>(); + payload.put("customerId",smsUserName); + payload.put("destinationAddress", contactNo); + payload.put("message", message); + payload.put("sourceAddress", smsSourceAddress); + payload.put("messageType", "SERVICE_IMPLICIT"); + payload.put("dltTemplateId", dltTemplateId); + payload.put("entityId",smsEntityId ); + // Set headers + HttpHeaders headers = new HttpHeaders(); + String auth = smsUserName + ":" + smsPassword; + headers.add("Authorization", + "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); + + headers.setContentType(MediaType.APPLICATION_JSON); + logger.info("payload: "+payload); + HttpEntity> request = new HttpEntity<>(payload, headers); + + // Call API + ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); + logger.info("sms-response:"+response.getBody()); + if(response.getStatusCode().value()==200){ + return "OTP sent successfully on register mobile number"; + }else { + return "Fail"; + + } + + } catch (Exception e) { + return "Error sending SMS: " + e.getMessage().toString(); + } + + } +} From e84e28ffc7ba68a221212833e6786fb51bac212a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:02:31 +0530 Subject: [PATCH 192/318] fix issue --- .../beneficiary/RegisterBenificiaryServiceImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 8bef307b..51769236 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -184,12 +184,12 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); - identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); - identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); - identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); - identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); - identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); - identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); +// identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); +// identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); +// identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); +// identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); +// identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); +// identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); From 2b806a70b19adc1ebb06d516b4c671e3894eec71 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:18:21 +0530 Subject: [PATCH 193/318] fix issue --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 644994e1..208c3c33 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,3 +381,4 @@ secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true +START_GRIEVANCEDATASYNC_SCHEDULER = \ No newline at end of file From d2d8fb6eb394ec6c09e7eb43081b661e4e0b6f09 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:45:33 +0530 Subject: [PATCH 194/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 208c3c33..888c7836 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -381,4 +381,4 @@ secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true -START_GRIEVANCEDATASYNC_SCHEDULER = \ No newline at end of file +video-call-url = From 7a5e8cd6f44936534b404c6133063f08f49fb907 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 13 Aug 2025 14:25:55 +0530 Subject: [PATCH 195/318] Update application.properties --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 888c7836..23d8be4b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -382,3 +382,4 @@ secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true video-call-url = + From 3a14f56e04029fc6c3b8d400a50c846c54ed626f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 14:52:44 +0530 Subject: [PATCH 196/318] fix issue --- .../common/config/quartz/ScheduleForGrievanceDataSync.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index f016de3d..e64f604f 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag; + //@Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag = true; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From 00197a2402369152577c77c0338665200c831c23 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:01:15 +0530 Subject: [PATCH 197/318] fix issue --- .../controller/nhmdashboard/NHMDetailCallReportScheduler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 5fd3e281..3ce4b913 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag; +// @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag = true; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") From df1c324145a101c7b92fbc6c20073743a66bdf90 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:23:09 +0530 Subject: [PATCH 198/318] fix issue --- .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 51769236..220a0bac 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -218,8 +218,8 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } - if(identityDTO.getContact().getEmergencyContactNum()!=null){ - welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(identityDTO.getContact().getEmergencyContactNum(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + if(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); } } return OutputMapper.gson().toJson(beneficiary); From d61a2dcba0cc527f3466296493f100e98701649f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 15:24:07 +0530 Subject: [PATCH 199/318] fix issue --- .../beneficiary/RegisterBenificiaryServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 220a0bac..aa0c2a71 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -218,9 +218,12 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet } else { return response.toString(); } - if(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo()!=null){ - welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiaryModel.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + if(beneficiary!=null){ + if(beneficiary.getBenPhoneMaps().get(0).getPhoneNo()!=null){ + welcomeBenificarySmsService.sendWelcomeSMStoBenificiary(beneficiary.getBenPhoneMaps().get(0).getPhoneNo(),beneficiary.getFirstName()+" "+beneficiary.getLastName(),beneficiary.getBeneficiaryID()); + } } + } return OutputMapper.gson().toJson(beneficiary); } From bbbb623b84c98b0f7d6e5cfac7a15f094889b276 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 13 Aug 2025 16:43:53 +0530 Subject: [PATCH 200/318] fix issue --- .../service/welcomeSms/WelcomeBenificarySmsServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 8bc8da51..9a4e9602 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -26,8 +26,8 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") - private String smsSourceAddress; +// @Value("${source-address}") + private String smsSourceAddress ="PSMRAM"; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 1237757638ed1f32a0773a5179d7170448b10825 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 14:51:28 +0530 Subject: [PATCH 201/318] fix issue --- .../utils/JwtUserIdValidationFilter.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index d027ea74..4c2e0c9e 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -156,26 +156,27 @@ private boolean isMobileClient(String userAgent) { return userAgent.contains("okhttp") || userAgent.contains("java/"); // iOS (custom clients) } - private boolean shouldSkipAuthentication(String path, String contextPath) { - return path.equals(contextPath + "/user/userAuthenticate") - || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") - || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") - || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") - || path.startsWith(contextPath + "/user/superUserAuthenticate") - || path.startsWith(contextPath + "/user/user/userAuthenticateNew") - || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") - || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") - || path.startsWith(contextPath + "/firebaseNotification/sendNotification") - || path.startsWith(contextPath + "/user/userAuthenticateV1") - || path.startsWith(contextPath + "/user/forgetPassword") - || path.startsWith(contextPath + "/user/setForgetPassword") - || path.startsWith(contextPath + "/user/changePassword") - || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") - || path.startsWith(contextPath + "/user/userLogout") - || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") - || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); - } + private boolean shouldSkipAuthentication(String path, String contextPath) { + return path.equals(contextPath + "/user/userAuthenticate") + || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") + || path.startsWith(contextPath + "/swagger-ui") || path.startsWith(contextPath + "/v3/api-docs") + || path.startsWith(contextPath + "/public") || path.equals(contextPath + "/user/refreshToken") + || path.startsWith(contextPath + "/user/superUserAuthenticate") + || path.startsWith(contextPath + "/user/user/userAuthenticateNew") + || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") + || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/dynamicForm") + || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") + || path.startsWith(contextPath + "/firebaseNotification/sendNotification") + || path.startsWith(contextPath + "/user/userAuthenticateV1") + || path.startsWith(contextPath + "/user/forgetPassword") + || path.startsWith(contextPath + "/user/setForgetPassword") + || path.startsWith(contextPath + "/user/changePassword") + || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") + || path.startsWith(contextPath + "/user/userLogout") + || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") + || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + } private String getJwtTokenFromCookies(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); From 254a9a01f0ad7b53484eee6725123698f3b025d7 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:20:28 +0530 Subject: [PATCH 202/318] Update WelcomeBenificarySmsServiceImpl.java --- .../service/welcomeSms/WelcomeBenificarySmsServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 9a4e9602..50e2353f 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -20,8 +20,8 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword; + // @Value("${sms-password}") + private String smsPassword = "]Kt9GAp8}$S*@"; @Value("${sms-entityid}") private String smsEntityId; From e1cf6bd1f5167a8d7aa30968c08357e3fd235a36 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:07:07 +0530 Subject: [PATCH 203/318] Update application.properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 23d8be4b..f410bd30 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -364,7 +364,7 @@ logging.file.name=logs/common-api.log captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify -captcha.enable-captcha=true +captcha.enable-captcha=false cors.allowed-origins=http://localhost:* From 5bc5445b7c6ed9f56225e78c211f1a195dec0779 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 20 Aug 2025 12:20:01 +0530 Subject: [PATCH 204/318] Update IEMRAdminController.java --- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index e1b20d66..ed3760bc 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - @Value("${captcha.enable-captcha}") - private boolean enableCaptcha; + // @Value("${captcha.enable-captcha}") + private boolean enableCaptcha = false; @Autowired private CaptchaValidationService captchaValidatorService; From 0aed4f0b080f0f8309b3e8256288de89b4c14628 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 14:59:51 +0530 Subject: [PATCH 205/318] fix issue --- .../common/controller/dynamicForm/DynamicFormController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 065cdb14..5d8542be 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -82,7 +82,7 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } } - @GetMapping(value = "form/{formId}/fields",headers = "Authorization") + @GetMapping(value = "form/{formId}/fields") public ResponseEntity> getStructuredForm(@PathVariable String formId) { try { Object result = formMasterService.getStructuredFormByFormId(formId); From 1b2e7a040de69615371c8eb8737c8c3e2d26e881 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 15:00:48 +0530 Subject: [PATCH 206/318] fix issue --- .../common/controller/dynamicForm/DynamicFormController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 5d8542be..2c8cb9dc 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -13,7 +13,7 @@ import java.util.List; -@RequestMapping(value = "dynamicForm",headers = "Authorization") +@RequestMapping(value = "dynamicForm") @RestController public class DynamicFormController { @Autowired From 2802fb352864fcb547fc197ea4412a39a536abe1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 16:20:38 +0530 Subject: [PATCH 207/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f410bd30..49c167ed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://localhost:* +cors.allowed-origins=http://localhost:*,http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 7030151865c3b62bd164df2513d136c9bc1e17ad Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 17:57:44 +0530 Subject: [PATCH 208/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 49c167ed..1b75e9d9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://localhost:*,http://devbox.bizbrolly.com:4901 +cors.allowed-origins=http://devbox.bizbrolly.com:4901:*,http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 7a280b6f9f39c0df62dabb984118db0bbec34654 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 18:09:13 +0530 Subject: [PATCH 209/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1b75e9d9..b8547e15 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:4901:*,http://localhost:* +cors.allowed-origins=http://devbox.bizbrolly.com:*,http://localhost:* # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From b92d7d7e1f8775fed52bfa5da0997c73f75fc3b9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 18:38:25 +0530 Subject: [PATCH 210/318] fix issue --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b8547e15..e903ded1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:*,http://localhost:* +cors.allowed-origins=http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 4ed67988c47e5afb0fa92db56abcf13a407031b4 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 19:00:37 +0530 Subject: [PATCH 211/318] fix issue --- .../iemr/common/utils/http/HTTPRequestInterceptor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 23b0af62..be8d564c 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -38,6 +38,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + +import java.util.Arrays; +import java.util.List; + @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { @@ -125,18 +129,22 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons break; } } catch (Exception e) { + String origin = request.getHeader("Origin"); + OutputResponse output = new OutputResponse(); output.setError(e); response.getOutputStream().print(output.toString()); response.setContentType(MediaType.APPLICATION_JSON); response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Origin", "http://devbox.bizbrolly.com:4901"); status = false; } } return status; } + + @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) throws Exception { From ae5bc540ce5c126ae5d445328d1ba59fc9e0195b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 19:07:30 +0530 Subject: [PATCH 212/318] fix issue --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- src/main/resources/application.properties | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 2e226b79..84f5e865 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Override diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 9f6efb13..379eb180 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Bean diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e903ded1..5bef996b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,8 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins=http://devbox.bizbrolly.com:4901 +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 9d05db2f9d0cbe56a43ef23addca0c678549215b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 21 Aug 2025 21:43:27 +0530 Subject: [PATCH 213/318] fix issue --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 4c2e0c9e..65e16f7f 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -165,6 +165,8 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/user/userAuthenticateNew") || path.startsWith(contextPath + "/beneficiaryConsent/sendConsent") || path.startsWith(contextPath + "/beneficiaryConsent/validateConsent") + || path.startsWith(contextPath + "/bulkRegistration") + || path.startsWith(contextPath + "/download-error-sheet") || path.startsWith(contextPath + "/dynamicForm") || path.startsWith(contextPath + "/beneficiaryConsent/resendConsent") || path.startsWith(contextPath + "/firebaseNotification/sendNotification") From 9ebd258cc8abee156812fbdd84ccaae9f59b364e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 27 Aug 2025 17:48:14 +0530 Subject: [PATCH 214/318] fix firebase issue --- .../firebase/FirebaseMessagingConfig.java | 39 +++++++++++++------ .../FirebaseNotificationService.java | 6 ++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java index ebb98b59..ebb697ec 100644 --- a/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java +++ b/src/main/java/com/iemr/common/config/firebase/FirebaseMessagingConfig.java @@ -4,7 +4,10 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @@ -16,6 +19,7 @@ @Configuration public class FirebaseMessagingConfig { + private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); @Value("${firebase.enabled:false}") private boolean firebaseEnabled; @@ -25,26 +29,37 @@ public class FirebaseMessagingConfig { @Bean + @ConditionalOnProperty(name = "firebase.enabled", havingValue = "true") public FirebaseMessaging firebaseMessaging() throws IOException { if (!firebaseEnabled) { - throw new IllegalStateException("Firebase is disabled"); + logger.error("⚠️ Firebase disabled by config"); + return null; } - if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { - throw new IllegalStateException("No Firebase credentials path provided"); - } + try { + if (firebaseCredentialFile == null || firebaseCredentialFile.isBlank()) { + logger.error("⚠️ No Firebase credentials path provided"); + return null; // don't throw, app will still start + } + + GoogleCredentials credentials = GoogleCredentials.fromStream( + new ClassPathResource(firebaseCredentialFile).getInputStream() + ); + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(credentials) + .build(); - GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(firebaseCredentialFile)); + FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() + ? FirebaseApp.initializeApp(options) + : FirebaseApp.getInstance(); - FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(credentials) - .build(); + return FirebaseMessaging.getInstance(firebaseApp); - FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() - ? FirebaseApp.initializeApp(options) - : FirebaseApp.getInstance(); + } catch (Exception e) { + logger.error("⚠️ Firebase init failed: " + e.getMessage()); + return null; // keep app running + } - return FirebaseMessaging.getInstance(firebaseApp); } } diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index 7c76c9ee..d59a63f0 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -50,7 +50,7 @@ public class FirebaseNotificationService { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Autowired + @Autowired(required = false) FirebaseMessaging firebaseMessaging; @Autowired @@ -64,6 +64,10 @@ public class FirebaseNotificationService { public String sendNotification(NotificationMessage notificationMessage) { + if (firebaseMessaging == null) { + logger.error("⚠️ Firebase is not configured, skipping notification"); + return null; + } Notification notification = Notification.builder().setTitle(notificationMessage.getTitle()).setBody(notificationMessage.getBody()).build(); From 100245bd8a344c9f727d8df34429c82c46318629 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 26 Aug 2025 15:34:50 +0530 Subject: [PATCH 215/318] changed the pom correction --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ae3d0b9..e4502198 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.4.0 + 3.6.0 war Common-API From 3379b71c4a8c8d20a831413f7bd513109d48b34c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 10:42:40 +0530 Subject: [PATCH 216/318] fix sms issue --- .../repository/sms/SMSTemplateRepository.java | 3 ++ .../BeneficiaryOTPHandlerImpl.java | 34 +++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java index e5d741f0..7e898710 100644 --- a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java +++ b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java @@ -22,6 +22,7 @@ package com.iemr.common.repository.sms; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -56,6 +57,8 @@ public List getSMSTemplateByProviderServiceMapIDAndSMSTypeID( @Query("select smsTemplate.dltTemplateId from SMSTemplate smsTemplate where smsTemplate.smsTemplateID = :smsTemplateID and smsTemplate.deleted <> true") public String findDLTTemplateID(@Param("smsTemplateID") Integer smsTemplateID ); + + public Optional findBySmsTemplateName(String smsTemplateName); SMSTemplate findBySmsTemplateID(Integer smsTemplateID); diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index ef83e448..9b17bdaa 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -67,18 +67,24 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Autowired SMSTypeRepository smsTypeRepository; + @Value("${sms-template-name}") + private String smsTemplateName ; + private String smsTemplate; @Value("${sms-username}") private String smsUserName; - // @Value("${sms-password}") - private String smsPassword ="]Kt9GAp8}$S*@"; + @Value("${sms-password}") + private String smsPassword ; + + @Value("${sms-message-type}") + private String smsMessageType; @Value("${sms-entityid}") private String smsEntityId; - // @Value("${source-address}") - private String smsSourceAddress = "PSMRAM"; + @Value("${source-address}") + private String smsSourceAddress ; @Value("${send-message-url}") private String SMS_GATEWAY_URL; @@ -174,18 +180,18 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { final RestTemplate restTemplate = new RestTemplate(); - String dltTemplateId = smsTemplateRepository.findDLTTemplateID(28); - SMSTemplate template = smsTemplateRepository.findBySmsTemplateID(28); + Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + if(smsTemplateData.isPresent()){ + smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); + + } String sendSMSAPI = SMS_GATEWAY_URL; - logger.info("sms template"+template); + logger.info("sms template"+smsTemplate); try { - String message ="Hello! Your OTP for providing consent for registration on AMRIT is "+otp+". This OTP is valid for 10 minutes. Kindly share it only with Asha to complete the process. Regards PSMRI"; -// String message = template.getSmsTemplate() -// .replace("$$OTP$$",String.valueOf(otp)) -// .replace("$$UserName$$", obj.getUserName()) -// .replace("$$Designation$$", obj.getDesignation()); + String message = smsTemplate + .replace("$$OTP$$",String.valueOf(otp)); // Build payload Map payload = new HashMap<>(); @@ -193,8 +199,8 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("destinationAddress", obj.getMobNo()); payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); - payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", "1007730329175402034"); + payload.put("messageType", smsMessageType); + payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); payload.put("entityId",smsEntityId ); payload.put("otp", true); // Set headers From 36a177e27d386405ac0c990e7400f896a26fe06d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:41:14 +0530 Subject: [PATCH 217/318] fix sms issue --- src/main/resources/application.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5bef996b..060096fa 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -384,3 +384,6 @@ secondary.datasource.driver-class-name=com.mysql.jdbc.Driver firebase.enabled=true video-call-url = +##sms details for beneficiary otp cosent +sms-template-name = otp_consent + From 2f7b7d36867058c1b7571ffb79fee518450e332d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:48:15 +0530 Subject: [PATCH 218/318] fix firebase code issue --- .../FirebaseNotificationController.java | 6 +++--- .../firebaseNotification/FirebaseNotificationService.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java index 1fe15720..3bb10cfc 100644 --- a/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java +++ b/src/main/java/com/iemr/common/controller/firebaseNotification/FirebaseNotificationController.java @@ -34,19 +34,19 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping(value= "/firebaseNotification") +@RequestMapping(value= "/firebaseNotification",headers = "Authorization") public class FirebaseNotificationController { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired FirebaseNotificationService firebaseNotificationService; - @RequestMapping(value = "sendNotification",method = RequestMethod.POST) + @RequestMapping(value = "sendNotification",method = RequestMethod.POST,headers = "Authorization") public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ return firebaseNotificationService.sendNotification(notificationMessage); } - @RequestMapping(value = "updateToken",method = RequestMethod.POST) + @RequestMapping(value = "updateToken",method = RequestMethod.POST,headers = "Authorization") public String updateToken(@RequestBody UserToken userToken){ return firebaseNotificationService.updateToken(userToken); } diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index d59a63f0..b97ac4de 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -62,6 +62,8 @@ public class FirebaseNotificationService { @Autowired private JwtUtil jwtUtil; + private Message message; + public String sendNotification(NotificationMessage notificationMessage) { if (firebaseMessaging == null) { From 4e65a3367ac7b98837cdc9ce76944e6a27c28663 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 11:54:07 +0530 Subject: [PATCH 219/318] fix code issue --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- .../config/quartz/ScheduleForGrievanceDataSync.java | 4 ++-- .../nhmdashboard/NHMDetailCallReportScheduler.java | 4 ++-- .../common/controller/users/IEMRAdminController.java | 10 ++-------- .../iemr/common/utils/http/HTTPRequestInterceptor.java | 4 +--- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 84f5e865..2e226b79 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Override diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index e64f604f..c9284574 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - //@Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag = true; + @Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag ; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 3ce4b913..c63d5aa2 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); -// @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag = true; + @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag ; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index ed3760bc..87fa007a 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - // @Value("${captcha.enable-captcha}") - private boolean enableCaptcha = false; + @Value("${captcha.enable-captcha}") + private boolean enableCaptcha ; @Autowired private CaptchaValidationService captchaValidatorService; @@ -257,34 +257,28 @@ public ResponseEntity refreshToken(@RequestBody Map request) logger.warn("Token validation failed: invalid token provided."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - Claims claims = jwtUtil.getAllClaimsFromToken(refreshToken); - // Verify token type if (!"refresh".equals(claims.get("token_type", String.class))) { logger.warn("Token validation failed: incorrect token type in refresh request."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - // Check revocation using JTI String jti = claims.getId(); if (!redisTemplate.hasKey("refresh:" + jti)) { logger.warn("Token validation failed: refresh token is revoked or not found in store."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - // Get user details // Get user details String userId = claims.get("userId", String.class); User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); - // Validate that the user still exists and is active if (user == null) { logger.warn("Token validation failed: user not found for userId in token."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - if (user.getM_status() == null || !"Active".equalsIgnoreCase(user.getM_status().getStatus())) { logger.warn("Token validation failed: user account is inactive or not in 'Active' status."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index be8d564c..fe738905 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -129,14 +129,12 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons break; } } catch (Exception e) { - String origin = request.getHeader("Origin"); - OutputResponse output = new OutputResponse(); output.setError(e); response.getOutputStream().print(output.toString()); response.setContentType(MediaType.APPLICATION_JSON); response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "http://devbox.bizbrolly.com:4901"); + response.setHeader("Access-Control-Allow-Origin", "*"); status = false; } } From dd0957db427bcc63e5b61d873aa9b27a0dd6cffd Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:14:59 +0530 Subject: [PATCH 220/318] fix code issue --- .../common/config/quartz/ScheduleForGrievanceDataSync.java | 2 +- .../controller/nhmdashboard/NHMDetailCallReportScheduler.java | 2 +- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index c9284574..f016de3d 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -15,7 +15,7 @@ public class ScheduleForGrievanceDataSync { @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag ; + private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index c63d5aa2..5fd3e281 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -39,7 +39,7 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag ; + private boolean startCtiDataCheckFlag; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 87fa007a..ffc6fad4 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - @Value("${captcha.enable-captcha}") - private boolean enableCaptcha ; + @Value("${captcha.enable-captcha}") + private boolean enableCaptcha; @Autowired private CaptchaValidationService captchaValidatorService; From 300659b8bfef3fe8fad9ddd60f91dd3abea6b595 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:17:06 +0530 Subject: [PATCH 221/318] fix code issue --- .../java/com/iemr/common/utils/http/HTTPRequestInterceptor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index fe738905..3f0268d1 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -141,8 +141,6 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons return status; } - - @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) throws Exception { From 6112a78daca9f2af5ea5325c8b70e4c3af321564 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:18:41 +0530 Subject: [PATCH 222/318] fix code issue --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 060096fa..57f84fd9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,8 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 -cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org # DB Connections spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr From 7531f303fb90a36e3921440dd2c0adac5e5a1409 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:24:04 +0530 Subject: [PATCH 223/318] fix code issue --- .../welcomeSms/WelcomeBenificarySmsServiceImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index 50e2353f..f154b8fa 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -20,14 +20,14 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${sms-username}") private String smsUserName; - // @Value("${sms-password}") - private String smsPassword = "]Kt9GAp8}$S*@"; + @Value("${sms-password}") + private String smsPassword ; @Value("${sms-entityid}") private String smsEntityId; -// @Value("${source-address}") - private String smsSourceAddress ="PSMRAM"; + @Value("${source-address}") + private String smsSourceAddress; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 268642e80beebe3e37d0b3bccd8b2bf2d500033c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:31:01 +0530 Subject: [PATCH 224/318] fix code issue --- .../WelcomeBenificarySmsServiceImpl.java | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index f154b8fa..fe5a4b72 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -1,8 +1,12 @@ package com.iemr.common.service.welcomeSms; +import com.google.common.cache.LoadingCache; import com.iemr.common.data.sms.SMSTemplate; +import com.iemr.common.repository.sms.SMSTemplateRepository; +import com.iemr.common.repository.sms.SMSTypeRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -14,14 +18,16 @@ import java.util.Base64; import java.util.HashMap; import java.util.Map; +import java.util.Optional; + @Service -public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsService{ +public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsService { final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Value("${sms-username}") private String smsUserName; - @Value("${sms-password}") - private String smsPassword ; + @Value("${sms-password}") + private String smsPassword; @Value("${sms-entityid}") private String smsEntityId; @@ -29,28 +35,45 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsS @Value("${source-address}") private String smsSourceAddress; @Value("${send-message-url}") - private String SMS_GATEWAY_URL; + private String SMS_GATEWAY_URL; + + @Autowired + SMSTemplateRepository smsTemplateRepository; + + @Autowired + SMSTypeRepository smsTypeRepository; + + private String smsTemplateName = "welcome_sms"; + + private String smsTemplate; @Override - public String sendWelcomeSMStoBenificiary(String contactNo,String beneficiaryName,String beneficiaryId) { + public String sendWelcomeSMStoBenificiary(String contactNo, String beneficiaryName, String beneficiaryId) { final RestTemplate restTemplate = new RestTemplate(); - String dltTemplateId = "1007006798022225953"; + Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + if (smsTemplateData.isPresent()) { + smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); + + } + + logger.info("sms template" + smsTemplate); + String sendSMSAPI = SMS_GATEWAY_URL; try { - String message = "Dear "+beneficiaryName+", your unique Beneficiary ID is "+beneficiaryId+". Thank you for registering. Regards PSMRI"; + String message = smsTemplate.replace("$$BENE_NAME$$", beneficiaryName).replace("$$BEN_ID$$", beneficiaryId); // Build payload Map payload = new HashMap<>(); - payload.put("customerId",smsUserName); + payload.put("customerId", smsUserName); payload.put("destinationAddress", contactNo); payload.put("message", message); payload.put("sourceAddress", smsSourceAddress); payload.put("messageType", "SERVICE_IMPLICIT"); - payload.put("dltTemplateId", dltTemplateId); - payload.put("entityId",smsEntityId ); + payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); + payload.put("entityId", smsEntityId); // Set headers HttpHeaders headers = new HttpHeaders(); String auth = smsUserName + ":" + smsPassword; @@ -58,15 +81,15 @@ public String sendWelcomeSMStoBenificiary(String contactNo,String beneficiaryNa "Basic " + Base64.getEncoder().encodeToString(auth.getBytes())); headers.setContentType(MediaType.APPLICATION_JSON); - logger.info("payload: "+payload); + logger.info("payload: " + payload); HttpEntity> request = new HttpEntity<>(payload, headers); // Call API ResponseEntity response = restTemplate.postForEntity(sendSMSAPI, request, String.class); - logger.info("sms-response:"+response.getBody()); - if(response.getStatusCode().value()==200){ - return "OTP sent successfully on register mobile number"; - }else { + logger.info("sms-response:" + response.getBody()); + if (response.getStatusCode().value() == 200) { + return "OTP sent successfully on register mobile number"; + } else { return "Fail"; } From ff5dc76fbdb66b6ed602b00d3e6143666b33f3c8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:36:23 +0530 Subject: [PATCH 225/318] fix code issue --- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 379eb180..9f6efb13 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Bean diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 65e16f7f..1ffbe50a 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -178,6 +178,7 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/userLogout") || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + } private String getJwtTokenFromCookies(HttpServletRequest request) { From e9c9deaf72314fe83056dd76ef438eca96516f44 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:41:35 +0530 Subject: [PATCH 226/318] fix code issue --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 1 - .../com/iemr/common/utils/exception/GlobalExceptionHandler.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 893c1c8a..19864742 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -145,7 +145,6 @@ public FormResponseDTO getStructuredFormByFormId(String formId) { } } catch (JsonProcessingException e) { System.err.println("JSON Parsing Error in field: " + field.getFieldId()); - e.printStackTrace(); throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); } diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java index 90a06c79..632e90d2 100644 --- a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -14,7 +14,6 @@ public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity> handleException(Exception ex) { - ex.printStackTrace(); // Log for debugging return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(),null)); } From a1ec0ee05b33fc46905ac18a24c3cc3eb0be0ce1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 12:56:06 +0530 Subject: [PATCH 227/318] fix code issue --- .../iemr/common/config/quartz/ScheduleForGrievanceDataSync.java | 2 +- .../iemr/common/service/notification/NotificationService.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index f016de3d..ba840321 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,7 +14,7 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler}") + @Value("${start-grievancedatasync-scheduler:false}") private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/service/notification/NotificationService.java b/src/main/java/com/iemr/common/service/notification/NotificationService.java index 6fa8ee8d..a3c85387 100644 --- a/src/main/java/com/iemr/common/service/notification/NotificationService.java +++ b/src/main/java/com/iemr/common/service/notification/NotificationService.java @@ -55,5 +55,4 @@ String createEmergencyContacts(String request) String updateEmergencyContacts(String request) throws JSONException, NoSuchAlgorithmException, IOException, IEMRException, Exception; - } From f69fab4e103e5d731e4b3c8a3458ef55603c7d9b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:00:09 +0530 Subject: [PATCH 228/318] fix code issue --- .../java/com/iemr/common/utils/http/HTTPRequestInterceptor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 3f0268d1..a116f3a7 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -39,8 +39,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.util.Arrays; -import java.util.List; @Configuration @Component From 717148cb1eef0ea197f1cf666ca866d3a45933f8 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:03:24 +0530 Subject: [PATCH 229/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index c4800782..2a5068f6 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -83,6 +83,5 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - } From 59e7a85b785a5eae85437f9894854d8a6fc4fc56 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:04:14 +0530 Subject: [PATCH 230/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 2a5068f6..feeb18c8 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -85,3 +85,4 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor } + From acb2ff2e39b88e8d0f776fee14ccd9468d004b04 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:04:52 +0530 Subject: [PATCH 231/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index feeb18c8..a66b6d9a 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -82,7 +82,4 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } - } - - From d5fdbd752000eb869c6491890020370353b0e879 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:05:23 +0530 Subject: [PATCH 232/318] fix code issue --- src/main/java/com/iemr/common/CommonApplication.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index a66b6d9a..442a9ffe 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -44,8 +44,6 @@ import com.iemr.common.data.users.User; import com.iemr.common.utils.IEMRApplBeans; -import java.io.IOException; - @SpringBootApplication @EnableScheduling public class CommonApplication extends SpringBootServletInitializer { From 9aebcc7bf2493406a3134d6ac5cfae7d9e12f40a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 28 Aug 2025 13:06:18 +0530 Subject: [PATCH 233/318] fix code issue --- .../iemr/common/config/quartz/ScheduleForGrievanceDataSync.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index ba840321..f016de3d 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,7 +14,7 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler:false}") + @Value("${start-grievancedatasync-scheduler}") private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); From aabe28760f54b4f21f97e54b796384986868f627 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 2 Sep 2025 11:37:12 +0530 Subject: [PATCH 234/318] fix code issue --- src/main/environment/common_ci.properties | 1 + src/main/environment/common_docker.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 5f6fda30..cbd6c2d7 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -32,6 +32,7 @@ identity-1097-api-url = @env.IDENTITY_1097_API_URL@ send-sms=@env.SEND_SMS@ sendSMSUrl = @env.SEND_SMS_URL@ source-address=@env.SMS_SOURCE_ADDRESS@ +sms_consent_source-address=@env.SMS_CONSENT_SOURCE_ADDRESS@ sms-username=@env.SMS_USERNAME@ sms-password=@env.SMS_PASSWORD@ send-message-url=@env.SMS_MESSAGE_URL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index fd69c7e4..03355987 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -32,6 +32,7 @@ identity-1097-api-url = ${IDENTITY_1097_API_URL} send-sms=${SEND_SMS} sendSMSUrl = ${SEND_SMS_URL} source-address=${SMS_SOURCE_ADDRESS} +sms-consent-source-address=${SMS_CONSENT_SOURCE_ADDRESS} sms-username=${SMS_USERNAME} sms-password=${SMS_PASSWORD} send-message-url=${SMS_MESSAGE_URL} From aaf013c1cc3598bf0e950d76dc64439631734292 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 14:28:32 +0530 Subject: [PATCH 235/318] fix code issue --- .../common/repository/sms/SMSTemplateRepository.java | 4 ++-- .../BeneficiaryOTPHandlerImpl.java | 10 +++++++--- .../welcomeSms/WelcomeBenificarySmsServiceImpl.java | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java index 7e898710..06745eb0 100644 --- a/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java +++ b/src/main/java/com/iemr/common/repository/sms/SMSTemplateRepository.java @@ -58,8 +58,8 @@ public List getSMSTemplateByProviderServiceMapIDAndSMSTypeID( @Query("select smsTemplate.dltTemplateId from SMSTemplate smsTemplate where smsTemplate.smsTemplateID = :smsTemplateID and smsTemplate.deleted <> true") public String findDLTTemplateID(@Param("smsTemplateID") Integer smsTemplateID ); - public Optional findBySmsTemplateName(String smsTemplateName); - + Optional findBySmsTemplateName(String smsTemplateName); + SMSTemplate findBySmsTemplateID(Integer smsTemplateID); } diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index 9b17bdaa..f74f7e6d 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -83,8 +83,8 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") - private String smsSourceAddress ; + @Value("${sms_consent_source-address}") + private String smsConsentSourceAddress ; @Value("${send-message-url}") private String SMS_GATEWAY_URL; @@ -177,10 +177,14 @@ private String getEncryptedOTP(int otp) throws Exception { public String sendSMS(int otp, BeneficiaryConsentRequest obj) { + logger.info("templateName"+smsTemplateName); final RestTemplate restTemplate = new RestTemplate(); Optional smsTemplateData = smsTemplateRepository.findBySmsTemplateName(smsTemplateName); + List smsTemplateAllData = (List) smsTemplateRepository.findAll(); + logger.info("AllData"+smsTemplateAllData.stream().toArray()); + if(smsTemplateData.isPresent()){ smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplateData.get().getSmsTemplateID()).getSmsTemplate(); @@ -198,7 +202,7 @@ public String sendSMS(int otp, BeneficiaryConsentRequest obj) { payload.put("customerId",smsUserName); payload.put("destinationAddress", obj.getMobNo()); payload.put("message", message); - payload.put("sourceAddress", smsSourceAddress); + payload.put("sourceAddress", smsConsentSourceAddress); payload.put("messageType", smsMessageType); payload.put("dltTemplateId", smsTemplateData.get().getDltTemplateId()); payload.put("entityId",smsEntityId ); diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index fe5a4b72..ba4d3562 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -32,7 +32,7 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsServ @Value("${sms-entityid}") private String smsEntityId; - @Value("${source-address}") + @Value("${sms_consent_source-address}") private String smsSourceAddress; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From cf526ce1727feefeca7580dcdcaca6b47efa7d27 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 14:29:39 +0530 Subject: [PATCH 236/318] fix code issue --- src/main/environment/common_docker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index b7f7c605..6e68346c 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -32,7 +32,7 @@ identity-1097-api-url = ${IDENTITY_1097_API_URL} send-sms=${SEND_SMS} sendSMSUrl = ${SEND_SMS_URL} source-address=${SMS_SOURCE_ADDRESS} -sms-consent-source-address=${SMS_CONSENT_SOURCE_ADDRESS} +sms-consent-source-address=${SMS_SOURCE_CONSENT_ADDRESS} sms-username=${SMS_USERNAME} sms-password=${SMS_PASSWORD} send-message-url=${SMS_MESSAGE_URL} From 8938dd13d0eaf48fc0ab7e607f72e609c9f59b55 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:11:37 +0530 Subject: [PATCH 237/318] Update application.properties --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 929729d2..62fb2215 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -257,7 +257,6 @@ start-nhmdashboard-scheduler=true cron-scheduler-nhmdashboard=0 1 * * * ? * ##----------------------------------------------------#grievance data sync----------------------------------------------------------- -start-grievancedatasync-scheduler=false cron-scheduler-grievancedatasync=0 0/2 * * * ? ### Redis IP From 5f0d92b74235bbd445a95c3ec0d76848a05a2d0c Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:15:40 +0530 Subject: [PATCH 238/318] Update ScheduleForGrievanceDataSync.java --- .../common/config/quartz/ScheduleForGrievanceDataSync.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index f016de3d..0cd95400 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag; + // @Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag=true; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @@ -37,3 +37,4 @@ public void execute() { } } + From 0cb6287441ba11c55fc6e1c547157de82cccccd2 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:19:14 +0530 Subject: [PATCH 239/318] Update BeneficiaryOTPHandlerImpl.java --- .../beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java index f74f7e6d..42e0acfe 100644 --- a/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiaryOTPHandler/BeneficiaryOTPHandlerImpl.java @@ -83,7 +83,8 @@ public class BeneficiaryOTPHandlerImpl implements BeneficiaryOTPHandler { @Value("${sms-entityid}") private String smsEntityId; - @Value("${sms_consent_source-address}") + @Value("${sms-consent-source-address}") + private String smsConsentSourceAddress ; @Value("${send-message-url}") private String SMS_GATEWAY_URL; From c584be71fbed9f1e2878ce20c9bbee5576578325 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:19:47 +0530 Subject: [PATCH 240/318] Update WelcomeBenificarySmsServiceImpl.java --- .../service/welcomeSms/WelcomeBenificarySmsServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java index ba4d3562..67b642ab 100644 --- a/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java +++ b/src/main/java/com/iemr/common/service/welcomeSms/WelcomeBenificarySmsServiceImpl.java @@ -32,8 +32,9 @@ public class WelcomeBenificarySmsServiceImpl implements WelcomeBenificarySmsServ @Value("${sms-entityid}") private String smsEntityId; - @Value("${sms_consent_source-address}") + @Value("${sms-consent-source-address}") private String smsSourceAddress; + @Value("${send-message-url}") private String SMS_GATEWAY_URL; From 8fbf9f1db2f3b37184007837c8e45a2719a859aa Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:21:30 +0530 Subject: [PATCH 241/318] Update application.properties --- src/main/resources/application.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 62fb2215..f81ea0b5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -383,4 +383,6 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent +sms-consent-source-address + From f9285238b061746e75a1408a957cd7eef86c6514 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:25:51 +0530 Subject: [PATCH 242/318] Update common_ci.properties --- src/main/environment/common_ci.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index cbd6c2d7..e333a938 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -32,7 +32,6 @@ identity-1097-api-url = @env.IDENTITY_1097_API_URL@ send-sms=@env.SEND_SMS@ sendSMSUrl = @env.SEND_SMS_URL@ source-address=@env.SMS_SOURCE_ADDRESS@ -sms_consent_source-address=@env.SMS_CONSENT_SOURCE_ADDRESS@ sms-username=@env.SMS_USERNAME@ sms-password=@env.SMS_PASSWORD@ send-message-url=@env.SMS_MESSAGE_URL@ @@ -191,4 +190,4 @@ cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS@ video-call-url=@env.VIDEO_CALL_URL@ jibri.output.path=@env.JIBRI_OUTPUT_PATH@ -video.recording.path=@env.VIDEO_RECORDING_PATH@ \ No newline at end of file +video.recording.path=@env.VIDEO_RECORDING_PATH@ From 3adda88759229c5ad017faaafd8e90ab1927f69d Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:26:10 +0530 Subject: [PATCH 243/318] Update common_docker.properties --- src/main/environment/common_docker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 6e68346c..0193be40 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -32,7 +32,6 @@ identity-1097-api-url = ${IDENTITY_1097_API_URL} send-sms=${SEND_SMS} sendSMSUrl = ${SEND_SMS_URL} source-address=${SMS_SOURCE_ADDRESS} -sms-consent-source-address=${SMS_SOURCE_CONSENT_ADDRESS} sms-username=${SMS_USERNAME} sms-password=${SMS_PASSWORD} send-message-url=${SMS_MESSAGE_URL} @@ -195,3 +194,4 @@ firebase.credential-file=${FIREBASE_CREDENTIAL} video-call-url=${VIDEO_CALL_URL} jibri.output.path={JIBRI_OUTPUT_PATH} video.recording.path={VIDEO_RECORDING_PATH} + From 175302122a9654a41fd8660a36c3e1d0bdcd90c1 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 3 Sep 2025 19:39:57 +0530 Subject: [PATCH 244/318] Update NHMDetailCallReportScheduler.java --- .../nhmdashboard/NHMDetailCallReportScheduler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 5fd3e281..4542322d 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag; + // @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag=true; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") @@ -181,3 +181,4 @@ private BeneficiaryCall getCallDetail(DetailedCallReport detailedCallReport) { } } + From c504ef903e2e85f963bed1f295f4cd05f376054b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 20:26:48 +0530 Subject: [PATCH 245/318] merge with main --- .../controller/users/IEMRAdminController.java | 176 +++++++++--------- .../java/com/iemr/common/utils/JwtUtil.java | 118 +++++++++--- 2 files changed, 179 insertions(+), 115 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index ffc6fad4..5ac50aaa 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -1,24 +1,24 @@ /* -* AMRIT – Accessible Medical Records via Integrated Technology -* Integrated EHR (Electronic Health Records) Solution -* -* Copyright (C) "Piramal Swasthya Management and Research Institute" -* -* This file is part of AMRIT. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see https://www.gnu.org/licenses/. -*/ + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.controller.users; import java.util.*; @@ -170,9 +170,9 @@ public String userAuthenticate( JSONObject serviceRoleMap = new JSONObject(); JSONArray serviceRoleList = new JSONArray(); JSONObject previlegeObj = new JSONObject(); - if (m_User.getUserName() != null - && (m_User.getDoLogout() == null || !m_User.getDoLogout()) - && (m_User.getWithCredentials() != null && m_User.getWithCredentials())) { + if (m_User.getUserName() != null + && (m_User.getDoLogout() == null || !m_User.getDoLogout()) + && (m_User.getWithCredentials() != null && m_User.getWithCredentials())) { String tokenFromRedis = getConcurrentCheckSessionObjectAgainstUser( m_User.getUserName().trim().toLowerCase()); if (tokenFromRedis != null) { @@ -187,7 +187,7 @@ public String userAuthenticate( String refreshToken = null; if (mUser.size() == 1) { jwtToken = jwtUtil.generateToken(m_User.getUserName(), mUser.get(0).getUserID().toString()); - + User user = new User(); // Assuming the Users class exists user.setUserID(mUser.get(0).getUserID()); user.setUserName(mUser.get(0).getUserName()); @@ -257,28 +257,34 @@ public ResponseEntity refreshToken(@RequestBody Map request) logger.warn("Token validation failed: invalid token provided."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } + Claims claims = jwtUtil.getAllClaimsFromToken(refreshToken); + // Verify token type if (!"refresh".equals(claims.get("token_type", String.class))) { logger.warn("Token validation failed: incorrect token type in refresh request."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } + // Check revocation using JTI String jti = claims.getId(); if (!redisTemplate.hasKey("refresh:" + jti)) { logger.warn("Token validation failed: refresh token is revoked or not found in store."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } + // Get user details // Get user details String userId = claims.get("userId", String.class); User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); + // Validate that the user still exists and is active if (user == null) { logger.warn("Token validation failed: user not found for userId in token."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } + if (user.getM_status() == null || !"Active".equalsIgnoreCase(user.getM_status().getStatus())) { logger.warn("Token validation failed: user account is inactive or not in 'Active' status."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); @@ -288,15 +294,15 @@ public ResponseEntity refreshToken(@RequestBody Map request) Map tokens = new HashMap<>(); tokens.put("jwtToken", newJwt); - + // Generate and store a new refresh token (token rotation) String newRefreshToken = jwtUtil.generateRefreshToken(user.getUserName(), userId); String newJti = jwtUtil.getJtiFromToken(newRefreshToken); redisTemplate.opsForValue().set( - "refresh:" + newJti, - userId, - jwtUtil.getRefreshTokenExpiration(), - TimeUnit.MILLISECONDS + "refresh:" + newJti, + userId, + jwtUtil.getRefreshTokenExpiration(), + TimeUnit.MILLISECONDS ); tokens.put("refreshToken", newRefreshToken); @@ -354,7 +360,7 @@ public String logOutUserFromConcurrentSession( } /** - * + * * function to return session object against userName */ private String getConcurrentCheckSessionObjectAgainstUser(String userName) { @@ -368,7 +374,7 @@ private String getConcurrentCheckSessionObjectAgainstUser(String userName) { } private void createUserMapping(User mUser, JSONObject resMap, JSONObject serviceRoleMultiMap, - JSONObject serviceRoleMap, JSONArray serviceRoleList, JSONObject previlegeObj) { + JSONObject serviceRoleMap, JSONArray serviceRoleList, JSONObject previlegeObj) { System.out.println(mUser); String fName = mUser.getFirstName(); String lName = mUser.getLastName(); @@ -460,10 +466,10 @@ public String superUserAuthenticate( resMap.put("isAuthenticated", /* Boolean.valueOf(true) */true); resMap.put("userName", mUser.getUserName()); jwtToken = jwtUtil.generateToken(m_User.getUserName(), mUser.getUserID().toString()); - + User user = new User(); // Assuming the Users class exists - user.setUserID(mUser.getUserID()); - user.setUserName(mUser.getUserName()); + user.setUserID(mUser.getUserID()); + user.setUserName(mUser.getUserName()); String userAgent = request.getHeader("User-Agent"); isMobile = UserAgentUtil.isMobileDevice(userAgent); @@ -555,7 +561,7 @@ public String getLoginResponse(HttpServletRequest request) { if (authHeader.isEmpty()) { // Try JWT token from header first String jwtToken = request.getHeader("Jwttoken"); - + // If not in header, try cookie if (jwtToken == null) { Cookie[] cookies = request.getCookies(); @@ -568,15 +574,15 @@ public String getLoginResponse(HttpServletRequest request) { } } } - + if (jwtToken == null) { logger.warn("Authentication failed: no token found in header or cookies."); throw new IEMRException("Authentication failed. Please log in again."); } - + // Extract user ID from the JWT token - String userId = jwtUtil.extractUserId(jwtToken); - + String userId = jwtUtil.getUserIdFromToken(jwtToken); + // Get user details and prepare response User user = iemrAdminUserServiceImpl.getUserById(Long.parseLong(userId)); if (user == null) { @@ -753,7 +759,7 @@ public String saveUserSecurityQuesAns( } /** - * + * * @return security qtns */ @Operation(summary = "Get security quetions") @@ -902,7 +908,7 @@ public String userLogout(HttpServletRequest request) { } /** - * + * * @param key * @return */ @@ -936,54 +942,54 @@ private void deleteSessionObject(String key) { @Operation(summary = "Force log out") @RequestMapping(value = "/forceLogout", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String forceLogout(@RequestBody ForceLogoutRequestModel request, HttpServletRequest httpRequest, HttpServletResponse response) { - OutputResponse outputResponse = new OutputResponse(); - try { - // Perform the force logout logic - iemrAdminUserServiceImpl.forceLogout(request); - - // Extract token from cookies or headers - String token = getJwtTokenFromCookies(httpRequest); - if (token == null) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - outputResponse.setError(new RuntimeException("No JWT token found in request")); - return outputResponse.toString(); - } - - // Validate the token: Check if it is expired or in the deny list - Claims claims = jwtUtil.validateToken(token); - if (claims.isEmpty() || claims.getExpiration() == null || claims.getId() == null) { // If token is either expired or in the deny list, return 401 Unauthorized - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - outputResponse.setError(new RuntimeException("Token is expired or has been logged out")); - return outputResponse.toString(); - } - - // Extract the jti (JWT ID) and expiration time from the validated claims - String jti = claims.getId(); // jti is in the 'id' field of claims - long expirationTime = claims.getExpiration().getTime(); // Use expiration from claims - long ttlMillis = expirationTime - System.currentTimeMillis(); - tokenDenylist.addTokenToDenylist(jti, ttlMillis); - - // Set the response message - outputResponse.setResponse("Success"); - } catch (Exception e) { - outputResponse.setError(e); - } - return outputResponse.toString(); + OutputResponse outputResponse = new OutputResponse(); + try { + // Perform the force logout logic + iemrAdminUserServiceImpl.forceLogout(request); + + // Extract token from cookies or headers + String token = getJwtTokenFromCookies(httpRequest); + if (token == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + outputResponse.setError(new RuntimeException("No JWT token found in request")); + return outputResponse.toString(); + } + + // Validate the token: Check if it is expired or in the deny list + Claims claims = jwtUtil.validateToken(token); + if (claims.isEmpty() || claims.getExpiration() == null || claims.getId() == null) { // If token is either expired or in the deny list, return 401 Unauthorized + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + outputResponse.setError(new RuntimeException("Token is expired or has been logged out")); + return outputResponse.toString(); + } + + // Extract the jti (JWT ID) and expiration time from the validated claims + String jti = claims.getId(); // jti is in the 'id' field of claims + long expirationTime = claims.getExpiration().getTime(); // Use expiration from claims + long ttlMillis = expirationTime - System.currentTimeMillis(); + tokenDenylist.addTokenToDenylist(jti, ttlMillis); + + // Set the response message + outputResponse.setResponse("Success"); + } catch (Exception e) { + outputResponse.setError(e); + } + return outputResponse.toString(); } private String getJwtTokenFromCookies(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equalsIgnoreCase(Constants.JWT_TOKEN)) { - return cookie.getValue(); - } - } - } - return null; + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equalsIgnoreCase(Constants.JWT_TOKEN)) { + return cookie.getValue(); + } + } + } + return null; } - + @Operation(summary = "User force log out") @RequestMapping(value = "/userForceLogout", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String userForceLogout( @@ -1206,4 +1212,4 @@ private JSONObject prepareAuthenticationResponse(User mUser, String remoteAddres return iemrAdminUserServiceImpl.generateKeyAndValidateIP(responseObj, remoteAddress, remoteHost); } -} +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index 0ea70bda..a4434e34 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -1,21 +1,16 @@ package com.iemr.common.utils; -import java.util.Date; -import java.util.UUID; -import java.util.function.Function; +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.UnsupportedJwtException; -import io.jsonwebtoken.security.Keys; -import io.jsonwebtoken.security.SignatureException; - import javax.crypto.SecretKey; +import java.util.Date; +import java.util.UUID; +import java.util.function.Function; @Component public class JwtUtil { @@ -29,6 +24,9 @@ public class JwtUtil { @Value("${jwt.refresh.expiration}") private long REFRESH_EXPIRATION_TIME; + @Autowired + private TokenDenylist tokenDenylist; + private SecretKey getSigningKey() { if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { throw new IllegalStateException("JWT secret key is not set in application.properties"); @@ -36,14 +34,37 @@ private SecretKey getSigningKey() { return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); } + /** + * Generate an access token. + * + * @param username the username of the user + * @param userId the user ID + * @return the generated JWT access token + */ public String generateToken(String username, String userId) { return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); } + /** + * Generate a refresh token. + * + * @param username the username of the user + * @param userId the user ID + * @return the generated JWT refresh token + */ public String generateRefreshToken(String username, String userId) { return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); } + /** + * Build a JWT token with the specified parameters. + * + * @param username the username of the user + * @param userId the user ID + * @param tokenType the type of the token (access or refresh) + * @param expiration the expiration time of the token in milliseconds + * @return the generated JWT token + */ private String buildToken(String username, String userId, String tokenType, long expiration) { return Jwts.builder() .subject(username) @@ -56,51 +77,88 @@ private String buildToken(String username, String userId, String tokenType, long .compact(); } + /** + * Validate the JWT token, checking if it is expired and if it's blacklisted + * @param token the JWT token + * @return Claims if valid, null if invalid (expired or denylisted) + */ public Claims validateToken(String token) { try { - return Jwts.parser() - .verifyWith(getSigningKey()) - .build() - .parseSignedClaims(token) - .getPayload(); + Claims claims = Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); + String jti = claims.getId(); + + // Check if token is denylisted (only if jti exists) + if (jti != null && tokenDenylist.isTokenDenylisted(jti)) { + return null; + } + return claims; } catch (ExpiredJwtException ex) { - // Handle expired token specifically if needed + + return null; // Token is expired, so return null } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { - // Log specific error types + return null; // Return null for any other JWT-related issue (invalid format, bad signature, etc.) } - return null; - } - - public T getClaimFromToken(String token, Function claimsResolver) { - final Claims claims = getAllClaimsFromToken(token); - return claimsResolver.apply(claims); } + /** + * Extract claims from the token + * @param token the JWT token + * @return all claims from the token + */ public Claims getAllClaimsFromToken(String token) { return Jwts.parser() .verifyWith(getSigningKey()) .build() .parseSignedClaims(token) .getPayload(); - } + } - public long getRefreshTokenExpiration() { - return REFRESH_EXPIRATION_TIME; + /** + * Extract a specific claim from the token using a function + * @param token the JWT token + * @param claimsResolver the function to extract the claim + * @param the type of the claim + * @return the extracted claim + */ + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); } - // Additional helper methods + /** + * Get the JWT ID (JTI) from the token + * @param token the JWT token + * @return the JWT ID + */ public String getJtiFromToken(String token) { return getAllClaimsFromToken(token).getId(); } + /** + * Get the username from the token + * @param token the JWT token + * @return the username + */ public String getUsernameFromToken(String token) { return getAllClaimsFromToken(token).getSubject(); } - public String extractUserId(String token) { - return getAllClaimsFromToken(token).getId(); + /** + * Get the user ID from the token + * @param token the JWT token + * @return the user ID + */ + public String getUserIdFromToken(String token) { + return getAllClaimsFromToken(token).get("userId", String.class); + } + /** + * Get the expiration time of the refresh token + * @return the expiration time in milliseconds + */ + public long getRefreshTokenExpiration() { + return REFRESH_EXPIRATION_TIME; } } \ No newline at end of file From 7dbc8eeb463e7e09931384e87abfd856425f62df Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 20:29:37 +0530 Subject: [PATCH 246/318] merge with main --- .../firebaseNotification/FirebaseNotificationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java index b97ac4de..7f33c453 100644 --- a/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java +++ b/src/main/java/com/iemr/common/service/firebaseNotification/FirebaseNotificationService.java @@ -110,7 +110,7 @@ public String getUserToken() throws IEMRException { HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader); - return userTokenRepo.findById(Integer.parseInt(jwtUtil.extractUserId(jwtTokenFromCookie))) // because your userId is Long in DB + return userTokenRepo.findById(Integer.parseInt(jwtUtil.getUserIdFromToken(jwtTokenFromCookie))) // because your userId is Long in DB .map(UserTokenData::getToken) .orElse(null); // } From e4717c844000a294042f0c0e02c90300959be696 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 23:28:26 +0530 Subject: [PATCH 247/318] merge with main --- src/main/environment/common_ci.properties | 1 + src/main/environment/common_docker.properties | 3 +- .../com/iemr/common/CommonApplication.java | 7 +- .../quartz/ScheduleForGrievanceDataSync.java | 4 +- .../NHMDetailCallReportScheduler.java | 4 +- .../common/controller/otp/OTPGateway.java | 9 +- .../controller/users/IEMRAdminController.java | 144 ++++----- .../model/beneficiary/BeneficiaryModel.java | 2 - .../KMFileManagerServiceImpl.java | 130 +++----- .../utils/JwtUserIdValidationFilter.java | 3 - .../java/com/iemr/common/utils/JwtUtil.java | 284 +++++++++--------- .../utils/http/HTTPRequestInterceptor.java | 2 - 12 files changed, 269 insertions(+), 324 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index e333a938..1303d624 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -32,6 +32,7 @@ identity-1097-api-url = @env.IDENTITY_1097_API_URL@ send-sms=@env.SEND_SMS@ sendSMSUrl = @env.SEND_SMS_URL@ source-address=@env.SMS_SOURCE_ADDRESS@ +sms-consent-source-address = @env.SMS_CONSENT_SOURCE_ADDRESS@ sms-username=@env.SMS_USERNAME@ sms-password=@env.SMS_PASSWORD@ send-message-url=@env.SMS_MESSAGE_URL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 0193be40..2bf481ed 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -25,13 +25,14 @@ cti-server-ip=${CTI_SERVER_IP} cti-logger_base_url=${CTI_SERVER_LOGGER_BASE}/logger # Identity Config -identity-api-url = ${IDENTITY_API_BASE_URL} +identity-api-url = ${IDENTITY_API_URL} identity-1097-api-url = ${IDENTITY_1097_API_URL} #### SMS Configuration send-sms=${SEND_SMS} sendSMSUrl = ${SEND_SMS_URL} source-address=${SMS_SOURCE_ADDRESS} +sms-consent-source-address=${SMS_CONSENT_SOURCE_ADDRESS} sms-username=${SMS_USERNAME} sms-password=${SMS_PASSWORD} send-message-url=${SMS_MESSAGE_URL} diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index 442a9ffe..e4a59994 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -21,20 +21,14 @@ */ package com.iemr.common; -import com.google.auth.oauth2.GoogleCredentials; -import com.google.firebase.FirebaseApp; -import com.google.firebase.FirebaseOptions; -import com.google.firebase.messaging.FirebaseMessaging; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; -import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; -import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.client.RestTemplate; @@ -80,4 +74,5 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factor return template; } + } diff --git a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java index 0cd95400..314b31ac 100644 --- a/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java +++ b/src/main/java/com/iemr/common/config/quartz/ScheduleForGrievanceDataSync.java @@ -14,8 +14,8 @@ @Component public class ScheduleForGrievanceDataSync { - // @Value("${start-grievancedatasync-scheduler}") - private boolean grievanceFlag=true; + @Value("${start-grievancedatasync-scheduler}") + private boolean grievanceFlag; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); diff --git a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java index 4542322d..d02eb3f2 100644 --- a/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java +++ b/src/main/java/com/iemr/common/controller/nhmdashboard/NHMDetailCallReportScheduler.java @@ -38,8 +38,8 @@ public class NHMDetailCallReportScheduler { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - // @Value("${start-ctidatacheck-scheduler}") - private boolean startCtiDataCheckFlag=true; + @Value("${start-ctidatacheck-scheduler}") + private boolean startCtiDataCheckFlag; @Scheduled(cron = "${cron-scheduler-ctidatacheck}") diff --git a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java index 57c1762b..777503b8 100644 --- a/src/main/java/com/iemr/common/controller/otp/OTPGateway.java +++ b/src/main/java/com/iemr/common/controller/otp/OTPGateway.java @@ -53,7 +53,6 @@ public class OTPGateway { @Operation(summary = "Send OTP") @RequestMapping(value = "/sendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { - logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -61,8 +60,7 @@ public String sendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody Stri OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.sendOTP(obj); - logger.info(success.toString()); - if (success.contains("otp")) + if (success.equalsIgnoreCase("success")) response.setResponse(success); else response.setError(5000, "failure"); @@ -100,7 +98,6 @@ public String validateOTP( @Operation(summary = "Resend OTP") @RequestMapping(value = "/resendOTP", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody String requestOBJ) { - logger.info(requestOBJ.toString()); OutputResponse response = new OutputResponse(); @@ -108,9 +105,7 @@ public String resendOTP(@Param(value = "{\"mobNo\":\"String\"}") @RequestBody St OTPRequestParsor obj = InputMapper.gson().fromJson(requestOBJ, OTPRequestParsor.class); String success = otpHandler.resendOTP(obj); - logger.info(success.toString()); - - if (success.contains("otp")) + if (success.equalsIgnoreCase("success")) response.setResponse(success); else response.setError(5000, "failure"); diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 5ac50aaa..bbe70dd4 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -1,24 +1,24 @@ /* - * AMRIT – Accessible Medical Records via Integrated Technology - * Integrated EHR (Electronic Health Records) Solution - * - * Copyright (C) "Piramal Swasthya Management and Research Institute" - * - * This file is part of AMRIT. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ package com.iemr.common.controller.users; import java.util.*; @@ -171,8 +171,8 @@ public String userAuthenticate( JSONArray serviceRoleList = new JSONArray(); JSONObject previlegeObj = new JSONObject(); if (m_User.getUserName() != null - && (m_User.getDoLogout() == null || !m_User.getDoLogout()) - && (m_User.getWithCredentials() != null && m_User.getWithCredentials())) { + && (m_User.getDoLogout() == null || !m_User.getDoLogout()) + && (m_User.getWithCredentials() != null && m_User.getWithCredentials())) { String tokenFromRedis = getConcurrentCheckSessionObjectAgainstUser( m_User.getUserName().trim().toLowerCase()); if (tokenFromRedis != null) { @@ -299,10 +299,10 @@ public ResponseEntity refreshToken(@RequestBody Map request) String newRefreshToken = jwtUtil.generateRefreshToken(user.getUserName(), userId); String newJti = jwtUtil.getJtiFromToken(newRefreshToken); redisTemplate.opsForValue().set( - "refresh:" + newJti, - userId, - jwtUtil.getRefreshTokenExpiration(), - TimeUnit.MILLISECONDS + "refresh:" + newJti, + userId, + jwtUtil.getRefreshTokenExpiration(), + TimeUnit.MILLISECONDS ); tokens.put("refreshToken", newRefreshToken); @@ -374,7 +374,7 @@ private String getConcurrentCheckSessionObjectAgainstUser(String userName) { } private void createUserMapping(User mUser, JSONObject resMap, JSONObject serviceRoleMultiMap, - JSONObject serviceRoleMap, JSONArray serviceRoleList, JSONObject previlegeObj) { + JSONObject serviceRoleMap, JSONArray serviceRoleList, JSONObject previlegeObj) { System.out.println(mUser); String fName = mUser.getFirstName(); String lName = mUser.getLastName(); @@ -468,8 +468,8 @@ public String superUserAuthenticate( jwtToken = jwtUtil.generateToken(m_User.getUserName(), mUser.getUserID().toString()); User user = new User(); // Assuming the Users class exists - user.setUserID(mUser.getUserID()); - user.setUserName(mUser.getUserName()); + user.setUserID(mUser.getUserID()); + user.setUserName(mUser.getUserName()); String userAgent = request.getHeader("User-Agent"); isMobile = UserAgentUtil.isMobileDevice(userAgent); @@ -942,51 +942,51 @@ private void deleteSessionObject(String key) { @Operation(summary = "Force log out") @RequestMapping(value = "/forceLogout", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String forceLogout(@RequestBody ForceLogoutRequestModel request, HttpServletRequest httpRequest, HttpServletResponse response) { - OutputResponse outputResponse = new OutputResponse(); - try { - // Perform the force logout logic - iemrAdminUserServiceImpl.forceLogout(request); - - // Extract token from cookies or headers - String token = getJwtTokenFromCookies(httpRequest); - if (token == null) { - response.setStatus(HttpServletResponse.SC_BAD_REQUEST); - outputResponse.setError(new RuntimeException("No JWT token found in request")); - return outputResponse.toString(); - } - - // Validate the token: Check if it is expired or in the deny list - Claims claims = jwtUtil.validateToken(token); - if (claims.isEmpty() || claims.getExpiration() == null || claims.getId() == null) { // If token is either expired or in the deny list, return 401 Unauthorized - response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - outputResponse.setError(new RuntimeException("Token is expired or has been logged out")); - return outputResponse.toString(); - } - - // Extract the jti (JWT ID) and expiration time from the validated claims - String jti = claims.getId(); // jti is in the 'id' field of claims - long expirationTime = claims.getExpiration().getTime(); // Use expiration from claims - long ttlMillis = expirationTime - System.currentTimeMillis(); - tokenDenylist.addTokenToDenylist(jti, ttlMillis); - - // Set the response message - outputResponse.setResponse("Success"); - } catch (Exception e) { - outputResponse.setError(e); - } - return outputResponse.toString(); + OutputResponse outputResponse = new OutputResponse(); + try { + // Perform the force logout logic + iemrAdminUserServiceImpl.forceLogout(request); + + // Extract token from cookies or headers + String token = getJwtTokenFromCookies(httpRequest); + if (token == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + outputResponse.setError(new RuntimeException("No JWT token found in request")); + return outputResponse.toString(); + } + + // Validate the token: Check if it is expired or in the deny list + Claims claims = jwtUtil.validateToken(token); + if (claims.isEmpty() || claims.getExpiration() == null || claims.getId() == null) { // If token is either expired or in the deny list, return 401 Unauthorized + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + outputResponse.setError(new RuntimeException("Token is expired or has been logged out")); + return outputResponse.toString(); + } + + // Extract the jti (JWT ID) and expiration time from the validated claims + String jti = claims.getId(); // jti is in the 'id' field of claims + long expirationTime = claims.getExpiration().getTime(); // Use expiration from claims + long ttlMillis = expirationTime - System.currentTimeMillis(); + tokenDenylist.addTokenToDenylist(jti, ttlMillis); + + // Set the response message + outputResponse.setResponse("Success"); + } catch (Exception e) { + outputResponse.setError(e); + } + return outputResponse.toString(); } private String getJwtTokenFromCookies(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equalsIgnoreCase(Constants.JWT_TOKEN)) { - return cookie.getValue(); - } - } - } - return null; + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equalsIgnoreCase(Constants.JWT_TOKEN)) { + return cookie.getValue(); + } + } + } + return null; } @@ -1212,4 +1212,4 @@ private JSONObject prepareAuthenticationResponse(User mUser, String remoteAddres return iemrAdminUserServiceImpl.generateKeyAndValidateIP(responseObj, remoteAddress, remoteHost); } -} \ No newline at end of file +} diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index 184a5637..ed7c9cad 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -92,8 +92,6 @@ public class BeneficiaryModel implements Comparable { private TitleModel m_title; @Expose private String firstName; - - @Expose private String middleName; @Expose diff --git a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java index 1446787d..39130288 100644 --- a/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java +++ b/src/main/java/com/iemr/common/service/kmfilemanager/KMFileManagerServiceImpl.java @@ -1,8 +1,8 @@ /* -* AMRIT – Accessible Medical Records via Integrated Technology -* Integrated EHR (Electronic Health Records) Solution +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution * -* Copyright (C) "Piramal Swasthya Management and Research Institute" +* Copyright (C) "Piramal Swasthya Management and Research Institute" * * This file is part of AMRIT. * @@ -34,14 +34,12 @@ import java.util.Objects; import java.util.Set; -import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.DigestUtils; @@ -86,9 +84,6 @@ public void setSubCategoryRepository(SubCategoryRepository subCategoryRepository private InputMapper inputMapper = new InputMapper(); - @Value("${allowed.file.extensions}") - private String allowedFileExtensions; - @Override public String getKMFileLists(String request) throws Exception { ObjectMapper objectMapper = new ObjectMapper(); @@ -130,84 +125,49 @@ public String addKMFile(String request) throws IOException, NoSuchAlgorithmExcep return kmFileManagers.toString(); } - + private ArrayList addKMFile(Iterable kmFileManagers) throws IOException, NoSuchAlgorithmException { ArrayList savedFileManagers = new ArrayList(); FileOutputStream newFile = null; FileInputStream fis = null; - try { - for (KMFileManager kmFileManager : kmFileManagers) { - if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null - && kmFileManager.getFileContent() != null) { - - if (allowedFileExtensions == null || allowedFileExtensions.trim().isEmpty()) { - throw new IllegalStateException( - "Environment variable 'allowed.file.extensions' is not configured or is empty"); - } - List allowedExtensions = Arrays.asList(allowedFileExtensions.split(",")); - logger.info("Allowed extensions: " + allowedExtensions); - - - // Extract extension from fileName - String extensionFromName = FilenameUtils.getExtension(kmFileManager.getFileName()); - logger.info("extensionFromName " + extensionFromName); - - // Normalize payload fileExtension (remove dot if present) - String extensionFromPayload = kmFileManager.getFileExtension(); - logger.info("extensionPayload " + extensionFromPayload); - - if (extensionFromPayload != null && extensionFromPayload.startsWith(".")) { - extensionFromPayload = extensionFromPayload.substring(1); - } - - // Validate extensions - if (extensionFromName == null || extensionFromPayload == null) { - throw new IOException("File extension missing"); - } - - if (!extensionFromName.equalsIgnoreCase(extensionFromPayload)) { - throw new IOException( - "File extension mismatch: " + extensionFromName + " vs " + extensionFromPayload); - } - - if (!allowedExtensions.contains(extensionFromName.toLowerCase())) { - throw new IOException("File extension not allowed: " + extensionFromName); - } - - kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "") - .replace("$", "") - .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") - .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") - .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") - .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") - .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") - .replace("=", "").replace("\"", "").replace("'", "")); - String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); - newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); - newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); - newFile.flush(); - newFile.close(); - fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); - String checksum = DigestUtils.md5DigestAsHex(fis); - fis.close(); - logger.info("File is " + kmFileManager.getFileName()); - logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); - logger.info("File checksum is " + checksum); - logger.info("File checksum length is " + checksum.length()); - kmFileManager.setFileCheckSum(checksum); - kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); - String version = getFileVersion(kmFileManager); - kmFileManager.setVersionNo(version); - String documentPath = kmFileManager.getProviderServiceMapID() + "/"; - if (kmFileManager.getCategoryID() != null) { - documentPath += kmFileManager.getCategoryID() + "/"; - } - if (kmFileManager.getSubCategoryID() != null) { - documentPath += kmFileManager.getSubCategoryID() + "/"; - } - if (kmFileManager.getVanID() != null) - documentPath += kmFileManager.getVanID() + "/"; + try + { + for (KMFileManager kmFileManager : kmFileManagers) { + if (kmFileManager.getFileName() != null && kmFileManager.getProviderServiceMapID() != null + && kmFileManager.getFileContent() != null) { + kmFileManager.setFileName(kmFileManager.getFileName().replace("`", "").replace("'", "").replace("$", "") + .replace("\\", "").replace("/", "").replace("~", "").replace("`", "").replace("!", "") + .replace("@", "").replace("#", "").replace("$", "").replace("%", "").replace("^", "") + .replace("&", "").replace("*", "").replace("(", "").replace(")", "").replace("{", "") + .replace("}", "").replace("[", "").replace("]", "").replace("|", "").replace("\\", "") + .replace(":", "").replace(";", "").replace("-", "").replace("_", "").replace("+", "") + .replace("=", "").replace("\"", "").replace("'", "")); + String tempFilePath = ConfigProperties.getPropertyByName("tempFilePath"); + newFile = new FileOutputStream(tempFilePath + "/" + kmFileManager.getFileName()); + newFile.write(Base64.getDecoder().decode(kmFileManager.getFileContent())); + newFile.flush(); + newFile.close(); + fis = new FileInputStream(tempFilePath + "/" + kmFileManager.getFileName()); + String checksum = DigestUtils.md5DigestAsHex(fis); + fis.close(); + logger.info("File is " + kmFileManager.getFileName()); + logger.info("File size is " + new File(tempFilePath + "/" + kmFileManager.getFileName()).length()); + logger.info("File checksum is " + checksum); + logger.info("File checksum length is " + checksum.length()); + kmFileManager.setFileCheckSum(checksum); + kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_PENDING); + String version = getFileVersion(kmFileManager); + kmFileManager.setVersionNo(version); + String documentPath = kmFileManager.getProviderServiceMapID() + "/"; + if (kmFileManager.getCategoryID() != null) { + documentPath += kmFileManager.getCategoryID() + "/"; + } + if (kmFileManager.getSubCategoryID() != null) { + documentPath += kmFileManager.getSubCategoryID() + "/"; + } + if (kmFileManager.getVanID() != null) + documentPath += kmFileManager.getVanID() + "/"; documentPath += version + "/"; documentPath += kmFileManager.getFileName(); @@ -216,9 +176,9 @@ private ArrayList addKMFile(Iterable kmFileManager if (uuid != null) { kmFileManager.setKmUploadStatus(KM_UPLOADSTATUS_COMPLETED); kmFileManager.setFileUID(uuid); - + kmFileManager.setSubCategoryID(kmFileManager.getSubCategoryID()); - + savedFileManagers.add(kmFileManagerRepository.save(kmFileManager)); if (kmFileManager.getSubCategoryID() != null) { updateSubcategoryFilePath(kmFileManager); @@ -234,7 +194,7 @@ private ArrayList addKMFile(Iterable kmFileManager finally { if(newFile !=null) - newFile.close(); + newFile.close(); if(fis !=null) fis.close(); } @@ -251,7 +211,7 @@ private String getFileVersion(KMFileManager kmFileManager) { List files = kmFileManagerRepository.getKMFileByFileName(kmFileManager.getProviderServiceMapID(), kmFileManager.getFileName()); version = "V" + (files.size() + 1); - + return version; } } diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 98215dfd..13eaea2f 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -59,7 +59,6 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); - // Log cookies for debugging Cookie[] cookies = request.getCookies(); if (cookies != null) { @@ -171,10 +170,8 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/userLogout") || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); - } - private String getJwtTokenFromCookies(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index a4434e34..d8414968 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -15,150 +15,150 @@ @Component public class JwtUtil { - @Value("${jwt.secret}") - private String SECRET_KEY; - - @Value("${jwt.access.expiration}") - private long ACCESS_EXPIRATION_TIME; - - @Value("${jwt.refresh.expiration}") - private long REFRESH_EXPIRATION_TIME; - - @Autowired - private TokenDenylist tokenDenylist; - - private SecretKey getSigningKey() { - if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { - throw new IllegalStateException("JWT secret key is not set in application.properties"); - } - return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); - } - - /** - * Generate an access token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT access token - */ - public String generateToken(String username, String userId) { - return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); - } - - /** - * Generate a refresh token. - * - * @param username the username of the user - * @param userId the user ID - * @return the generated JWT refresh token - */ - public String generateRefreshToken(String username, String userId) { - return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); - } - - /** - * Build a JWT token with the specified parameters. - * - * @param username the username of the user - * @param userId the user ID - * @param tokenType the type of the token (access or refresh) - * @param expiration the expiration time of the token in milliseconds - * @return the generated JWT token - */ - private String buildToken(String username, String userId, String tokenType, long expiration) { - return Jwts.builder() - .subject(username) - .claim("userId", userId) - .claim("token_type", tokenType) - .id(UUID.randomUUID().toString()) - .issuedAt(new Date()) - .expiration(new Date(System.currentTimeMillis() + expiration)) - .signWith(getSigningKey()) - .compact(); - } - - /** - * Validate the JWT token, checking if it is expired and if it's blacklisted - * @param token the JWT token - * @return Claims if valid, null if invalid (expired or denylisted) - */ - public Claims validateToken(String token) { - try { - Claims claims = Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); - String jti = claims.getId(); - - // Check if token is denylisted (only if jti exists) - if (jti != null && tokenDenylist.isTokenDenylisted(jti)) { - return null; - } - - return claims; - } catch (ExpiredJwtException ex) { - - return null; // Token is expired, so return null - } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { - return null; // Return null for any other JWT-related issue (invalid format, bad signature, etc.) - } - } - - /** - * Extract claims from the token - * @param token the JWT token - * @return all claims from the token - */ - public Claims getAllClaimsFromToken(String token) { - return Jwts.parser() + @Value("${jwt.secret}") + private String SECRET_KEY; + + @Value("${jwt.access.expiration}") + private long ACCESS_EXPIRATION_TIME; + + @Value("${jwt.refresh.expiration}") + private long REFRESH_EXPIRATION_TIME; + + @Autowired + private TokenDenylist tokenDenylist; + + private SecretKey getSigningKey() { + if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { + throw new IllegalStateException("JWT secret key is not set in application.properties"); + } + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + + /** + * Generate an access token. + * + * @param username the username of the user + * @param userId the user ID + * @return the generated JWT access token + */ + public String generateToken(String username, String userId) { + return buildToken(username, userId, "access", ACCESS_EXPIRATION_TIME); + } + + /** + * Generate a refresh token. + * + * @param username the username of the user + * @param userId the user ID + * @return the generated JWT refresh token + */ + public String generateRefreshToken(String username, String userId) { + return buildToken(username, userId, "refresh", REFRESH_EXPIRATION_TIME); + } + + /** + * Build a JWT token with the specified parameters. + * + * @param username the username of the user + * @param userId the user ID + * @param tokenType the type of the token (access or refresh) + * @param expiration the expiration time of the token in milliseconds + * @return the generated JWT token + */ + private String buildToken(String username, String userId, String tokenType, long expiration) { + return Jwts.builder() + .subject(username) + .claim("userId", userId) + .claim("token_type", tokenType) + .id(UUID.randomUUID().toString()) + .issuedAt(new Date()) + .expiration(new Date(System.currentTimeMillis() + expiration)) + .signWith(getSigningKey()) + .compact(); + } + + /** + * Validate the JWT token, checking if it is expired and if it's blacklisted + * @param token the JWT token + * @return Claims if valid, null if invalid (expired or denylisted) + */ + public Claims validateToken(String token) { + try { + Claims claims = Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); + String jti = claims.getId(); + + // Check if token is denylisted (only if jti exists) + if (jti != null && tokenDenylist.isTokenDenylisted(jti)) { + return null; + } + + return claims; + } catch (ExpiredJwtException ex) { + + return null; // Token is expired, so return null + } catch (UnsupportedJwtException | MalformedJwtException | SignatureException | IllegalArgumentException ex) { + return null; // Return null for any other JWT-related issue (invalid format, bad signature, etc.) + } + } + + /** + * Extract claims from the token + * @param token the JWT token + * @return all claims from the token + */ + public Claims getAllClaimsFromToken(String token) { + return Jwts.parser() .verifyWith(getSigningKey()) .build() .parseSignedClaims(token) .getPayload(); - } - - /** - * Extract a specific claim from the token using a function - * @param token the JWT token - * @param claimsResolver the function to extract the claim - * @param the type of the claim - * @return the extracted claim - */ - public T getClaimFromToken(String token, Function claimsResolver) { - final Claims claims = getAllClaimsFromToken(token); - return claimsResolver.apply(claims); - } - - /** - * Get the JWT ID (JTI) from the token - * @param token the JWT token - * @return the JWT ID - */ - public String getJtiFromToken(String token) { - return getAllClaimsFromToken(token).getId(); - } - - /** - * Get the username from the token - * @param token the JWT token - * @return the username - */ - public String getUsernameFromToken(String token) { - return getAllClaimsFromToken(token).getSubject(); - } - - /** - * Get the user ID from the token - * @param token the JWT token - * @return the user ID - */ - public String getUserIdFromToken(String token) { - return getAllClaimsFromToken(token).get("userId", String.class); - } - - /** - * Get the expiration time of the refresh token - * @return the expiration time in milliseconds - */ - public long getRefreshTokenExpiration() { - return REFRESH_EXPIRATION_TIME; - } -} \ No newline at end of file + } + + /** + * Extract a specific claim from the token using a function + * @param token the JWT token + * @param claimsResolver the function to extract the claim + * @param the type of the claim + * @return the extracted claim + */ + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + /** + * Get the JWT ID (JTI) from the token + * @param token the JWT token + * @return the JWT ID + */ + public String getJtiFromToken(String token) { + return getAllClaimsFromToken(token).getId(); + } + + /** + * Get the username from the token + * @param token the JWT token + * @return the username + */ + public String getUsernameFromToken(String token) { + return getAllClaimsFromToken(token).getSubject(); + } + + /** + * Get the user ID from the token + * @param token the JWT token + * @return the user ID + */ + public String getUserIdFromToken(String token) { + return getAllClaimsFromToken(token).get("userId", String.class); + } + + /** + * Get the expiration time of the refresh token + * @return the expiration time in milliseconds + */ + public long getRefreshTokenExpiration() { + return REFRESH_EXPIRATION_TIME; + } +} diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index a116f3a7..23b0af62 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -38,8 +38,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - - @Configuration @Component public class HTTPRequestInterceptor implements HandlerInterceptor { From c32fb6b00e5655ac8235c10010375b0cbb7da775 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 3 Sep 2025 23:30:47 +0530 Subject: [PATCH 248/318] merge with main --- src/main/resources/application.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f81ea0b5..1a6a6e6f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -383,6 +383,3 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent -sms-consent-source-address - - From 50e2313b78b5ae6eecdf014ed06172e56027c29e Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Fri, 5 Sep 2025 11:25:25 +0530 Subject: [PATCH 249/318] fix: fix the session expiry issue (#286) --- .../com/iemr/common/controller/users/IEMRAdminController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 28c7e4b9..12e0e9e4 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -343,9 +343,10 @@ public String logOutUserFromConcurrentSession( deleteSessionObjectByGettingSessionDetails(previousTokenFromRedis); sessionObject.deleteSessionObject(previousTokenFromRedis); response.setResponse("User successfully logged out"); - } else + } else{ logger.error("Unable to fetch session from redis"); throw new IEMRException("Session error. Please try again later"); + } } } else { throw new IEMRException("Invalid request object"); From c181b2ab1c8f53044174af0b00e184a546303390 Mon Sep 17 00:00:00 2001 From: ravishanigarapu <133210792+ravishanigarapu@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:55:30 +0530 Subject: [PATCH 250/318] Content disposition modified signature (#287) * Content disposition modified signature * Coderabbit comments addressed --- .../users/EmployeeSignatureController.java | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java b/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java index a2156af1..e04fffc5 100644 --- a/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java +++ b/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java @@ -21,22 +21,28 @@ */ package com.iemr.common.controller.users; +import java.nio.charset.StandardCharsets; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.PropertySource; +import org.springframework.http.CacheControl; +import org.springframework.http.ContentDisposition; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.InvalidMediaTypeException; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; import com.google.gson.Gson; import com.iemr.common.data.users.EmployeeSignature; import com.iemr.common.service.users.EmployeeSignatureServiceImpl; -import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.response.OutputResponse; import io.swagger.v3.oas.annotations.Operation; @@ -51,29 +57,45 @@ public class EmployeeSignatureController { @Autowired EmployeeSignatureServiceImpl employeeSignatureServiceImpl; - private InputMapper inputMapper = new InputMapper(); - private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); @Operation(summary = "Fetch file") @RequestMapping(value = "/{userID}", headers = "Authorization", method = { RequestMethod.GET }) public ResponseEntity fetchFile(@PathVariable("userID") Long userID) throws Exception { - OutputResponse response = new OutputResponse(); logger.debug("File download for userID" + userID); try { - EmployeeSignature userSignID = employeeSignatureServiceImpl.fetchSignature(userID); - return ResponseEntity.ok().contentType(MediaType.parseMediaType(userSignID.getFileType())) - .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + userSignID.getFileName() + "\"") - .body(userSignID.getSignature()); + String originalName = userSignID.getFileName(); + if (originalName == null || originalName.isBlank()) { + originalName = "signature"; + } + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentDisposition( + ContentDisposition.attachment().filename(originalName, StandardCharsets.UTF_8).build()); + responseHeaders.setCacheControl(CacheControl.noStore()); + responseHeaders.add(HttpHeaders.PRAGMA, "no-cache"); + responseHeaders.setExpires(0); + MediaType mediaType; + try { + mediaType = MediaType.parseMediaType(userSignID.getFileType()); + } catch (InvalidMediaTypeException | NullPointerException e) { + mediaType = MediaType.APPLICATION_OCTET_STREAM; + } + + byte[] fileBytes = userSignID.getSignature(); // MUST be byte[] + if (fileBytes == null || fileBytes.length == 0) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Signature not found for userID: " + userID); + } + + return ResponseEntity.ok().headers(responseHeaders).contentType(mediaType).contentLength(fileBytes.length) + .body(fileBytes); } catch (Exception e) { logger.error("File download for userID failed with exception " + e.getMessage(), e); + throw new Exception("Error while downloading file. Please contact administrator.."); } - return ResponseEntity.badRequest().body(new byte[] {}); - } @Operation(summary = "Fetch file from central") From 5e39ca11dd9f787d84825de88e46c0df3c8290f7 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Wed, 10 Sep 2025 21:14:23 +0530 Subject: [PATCH 251/318] feat: amm-1337 platform feedback module --- pom.xml | 2 +- src/main/environment/common_ci.properties | 13 +- src/main/environment/common_docker.properties | 13 +- .../environment/common_example.properties | 17 ++ .../com/iemr/common/config/RedisConfig.java | 7 + .../PlatformFeedbackController.java | 74 ++++++ .../data/platform_feedback/Feedback.java | 203 ++++++++++++++++ .../platform_feedback/FeedbackCategory.java | 157 +++++++++++++ .../platform_feedback/CategoryResponse.java | 24 ++ .../platform_feedback/FeedbackRequest.java | 38 +++ .../platform_feedback/FeedbackResponse.java | 26 +++ .../common/exception/BadRequestException.java | 31 +++ .../PlatformFeedbackRateLimitFilter.java | 216 ++++++++++++++++++ .../PlatformFeedbackCategoryRepository.java | 34 +++ .../PlatformFeedbackRepository.java | 30 +++ .../PlatformFeedbackService.java | 113 +++++++++ .../com/iemr/common/utils/FilterConfig.java | 102 +++++++-- .../utils/JwtUserIdValidationFilter.java | 41 ++++ 18 files changed, 1124 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java create mode 100644 src/main/java/com/iemr/common/data/platform_feedback/Feedback.java create mode 100644 src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java create mode 100644 src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java create mode 100644 src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java create mode 100644 src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java create mode 100644 src/main/java/com/iemr/common/exception/BadRequestException.java create mode 100644 src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java create mode 100644 src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java create mode 100644 src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java create mode 100644 src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java diff --git a/pom.xml b/pom.xml index d4749c5a..a2e6e019 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.1.0 + 3.5.0 war Common-API diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index a5e66660..14e78c13 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -185,4 +185,15 @@ cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS@ video-call-url=@env.VIDEO_CALL_URL@ jibri.output.path=@env.JIBRI_OUTPUT_PATH@ -video.recording.path=@env.VIDEO_RECORDING_PATH@ \ No newline at end of file +video.recording.path=@env.VIDEO_RECORDING_PATH@ + +# Platform Feedback module +platform.feedback.ratelimit.enabled=@env.PLATFORM_FEEDBACK_RATELIMIT_ENABLED@ +platform.feedback.ratelimit.pepper=@env.PLATFORM_FEEDBACK_RATELIMIT_PEPPER@ +platform.feedback.ratelimit.trust-forwarded-for=@env.PLATFORM_FEEDBACK_RATELIMIT_TRUST_FORWARDED_FOR@ +platform.feedback.ratelimit.forwarded-for-header=@env.PLATFORM_FEEDBACK_RATELIMIT_FORWARDED_FOR_HEADER@ +platform.feedback.ratelimit.minute-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_MINUTE_LIMIT@ +platform.feedback.ratelimit.day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT@ +platform.feedback.ratelimit.user-day-limit=@env.PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT@ +platform.feedback.ratelimit.fail-window-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES@ +platform.feedback.ratelimit.backoff-minutes=@env.PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES@ \ No newline at end of file diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 41881886..d96a999e 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -187,4 +187,15 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS} video-call-url=${VIDEO_CALL_URL} jibri.output.path={JIBRI_OUTPUT_PATH} -video.recording.path={VIDEO_RECORDING_PATH} \ No newline at end of file +video.recording.path={VIDEO_RECORDING_PATH} + +# Platform Feedback module +platform.feedback.ratelimit.enabled=${PLATFORM_FEEDBACK_RATELIMIT_ENABLED} +platform.feedback.ratelimit.pepper=${PLATFORM_FEEDBACK_RATELIMIT_PEPPER} +platform.feedback.ratelimit.trust-forwarded-for=${PLATFORM_FEEDBACK_RATELIMIT_TRUST_FORWARDED_FOR} +platform.feedback.ratelimit.forwarded-for-header=${PLATFORM_FEEDBACK_RATELIMIT_FORWARDED_FOR_HEADER} +platform.feedback.ratelimit.minute-limit=${PLATFORM_FEEDBACK_RATELIMIT_MINUTE_LIMIT} +platform.feedback.ratelimit.day-limit=${PLATFORM_FEEDBACK_RATELIMIT_DAY_LIMIT} +platform.feedback.ratelimit.user-day-limit=${PLATFORM_FEEDBACK_RATELIMIT_USER_DAY_LIMIT} +platform.feedback.ratelimit.fail-window-minutes=${PLATFORM_FEEDBACK_RATELIMIT_FAIL_WINDOW_MINUTES} +platform.feedback.ratelimit.backoff-minutes=${PLATFORM_FEEDBACK_RATELIMIT_BACKOFF_MINUTES} diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 09a526dd..9aa75988 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -208,3 +208,20 @@ captcha.enable-captcha=true cors.allowed-origins=http://localhost:* +# ---Platform Feedback module --- +# Rate limiter OFF locally (no Redis required) +platform.feedback.ratelimit.enabled=true +platform.feedback.ratelimit.pepper=dev-pepper-123 # dummy + +# trust forwarded-for locally is harmless (localhost only) +platform.feedback.ratelimit.trust-forwarded-for=false +platform.feedback.ratelimit.forwarded-for-header=X-Forwarded-For + +# Optional overrides (not needed if disabled) +platform.feedback.ratelimit.minute-limit=10 +platform.feedback.ratelimit.day-limit=100 +platform.feedback.ratelimit.user-day-limit=50 +platform.feedback.ratelimit.fail-window-minutes=5 +platform.feedback.ratelimit.backoff-minutes=15 + + diff --git a/src/main/java/com/iemr/common/config/RedisConfig.java b/src/main/java/com/iemr/common/config/RedisConfig.java index faac71ae..e39692b7 100644 --- a/src/main/java/com/iemr/common/config/RedisConfig.java +++ b/src/main/java/com/iemr/common/config/RedisConfig.java @@ -30,6 +30,7 @@ import org.springframework.session.data.redis.config.ConfigureRedisAction; import com.iemr.common.data.users.User; +import org.springframework.data.redis.core.StringRedisTemplate; @Configuration public class RedisConfig { @@ -54,4 +55,10 @@ public RedisTemplate redisTemplate(RedisConnectionFactory factory) return template; } + // new bean for rate limiting & counters + @Bean + public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { + return new StringRedisTemplate(factory); + } + } diff --git a/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java new file mode 100644 index 00000000..fd9aad90 --- /dev/null +++ b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java @@ -0,0 +1,74 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.controller; + +import com.iemr.common.dto.*; +import com.iemr.common.service.PlatformFeedbackService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.media.Content; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Tag(name = "Platform Feedback", description = "Feedback ingestion and category listing for platform-wide feedback") +@RestController +@RequestMapping("/platform-feedback") +@Validated +public class PlatformFeedbackController { + + private final PlatformFeedbackService service; + + public PlatformFeedbackController(PlatformFeedbackService service) { + this.service = service; + } + + @Operation(summary = "Submit feedback (public endpoint)", + description = "Accepts feedback (anonymous or identified). Accepts categoryId or categorySlug; slug is preferred.") + @ApiResponse(responseCode = "201", description = "Feedback accepted") + @ApiResponse(responseCode = "400", description = "Validation or business error", content = @Content) + @PostMapping + public ResponseEntity submit( + @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Feedback payload") + @Valid @RequestBody FeedbackRequest req) { + FeedbackResponse resp = service.submitFeedback(req); + return ResponseEntity.status(HttpStatus.CREATED).body(resp); + } + + @Operation(summary = "List active categories", + description = "Returns active categories. Optionally filter by serviceLine (frontend convenience).") + @ApiResponse(responseCode = "200", description = "List of categories") + @GetMapping("/categories") + public ResponseEntity> list( + @Parameter(description = "Optional serviceLine to prefer scopes (1097|104|AAM|MMU|TM|ECD)") + @RequestParam(required = false) String serviceLine) { + if (serviceLine == null) serviceLine = "GLOBAL"; + List list = service.listCategories(serviceLine); + return ResponseEntity.ok(list); + } +} diff --git a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java new file mode 100644 index 00000000..cbce9b07 --- /dev/null +++ b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java @@ -0,0 +1,203 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Represents feedback provided by users for a specific service or category. + * Mapped to "m_platform_feedback". + */ +@Entity +@Table(name = "m_platform_feedback") +public class Feedback { + + @Id + @Column(name = "FeedbackID", length = 36, updatable = false, nullable = false) + private String feedbackId; + + @Column(name = "CreatedAt", nullable = false) + private LocalDateTime createdAt; + + @Column(name = "UpdatedAt", nullable = false) + private LocalDateTime updatedAt; + + @Min(1) + @Max(5) + @Column(name = "Rating", nullable = false) + private int rating; + + @NotBlank(message = "Comment cannot be blank") + @Size(max = 2000, message = "Comment cannot exceed 2000 characters") + @Column(name = "Comment", columnDefinition = "TEXT", nullable = false) + private String comment; + + @Column(name = "ServiceLine", nullable = false, length = 10) + private String serviceLine; + + @Column(name = "IsAnonymous", nullable = false) + private boolean isAnonymous; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "CategoryID", referencedColumnName = "CategoryID", nullable = false) + private FeedbackCategory category; + + /** + * We store the numeric UserID if the submission is identified. We don't map to a User + * entity here to avoid cross-module coupling; the DB should have the FK enforced if desired. + */ + @Column(name = "UserID") + private Integer userId; + + // ===== Constructors ===== + public Feedback() { + // default constructor for JPA + } + + // convenience constructor (optional) + public Feedback(int rating, String comment, String serviceLine, boolean isAnonymous, FeedbackCategory category, Integer userId) { + this.feedbackId = UUID.randomUUID().toString(); + this.createdAt = LocalDateTime.now(); + this.updatedAt = this.createdAt; + this.setRating(rating); + this.setComment(comment); + this.setServiceLine(serviceLine); + this.isAnonymous = isAnonymous; + this.category = category; + this.userId = userId; + } + + // ======= JPA lifecycle callbacks ======= + @PrePersist + protected void onCreate() { + if (this.feedbackId == null) { + this.feedbackId = UUID.randomUUID().toString(); + } + if (this.createdAt == null) { + this.createdAt = LocalDateTime.now(); + } + this.updatedAt = this.createdAt; + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + // ======= Getters & Setters ======= + public String getFeedbackId() { + return feedbackId; + } + + public void setFeedbackId(String feedbackId) { + this.feedbackId = feedbackId; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + // createdAt should only be set once; still exposing setter if needed + public void setCreatedAt(LocalDateTime createdAt) { + if (this.createdAt == null) { + this.createdAt = createdAt; + } + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + // updatedAt is managed by lifecycle callbacks but a setter is fine for tests/migration + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public int getRating() { + return rating; + } + + public void setRating(int rating) { + if (rating < 1 || rating > 5) { + throw new IllegalArgumentException("Rating must be between 1 and 5."); + } + this.rating = rating; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + if (comment == null || comment.trim().isEmpty()) { + throw new IllegalArgumentException("Comment cannot be blank"); + } + if (comment.length() > 2000) { + throw new IllegalArgumentException("Comment cannot exceed 2000 characters"); + } + this.comment = comment; + } + + public String getServiceLine() { + return serviceLine; + } + + public void setServiceLine(String serviceLine) { + if (serviceLine == null || serviceLine.trim().isEmpty()) { + throw new IllegalArgumentException("ServiceLine must not be null or empty."); + } + this.serviceLine = serviceLine; + } + + public boolean isAnonymous() { + return isAnonymous; + } + + public void setAnonymous(boolean anonymous) { + isAnonymous = anonymous; + } + + public FeedbackCategory getCategory() { + return category; + } + + public void setCategory(FeedbackCategory category) { + if (category == null) { + throw new IllegalArgumentException("Category must not be null."); + } + this.category = category; + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java new file mode 100644 index 00000000..490805c4 --- /dev/null +++ b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java @@ -0,0 +1,157 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.model; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * FeedbackCategory maps to the m_feedback_category table. + */ +@Entity +@Table(name = "m_feedback_category", uniqueConstraints = { + @UniqueConstraint(name = "uq_category_slug", columnNames = "Slug") +}) +public class FeedbackCategory { + + @Id + @Column(name = "CategoryID", length = 36, updatable = false, nullable = false) + private String categoryId; + + @NotBlank + @Pattern(regexp = "^[a-z0-9]+(?:-[a-z0-9]+)*$", message = "Slug must be lowercase alphanumeric with optional single dashes") + @Size(max = 64) + @Column(name = "Slug", nullable = false, length = 64) + private String slug; + + @NotBlank + @Size(max = 128) + @Column(name = "Label", nullable = false, length = 128) + private String label; + + @NotBlank + @Size(max = 20) + @Column(name = "Scope", nullable = false, length = 20) + private String scope; + + @Column(name = "Active", nullable = false) + private boolean active; + + @Column(name = "CreatedAt", nullable = false) + private LocalDateTime createdAt; + + @Column(name = "UpdatedAt", nullable = false) + private LocalDateTime updatedAt; + + // ===== Constructors ===== + public FeedbackCategory() { + // default ctor for JPA + } + + public FeedbackCategory(String slug, String label, String scope, boolean active) { + this.slug = slug; + this.label = label; + this.scope = scope; + this.active = active; + } + + // ===== JPA lifecycle hooks ===== + @PrePersist + protected void onCreate() { + if (this.categoryId == null) { + this.categoryId = UUID.randomUUID().toString(); + } + if (this.createdAt == null) { + this.createdAt = LocalDateTime.now(); + } + this.updatedAt = this.createdAt; + } + + @PreUpdate + protected void onUpdate() { + this.updatedAt = LocalDateTime.now(); + } + + // ===== Getters & Setters ===== + public String getCategoryId() { + return categoryId; + } + + // categoryId is generated at persist; setter kept for migration/tests + public void setCategoryId(String categoryId) { + this.categoryId = categoryId; + } + + public String getSlug() { + return slug; + } + + public void setSlug(String slug) { + this.slug = slug; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + // CreatedAt normally set by lifecycle; setter available for tests/migrations + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + // UpdatedAt normally managed by lifecycle + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } +} diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java new file mode 100644 index 00000000..df1c7184 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java @@ -0,0 +1,24 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.dto; + +public record CategoryResponse(String categoryId, String slug, String label, String scope, boolean active) {} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java new file mode 100644 index 00000000..7002ece9 --- /dev/null +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java @@ -0,0 +1,38 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.dto; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.time.LocalDateTime; + +public record FeedbackRequest( + @Min(1) @Max(5) int rating, + String categoryId, + String categorySlug, + @Size(max = 2000) String comment, + boolean isAnonymous, + @Pattern(regexp = "^(1097|104|AAM|MMU|TM|ECD)$") String serviceLine, + Integer userId +) {} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java new file mode 100644 index 00000000..6b348f6e --- /dev/null +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java @@ -0,0 +1,26 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.dto; +import java.time.LocalDateTime; + + +public record FeedbackResponse(String id, LocalDateTime createdAt) {} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/exception/BadRequestException.java b/src/main/java/com/iemr/common/exception/BadRequestException.java new file mode 100644 index 00000000..65d146a6 --- /dev/null +++ b/src/main/java/com/iemr/common/exception/BadRequestException.java @@ -0,0 +1,31 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.BAD_REQUEST) +public class BadRequestException extends RuntimeException { + public BadRequestException(String message) { super(message); } + public BadRequestException(String message, Throwable cause) { super(message, cause); } +} diff --git a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java new file mode 100644 index 00000000..95126093 --- /dev/null +++ b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java @@ -0,0 +1,216 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.time.Duration; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Base64; +import java.util.concurrent.TimeUnit; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + + +@Component +@ConditionalOnProperty(prefix = "platform.feedback.ratelimit", name = "enabled", havingValue = "true", matchIfMissing = false) +@Order(Ordered.HIGHEST_PRECEDENCE + 10) // run early (adjust order as needed) +public class PlatformFeedbackRateLimitFilter extends OncePerRequestFilter { + + private final StringRedisTemplate redis; + private final String pepper; + private final boolean trustForwardedFor; + private final String forwardedForHeader; + + // Limits & TTLs (tweak if needed) + private static final int MINUTE_LIMIT = 10; + private static final int DAY_LIMIT = 100; + private static final int USER_DAY_LIMIT = 50; // for identified users + private static final Duration MINUTE_WINDOW = Duration.ofMinutes(1); + private static final Duration DAY_WINDOW = Duration.ofHours(48); // keep key TTL ~48h + private static final Duration FAIL_COUNT_WINDOW = Duration.ofMinutes(5); + private static final int FAILS_TO_BACKOFF = 3; + private static final Duration BACKOFF_WINDOW = Duration.ofMinutes(15); + + public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis, + org.springframework.core.env.Environment env) { + this.redis = redis; + this.pepper = env.getProperty("platform.feedback.pepper", ""); + this.trustForwardedFor = Boolean.parseBoolean(env.getProperty("platform.feedback.trust-forwarded-for", "true")); + this.forwardedForHeader = env.getProperty("platform.feedback.forwarded-for-header", "X-Forwarded-For"); + } + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + // Only filter specific endpoints (POST to platform-feedback). Keep it narrow. + String path = request.getRequestURI(); + String method = request.getMethod(); + // adjust path as needed (supports /common-api/platform-feedback and subpaths) + return !("POST".equalsIgnoreCase(method) && path != null && path.matches("^/platform-feedback(?:/.*)?$")); + } + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + // compute day key + String clientIp = extractClientIp(request); + if (clientIp == null || clientIp.isBlank()) { + // If we can't identify an IP, be conservative and allow but log (or optionally block) + filterChain.doFilter(request, response); + return; + } + + String today = LocalDate.now(ZoneId.of("Asia/Kolkata")).toString().replaceAll("-", ""); // yyyyMMdd + String ipHash = sha256Base64(clientIp + pepper + today); // base64 shorter storage; not reversible without pepper + String minKey = "rl:fb:min:" + ipHash + ":" + (System.currentTimeMillis() / 60000L); // minute-slotted + String dayKey = "rl:fb:day:" + today + ":" + ipHash; + String failKey = "rl:fb:fail:" + ipHash; + String backoffKey = "rl:fb:backoff:" + ipHash; + + // If under backoff -> respond 429 with Retry-After = TTL + Long backoffTtl = getTtlSeconds(backoffKey); + if (backoffTtl != null && backoffTtl > 0) { + sendTooMany(response, backoffTtl); + return; + } + + // Minute window check (INCR + TTL if first) + long minuteCount = incrementWithExpire(minKey, 1, MINUTE_WINDOW.getSeconds()); + if (minuteCount > MINUTE_LIMIT) { + handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); + return; + } + + // Day window check + long dayCount = incrementWithExpire(dayKey, 1, DAY_WINDOW.getSeconds()); + if (dayCount > DAY_LIMIT) { + handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); + return; + } + + // Optional: per-user daily cap if we can extract an authenticated user id from header/jwt + Integer userId = extractUserIdFromRequest(request); // implement extraction as per your JWT scheme + if (userId != null) { + String userDayKey = "rl:fb:user:" + today + ":" + userId; + long ucount = incrementWithExpire(userDayKey, 1, DAY_WINDOW.getSeconds()); + if (ucount > USER_DAY_LIMIT) { + handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, userDayKey); + return; + } + } + + // All checks passed — proceed to controller + filterChain.doFilter(request, response); + } + + // increments key by delta; sets TTL when key is new (INCR returns 1) + private long incrementWithExpire(String key, long delta, long ttlSeconds) { + Long value = redis.opsForValue().increment(key, delta); + if (value != null && value == 1L) { + redis.expire(key, ttlSeconds, TimeUnit.SECONDS); + } + return value == null ? 0L : value; + } + + private void handleFailureAndMaybeBackoff(String failKey, String backoffKey, HttpServletResponse response, String trigKey, String dayKey) throws IOException { + // increment fail counter and possibly set backoff + Long fails = redis.opsForValue().increment(failKey, 1); + if (fails != null && fails == 1L) { + redis.expire(failKey, FAIL_COUNT_WINDOW.getSeconds(), TimeUnit.SECONDS); + } + if (fails != null && fails >= FAILS_TO_BACKOFF) { + // set backoff flag + redis.opsForValue().set(backoffKey, "1", BACKOFF_WINDOW.getSeconds(), TimeUnit.SECONDS); + sendTooMany(response, BACKOFF_WINDOW.getSeconds()); + return; + } + + // otherwise respond with Retry-After for the triggering key TTL (minute/day) + Long retryAfter = getTtlSeconds(trigKey); + if (retryAfter == null || retryAfter <= 0) retryAfter = 60L; + sendTooMany(response, retryAfter); + } + + private void sendTooMany(HttpServletResponse response, long retryAfterSeconds) throws IOException { + response.setStatus(429); + response.setHeader("Retry-After", String.valueOf(retryAfterSeconds)); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + String body = String.format("{\"code\":\"RATE_LIMITED\",\"message\":\"Too many requests\",\"retryAfter\":%d}", retryAfterSeconds); + response.getWriter().write(body); + } + + private Long getTtlSeconds(String key) { + Long ttl = redis.getExpire(key, TimeUnit.SECONDS); + return ttl == null || ttl < 0 ? null : ttl; + } + + private String extractClientIp(HttpServletRequest request) { + if (trustForwardedFor) { + String header = request.getHeader(forwardedForHeader); + if (StringUtils.hasText(header)) { + // X-Forwarded-For may contain comma-separated list; take the first (client) entry + String[] parts = header.split(","); + if (parts.length > 0) { + String ip = parts[0].trim(); + if (StringUtils.hasText(ip)) return ip; + } + } + } + return request.getRemoteAddr(); + } + + private Integer extractUserIdFromRequest(HttpServletRequest request) { + // implement based on how you propagate JWT or user info. + // Example: if your gateway injects header X-User-Id for authenticated requests: + String s = request.getHeader("X-User-Id"); + if (StringUtils.hasText(s)) { + try { return Integer.valueOf(s); } catch (NumberFormatException ignored) {} + } + // If JWT parsing required, do it here, but keep this filter light — prefer upstream auth filter to populate a header. + return null; + } + + private static String sha256Base64(String input) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hashed = digest.digest(input.getBytes(StandardCharsets.UTF_8)); + // base64 url-safe or normal base64 — either is fine; base64 is shorter than hex + return Base64.getUrlEncoder().withoutPadding().encodeToString(hashed); + } catch (Exception ex) { + throw new RuntimeException("sha256 failure", ex); + } + } +} diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java new file mode 100644 index 00000000..083ca5f7 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java @@ -0,0 +1,34 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.repository.platform_feedback; + +import com.iemr.common.model.FeedbackCategory; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PlatformFeedbackCategoryRepository extends JpaRepository { + Optional findBySlugIgnoreCase(String slug); + List findByActiveTrueOrderByLabelAsc(); +} diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java new file mode 100644 index 00000000..fd00bdbc --- /dev/null +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java @@ -0,0 +1,30 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.repository.platform_feedback; + +import com.iemr.common.model.Feedback; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PlatformFeedbackRepository extends JpaRepository { +} diff --git a/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java new file mode 100644 index 00000000..5149e3ed --- /dev/null +++ b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java @@ -0,0 +1,113 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ +package com.iemr.common.service; + +import com.iemr.common.dto.*; +import com.iemr.common.model.Feedback; +import com.iemr.common.model.FeedbackCategory; +import com.iemr.common.repository.platform_feedback.PlatformFeedbackCategoryRepository; +import com.iemr.common.repository.platform_feedback.PlatformFeedbackRepository; +import com.iemr.common.exception.BadRequestException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +@Service +public class PlatformFeedbackService { + + private final PlatformFeedbackRepository feedbackRepo; + private final PlatformFeedbackCategoryRepository categoryRepo; + + public PlatformFeedbackService(PlatformFeedbackRepository feedbackRepo, + PlatformFeedbackCategoryRepository categoryRepo) { + this.feedbackRepo = feedbackRepo; + this.categoryRepo = categoryRepo; + } + + @Transactional + public FeedbackResponse submitFeedback(FeedbackRequest req) { + // basic validations + if (req.rating() < 1 || req.rating() > 5) { + throw new BadRequestException("rating must be between 1 and 5"); + } + if (!req.isAnonymous() && req.userId() == null) { + throw new BadRequestException("userId required when isAnonymous=false"); + } + + FeedbackCategory category = resolveCategory(req.categoryId(), req.categorySlug(), req.serviceLine()); + + Feedback fb = new Feedback(); + fb.setFeedbackId(UUID.randomUUID().toString()); + fb.setCreatedAt(LocalDateTime.now()); + fb.setUpdatedAt(LocalDateTime.now()); + fb.setRating(req.rating()); + fb.setComment(req.comment() == null ? "" : req.comment()); + fb.setServiceLine(req.serviceLine()); + fb.setAnonymous(req.isAnonymous()); + fb.setCategory(category); + fb.setUserId(req.userId()); + + feedbackRepo.save(fb); + return new FeedbackResponse(fb.getFeedbackId(), fb.getCreatedAt()); + } + + private FeedbackCategory resolveCategory(String categoryId, String categorySlug, String serviceLine) { + if (categoryId != null && categorySlug != null) { + FeedbackCategory byId = categoryRepo.findById(categoryId) + .orElseThrow(() -> new BadRequestException("invalid categoryId")); + if (!byId.getSlug().equalsIgnoreCase(categorySlug)) { + throw new BadRequestException("categoryId and categorySlug mismatch"); + } + if (!byId.isActive()) throw new BadRequestException("category inactive"); + // optional: check scope matches serviceLine or GLOBAL + return byId; + } + + if (categoryId != null) { + FeedbackCategory byId = categoryRepo.findById(categoryId) + .orElseThrow(() -> new BadRequestException("invalid categoryId")); + if (!byId.isActive()) throw new BadRequestException("category inactive"); + return byId; + } + + if (categorySlug != null) { + FeedbackCategory bySlug = categoryRepo.findBySlugIgnoreCase(categorySlug) + .orElseThrow(() -> new BadRequestException("invalid categorySlug")); + if (!bySlug.isActive()) throw new BadRequestException("category inactive"); + return bySlug; + } + + throw new BadRequestException("categoryId or categorySlug required"); + } + + @Transactional(readOnly = true) + public List listCategories(String serviceLine) { + List all = categoryRepo.findByActiveTrueOrderByLabelAsc(); + // filter by scope or return all; FE can filter further + return all.stream() + .filter(c -> "GLOBAL".equals(c.getScope()) || c.getScope().equalsIgnoreCase(serviceLine)) + .map(c -> new CategoryResponse(c.getCategoryId(), c.getSlug(), c.getLabel(), c.getScope(), c.isActive())) + .toList(); + } +} diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 9f6efb13..8664199c 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -1,28 +1,102 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.utils; +import com.iemr.common.filter.PlatformFeedbackRateLimitFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.data.redis.core.StringRedisTemplate; @Configuration public class FilterConfig { - @Value("${cors.allowed-origins}") - private String allowedOrigins; + private static final Logger log = LoggerFactory.getLogger(FilterConfig.class); + + @Value("${cors.allowed-origins}") + private String allowedOrigins; + + @Bean + public FilterRegistrationBean jwtUserIdValidationFilter( + JwtAuthenticationUtil jwtAuthenticationUtil) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + + // Pass allowedOrigins explicitly to the filter constructor + JwtUserIdValidationFilter filter = new JwtUserIdValidationFilter(jwtAuthenticationUtil, allowedOrigins); + + registrationBean.setFilter(filter); + registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); + registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints + log.info("Registered JwtUserIdValidationFilter on /* with order {}", Ordered.HIGHEST_PRECEDENCE); + return registrationBean; + } + + /** + * Register the platform feedback rate-limit filter in a non-invasive way. + * + * - The filter is mapped only to the public feedback endpoints to avoid affecting other routes. + * - Order is intentionally set after the Jwt filter so authentication runs first. + */ + @Bean + public FilterRegistrationBean platformFeedbackRateLimitFilter( + StringRedisTemplate stringRedisTemplate, + Environment env) { + + // Read flag from environment (property file or env var) + boolean enabled = Boolean.parseBoolean(env.getProperty("platform.feedback.ratelimit.enabled", "false")); + + // Allow optional override for order if needed + int defaultOrder = Ordered.HIGHEST_PRECEDENCE + 10; + int order = defaultOrder; + String orderStr = env.getProperty("platform.feedback.ratelimit.order"); + if (orderStr != null) { + try { + order = Integer.parseInt(orderStr); + } catch (NumberFormatException e) { + log.warn("Invalid platform.feedback.ratelimit.order value '{}', using default {}", orderStr, defaultOrder); + } + } + + PlatformFeedbackRateLimitFilter filter = new PlatformFeedbackRateLimitFilter(stringRedisTemplate, env); + + FilterRegistrationBean reg = new FilterRegistrationBean<>(filter); + + reg.addUrlPatterns( + "/platform-feedback/*", + "/platform-feedback" + ); - @Bean - public FilterRegistrationBean jwtUserIdValidationFilter( - JwtAuthenticationUtil jwtAuthenticationUtil) { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + reg.setOrder(order); + // Do not remove the bean from context when disabled; keep registration but disable execution + reg.setEnabled(enabled); - // Pass allowedOrigins explicitly to the filter constructor - JwtUserIdValidationFilter filter = new JwtUserIdValidationFilter(jwtAuthenticationUtil, allowedOrigins); + log.info("Registered PlatformFeedbackRateLimitFilter (enabled={}, order={}) mapped to {}", + enabled, order, reg.getUrlPatterns()); - registrationBean.setFilter(filter); - registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); - registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints - return registrationBean; - } + return reg; + } } diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 0b8f6f94..0f35e6c5 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -1,3 +1,24 @@ +/* + * AMRIT – Accessible Medical Records via Integrated Technology + * Integrated EHR (Electronic Health Records) Solution + * + * Copyright (C) "Piramal Swasthya Management and Research Institute" + * + * This file is part of AMRIT. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ package com.iemr.common.utils; import java.io.IOException; @@ -59,6 +80,13 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); + // NEW: if this is a platform-feedback endpoint, treat it as public (skip auth) + // and also ensure we don't clear any user cookies for these requests. + if (isPlatformFeedbackPath(path, contextPath)) { + logger.debug("Platform-feedback path detected - skipping authentication and leaving cookies intact: {}", path); + filterChain.doFilter(servletRequest, servletResponse); + return; + } // Log cookies for debugging Cookie[] cookies = request.getCookies(); if (cookies != null) { @@ -127,6 +155,19 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo } } + /** + * New helper: identifies platform-feedback endpoints so we can treat them + * specially (public + preserve cookies). + */ + private boolean isPlatformFeedbackPath(String path, String contextPath) { + if (path == null) return false; + String normalized = path.toLowerCase(); + String base = (contextPath == null ? "" : contextPath).toLowerCase(); + // match /platform-feedback and anything under it + return normalized.startsWith(base + "/platform-feedback"); + } + + private boolean isOriginAllowed(String origin) { if (origin == null || allowedOrigins == null || allowedOrigins.trim().isEmpty()) { logger.warn("No allowed origins configured or origin is null"); From d2f44b1d0a303c212f6f953a16facdd3e1af7acf Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 11 Sep 2025 12:58:31 +0530 Subject: [PATCH 252/318] feat: amm-1337 entities updated based on change in DDL --- .../data/platform_feedback/Feedback.java | 70 +++++-------------- .../platform_feedback/FeedbackCategory.java | 30 ++++---- 2 files changed, 32 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java index cbce9b07..b499ef3a 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java @@ -24,15 +24,10 @@ import jakarta.persistence.*; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; import java.time.LocalDateTime; import java.util.UUID; -/** - * Represents feedback provided by users for a specific service or category. - * Mapped to "m_platform_feedback". - */ @Entity @Table(name = "m_platform_feedback") public class Feedback { @@ -41,10 +36,10 @@ public class Feedback { @Column(name = "FeedbackID", length = 36, updatable = false, nullable = false) private String feedbackId; - @Column(name = "CreatedAt", nullable = false) + @Column(name = "CreatedAt", nullable = false, insertable = false, updatable = false) private LocalDateTime createdAt; - @Column(name = "UpdatedAt", nullable = false) + @Column(name = "UpdatedAt", nullable = false, insertable = false, updatable = false) private LocalDateTime updatedAt; @Min(1) @@ -52,38 +47,29 @@ public class Feedback { @Column(name = "Rating", nullable = false) private int rating; - @NotBlank(message = "Comment cannot be blank") - @Size(max = 2000, message = "Comment cannot exceed 2000 characters") - @Column(name = "Comment", columnDefinition = "TEXT", nullable = false) + @Size(max = 2000) + @Column(name = "Comment", columnDefinition = "TEXT", nullable = true) private String comment; @Column(name = "ServiceLine", nullable = false, length = 10) private String serviceLine; @Column(name = "IsAnonymous", nullable = false) - private boolean isAnonymous; + private boolean isAnonymous = true; @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "CategoryID", referencedColumnName = "CategoryID", nullable = false) private FeedbackCategory category; - /** - * We store the numeric UserID if the submission is identified. We don't map to a User - * entity here to avoid cross-module coupling; the DB should have the FK enforced if desired. - */ - @Column(name = "UserID") + @Column(name = "UserID", nullable = true) private Integer userId; - // ===== Constructors ===== public Feedback() { - // default constructor for JPA + this.feedbackId = UUID.randomUUID().toString(); } - // convenience constructor (optional) public Feedback(int rating, String comment, String serviceLine, boolean isAnonymous, FeedbackCategory category, Integer userId) { - this.feedbackId = UUID.randomUUID().toString(); - this.createdAt = LocalDateTime.now(); - this.updatedAt = this.createdAt; + this(); // ensures feedbackId this.setRating(rating); this.setComment(comment); this.setServiceLine(serviceLine); @@ -92,28 +78,11 @@ public Feedback(int rating, String comment, String serviceLine, boolean isAnonym this.userId = userId; } - // ======= JPA lifecycle callbacks ======= - @PrePersist - protected void onCreate() { - if (this.feedbackId == null) { - this.feedbackId = UUID.randomUUID().toString(); - } - if (this.createdAt == null) { - this.createdAt = LocalDateTime.now(); - } - this.updatedAt = this.createdAt; - } - - @PreUpdate - protected void onUpdate() { - this.updatedAt = LocalDateTime.now(); - } - - // ======= Getters & Setters ======= public String getFeedbackId() { return feedbackId; } + // Don't usually set feedbackId externally, but keep setter for testing/migration if needed public void setFeedbackId(String feedbackId) { this.feedbackId = feedbackId; } @@ -122,18 +91,14 @@ public LocalDateTime getCreatedAt() { return createdAt; } - // createdAt should only be set once; still exposing setter if needed public void setCreatedAt(LocalDateTime createdAt) { - if (this.createdAt == null) { - this.createdAt = createdAt; - } + this.createdAt = createdAt; } public LocalDateTime getUpdatedAt() { return updatedAt; } - // updatedAt is managed by lifecycle callbacks but a setter is fine for tests/migration public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; } @@ -154,13 +119,10 @@ public String getComment() { } public void setComment(String comment) { - if (comment == null || comment.trim().isEmpty()) { - throw new IllegalArgumentException("Comment cannot be blank"); - } - if (comment.length() > 2000) { + if (comment != null && comment.length() > 2000) { throw new IllegalArgumentException("Comment cannot exceed 2000 characters"); } - this.comment = comment; + this.comment = (comment == null || comment.trim().isEmpty()) ? null : comment.trim(); } public String getServiceLine() { @@ -180,6 +142,9 @@ public boolean isAnonymous() { public void setAnonymous(boolean anonymous) { isAnonymous = anonymous; + if (anonymous) { + this.userId = null; + } } public FeedbackCategory getCategory() { @@ -199,5 +164,8 @@ public Integer getUserId() { public void setUserId(Integer userId) { this.userId = userId; + if (userId != null) { + this.isAnonymous = false; + } } -} \ No newline at end of file +} diff --git a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java index 490805c4..ee9ffffe 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java @@ -58,17 +58,18 @@ public class FeedbackCategory { private String scope; @Column(name = "Active", nullable = false) - private boolean active; + private boolean active = true; - @Column(name = "CreatedAt", nullable = false) + + @Column(name = "CreatedAt", nullable = false, insertable = false, updatable = false) private LocalDateTime createdAt; - @Column(name = "UpdatedAt", nullable = false) + @Column(name = "UpdatedAt", nullable = false, insertable = false, updatable = false) private LocalDateTime updatedAt; // ===== Constructors ===== public FeedbackCategory() { - // default ctor for JPA + // nothing — categoryId will be generated at persist if not provided } public FeedbackCategory(String slug, String label, String scope, boolean active) { @@ -79,20 +80,15 @@ public FeedbackCategory(String slug, String label, String scope, boolean active) } // ===== JPA lifecycle hooks ===== + /** + * Ensure CategoryID exists for new rows created via JPA. If DB seeding provides IDs, + * those will be used instead (we only set if null). + */ @PrePersist - protected void onCreate() { - if (this.categoryId == null) { + protected void ensureId() { + if (this.categoryId == null || this.categoryId.trim().isEmpty()) { this.categoryId = UUID.randomUUID().toString(); } - if (this.createdAt == null) { - this.createdAt = LocalDateTime.now(); - } - this.updatedAt = this.createdAt; - } - - @PreUpdate - protected void onUpdate() { - this.updatedAt = LocalDateTime.now(); } // ===== Getters & Setters ===== @@ -141,7 +137,7 @@ public LocalDateTime getCreatedAt() { return createdAt; } - // CreatedAt normally set by lifecycle; setter available for tests/migrations + // CreatedAt normally set by DB; setter available for tests/migrations public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } @@ -150,7 +146,7 @@ public LocalDateTime getUpdatedAt() { return updatedAt; } - // UpdatedAt normally managed by lifecycle + // UpdatedAt normally managed by DB public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; } From 4149b14c9958f4ff31d179128365609e077149f9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 12 Sep 2025 11:41:42 +0530 Subject: [PATCH 253/318] merge with main --- .../BeneficiaryRegistrationController.java | 4 + .../model/beneficiary/BeneficiaryModel.java | 23 + .../RMNCHBeneficiaryDetailsRmnch.java | 498 ++++++++++++++++++ .../BeneficiaryDetailsRmnchRepository.java | 8 + 4 files changed, 533 insertions(+) create mode 100644 src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java create mode 100644 src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java diff --git a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java index d9b0f06f..69e04b92 100644 --- a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java +++ b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.MediaType; +import com.iemr.common.repository.beneficiary.BeneficiaryDetailsRmnchRepository; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -103,6 +104,9 @@ public class BeneficiaryRegistrationController { private BeneficiaryOccupationService beneficiaryOccupationService; private GovtIdentityTypeService govtIdentityTypeService; + @Autowired + private BeneficiaryDetailsRmnchRepository beneficiaryDetailsRmnchRepository; + @Autowired public void setBenRelationshipTypeService(BenRelationshipTypeService benRelationshipTypeService) { this.benRelationshipTypeService = benRelationshipTypeService; diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index ed7c9cad..b4ee2b06 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -81,6 +81,29 @@ public class BeneficiaryModel implements Comparable { @Expose private Boolean isConsent=false; + @Expose + private Boolean isDeath; + + @Expose + private String isDeathValue; + + @Expose + private String timeOfDeath; + + @Expose + private String reasonOfDeath; + + @Expose + private Integer reasonOfDeathId; + + @Expose + private String placeOfDeath; + + @Expose + private Integer placeOfDeathId; + + @Expose + private String otherPlaceOfDeath; @Expose private String beneficiaryID; diff --git a/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java new file mode 100644 index 00000000..87757e43 --- /dev/null +++ b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java @@ -0,0 +1,498 @@ +package com.iemr.common.model.beneficiary; + +import com.google.gson.annotations.Expose; +import lombok.Data; + +import jakarta.persistence.*; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; + +@Entity +@Table(name = "i_beneficiarydetails_rmnch") +@Data +public class RMNCHBeneficiaryDetailsRmnch { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Expose + @Column(name = "beneficiaryDetails_RmnchId", insertable = false, updatable = false) + private Long beneficiaryDetails_RmnchId; + + @Expose + @Column(name = "BeneficiaryRegID") + private Long BenRegId; + + @Expose + @Column(name = "aadhaNo") + private String aadhaNo; + + @Expose + @Column(name = "aadha_no") + private String aadha_no; + + @Expose + @Column(name = "aadha_noId") + private Integer aadha_noId; + + @Expose + @Column(name = "age") + private Integer age; + + @Expose + @Column(name = "ageAtMarriage") + private Integer ageAtMarriage; + + @Expose + @Column(name = "age_unit") + private String age_unit; + + @Expose + @Column(name = "age_unitId") + private Integer age_unitId; + + @Expose + @Column(name = "childRegisteredAWCID") + private Long childRegisteredAWCID; + + @Expose + @Column(name = "childRegisteredSchoolID") + private Integer childRegisteredSchoolID; + + @Expose + @Column(name = "dateofdelivey") + private Timestamp dateofdelivey; + + @Expose + @Column(name = "expectedDateofDelivery") + private Timestamp expectedDateOfDelivery; + + @Expose + @Column(name = "facilitySectionID") + private Integer facilitySectionID; + + @Expose + @Column(name = "guidelineId") + private String guidelineId; + + @Expose + @Column(name = "houseoldId") + private Long houseoldId; + + @Expose + @Column(name = "lastDeliveryConductedID") + private Integer lastDeliveryConductedID; + + @Expose + @Column(name = "lastMenstrualPeriod") + private String lastMenstrualPeriod; + + @Expose + @Column(name = "latitude") + private BigDecimal latitude; + + @Expose + @Column(name = "lengthofMenstrualCycleId") + private Integer lengthofMenstrualCycleId; + + @Expose + @Column(name = "literacyId") + private Integer literacyId; + + @Expose + @Column(name = "longitude") + private BigDecimal longitude; + + @Expose + @Column(name = "menstrualBFDId") + private Integer menstrualBFDId; + + @Expose + @Column(name = "menstrualProblemId") + private Integer menstrualProblemId; + + @Expose + @Column(name = "menstrualStatusId") + private Integer menstrualStatusId; + + @Expose + @Column(name = "mobileOthers") + private String mobileOthers; + + @Expose + @Column(name = "mobilenoofRelation") + private String mobilenoofRelation; + + @Expose + @Column(name = "mobilenoofRelationId") + private Integer mobilenoofRelationId; + + @Expose + @Column(name = "motherName") + private String motherName; + + @Expose + @Column(name = "ncd_priority") + private Integer ncd_priority; + + @Expose + @Column(name = "need_opcareId") + private Integer need_opcareId; + + @Expose + @Column(name = "previousLiveBirth") + private String previousLiveBirth; + + @Expose + @Column(name = "rchid") + private String rchid; + + @Expose + @Column(name = "registrationDate") + private Timestamp registrationDate; + + @Expose + @Column(name = "registrationType") + private String registrationType; + + @Expose + @Column(name = "regularityofMenstrualCycleId") + private Integer regularityofMenstrualCycleId; + + @Expose + @Column(name = "religionOthers") + private String religionOthers; + + @Expose + @Column(name = "reproductiveStatus") + private String reproductiveStatus; + + @Expose + @Column(name = "reproductiveStatusId") + private Integer reproductiveStatusId; + + @Expose + @Column(name = "serverUpdatedStatus") + private Integer serverUpdatedStatus; + + @Expose + @Column(name = "typeofSchoolID") + private Integer typeofSchoolID; + + @Expose + @Column(name = "whoConductedDeliveryID") + private Integer whoConductedDeliveryID; + + @Expose + @Column(name = "Deleted") + private Boolean deleted; + + @Expose + @Column(name = "Processed") + private String Processed = "N"; + + @Expose + @Column(name = "CreatedBy") + private String createdBy; + + @Expose + @Column(name = "CreatedDate") + private Timestamp createdDate; + + @Expose + @Column(name = "Reserved") + private Boolean reserved; + + @Expose + @Column(name = "ReservedFor") + private String reservedFor; + + @Expose + @Column(name = "ReservedOn") + private String reservedOn; + + @Expose + @Column(name = "ReservedById") + private Integer reservedById; + + @Expose + @Column(name = "ModifiedBy") + private String updatedBy; + + @Expose + @Column(name = "LastModDate") + private Timestamp updatedDate; + + @Expose + @Column(name = "VanSerialNo") + private Long id; + + @Expose + @Column(name = "VanID") + private Integer VanID; + + @Expose + @Column(name = "VehicalNo") + private String vehicalNo; + + @Expose + @Column(name = "ParkingPlaceID") + private Integer parkingPlaceID; + + @Expose + @Column(name = "SyncedBy") + private String syncedBy; + + @Expose + @Column(name = "SyncedDate") + private Timestamp syncedDate; + + @Expose + @Column(name = "ProviderServiceMapID") + private Integer ProviderServiceMapID; + + @Expose + @Column(name = "deviceId") + private Integer deviceId; + + @Expose + @Column(name = "beneficiaryId") + private Long benficieryid; + + // new fields 30-06-2021 + @Expose + @Column(name = "RelatedBeneficiaryIds") + private String relatedBeneficiaryIdsDB; + @Expose + @Column(name = "HRPStatus") + private Boolean hrpStatus; + @Expose + @Column(name = "ImmunizationStatus") + private Boolean immunizationStatus; + @Expose + @Column(name = "NishchayPregnancyStatus") + private String nishchayPregnancyStatus; + @Expose + @Column(name = "NishchayPregnancyStatusPosition") + private Integer nishchayPregnancyStatusPosition; + @Expose + @Column(name = "NishchayDeliveryStatus") + private String nishchayDeliveryStatus; + @Expose + @Column(name = "NishchayDeliveryStatusPosition") + private Integer nishchayDeliveryStatusPosition; + + @Expose + @Column(name = "FamilyHeadRelation") + private String familyHeadRelation; + @Expose + @Column(name = "FamilyHeadRelationPosition") + private Integer familyHeadRelationPosition; + + @Expose + @Column(name = "MenstrualStatus") + private String menstrualStatus; + @Expose + @Column(name = "ComplicationsOthers") + private String complicationsOthers; + + @Expose + @Transient + private Long[] relatedBeneficiaryIds; + + @Expose + @Transient + private String literacyStatus; + + @Expose + @Transient + private String branchName; + + // location + @Expose + @Transient + private Integer countryId; + @Expose + @Transient + private String countryName; + @Expose + @Transient + private Integer stateId; + @Expose + @Transient + private String stateName; +// @Expose +// @Transient +// private Integer districtId; +// @Expose +// @Transient +// private String districtName; + @Expose + @Transient + private Integer blockId; + @Expose + @Transient + private String blockName; + @Expose + @Transient + private Integer villageId; + @Expose + @Transient + private String villageName; + + @Expose + @Transient + private Integer servicePointID; + @Expose + @Transient + private String servicePointName; + + @Expose + @Transient + private Integer zoneID; + @Expose + @Transient + private String zoneName; + + @Expose + @Transient + private String addressLine1; + @Expose + @Transient + private String addressLine2; + @Expose + @Transient + private String addressLine3; + + // ---------------------------------------------- + + // Extra data from platform + @Expose + @Transient + private String bankAccount; + @Expose + @Transient + private String community; + @Expose + @Transient + private Integer communityId; + @Expose + @Transient + private String contact_number; + @Expose + @Transient + private Integer currSubDistrictId; + @Expose + @Transient + private Integer districtid; + @Expose + @Transient + private String districtname; + @Expose + @Transient + private Timestamp dob; + @Expose + @Transient + private String fatherName; + @Expose + @Transient + private String firstName; + @Expose + @Transient + private String gender; + @Expose + @Transient + private Integer genderId; + @Expose + @Transient + private String ifscCode; + @Expose + @Transient + private String lastName; + @Expose + @Transient + private String maritalstatus; + @Expose + @Transient + private Integer maritalstatusId; + @Expose + @Transient + private Timestamp marriageDate; + @Expose + @Transient + private String nameOfBank; + @Expose + @Transient + private String religion; + @Expose + @Transient + private BigInteger religionID; + @Expose + @Transient + private String spousename; + @Expose + @Transient + private String user_image; + + // 08102020 + @Expose + @Transient + private String ageFull; + + @Expose + private Boolean isDeath; + + @Expose + private String isDeathValue; + + @Expose + private String timeOfDeath; + + @Expose + private String reasonOfDeath; + + @Expose + private Integer reasonOfDeathId; + + @Expose + private String placeOfDeath; + + @Expose + private Integer placeOfDeathId; + + @Expose + private String otherPlaceOfDeath; + + // 07-07-2021 + @Expose + @Column(name = "WhoConductedDelivery") + private String whoConductedDelivery; + @Expose + @Column(name = "LastDeliveryConducted") + private String lastDeliveryConducted; + @Expose + @Column(name = "FacilitySelection") + private String facilitySelection; + @Expose + @Column(name = "DeliveryDate") + private String deliveryDate; + @Expose + @Column(name = "ChildRegisteredSchool") + private String childRegisteredSchool; + @Expose + @Column(name = "TypeOfSchool") + private String typeOfSchool; +// 13-04-2022 + @Expose + @Column(name = "dateMarriage") + private Timestamp dateMarriage; + @Expose + @Column(name = "nayiPahalDeliveryStatus") + private String nayiPahalDeliveryStatus; + @Expose + @Column(name = "nayiPahalDeliveryStatusPosition") + private Integer nayiPahalDeliveryStatusPosition; + @Expose + @Column(name = "noOfDaysForDelivery") + private Integer noOfDaysForDelivery; + +} diff --git a/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java new file mode 100644 index 00000000..4c1e4c30 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java @@ -0,0 +1,8 @@ +package com.iemr.common.repository.beneficiary; + +import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BeneficiaryDetailsRmnchRepository extends JpaRepository { + +} From 1fca232a5e86cdbc0efd2041c6c03ff5df758372 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 12 Sep 2025 11:58:55 +0530 Subject: [PATCH 254/318] merge with main --- .../model/beneficiary/BeneficiaryModel.java | 3 ++ .../RMNCHBeneficiaryDetailsRmnch.java | 4 +++ .../RegisterBenificiaryServiceImpl.java | 36 ++++++++++++++----- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index b4ee2b06..d61659f0 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -84,6 +84,9 @@ public class BeneficiaryModel implements Comparable { @Expose private Boolean isDeath; + @Expose + private String dateOfDeath; + @Expose private String isDeathValue; diff --git a/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java index 87757e43..3320df2d 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java +++ b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java @@ -444,6 +444,10 @@ public class RMNCHBeneficiaryDetailsRmnch { @Expose private String isDeathValue; + @Expose + private String dateOfDeath; + + @Expose private String timeOfDeath; diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index aa0c2a71..183b9c72 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -30,6 +30,8 @@ import java.util.ArrayList; import java.util.List; +import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; +import com.iemr.common.repository.beneficiary.BeneficiaryDetailsRmnchRepository; import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService; import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsServiceImpl; import org.json.JSONObject; @@ -81,6 +83,11 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired Validator validator; + @Autowired + private BeneficiaryDetailsRmnchRepository beneficiaryDetailsRmnchRepository; + + + @Autowired @@ -120,6 +127,8 @@ public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String aut Integer updatedRows = 0; IdentityEditDTO identityEditDTO = identityBenEditMapper.BenToIdentityEditMapper(benificiaryDetails); setDemographicDetails(identityEditDTO,benificiaryDetails); + + if (benificiaryDetails.getBeneficiaryIdentities() != null && benificiaryDetails.getBeneficiaryIdentities().size() > 0) { @@ -129,9 +138,21 @@ public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String aut identityEditDTO.setDob(benificiaryDetails.getDOB()); updatedRows = identityBeneficiaryService.editIdentityEditDTO(identityEditDTO, auth, benificiaryDetails.getIs1097()); - + updateDeathOfBenificiary(benificiaryDetails); return updatedRows; } + private void updateDeathOfBenificiary(BeneficiaryModel beneficiaryModel){ + RMNCHBeneficiaryDetailsRmnch rmnchBeneficiaryDetailsRmnch = new RMNCHBeneficiaryDetailsRmnch(); + rmnchBeneficiaryDetailsRmnch.setIsDeath(beneficiaryModel.getIsDeath()); + rmnchBeneficiaryDetailsRmnch.setPlaceOfDeathId(beneficiaryModel.getPlaceOfDeathId()); + rmnchBeneficiaryDetailsRmnch.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); + rmnchBeneficiaryDetailsRmnch.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); + rmnchBeneficiaryDetailsRmnch.setReasonOfDeath(beneficiaryModel.getReasonOfDeath()); + rmnchBeneficiaryDetailsRmnch.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); + rmnchBeneficiaryDetailsRmnch.setDateOfDeath(beneficiaryModel.getDateOfDeath()); + + beneficiaryDetailsRmnchRepository.save(rmnchBeneficiaryDetailsRmnch); + } private void setDemographicDetails(IdentityEditDTO identityEditDTO, BeneficiaryModel benificiaryDetails) { if(null != benificiaryDetails.getI_bendemographics()) { @@ -164,6 +185,9 @@ else if(null != benificiaryDetails.getI_bendemographics().getReligion()) else identityEditDTO.setIncomeStatus(benificiaryDetails.getI_bendemographics().getIncomeStatus()); } + if(benificiaryDetails!=null){ + updateDeathOfBenificiary(benificiaryDetails); + } } @@ -184,13 +208,6 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet setSaveDemographicDetails(identityDTO,beneficiaryModel); // identityDTO.setOtherFields(beneficiaryModel.getOtherFields()); identityDTO.setIsConsent(beneficiaryModel.getIsConsent()); -// identityDTO.setIsDeath(beneficiaryModel.getIsDeath()); -// identityDTO.setIsDeathValue(beneficiaryModel.getIsDeathValue()); -// identityDTO.setDateOfDeath(beneficiaryModel.getDateOfDeath()); -// identityDTO.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); -// identityDTO.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); -// identityDTO.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); - identityDTO.setFaceEmbedding(beneficiaryModel.getFaceEmbedding()); identityDTO.setEmergencyRegistration(beneficiaryModel.isEmergencyRegistration()); @@ -228,7 +245,10 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet return OutputMapper.gson().toJson(beneficiary); } + private void saveBeneficiarDeathDetails(BeneficiaryModel beneficiaryModel){ + + } private void setSaveDemographicDetails(CommonIdentityDTO identityDTO, BeneficiaryModel beneficiaryModel) { if(null != beneficiaryModel.getI_bendemographics()) { From 896012c67cb37aa470e8fb9ec467bb70e6583aab Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 12 Sep 2025 12:11:24 +0530 Subject: [PATCH 255/318] merge with main --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a0191c9..c54201ff 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.0 + 3.7.0 war Common-API From ac39698c27d21c83c8974f9cbd5315e939ef6dbb Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 12 Sep 2025 12:38:28 +0530 Subject: [PATCH 256/318] fix ben death param issue --- .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 183b9c72..273a1cf5 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -283,6 +283,9 @@ else if(null != beneficiaryModel.getI_bendemographics().getReligion()) else identityDTO.setIncomeStatus(beneficiaryModel.getI_bendemographics().getIncomeStatus()); } + if(beneficiaryModel!=null){ + updateDeathOfBenificiary(beneficiaryModel); + } } From ce7fa317cab1855351e937e40275446b714d2520 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 12 Sep 2025 13:58:12 +0530 Subject: [PATCH 257/318] fix ben death param issue --- .../service/beneficiary/RegisterBenificiaryServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 273a1cf5..055ebdee 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -138,6 +138,7 @@ public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String aut identityEditDTO.setDob(benificiaryDetails.getDOB()); updatedRows = identityBeneficiaryService.editIdentityEditDTO(identityEditDTO, auth, benificiaryDetails.getIs1097()); + logger.info("updateBen"); updateDeathOfBenificiary(benificiaryDetails); return updatedRows; } @@ -245,11 +246,8 @@ public String save(BeneficiaryModel beneficiaryModel, HttpServletRequest servlet return OutputMapper.gson().toJson(beneficiary); } - private void saveBeneficiarDeathDetails(BeneficiaryModel beneficiaryModel){ - } - private void setSaveDemographicDetails(CommonIdentityDTO identityDTO, BeneficiaryModel beneficiaryModel) { if(null != beneficiaryModel.getI_bendemographics()) { identityDTO.setCommunity(beneficiaryModel.getI_bendemographics().getCommunityName()); From e5d4234052f49e6a7e5336c76e4cec0c7bcab525 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 16:09:50 +0530 Subject: [PATCH 258/318] fix strict-origin-when-cross-origin --- src/main/resources/application.properties | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1a6a6e6f..101d3c2e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -203,10 +203,10 @@ genben-api=http://localhost:8092/ #### SMS Configuration send-sms=false sendSMSUrl = http://localhost:8080/sms/sendSMS -source-address=AIDSHL -sms-username= -sms-password= -send-message-url= +#source-address=AIDSHL +#sms-username= +#sms-password= +#send-message-url= ###SMS Scheduler configurations start-sms-scheduler=false @@ -363,18 +363,8 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com -# DB Connections -spring.datasource.url=jdbc:mysql://localhost:3306/db_iemr -spring.datasource.username= -spring.datasource.password= - - -secondary.datasource.username= -secondary.datasource.password= -secondary.datasource.url=jdbc:mysql://localhost:3306/db_reporting -secondary.datasource.driver-class-name=com.mysql.jdbc.Driver video-call-url = @@ -383,3 +373,4 @@ allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt ##sms details for beneficiary otp cosent sms-template-name = otp_consent + From c4603b0cd2f54df9be689477dc6db2f81044a6cb Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 16:14:58 +0530 Subject: [PATCH 259/318] fix strict-origin-when-cross-origin --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 101d3c2e..48fbfab5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -363,7 +363,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com +cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 video-call-url = From 13aa4ba727e4e34e79fe128ce9046578a39574be Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 16:15:58 +0530 Subject: [PATCH 260/318] fix strict-origin-when-cross-origin --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- src/main/resources/application.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 2e226b79..84f5e865 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Override diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 9f6efb13..379eb180 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origins}") + @Value("${cors.allowed-origin}") private String allowedOrigins; @Bean diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 48fbfab5..98895750 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -363,7 +363,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origins= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 video-call-url = From b14952bc226bcc70d30064877c78544155075f27 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 16:22:58 +0530 Subject: [PATCH 261/318] fix strict-origin-when-cross-origin --- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index bbe70dd4..1c354ce3 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -80,8 +80,8 @@ public class IEMRAdminController { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private InputMapper inputMapper = new InputMapper(); - @Value("${captcha.enable-captcha}") - private boolean enableCaptcha; +// @Value("${captcha.enable-captcha}") + private boolean enableCaptcha =false; @Autowired private CaptchaValidationService captchaValidatorService; From eba0f4577000cf370fbc815365450281b98c141d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 17:48:44 +0530 Subject: [PATCH 262/318] fix strict-origin-when-cross-origin --- .../common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java index 3320df2d..b6bc8512 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java +++ b/src/main/java/com/iemr/common/model/beneficiary/RMNCHBeneficiaryDetailsRmnch.java @@ -9,7 +9,7 @@ import java.sql.Timestamp; @Entity -@Table(name = "i_beneficiarydetails_rmnch") +@Table(name = "i_beneficiarydetails_rmnch",schema = "db_identity") @Data public class RMNCHBeneficiaryDetailsRmnch { @Id From 0dfad088859771bd00dece45c6d7c376e44593a3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 18:12:58 +0530 Subject: [PATCH 263/318] fix strict-origin-when-cross-origin --- .../beneficiary/BeneficiaryDetailsRmnchRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java index 4c1e4c30..d2a9e3e1 100644 --- a/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java +++ b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java @@ -2,7 +2,9 @@ import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository public interface BeneficiaryDetailsRmnchRepository extends JpaRepository { } From 19ade966beecedb1852692055642c3b0ae834b4b Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Wed, 17 Sep 2025 18:26:35 +0530 Subject: [PATCH 264/318] fix: dev-linux issue fix --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 697322c6..7aa143dc 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -45,6 +45,7 @@ import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; +import org.springframework.beans.factory.annotation.Value; @Service public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryService { @@ -54,8 +55,10 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); - private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); + @Value("${identity-api-url}") + private String identityBaseURL; + @Value("${identity-1097-api-url}") + private String identity1097BaseURL; private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); From 8635a020ee50d68357b234504c7006806b6b5469 Mon Sep 17 00:00:00 2001 From: Amoghavarsh <93114621+5Amogh@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:35:18 +0530 Subject: [PATCH 265/318] fix: dev-linux issue fix (#291) --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index 697322c6..7aa143dc 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -45,6 +45,7 @@ import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; +import org.springframework.beans.factory.annotation.Value; @Service public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryService { @@ -54,8 +55,10 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - private String identityBaseURL = ConfigProperties.getPropertyByName("identity-api-url"); - private String identity1097BaseURL = ConfigProperties.getPropertyByName("identity-1097-api-url"); + @Value("${identity-api-url}") + private String identityBaseURL; + @Value("${identity-1097-api-url}") + private String identity1097BaseURL; private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; private static final String BEN_GEN = ConfigProperties.getPropertyByName("genben-api"); From d0dc555fae66461ddd21c08731d3db182c9f54b3 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 19:01:02 +0530 Subject: [PATCH 266/318] fix strict-origin-when-cross-origin --- .../BeneficiaryDetailsRmnchRepository.java | 20 +++++++++---------- .../RegisterBenificiaryServiceImpl.java | 12 +++++------ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java index d2a9e3e1..896d696a 100644 --- a/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java +++ b/src/main/java/com/iemr/common/repository/beneficiary/BeneficiaryDetailsRmnchRepository.java @@ -1,10 +1,10 @@ -package com.iemr.common.repository.beneficiary; - -import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface BeneficiaryDetailsRmnchRepository extends JpaRepository { - -} +//package com.iemr.common.repository.beneficiary; +// +//import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; +//import org.springframework.data.jpa.repository.JpaRepository; +//import org.springframework.stereotype.Repository; +// +//@Repository +//public interface BeneficiaryDetailsRmnchRepository extends JpaRepository { +// +//} diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 055ebdee..54637a4c 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -31,7 +31,6 @@ import java.util.List; import com.iemr.common.model.beneficiary.RMNCHBeneficiaryDetailsRmnch; -import com.iemr.common.repository.beneficiary.BeneficiaryDetailsRmnchRepository; import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsService; import com.iemr.common.service.welcomeSms.WelcomeBenificarySmsServiceImpl; import org.json.JSONObject; @@ -83,8 +82,7 @@ public class RegisterBenificiaryServiceImpl implements RegisterBenificiaryServic @Autowired Validator validator; - @Autowired - private BeneficiaryDetailsRmnchRepository beneficiaryDetailsRmnchRepository; + @@ -139,7 +137,7 @@ public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String aut updatedRows = identityBeneficiaryService.editIdentityEditDTO(identityEditDTO, auth, benificiaryDetails.getIs1097()); logger.info("updateBen"); - updateDeathOfBenificiary(benificiaryDetails); + //updateDeathOfBenificiary(benificiaryDetails); return updatedRows; } private void updateDeathOfBenificiary(BeneficiaryModel beneficiaryModel){ @@ -152,7 +150,7 @@ private void updateDeathOfBenificiary(BeneficiaryModel beneficiaryModel){ rmnchBeneficiaryDetailsRmnch.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); rmnchBeneficiaryDetailsRmnch.setDateOfDeath(beneficiaryModel.getDateOfDeath()); - beneficiaryDetailsRmnchRepository.save(rmnchBeneficiaryDetailsRmnch); + //beneficiaryDetailsRmnchRepository.save(rmnchBeneficiaryDetailsRmnch); } private void setDemographicDetails(IdentityEditDTO identityEditDTO, BeneficiaryModel benificiaryDetails) { @@ -187,7 +185,7 @@ else if(null != benificiaryDetails.getI_bendemographics().getReligion()) identityEditDTO.setIncomeStatus(benificiaryDetails.getI_bendemographics().getIncomeStatus()); } if(benificiaryDetails!=null){ - updateDeathOfBenificiary(benificiaryDetails); + //updateDeathOfBenificiary(benificiaryDetails); } } @@ -282,7 +280,7 @@ else if(null != beneficiaryModel.getI_bendemographics().getReligion()) identityDTO.setIncomeStatus(beneficiaryModel.getI_bendemographics().getIncomeStatus()); } if(beneficiaryModel!=null){ - updateDeathOfBenificiary(beneficiaryModel); + // updateDeathOfBenificiary(beneficiaryModel); } } From dddc108ddf1499ab3fa8ef67ae4abf95be93ff2a Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 17 Sep 2025 19:06:59 +0530 Subject: [PATCH 267/318] fix strict-origin-when-cross-origin --- .../beneficiary/BeneficiaryRegistrationController.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java index 69e04b92..8f573d6d 100644 --- a/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java +++ b/src/main/java/com/iemr/common/controller/beneficiary/BeneficiaryRegistrationController.java @@ -29,7 +29,6 @@ import javax.ws.rs.core.MediaType; -import com.iemr.common.repository.beneficiary.BeneficiaryDetailsRmnchRepository; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -104,8 +103,6 @@ public class BeneficiaryRegistrationController { private BeneficiaryOccupationService beneficiaryOccupationService; private GovtIdentityTypeService govtIdentityTypeService; - @Autowired - private BeneficiaryDetailsRmnchRepository beneficiaryDetailsRmnchRepository; @Autowired public void setBenRelationshipTypeService(BenRelationshipTypeService benRelationshipTypeService) { From 0505d4eaf599fce592c44a6410929e5c66baa3e6 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 18 Sep 2025 14:24:34 +0530 Subject: [PATCH 268/318] fix: dev-linux issue fix --- .../PlatformFeedbackRateLimitFilter.java | 39 +++++++++++-------- .../com/iemr/common/utils/FilterConfig.java | 24 ++++-------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java index 95126093..fcf286d1 100644 --- a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java +++ b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java @@ -42,6 +42,7 @@ import java.util.Base64; import java.util.concurrent.TimeUnit; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.beans.factory.annotation.Value; @Component @@ -50,26 +51,30 @@ public class PlatformFeedbackRateLimitFilter extends OncePerRequestFilter { private final StringRedisTemplate redis; - private final String pepper; - private final boolean trustForwardedFor; - private final String forwardedForHeader; + @Value("${platform.feedback.ratelimit.pepper}") + private String pepper; + @Value("${platform.feedback.ratelimit.trust-forwarded-for:false}") + private boolean trustForwardedFor; + @Value("${platform.feedback.ratelimit.forwarded-for-header:X-Forwarded-For}") + private String forwardedForHeader; // Limits & TTLs (tweak if needed) - private static final int MINUTE_LIMIT = 10; - private static final int DAY_LIMIT = 100; - private static final int USER_DAY_LIMIT = 50; // for identified users - private static final Duration MINUTE_WINDOW = Duration.ofMinutes(1); - private static final Duration DAY_WINDOW = Duration.ofHours(48); // keep key TTL ~48h - private static final Duration FAIL_COUNT_WINDOW = Duration.ofMinutes(5); - private static final int FAILS_TO_BACKOFF = 3; - private static final Duration BACKOFF_WINDOW = Duration.ofMinutes(15); - - public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis, - org.springframework.core.env.Environment env) { + @Value("${platform.feedback.ratelimit.minute-limit:10}") + private int MINUTE_LIMIT; + @Value("${platform.feedback.ratelimit.day-limit:100}") + private int DAY_LIMIT; + @Value("${platform.feedback.ratelimit.user-day-limit:50}") + private int USER_DAY_LIMIT; // for identified users + private Duration MINUTE_WINDOW = Duration.ofMinutes(1); + private Duration DAY_WINDOW = Duration.ofHours(48); // keep key TTL ~48h + @Value("${platform.feedback.ratelimit.fail-window-minutes:5}") + private Duration FAIL_COUNT_WINDOW; + private int FAILS_TO_BACKOFF = 3; + @Value("${platform.feedback.ratelimit.backoff-window-minutes:15}") + private Duration BACKOFF_WINDOW; + + public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis) { this.redis = redis; - this.pepper = env.getProperty("platform.feedback.pepper", ""); - this.trustForwardedFor = Boolean.parseBoolean(env.getProperty("platform.feedback.trust-forwarded-for", "true")); - this.forwardedForHeader = env.getProperty("platform.feedback.forwarded-for-header", "X-Forwarded-For"); } @Override diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 8664199c..fd862262 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -40,6 +40,10 @@ public class FilterConfig { @Value("${cors.allowed-origins}") private String allowedOrigins; + @Value("${platform.feedback.ratelimit.enabled:false}") + private boolean enabled; + + @Bean public FilterRegistrationBean jwtUserIdValidationFilter( JwtAuthenticationUtil jwtAuthenticationUtil) { @@ -63,25 +67,13 @@ public FilterRegistrationBean jwtUserIdValidationFilt */ @Bean public FilterRegistrationBean platformFeedbackRateLimitFilter( - StringRedisTemplate stringRedisTemplate, - Environment env) { + StringRedisTemplate stringRedisTemplate) { - // Read flag from environment (property file or env var) - boolean enabled = Boolean.parseBoolean(env.getProperty("platform.feedback.ratelimit.enabled", "false")); // Allow optional override for order if needed - int defaultOrder = Ordered.HIGHEST_PRECEDENCE + 10; - int order = defaultOrder; - String orderStr = env.getProperty("platform.feedback.ratelimit.order"); - if (orderStr != null) { - try { - order = Integer.parseInt(orderStr); - } catch (NumberFormatException e) { - log.warn("Invalid platform.feedback.ratelimit.order value '{}', using default {}", orderStr, defaultOrder); - } - } - - PlatformFeedbackRateLimitFilter filter = new PlatformFeedbackRateLimitFilter(stringRedisTemplate, env); + int order = Ordered.HIGHEST_PRECEDENCE + 10; + + PlatformFeedbackRateLimitFilter filter = new PlatformFeedbackRateLimitFilter(stringRedisTemplate); FilterRegistrationBean reg = new FilterRegistrationBean<>(filter); From a97d332c45834e4f6c228febbf1063ac11ebf9c1 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 18 Sep 2025 17:15:44 +0530 Subject: [PATCH 269/318] fix: dev-linux issue fix --- .../com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java index fcf286d1..1f94537c 100644 --- a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java +++ b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java @@ -70,7 +70,7 @@ public class PlatformFeedbackRateLimitFilter extends OncePerRequestFilter { @Value("${platform.feedback.ratelimit.fail-window-minutes:5}") private Duration FAIL_COUNT_WINDOW; private int FAILS_TO_BACKOFF = 3; - @Value("${platform.feedback.ratelimit.backoff-window-minutes:15}") + @Value("${platform.feedback.ratelimit.backoff-minutes:15}") private Duration BACKOFF_WINDOW; public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis) { From 70695b7494d9b03d863d250630a30f1764f1421f Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 18 Sep 2025 17:44:33 +0530 Subject: [PATCH 270/318] fix: dev-linux issue fix --- .../PlatformFeedbackRateLimitFilter.java | 149 ++++++++++++------ 1 file changed, 98 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java index 1f94537c..be574ca0 100644 --- a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java +++ b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java @@ -21,10 +21,13 @@ */ package com.iemr.common.filter; +import jakarta.annotation.PostConstruct; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.StringRedisTemplate; @@ -44,56 +47,83 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.beans.factory.annotation.Value; - @Component @ConditionalOnProperty(prefix = "platform.feedback.ratelimit", name = "enabled", havingValue = "true", matchIfMissing = false) -@Order(Ordered.HIGHEST_PRECEDENCE + 10) // run early (adjust order as needed) +@Order(Ordered.HIGHEST_PRECEDENCE + 10) public class PlatformFeedbackRateLimitFilter extends OncePerRequestFilter { + private static final Logger log = LoggerFactory.getLogger(PlatformFeedbackRateLimitFilter.class); + private final StringRedisTemplate redis; - @Value("${platform.feedback.ratelimit.pepper}") + + @Value("${platform.feedback.ratelimit.pepper:}") private String pepper; + @Value("${platform.feedback.ratelimit.trust-forwarded-for:false}") private boolean trustForwardedFor; + @Value("${platform.feedback.ratelimit.forwarded-for-header:X-Forwarded-For}") private String forwardedForHeader; - // Limits & TTLs (tweak if needed) @Value("${platform.feedback.ratelimit.minute-limit:10}") - private int MINUTE_LIMIT; + private int minuteLimit; + @Value("${platform.feedback.ratelimit.day-limit:100}") - private int DAY_LIMIT; + private int dayLimit; + @Value("${platform.feedback.ratelimit.user-day-limit:50}") - private int USER_DAY_LIMIT; // for identified users - private Duration MINUTE_WINDOW = Duration.ofMinutes(1); - private Duration DAY_WINDOW = Duration.ofHours(48); // keep key TTL ~48h + private int userDayLimit; + + private final Duration MINUTE_WINDOW = Duration.ofMinutes(1); + private final Duration DAY_WINDOW = Duration.ofHours(48); + @Value("${platform.feedback.ratelimit.fail-window-minutes:5}") - private Duration FAIL_COUNT_WINDOW; - private int FAILS_TO_BACKOFF = 3; + private long failCountWindowMinutes; + @Value("${platform.feedback.ratelimit.backoff-minutes:15}") - private Duration BACKOFF_WINDOW; + private long backoffWindowMinutes; + + @Value("${platform.feedback.ratelimit.fails-to-backoff:3}") + private int failsToBackoff; public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis) { this.redis = redis; } + @PostConstruct + public void validateConfig() { + if (!StringUtils.hasText(pepper)) { + throw new IllegalStateException("platform.feedback.ratelimit.pepper must be set"); + } + if (failCountWindowMinutes <= 0) { + throw new IllegalStateException("platform.feedback.ratelimit.fail-window-minutes must be > 0"); + } + if (backoffWindowMinutes <= 0) { + throw new IllegalStateException("platform.feedback.ratelimit.backoff-minutes must be > 0"); + } + if (minuteLimit <= 0 || dayLimit <= 0 || userDayLimit <= 0) { + log.warn("One of the rate limits is non-positive; please check configuration"); + } + log.info("PlatformFeedbackRateLimitFilter initialized (minuteLimit={}, dayLimit={}, userDayLimit={}, failWindowMinutes={}, backoffMinutes={}, failsToBackoff={})", + minuteLimit, dayLimit, userDayLimit, failCountWindowMinutes, backoffWindowMinutes, failsToBackoff); + } + @Override protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { // Only filter specific endpoints (POST to platform-feedback). Keep it narrow. String path = request.getRequestURI(); String method = request.getMethod(); - // adjust path as needed (supports /common-api/platform-feedback and subpaths) - return !("POST".equalsIgnoreCase(method) && path != null && path.matches("^/platform-feedback(?:/.*)?$")); + // Allow context path prefixes, e.g. /common-api/platform-feedback + return !("POST".equalsIgnoreCase(method) && path != null && path.matches(".*/platform-feedback(?:/.*)?$")); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - // compute day key String clientIp = extractClientIp(request); if (clientIp == null || clientIp.isBlank()) { - // If we can't identify an IP, be conservative and allow but log (or optionally block) + log.debug("Client IP could not be determined; allowing request (fail-open). RequestURI={}", request.getRequestURI()); filterChain.doFilter(request, response); return; } @@ -105,68 +135,77 @@ protected void doFilterInternal(HttpServletRequest request, String failKey = "rl:fb:fail:" + ipHash; String backoffKey = "rl:fb:backoff:" + ipHash; - // If under backoff -> respond 429 with Retry-After = TTL Long backoffTtl = getTtlSeconds(backoffKey); if (backoffTtl != null && backoffTtl > 0) { + log.debug("IP in backoff (ipHash={}, ttl={})", ipHash, backoffTtl); sendTooMany(response, backoffTtl); return; } - // Minute window check (INCR + TTL if first) long minuteCount = incrementWithExpire(minKey, 1, MINUTE_WINDOW.getSeconds()); - if (minuteCount > MINUTE_LIMIT) { + if (minuteCount > minuteLimit) { + log.info("Minute limit hit for ipHash={} minuteCount={}", ipHash, minuteCount); handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); return; } - // Day window check long dayCount = incrementWithExpire(dayKey, 1, DAY_WINDOW.getSeconds()); - if (dayCount > DAY_LIMIT) { + if (dayCount > dayLimit) { + log.info("Day limit hit for ipHash={} dayCount={}", ipHash, dayCount); handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); return; } - // Optional: per-user daily cap if we can extract an authenticated user id from header/jwt Integer userId = extractUserIdFromRequest(request); // implement extraction as per your JWT scheme if (userId != null) { String userDayKey = "rl:fb:user:" + today + ":" + userId; long ucount = incrementWithExpire(userDayKey, 1, DAY_WINDOW.getSeconds()); - if (ucount > USER_DAY_LIMIT) { + if (ucount > userDayLimit) { + log.info("User day limit hit for userId={} count={}", userId, ucount); handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, userDayKey); return; } } - // All checks passed — proceed to controller filterChain.doFilter(request, response); } - // increments key by delta; sets TTL when key is new (INCR returns 1) private long incrementWithExpire(String key, long delta, long ttlSeconds) { - Long value = redis.opsForValue().increment(key, delta); - if (value != null && value == 1L) { - redis.expire(key, ttlSeconds, TimeUnit.SECONDS); + try { + Long value = redis.opsForValue().increment(key, delta); + if (value != null && value == 1L) { + redis.expire(key, ttlSeconds, TimeUnit.SECONDS); + } + return value == null ? 0L : value; + } catch (Exception ex) { + log.error("Redis increment failed for key={} delta={} - failing open (allow request). Exception: {}", key, delta, ex.toString()); + return 0L; } - return value == null ? 0L : value; } private void handleFailureAndMaybeBackoff(String failKey, String backoffKey, HttpServletResponse response, String trigKey, String dayKey) throws IOException { - // increment fail counter and possibly set backoff - Long fails = redis.opsForValue().increment(failKey, 1); - if (fails != null && fails == 1L) { - redis.expire(failKey, FAIL_COUNT_WINDOW.getSeconds(), TimeUnit.SECONDS); - } - if (fails != null && fails >= FAILS_TO_BACKOFF) { - // set backoff flag - redis.opsForValue().set(backoffKey, "1", BACKOFF_WINDOW.getSeconds(), TimeUnit.SECONDS); - sendTooMany(response, BACKOFF_WINDOW.getSeconds()); - return; - } + try { + Long fails = redis.opsForValue().increment(failKey, 1); + if (fails != null && fails == 1L) { + redis.expire(failKey, getFailCountWindowSeconds(), TimeUnit.SECONDS); + } + log.debug("Fail counter for key {} is {}", failKey, fails); + + if (fails != null && fails >= failsToBackoff) { + long backoffSeconds = getBackoffWindowSeconds(); + redis.opsForValue().set(backoffKey, "1", backoffSeconds, TimeUnit.SECONDS); + log.info("Entering backoff for ip (backoffKey={}, backoffSeconds={})", backoffKey, backoffSeconds); + sendTooMany(response, backoffSeconds); + return; + } - // otherwise respond with Retry-After for the triggering key TTL (minute/day) - Long retryAfter = getTtlSeconds(trigKey); - if (retryAfter == null || retryAfter <= 0) retryAfter = 60L; - sendTooMany(response, retryAfter); + Long retryAfter = getTtlSeconds(trigKey); + if (retryAfter == null || retryAfter <= 0) retryAfter = 60L; + log.debug("Responding rate-limited with Retry-After={} for key={}", retryAfter, trigKey); + sendTooMany(response, retryAfter); + } catch (Exception ex) { + log.error("Error while handling failure/backoff; failing open and allowing request. Exception: {}", ex.toString()); + } } private void sendTooMany(HttpServletResponse response, long retryAfterSeconds) throws IOException { @@ -178,15 +217,19 @@ private void sendTooMany(HttpServletResponse response, long retryAfterSeconds) t } private Long getTtlSeconds(String key) { - Long ttl = redis.getExpire(key, TimeUnit.SECONDS); - return ttl == null || ttl < 0 ? null : ttl; + try { + Long ttl = redis.getExpire(key, TimeUnit.SECONDS); + return ttl == null || ttl < 0 ? null : ttl; + } catch (Exception ex) { + log.warn("Redis getExpire failed for key={} - treating as no TTL. Exception: {}", key, ex.toString()); + return null; + } } private String extractClientIp(HttpServletRequest request) { if (trustForwardedFor) { String header = request.getHeader(forwardedForHeader); if (StringUtils.hasText(header)) { - // X-Forwarded-For may contain comma-separated list; take the first (client) entry String[] parts = header.split(","); if (parts.length > 0) { String ip = parts[0].trim(); @@ -198,21 +241,25 @@ private String extractClientIp(HttpServletRequest request) { } private Integer extractUserIdFromRequest(HttpServletRequest request) { - // implement based on how you propagate JWT or user info. - // Example: if your gateway injects header X-User-Id for authenticated requests: String s = request.getHeader("X-User-Id"); if (StringUtils.hasText(s)) { try { return Integer.valueOf(s); } catch (NumberFormatException ignored) {} } - // If JWT parsing required, do it here, but keep this filter light — prefer upstream auth filter to populate a header. return null; } + private long getFailCountWindowSeconds() { + return Duration.ofMinutes(failCountWindowMinutes).getSeconds(); + } + + private long getBackoffWindowSeconds() { + return Duration.ofMinutes(backoffWindowMinutes).getSeconds(); + } + private static String sha256Base64(String input) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hashed = digest.digest(input.getBytes(StandardCharsets.UTF_8)); - // base64 url-safe or normal base64 — either is fine; base64 is shorter than hex return Base64.getUrlEncoder().withoutPadding().encodeToString(hashed); } catch (Exception ex) { throw new RuntimeException("sha256 failure", ex); From ae474a90d75ebfd9c6b9b66616c6f484e1238d40 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Fri, 19 Sep 2025 08:51:55 +0530 Subject: [PATCH 271/318] fix: dev-linux issue fix --- .../PlatformFeedbackRateLimitFilter.java | 174 ++++++------------ .../com/iemr/common/utils/FilterConfig.java | 26 ++- 2 files changed, 78 insertions(+), 122 deletions(-) diff --git a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java index be574ca0..d6dddf55 100644 --- a/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java +++ b/src/main/java/com/iemr/common/filter/PlatformFeedbackRateLimitFilter.java @@ -21,13 +21,10 @@ */ package com.iemr.common.filter; -import jakarta.annotation.PostConstruct; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.data.redis.core.StringRedisTemplate; @@ -45,67 +42,34 @@ import java.util.Base64; import java.util.concurrent.TimeUnit; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.beans.factory.annotation.Value; + @Component @ConditionalOnProperty(prefix = "platform.feedback.ratelimit", name = "enabled", havingValue = "true", matchIfMissing = false) -@Order(Ordered.HIGHEST_PRECEDENCE + 10) +@Order(Ordered.HIGHEST_PRECEDENCE + 10) // run early (adjust order as needed) public class PlatformFeedbackRateLimitFilter extends OncePerRequestFilter { - private static final Logger log = LoggerFactory.getLogger(PlatformFeedbackRateLimitFilter.class); - private final StringRedisTemplate redis; - - @Value("${platform.feedback.ratelimit.pepper:}") - private String pepper; - - @Value("${platform.feedback.ratelimit.trust-forwarded-for:false}") - private boolean trustForwardedFor; - - @Value("${platform.feedback.ratelimit.forwarded-for-header:X-Forwarded-For}") - private String forwardedForHeader; - - @Value("${platform.feedback.ratelimit.minute-limit:10}") - private int minuteLimit; - - @Value("${platform.feedback.ratelimit.day-limit:100}") - private int dayLimit; - - @Value("${platform.feedback.ratelimit.user-day-limit:50}") - private int userDayLimit; - - private final Duration MINUTE_WINDOW = Duration.ofMinutes(1); - private final Duration DAY_WINDOW = Duration.ofHours(48); - - @Value("${platform.feedback.ratelimit.fail-window-minutes:5}") - private long failCountWindowMinutes; - - @Value("${platform.feedback.ratelimit.backoff-minutes:15}") - private long backoffWindowMinutes; - - @Value("${platform.feedback.ratelimit.fails-to-backoff:3}") - private int failsToBackoff; - - public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis) { + private final String pepper; + private final boolean trustForwardedFor; + private final String forwardedForHeader; + + // Limits & TTLs (tweak if needed) + private static final int MINUTE_LIMIT = 10; + private static final int DAY_LIMIT = 100; + private static final int USER_DAY_LIMIT = 50; // for identified users + private static final Duration MINUTE_WINDOW = Duration.ofMinutes(1); + private static final Duration DAY_WINDOW = Duration.ofHours(48); // keep key TTL ~48h + private static final Duration FAIL_COUNT_WINDOW = Duration.ofMinutes(5); + private static final int FAILS_TO_BACKOFF = 3; + private static final Duration BACKOFF_WINDOW = Duration.ofMinutes(15); + + public PlatformFeedbackRateLimitFilter(StringRedisTemplate redis, + org.springframework.core.env.Environment env) { this.redis = redis; - } - - @PostConstruct - public void validateConfig() { - if (!StringUtils.hasText(pepper)) { - throw new IllegalStateException("platform.feedback.ratelimit.pepper must be set"); - } - if (failCountWindowMinutes <= 0) { - throw new IllegalStateException("platform.feedback.ratelimit.fail-window-minutes must be > 0"); - } - if (backoffWindowMinutes <= 0) { - throw new IllegalStateException("platform.feedback.ratelimit.backoff-minutes must be > 0"); - } - if (minuteLimit <= 0 || dayLimit <= 0 || userDayLimit <= 0) { - log.warn("One of the rate limits is non-positive; please check configuration"); - } - log.info("PlatformFeedbackRateLimitFilter initialized (minuteLimit={}, dayLimit={}, userDayLimit={}, failWindowMinutes={}, backoffMinutes={}, failsToBackoff={})", - minuteLimit, dayLimit, userDayLimit, failCountWindowMinutes, backoffWindowMinutes, failsToBackoff); + this.pepper = env.getProperty("platform.feedback.pepper", ""); + this.trustForwardedFor = Boolean.parseBoolean(env.getProperty("platform.feedback.trust-forwarded-for", "true")); + this.forwardedForHeader = env.getProperty("platform.feedback.forwarded-for-header", "X-Forwarded-For"); } @Override @@ -113,17 +77,18 @@ protected boolean shouldNotFilter(HttpServletRequest request) throws ServletExce // Only filter specific endpoints (POST to platform-feedback). Keep it narrow. String path = request.getRequestURI(); String method = request.getMethod(); - // Allow context path prefixes, e.g. /common-api/platform-feedback - return !("POST".equalsIgnoreCase(method) && path != null && path.matches(".*/platform-feedback(?:/.*)?$")); + // adjust path as needed (supports /common-api/platform-feedback and subpaths) + return !("POST".equalsIgnoreCase(method) && path != null && path.matches("^/platform-feedback(?:/.*)?$")); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + // compute day key String clientIp = extractClientIp(request); if (clientIp == null || clientIp.isBlank()) { - log.debug("Client IP could not be determined; allowing request (fail-open). RequestURI={}", request.getRequestURI()); + // If we can't identify an IP, be conservative and allow but log (or optionally block) filterChain.doFilter(request, response); return; } @@ -135,77 +100,68 @@ protected void doFilterInternal(HttpServletRequest request, String failKey = "rl:fb:fail:" + ipHash; String backoffKey = "rl:fb:backoff:" + ipHash; + // If under backoff -> respond 429 with Retry-After = TTL Long backoffTtl = getTtlSeconds(backoffKey); if (backoffTtl != null && backoffTtl > 0) { - log.debug("IP in backoff (ipHash={}, ttl={})", ipHash, backoffTtl); sendTooMany(response, backoffTtl); return; } + // Minute window check (INCR + TTL if first) long minuteCount = incrementWithExpire(minKey, 1, MINUTE_WINDOW.getSeconds()); - if (minuteCount > minuteLimit) { - log.info("Minute limit hit for ipHash={} minuteCount={}", ipHash, minuteCount); + if (minuteCount > MINUTE_LIMIT) { handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); return; } + // Day window check long dayCount = incrementWithExpire(dayKey, 1, DAY_WINDOW.getSeconds()); - if (dayCount > dayLimit) { - log.info("Day limit hit for ipHash={} dayCount={}", ipHash, dayCount); + if (dayCount > DAY_LIMIT) { handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, dayKey); return; } + // Optional: per-user daily cap if we can extract an authenticated user id from header/jwt Integer userId = extractUserIdFromRequest(request); // implement extraction as per your JWT scheme if (userId != null) { String userDayKey = "rl:fb:user:" + today + ":" + userId; long ucount = incrementWithExpire(userDayKey, 1, DAY_WINDOW.getSeconds()); - if (ucount > userDayLimit) { - log.info("User day limit hit for userId={} count={}", userId, ucount); + if (ucount > USER_DAY_LIMIT) { handleFailureAndMaybeBackoff(failKey, backoffKey, response, minKey, userDayKey); return; } } + // All checks passed — proceed to controller filterChain.doFilter(request, response); } + // increments key by delta; sets TTL when key is new (INCR returns 1) private long incrementWithExpire(String key, long delta, long ttlSeconds) { - try { - Long value = redis.opsForValue().increment(key, delta); - if (value != null && value == 1L) { - redis.expire(key, ttlSeconds, TimeUnit.SECONDS); - } - return value == null ? 0L : value; - } catch (Exception ex) { - log.error("Redis increment failed for key={} delta={} - failing open (allow request). Exception: {}", key, delta, ex.toString()); - return 0L; + Long value = redis.opsForValue().increment(key, delta); + if (value != null && value == 1L) { + redis.expire(key, ttlSeconds, TimeUnit.SECONDS); } + return value == null ? 0L : value; } private void handleFailureAndMaybeBackoff(String failKey, String backoffKey, HttpServletResponse response, String trigKey, String dayKey) throws IOException { - try { - Long fails = redis.opsForValue().increment(failKey, 1); - if (fails != null && fails == 1L) { - redis.expire(failKey, getFailCountWindowSeconds(), TimeUnit.SECONDS); - } - log.debug("Fail counter for key {} is {}", failKey, fails); - - if (fails != null && fails >= failsToBackoff) { - long backoffSeconds = getBackoffWindowSeconds(); - redis.opsForValue().set(backoffKey, "1", backoffSeconds, TimeUnit.SECONDS); - log.info("Entering backoff for ip (backoffKey={}, backoffSeconds={})", backoffKey, backoffSeconds); - sendTooMany(response, backoffSeconds); - return; - } - - Long retryAfter = getTtlSeconds(trigKey); - if (retryAfter == null || retryAfter <= 0) retryAfter = 60L; - log.debug("Responding rate-limited with Retry-After={} for key={}", retryAfter, trigKey); - sendTooMany(response, retryAfter); - } catch (Exception ex) { - log.error("Error while handling failure/backoff; failing open and allowing request. Exception: {}", ex.toString()); + // increment fail counter and possibly set backoff + Long fails = redis.opsForValue().increment(failKey, 1); + if (fails != null && fails == 1L) { + redis.expire(failKey, FAIL_COUNT_WINDOW.getSeconds(), TimeUnit.SECONDS); } + if (fails != null && fails >= FAILS_TO_BACKOFF) { + // set backoff flag + redis.opsForValue().set(backoffKey, "1", BACKOFF_WINDOW.getSeconds(), TimeUnit.SECONDS); + sendTooMany(response, BACKOFF_WINDOW.getSeconds()); + return; + } + + // otherwise respond with Retry-After for the triggering key TTL (minute/day) + Long retryAfter = getTtlSeconds(trigKey); + if (retryAfter == null || retryAfter <= 0) retryAfter = 60L; + sendTooMany(response, retryAfter); } private void sendTooMany(HttpServletResponse response, long retryAfterSeconds) throws IOException { @@ -217,19 +173,15 @@ private void sendTooMany(HttpServletResponse response, long retryAfterSeconds) t } private Long getTtlSeconds(String key) { - try { - Long ttl = redis.getExpire(key, TimeUnit.SECONDS); - return ttl == null || ttl < 0 ? null : ttl; - } catch (Exception ex) { - log.warn("Redis getExpire failed for key={} - treating as no TTL. Exception: {}", key, ex.toString()); - return null; - } + Long ttl = redis.getExpire(key, TimeUnit.SECONDS); + return ttl == null || ttl < 0 ? null : ttl; } private String extractClientIp(HttpServletRequest request) { if (trustForwardedFor) { String header = request.getHeader(forwardedForHeader); if (StringUtils.hasText(header)) { + // X-Forwarded-For may contain comma-separated list; take the first (client) entry String[] parts = header.split(","); if (parts.length > 0) { String ip = parts[0].trim(); @@ -241,28 +193,24 @@ private String extractClientIp(HttpServletRequest request) { } private Integer extractUserIdFromRequest(HttpServletRequest request) { + // implement based on how you propagate JWT or user info. + // Example: if your gateway injects header X-User-Id for authenticated requests: String s = request.getHeader("X-User-Id"); if (StringUtils.hasText(s)) { try { return Integer.valueOf(s); } catch (NumberFormatException ignored) {} } + // If JWT parsing required, do it here, but keep this filter light — prefer upstream auth filter to populate a header. return null; } - private long getFailCountWindowSeconds() { - return Duration.ofMinutes(failCountWindowMinutes).getSeconds(); - } - - private long getBackoffWindowSeconds() { - return Duration.ofMinutes(backoffWindowMinutes).getSeconds(); - } - private static String sha256Base64(String input) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] hashed = digest.digest(input.getBytes(StandardCharsets.UTF_8)); + // base64 url-safe or normal base64 — either is fine; base64 is shorter than hex return Base64.getUrlEncoder().withoutPadding().encodeToString(hashed); } catch (Exception ex) { throw new RuntimeException("sha256 failure", ex); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index fd862262..42bd04ad 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -40,10 +40,6 @@ public class FilterConfig { @Value("${cors.allowed-origins}") private String allowedOrigins; - @Value("${platform.feedback.ratelimit.enabled:false}") - private boolean enabled; - - @Bean public FilterRegistrationBean jwtUserIdValidationFilter( JwtAuthenticationUtil jwtAuthenticationUtil) { @@ -67,13 +63,25 @@ public FilterRegistrationBean jwtUserIdValidationFilt */ @Bean public FilterRegistrationBean platformFeedbackRateLimitFilter( - StringRedisTemplate stringRedisTemplate) { + StringRedisTemplate stringRedisTemplate, + Environment env) { + // Read flag from environment (property file or env var) + boolean enabled = Boolean.parseBoolean(env.getProperty("platform.feedback.ratelimit.enabled", "false")); // Allow optional override for order if needed - int order = Ordered.HIGHEST_PRECEDENCE + 10; - - PlatformFeedbackRateLimitFilter filter = new PlatformFeedbackRateLimitFilter(stringRedisTemplate); + int defaultOrder = Ordered.HIGHEST_PRECEDENCE + 10; + int order = defaultOrder; + String orderStr = env.getProperty("platform.feedback.ratelimit.order"); + if (orderStr != null) { + try { + order = Integer.parseInt(orderStr); + } catch (NumberFormatException e) { + log.warn("Invalid platform.feedback.ratelimit.order value '{}', using default {}", orderStr, defaultOrder); + } + } + + PlatformFeedbackRateLimitFilter filter = new PlatformFeedbackRateLimitFilter(stringRedisTemplate, env); FilterRegistrationBean reg = new FilterRegistrationBean<>(filter); @@ -91,4 +99,4 @@ public FilterRegistrationBean platformFeedbackR return reg; } -} +} \ No newline at end of file From 9ffee160d31c6476ab0ba7670a82faa6036a117f Mon Sep 17 00:00:00 2001 From: Amoghavarsh <93114621+5Amogh@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:38:31 +0530 Subject: [PATCH 272/318] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ae3d0b9..a2e6e019 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.4.0 + 3.5.0 war Common-API From aa94a5a219404c002ea107e83366d9de4cde0933 Mon Sep 17 00:00:00 2001 From: Amoghavarsh <93114621+5Amogh@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:39:12 +0530 Subject: [PATCH 273/318] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a2e6e019..159a28ad 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.5.0 + 3.8.0 war Common-API From 6c00a6b35c255d02ca6dce639cbb82dd5afc4706 Mon Sep 17 00:00:00 2001 From: Amoghavarsh <93114621+5Amogh@users.noreply.github.com> Date: Thu, 25 Sep 2025 12:46:51 +0530 Subject: [PATCH 274/318] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ae3d0b9..a98d44c6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.4.0 + 3.5.1 war Common-API From f93e2f4c7a5e61d1ae1250b20718bef0b9224881 Mon Sep 17 00:00:00 2001 From: ravishanigarapu <133210792+ravishanigarapu@users.noreply.github.com> Date: Thu, 25 Sep 2025 19:59:14 +0530 Subject: [PATCH 275/318] refresh token unauthorize issue (#296) * Update JwtUserIdValidationFilter.java * Added new condition for new user status * Status code changes from 5002 to 401 if it is Auauthorized * logger message changed --- .../controller/users/IEMRAdminController.java | 5 +-- .../utils/JwtUserIdValidationFilter.java | 3 +- .../utils/http/HTTPRequestInterceptor.java | 36 ++++++++++++++----- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index bbe70dd4..1475635a 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -285,8 +285,9 @@ public ResponseEntity refreshToken(@RequestBody Map request) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } - if (user.getM_status() == null || !"Active".equalsIgnoreCase(user.getM_status().getStatus())) { - logger.warn("Token validation failed: user account is inactive or not in 'Active' status."); + if (user.getM_status() == null || !("Active".equalsIgnoreCase(user.getM_status().getStatus()) + || "New".equalsIgnoreCase(user.getM_status().getStatus()))) { + logger.warn("Token validation failed: user account is neither 'Active' nor 'New'."); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized."); } // Generate new tokens diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 13eaea2f..16466ee5 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -169,7 +169,8 @@ private boolean shouldSkipAuthentication(String path, String contextPath) { || path.startsWith(contextPath + "/user/saveUserSecurityQuesAns") || path.startsWith(contextPath + "/user/userLogout") || path.startsWith(contextPath + "/user/validateSecurityQuestionAndAnswer") - || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession"); + || path.startsWith(contextPath + "/user/logOutUserFromConcurrentSession") + || path.startsWith(contextPath + "/user/refreshToken"); } private String getJwtTokenFromCookies(HttpServletRequest request) { diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 23b0af62..1c322dc4 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -21,7 +21,7 @@ */ package com.iemr.common.utils.http; - +import java.nio.charset.StandardCharsets; import javax.ws.rs.core.MediaType; import org.slf4j.Logger; @@ -32,10 +32,10 @@ import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; -import com.iemr.common.utils.response.OutputResponse; import com.iemr.common.utils.sessionobject.SessionObject; import com.iemr.common.utils.validator.Validator; +import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @Configuration @@ -125,12 +125,30 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons break; } } catch (Exception e) { - OutputResponse output = new OutputResponse(); - output.setError(e); - response.getOutputStream().print(output.toString()); - response.setContentType(MediaType.APPLICATION_JSON); - response.setContentLength(output.toString().length()); - response.setHeader("Access-Control-Allow-Origin", "*"); + logger.error("Authorization failed: {}", e.getMessage(), e); + + String errorMessage = e.getMessage(); + if (errorMessage == null || errorMessage.trim().isEmpty()) { + errorMessage = "Unauthorized access or session expired."; + } + + String jsonErrorResponse = "{" + + "\"status\": \"Unauthorized\"," + + "\"statusCode\": 401," + + "\"errorMessage\": \"" + errorMessage.replace("\"", "\\\"") + "\"" + + "}"; + + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 + response.setContentType(MediaType.APPLICATION_JSON); + response.setHeader("Access-Control-Allow-Origin", "*"); + + // Better to use getBytes().length for accurate byte size + byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); + response.setContentLength(responseBytes.length); + + ServletOutputStream out = response.getOutputStream(); + out.write(responseBytes); + out.flush(); status = false; } } @@ -164,4 +182,4 @@ public void afterCompletion(HttpServletRequest request, HttpServletResponse resp throws Exception { logger.debug("In afterCompletion Request Completed"); } -} \ No newline at end of file +} From e5789f4c75befd0c50e7bcfc58d304f56ee86dbd Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Fri, 26 Sep 2025 14:58:27 +0530 Subject: [PATCH 276/318] fix: missing env added --- src/main/environment/common_ci.properties | 3 ++- src/main/environment/common_docker.properties | 3 ++- src/main/environment/common_example.properties | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index a5e66660..856659f1 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -185,4 +185,5 @@ cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS@ video-call-url=@env.VIDEO_CALL_URL@ jibri.output.path=@env.JIBRI_OUTPUT_PATH@ -video.recording.path=@env.VIDEO_RECORDING_PATH@ \ No newline at end of file +video.recording.path=@env.VIDEO_RECORDING_PATH@ +generateBeneficiaryIDs-api-url=@env.GEN_BENEFICIARY_IDS_API_URL@ diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 41881886..030a7cfe 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -187,4 +187,5 @@ cors.allowed-origins=${CORS_ALLOWED_ORIGINS} video-call-url=${VIDEO_CALL_URL} jibri.output.path={JIBRI_OUTPUT_PATH} -video.recording.path={VIDEO_RECORDING_PATH} \ No newline at end of file +video.recording.path={VIDEO_RECORDING_PATH} +generateBeneficiaryIDs-api-url={GEN_BENEFICIARY_IDS_API_URL} diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 09a526dd..bea76523 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -208,3 +208,5 @@ captcha.enable-captcha=true cors.allowed-origins=http://localhost:* +### generate Beneficiary IDs URL +generateBeneficiaryIDs-api-url=/generateBeneficiaryController/generateBeneficiaryIDs From 435fb88b80e216437f713b9fc4e8fc1380664137 Mon Sep 17 00:00:00 2001 From: ravishanigarapu <133210792+ravishanigarapu@users.noreply.github.com> Date: Fri, 26 Sep 2025 19:51:44 +0530 Subject: [PATCH 277/318] finding userId baserd on createdBy (#299) --- .../controller/users/IEMRAdminController.java | 15 +++++++++++++++ .../service/users/IEMRAdminUserService.java | 2 ++ .../service/users/IEMRAdminUserServiceImpl.java | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 28c7e4b9..e6f9d4cd 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -1212,4 +1212,19 @@ private JSONObject prepareAuthenticationResponse(User mUser, String remoteAddres return iemrAdminUserServiceImpl.generateKeyAndValidateIP(responseObj, remoteAddress, remoteHost); } + @Operation(summary = "Get UserId based on userName") + @GetMapping(value = "/userName/{userName}", produces = MediaType.APPLICATION_JSON, headers = "Authorization") + public ResponseEntity getUserDetails(@PathVariable("userName") String userName) { + try { + List users = iemrAdminUserServiceImpl.getUserIdbyUserName(userName); + if (users.isEmpty()) { + return new ResponseEntity<>(Map.of("error", "UserName Not Found"), HttpStatus.NOT_FOUND); + } + User user = users.get(0); + return new ResponseEntity<>(Map.of("userName", user.getUserName(), "userId", user.getUserID()), HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(Map.of("error", "Internal server error"), HttpStatus.INTERNAL_SERVER_ERROR); + } + + } } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java index 89e238c0..d7dc6e2e 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserService.java @@ -121,6 +121,8 @@ public List getUserServiceRoleMappingForProvider(Integ List getUserServiceRoleMapping(Long userID) throws IEMRException; + List getUserIdbyUserName(String userName) throws IEMRException; + } diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java index 05854843..44bd2247 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java @@ -1218,4 +1218,10 @@ public User getUserById(Long userId) throws IEMRException { throw new IEMRException("Error fetching user with ID: " + userId, e); } } + + @Override + public List getUserIdbyUserName(String userName) { + + return iEMRUserRepositoryCustom.findByUserName(userName); + } } From 8fd476bde4ae8ec74e4c0acf6dc87c14a8a55d88 Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Fri, 26 Sep 2025 20:10:52 +0530 Subject: [PATCH 278/318] Nd/vs/fix ben (#300) * fix: add logs * fix: add url * fix: add logs * fix: revert the hardcoded url * removing static field type for env variables * fix: merge with 3.6.0 * fix: merge with 3.6.0 --------- Co-authored-by: 5Amogh --- .../beneficiary/IdentityBeneficiaryServiceImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index c31a927f..2e6ac1d4 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -59,11 +59,11 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic private static final String IDENTITY_BASE_URL = "IDENTITY_BASE_URL"; @Value("${genben-api}") - private static String BEN_GEN ; + private String BEN_GEN ; @Value("${generateBeneficiaryIDs-api-url}") - private static String BEN_GEN_API_URL ; + private String BEN_GEN_API_URL ; @Override @@ -529,8 +529,11 @@ public List generateBeneficiaryIDs(String request, String a if (auth != null) { header.put("Authorization", auth); } + + logger.info("Request to generate ben IDs: " + request); + logger.info("Generating ben IDs API URL: " + BEN_GEN + BEN_GEN_API_URL); result = httpUtils.post(BEN_GEN + BEN_GEN_API_URL, request, header); - +logger.info("Response from generate ben IDs: " + result); OutputResponse identityResponse = inputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { From 942ae417cd2cd3c38dca69a54c9290ad7d94dfca Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Mon, 6 Oct 2025 15:35:58 +0530 Subject: [PATCH 279/318] fix: swagger env values made dynamic --- src/main/environment/common_ci.properties | 4 ++-- src/main/resources/application.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index d8865adf..e2ab08ad 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -173,8 +173,8 @@ grievancePassword = @env.GRIEVANCE_PASSWORD@ grievanceUserAuthenticate = @env.GRIEVANCE_USER_AUTHENTICATE@ grievanceDataSyncDuration = @env.GRIEVANCE_DATA_SYNC_DURATION@ -springdoc.api-docs.enabled=false -springdoc.swagger-ui.enabled=false +springdoc.api-docs.enabled=@env.SWAGGER_DOC_ENABLED@ +springdoc.swagger-ui.enabled=@env.SWAGGER_UI_ENABLED@ isProduction=@env.IS_PRODUCTION@ diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 62fb2215..886eb969 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -350,8 +350,8 @@ grievancePassword = grievanceUserAuthenticate = grievanceDataSyncDuration = -springdoc.api-docs.enabled=true -springdoc.swagger-ui.enabled=true +springdoc.api-docs.enabled=@env.SWAGGER_DOC_ENABLED@ +springdoc.swagger-ui.enabled=@env.SWAGGER_UI_ENABLED@ isProduction=false grievanceAllocationRetryConfiguration=3 From c822bbbb3247b40778256700da3f0fced9514738 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Mon, 6 Oct 2025 15:44:32 +0530 Subject: [PATCH 280/318] fix: swagger env values made dynamic --- src/main/environment/common_docker.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index 2289c2c0..ba22283b 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -170,8 +170,8 @@ grievancePassword = ${GRIEVANCE_PASSWORD} grievanceUserAuthenticate = ${GRIEVANCE_USER_AUTHENTICATE} grievanceDataSyncDuration = ${GRIEVANCE_DATA_SYNC_DURATION} -springdoc.api-docs.enabled=false -springdoc.swagger-ui.enabled=false +springdoc.api-docs.enabled=${SWAGGER_DOC_ENABLED} +springdoc.swagger-ui.enabled=${SWAGGER_UI_ENABLED} isProduction=${IS_PRODUCTION} From 75d6fa0e5a6d3cc7ba65ca76df54dd9db9c1fd02 Mon Sep 17 00:00:00 2001 From: SnehaRH Date: Thu, 9 Oct 2025 19:12:26 +0530 Subject: [PATCH 281/318] fix: aam-1752 , fetch only active signature --- .../com/iemr/common/repository/users/EmployeeSignatureRepo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java index e1b343a9..c58c8bf5 100644 --- a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java +++ b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java @@ -33,7 +33,7 @@ public interface EmployeeSignatureRepo extends CrudRepository Date: Thu, 9 Oct 2025 22:37:33 +0530 Subject: [PATCH 282/318] Revert "fix: aam-1752 , fetch only active signature" --- .../com/iemr/common/repository/users/EmployeeSignatureRepo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java index c58c8bf5..e1b343a9 100644 --- a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java +++ b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java @@ -33,7 +33,7 @@ public interface EmployeeSignatureRepo extends CrudRepository Date: Fri, 10 Oct 2025 14:21:19 +0530 Subject: [PATCH 283/318] fix: only get the Active signature --- .../com/iemr/common/repository/users/EmployeeSignatureRepo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java index c58c8bf5..ceeb03b0 100644 --- a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java +++ b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java @@ -33,7 +33,7 @@ public interface EmployeeSignatureRepo extends CrudRepository Date: Fri, 10 Oct 2025 16:51:06 +0530 Subject: [PATCH 284/318] fix:active signature --- .../controller/users/EmployeeSignatureController.java | 7 ++++++- .../common/repository/users/EmployeeSignatureRepo.java | 1 + .../common/service/users/EmployeeSignatureService.java | 1 + .../common/service/users/EmployeeSignatureServiceImpl.java | 6 ++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java b/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java index e04fffc5..e29d3220 100644 --- a/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java +++ b/src/main/java/com/iemr/common/controller/users/EmployeeSignatureController.java @@ -65,7 +65,12 @@ public ResponseEntity fetchFile(@PathVariable("userID") Long userID) thr logger.debug("File download for userID" + userID); try { - EmployeeSignature userSignID = employeeSignatureServiceImpl.fetchSignature(userID); + EmployeeSignature userSignID = employeeSignatureServiceImpl.fetchActiveSignature(userID); + + if (userSignID == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, + "Active signature not found for userID: " + userID); + } String originalName = userSignID.getFileName(); if (originalName == null || originalName.isBlank()) { originalName = "signature"; diff --git a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java index ceeb03b0..f532c44b 100644 --- a/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java +++ b/src/main/java/com/iemr/common/repository/users/EmployeeSignatureRepo.java @@ -38,5 +38,6 @@ public interface EmployeeSignatureRepo extends CrudRepository0; From eafd70551411578af0db424d9088197f5698b5af Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Fri, 10 Oct 2025 17:15:01 +0530 Subject: [PATCH 285/318] fix:exception handling --- .../utils/exception/GlobalExceptionHandler.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java index 632e90d2..5969d65f 100644 --- a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.server.ResponseStatusException; import java.util.stream.Collectors; @@ -15,21 +16,27 @@ public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity> handleException(Exception ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(),null)); + .body(ApiResponse.error("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity> handleValidationException(MethodArgumentNotValidException ex) { String errorMessage = ex.getBindingResult().getFieldErrors().stream() - .map(error -> error.getField() + ": " + error.getDefaultMessage()) - .collect(Collectors.joining(", ")); + .map(error -> error.getField() + ": " + error.getDefaultMessage()) + .collect(Collectors.joining(", ")); return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(ApiResponse.error("Validation Error: " + errorMessage, HttpStatus.BAD_REQUEST.value(),null)); + .body(ApiResponse.error("Validation Error: " + errorMessage, HttpStatus.BAD_REQUEST.value(), null)); } @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity> handleIllegalArgException(IllegalArgumentException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(ApiResponse.error(ex.getMessage(), HttpStatus.BAD_REQUEST.value(),null)); + .body(ApiResponse.error(ex.getMessage(), HttpStatus.BAD_REQUEST.value(), null)); + } + + @ExceptionHandler(ResponseStatusException.class) + public ResponseEntity> handleResponseStatusException(ResponseStatusException ex) { + return ResponseEntity.status(ex.getStatusCode()) + .body(ApiResponse.error(ex.getReason(), ex.getStatusCode().value(), null)); } } From 09000bdd05b505c9a776884d72bd2a9a67892358 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Fri, 10 Oct 2025 17:36:58 +0530 Subject: [PATCH 286/318] fix:exception handling --- .../iemr/common/utils/exception/GlobalExceptionHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java index 5969d65f..c22b9616 100644 --- a/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/iemr/common/utils/exception/GlobalExceptionHandler.java @@ -36,7 +36,10 @@ public ResponseEntity> handleIllegalArgException(IllegalArgu @ExceptionHandler(ResponseStatusException.class) public ResponseEntity> handleResponseStatusException(ResponseStatusException ex) { + int statusCode = ex.getStatusCode().value(); // Get status code value + String message = ex.getReason() != null ? ex.getReason() : ex.getMessage(); + return ResponseEntity.status(ex.getStatusCode()) - .body(ApiResponse.error(ex.getReason(), ex.getStatusCode().value(), null)); + .body(ApiResponse.error(message, statusCode, null)); } } From 772a9e0c7d5b67e89d74b34642b217f252ae278f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 14 Oct 2025 16:56:15 +0530 Subject: [PATCH 287/318] fix strict-origin-when-cross-origin --- .../service/dynamicForm/FormMasterServiceImpl.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 19864742..f87215b6 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -1,6 +1,7 @@ package com.iemr.common.service.dynamicForm; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.iemr.common.data.dynamic_from.FormDefinition; import com.iemr.common.data.dynamic_from.FormField; @@ -122,8 +123,14 @@ public FormResponseDTO getStructuredFormByFormId(String formId) { try { // Handle options if (field.getOptions() != null && !field.getOptions().isBlank()) { - List options = objectMapper.readValue(field.getOptions(), new TypeReference<>() {}); - dto.setOptions(options.isEmpty() ? null : options); + JsonNode node = objectMapper.readTree(field.getOptions()); + List options = null; + if (node.isArray()) { + options = objectMapper.convertValue(node, new TypeReference<>() {}); + } else if (node.has("options")) { + options = objectMapper.convertValue(node.get("options"), new TypeReference<>() {}); + } + dto.setOptions(options == null || options.isEmpty() ? null : options); } else { dto.setOptions(null); } From 46048451bc0fb44789eaf1013a7664ad68877d2b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 15:37:52 +0530 Subject: [PATCH 288/318] fix strict-origin-when-cross-origin --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index f87215b6..86a6c1b6 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -162,7 +162,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId) { GroupedFieldResponseDTO singleSection = new GroupedFieldResponseDTO(); - singleSection.setSectionTitle("HBNC Form Fields"); // your custom section title + singleSection.setSectionTitle(singleSection.getSectionTitle()); // your custom section title singleSection.setFields(fieldDtos); FormResponseDTO response = new FormResponseDTO(); From 4b7cb3700202ef3b5772043e88c6e81639dc3d6d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 15:47:12 +0530 Subject: [PATCH 289/318] fix strict-origin-when-cross-origin --- .../dynamicForm/DynamicFormController.java | 13 +++++----- .../common/data/translation/Translation.java | 23 ++++++++++++++++++ .../translation/TranslationRepo.java | 13 ++++++++++ .../dynamicForm/FormMasterService.java | 2 +- .../dynamicForm/FormMasterServiceImpl.java | 24 +++++++++++++++++-- 5 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/translation/Translation.java create mode 100644 src/main/java/com/iemr/common/repository/translation/TranslationRepo.java diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index a5f72bbf..4c7f30a8 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -7,6 +7,7 @@ import com.iemr.common.utils.response.ApiResponse; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.repository.Query; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -19,7 +20,7 @@ public class DynamicFormController { @Autowired private FormMasterService formMasterService; - @PostMapping(value = "createModule",headers = "Authorization") + @PostMapping(value = "createModule") public ResponseEntity> createModule(@Valid @RequestBody ModuleDTO moduleDTO) { try { Object result = formMasterService.createModule(moduleDTO); @@ -34,7 +35,7 @@ public ResponseEntity> createModule(@Valid @RequestBody ModuleDTO } } - @PostMapping(value = "createForm",headers = "Authorization") + @PostMapping(value = "createForm") public ResponseEntity> createForm(@Valid @RequestBody FormDTO dto) { try { Object result = formMasterService.createForm(dto); @@ -46,7 +47,7 @@ public ResponseEntity> createForm(@Valid @RequestBody FormDTO dto } } - @PostMapping(value = "createFields",headers = "Authorization") + @PostMapping(value = "createFields") public ResponseEntity> createField(@Valid @RequestBody List dto) { try { Object result = formMasterService.createField(dto); @@ -83,14 +84,14 @@ public ResponseEntity> deleteField(@PathVariable Long fieldId) { } @GetMapping(value = "form/{formId}/fields") - public ResponseEntity> getStructuredForm(@PathVariable String formId) { + public ResponseEntity> getStructuredForm(@PathVariable String formId, @RequestParam(name = "lang", defaultValue = "en") String lang) { try { - Object result = formMasterService.getStructuredFormByFormId(formId); + Object result = formMasterService.getStructuredFormByFormId(formId,lang); return ResponseEntity.status(HttpStatus.OK) .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(ApiResponse.error("Failed to fetch form structure", HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + .body(ApiResponse.error("Failed to fetch form structure:"+e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); } } diff --git a/src/main/java/com/iemr/common/data/translation/Translation.java b/src/main/java/com/iemr/common/data/translation/Translation.java new file mode 100644 index 00000000..81a906fa --- /dev/null +++ b/src/main/java/com/iemr/common/data/translation/Translation.java @@ -0,0 +1,23 @@ +package com.iemr.common.data.translation; + +import jakarta.persistence.*; +import lombok.Data; + +@Entity +@Table(name = "m_translation") +@Data +public class Translation { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + @Column(name = "label_key") + private String labelKey; + @Column(name = "english") + private String english; + @Column(name = "hindi_translation") + private String hindiTranslation; + @Column(name = "is_active") + private Boolean isActive; +} diff --git a/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java b/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java new file mode 100644 index 00000000..f6a5dcb0 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/translation/TranslationRepo.java @@ -0,0 +1,13 @@ +package com.iemr.common.repository.translation; + +import com.iemr.common.data.translation.Translation; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; +@Repository +public interface TranslationRepo extends JpaRepository { + + Optional findByLabelKeyAndIsActive(String labelKey, boolean isActive); + +} diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java index c603cd65..6d22e59a 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterService.java @@ -16,7 +16,7 @@ public interface FormMasterService { List createField(List dto); FormField updateField(FieldDTO dto); - FormResponseDTO getStructuredFormByFormId(String formId); + FormResponseDTO getStructuredFormByFormId(String formId,String lang); void deleteField(Long fieldId); } diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 86a6c1b6..c4719809 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -6,10 +6,12 @@ import com.iemr.common.data.dynamic_from.FormDefinition; import com.iemr.common.data.dynamic_from.FormField; import com.iemr.common.data.dynamic_from.FormModule; +import com.iemr.common.data.translation.Translation; import com.iemr.common.dto.dynamicForm.*; import com.iemr.common.repository.dynamic_form.FieldRepository; import com.iemr.common.repository.dynamic_form.FormRepository; import com.iemr.common.repository.dynamic_form.ModuleRepository; +import com.iemr.common.repository.translation.TranslationRepo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.type.TypeReference; @@ -28,6 +30,9 @@ public class FormMasterServiceImpl implements FormMasterService { @Autowired private FormRepository formRepo; @Autowired private FieldRepository fieldRepo; + @Autowired + private TranslationRepo translationRepo; + @Override public FormModule createModule(ModuleDTO dto) { FormModule module = new FormModule(); @@ -98,7 +103,7 @@ public FormField updateField(FieldDTO dto) { } @Override - public FormResponseDTO getStructuredFormByFormId(String formId) { + public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { FormDefinition form = formRepo.findByFormId(formId) .orElseThrow(() -> new IllegalArgumentException("Invalid form ID")); @@ -107,13 +112,28 @@ public FormResponseDTO getStructuredFormByFormId(String formId) { List fieldDtos = fields.stream() .map(field -> { + String labelKey = field.getLabel(); // field label already contains label_key + + Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) + .orElse(null); + + String translatedLabel = labelKey; // fallback + + if (t != null) { + if ("hi".equalsIgnoreCase(lang)) { + translatedLabel = t.getHindiTranslation(); + } else { + translatedLabel = t.getEnglish(); + } + } + FieldResponseDTO dto = new FieldResponseDTO(); dto.setId(field.getId()); dto.setVisible(field.getIsVisible()); dto.setFormId(field.getForm().getFormId()); dto.setSectionTitle(field.getSectionTitle()); dto.setFieldId(field.getFieldId()); - dto.setLabel(field.getLabel()); + dto.setLabel(translatedLabel); dto.setType(field.getType()); dto.setIsRequired(field.getIsRequired()); dto.setDefaultValue(field.getDefaultValue()); From c66861047bff6312ee7090e2b14e414fae380df5 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 16:27:55 +0530 Subject: [PATCH 290/318] fix strict-origin-when-cross-origin --- src/main/environment/common_ci.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index e2ab08ad..a6451109 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -174,7 +174,7 @@ grievanceUserAuthenticate = @env.GRIEVANCE_USER_AUTHENTICATE@ grievanceDataSyncDuration = @env.GRIEVANCE_DATA_SYNC_DURATION@ springdoc.api-docs.enabled=@env.SWAGGER_DOC_ENABLED@ -springdoc.swagger-ui.enabled=@env.SWAGGER_UI_ENABLED@ +springdoc.swagger-ui.enabled=@env.SWAGGER_DOC_ENABLED@ isProduction=@env.IS_PRODUCTION@ From 9324652fcc11313ec21b3fc3fda61379d087cbf9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 17:21:51 +0530 Subject: [PATCH 291/318] fix strict-origin-when-cross-origin --- src/main/environment/common_docker.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/environment/common_docker.properties b/src/main/environment/common_docker.properties index ba22283b..1035af57 100644 --- a/src/main/environment/common_docker.properties +++ b/src/main/environment/common_docker.properties @@ -171,7 +171,7 @@ grievanceUserAuthenticate = ${GRIEVANCE_USER_AUTHENTICATE} grievanceDataSyncDuration = ${GRIEVANCE_DATA_SYNC_DURATION} springdoc.api-docs.enabled=${SWAGGER_DOC_ENABLED} -springdoc.swagger-ui.enabled=${SWAGGER_UI_ENABLED} +springdoc.swagger-ui.enabled=${SWAGGER_DOC_ENABLED} isProduction=${IS_PRODUCTION} From 168291aacb737b74b3c7ead33ccb47cdf92bbb71 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 17:50:47 +0530 Subject: [PATCH 292/318] fix strict-origin-when-cross-origin --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index c4719809..aa5b9bed 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -112,7 +112,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { List fieldDtos = fields.stream() .map(field -> { - String labelKey = field.getLabel(); // field label already contains label_key + String labelKey = field.getFieldId(); // field label already contains label_key Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) .orElse(null); From 1121b753a24945283cfae72f01e9cd3df1d160ef Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 7 Nov 2025 17:59:30 +0530 Subject: [PATCH 293/318] fix strict-origin-when-cross-origin --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index aa5b9bed..8e4d4707 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -117,7 +117,7 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { Translation t = translationRepo.findByLabelKeyAndIsActive(labelKey, true) .orElse(null); - String translatedLabel = labelKey; // fallback + String translatedLabel = field.getLabel(); // fallback if (t != null) { if ("hi".equalsIgnoreCase(lang)) { From de6f6b234afa502dbfc85d5809f2359d35bbfe33 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Mon, 10 Nov 2025 17:41:46 +0530 Subject: [PATCH 294/318] fix: amm-1930 wasa-validation added for sms template api --- .../common/controller/sms/SMSController.java | 3 +- .../exception/ValidationExceptionHandler.java | 54 +++++++++ .../common/model/sms/CreateSMSRequest.java | 15 +++ .../model/sms/SMSParameterMapModel.java | 8 ++ .../common/service/sms/SMSServiceImpl.java | 48 ++++++++ .../com/iemr/common/utils/InputSanitizer.java | 110 ++++++++++++++++++ 6 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iemr/common/exception/ValidationExceptionHandler.java create mode 100644 src/main/java/com/iemr/common/utils/InputSanitizer.java diff --git a/src/main/java/com/iemr/common/controller/sms/SMSController.java b/src/main/java/com/iemr/common/controller/sms/SMSController.java index ee985947..9bacf5b1 100644 --- a/src/main/java/com/iemr/common/controller/sms/SMSController.java +++ b/src/main/java/com/iemr/common/controller/sms/SMSController.java @@ -24,6 +24,7 @@ import java.util.Arrays; import javax.ws.rs.core.MediaType; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,7 +102,7 @@ public String getFullSMSTemplate( @Operation(summary = "Save SMS template") @PostMapping(value = "/saveSMSTemplate", produces = MediaType.APPLICATION_JSON, headers = "Authorization") public String saveSMSTemplate( - @Param(value = "\"{\\\"createdBy\\\":\\\"String\\\",\\\"providerServiceMapID\\\":\\\"String\\\",\\\"smsParameterMaps\\\":\\\"String\\\",\\\"smsTemplate\\\":\\\"String\\\",\\\"smsTemplateName\\\":\\\"String\\\",\\\"smsTypeID\\\":\\\"Integer\\\"}\"") @RequestBody CreateSMSRequest request, + @Param(value = "\"{\\\"createdBy\\\":\\\"String\\\",\\\"providerServiceMapID\\\":\\\"String\\\",\\\"smsParameterMaps\\\":\\\"String\\\",\\\"smsTemplate\\\":\\\"String\\\",\\\"smsTemplateName\\\":\\\"String\\\",\\\"smsTypeID\\\":\\\"Integer\\\"}\"") @Valid @RequestBody CreateSMSRequest request, HttpServletRequest serverRequest) { OutputResponse response = new OutputResponse(); logger.info("saveSMSTemplate received request"); diff --git a/src/main/java/com/iemr/common/exception/ValidationExceptionHandler.java b/src/main/java/com/iemr/common/exception/ValidationExceptionHandler.java new file mode 100644 index 00000000..750d221c --- /dev/null +++ b/src/main/java/com/iemr/common/exception/ValidationExceptionHandler.java @@ -0,0 +1,54 @@ +package com.iemr.common.exception; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.HashMap; +import java.util.Map; + +@RestControllerAdvice +public class ValidationExceptionHandler { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationErrors(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.put(fieldName, errorMessage); + }); + + logger.error("Validation failed: {}", errors); + + Map response = new HashMap<>(); + response.put("status", "ERROR"); + response.put("statusCode", 5000); + response.put("errorMessage", "Input validation failed"); + response.put("errors", errors); + + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(IllegalArgumentException.class) + public ResponseEntity> handleIllegalArgument(IllegalArgumentException ex) { + logger.error("Illegal argument: {}", ex.getMessage()); + + Map response = new HashMap<>(); + response.put("status", "ERROR"); + response.put("statusCode", 5000); + response.put("errorMessage", ex.getMessage()); + + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } +} + + diff --git a/src/main/java/com/iemr/common/model/sms/CreateSMSRequest.java b/src/main/java/com/iemr/common/model/sms/CreateSMSRequest.java index 358730c9..774a8517 100644 --- a/src/main/java/com/iemr/common/model/sms/CreateSMSRequest.java +++ b/src/main/java/com/iemr/common/model/sms/CreateSMSRequest.java @@ -23,17 +23,32 @@ import java.util.List; +import jakarta.validation.Valid; +import jakarta.validation.constraints.*; import lombok.Data; @Data public class CreateSMSRequest { Integer smsTemplateID; + @NotBlank(message = "SMS template name is required") + @Size(min = 3, max = 100, message = "Template name must be between 3 and 100 characters") + @Pattern(regexp = "^[a-zA-Z0-9_\\s-]+$", + message = "Template name can only contain alphanumeric characters, spaces, hyphens and underscores") String smsTemplateName; + @NotBlank(message = "SMS template content is required") + @Size(min = 10, max = 500, message = "Template content must be between 10 and 500 characters") + @Pattern(regexp = "^[^<>]*$", + message = "Template cannot contain < or > characters") String smsTemplate; Integer smsTypeID; SMSTypeModel smsType; + @NotNull(message = "Provider service map ID is required") + @Positive(message = "Provider service map ID must be positive") Integer providerServiceMapID; String createdBy; + @Valid + @NotEmpty(message = "At least one SMS parameter is required") + @Size(max = 20, message = "Maximum 20 parameters allowed") List smsParameterMaps; } diff --git a/src/main/java/com/iemr/common/model/sms/SMSParameterMapModel.java b/src/main/java/com/iemr/common/model/sms/SMSParameterMapModel.java index 032e90d2..fb9133e7 100644 --- a/src/main/java/com/iemr/common/model/sms/SMSParameterMapModel.java +++ b/src/main/java/com/iemr/common/model/sms/SMSParameterMapModel.java @@ -21,6 +21,7 @@ */ package com.iemr.common.model.sms; +import jakarta.validation.constraints.*; import lombok.Data; @Data @@ -30,7 +31,14 @@ public class SMSParameterMapModel Integer smsTemplateID; String createdBy; String modifiedBy; + @Size(max = 200, message = "Parameter value must not exceed 200 characters") + @Pattern(regexp = "^[^<>\"';&|`$(){}\\[\\]]*$", + message = "Parameter value contains invalid characters") String smsParameterValue; + @NotBlank(message = "Parameter name is required") + @Size(min = 2, max = 50, message = "Parameter name must be between 2 and 50 characters") + @Pattern(regexp = "^[a-zA-Z][a-zA-Z0-9_]*$", + message = "Parameter name must start with a letter and contain only alphanumeric and underscore") String smsParameterName; String smsParameterType; } diff --git a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java index 022fd1f8..af9cbf1c 100644 --- a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java +++ b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java @@ -104,10 +104,12 @@ import com.iemr.common.repository.videocall.VideoCallParameterRepository; import com.iemr.common.service.beneficiary.IEMRSearchUserService; import com.iemr.common.utils.CryptoUtil; +import com.iemr.common.utils.InputSanitizer; import com.iemr.common.utils.config.ConfigProperties; import com.iemr.common.utils.http.HttpUtils; import com.iemr.common.utils.mapper.OutputMapper; //import java.util.Date; +import org.springframework.transaction.annotation.Transactional; @Service public class SMSServiceImpl implements SMSService { @@ -206,7 +208,14 @@ public String updateSMSTemplate(UpdateSMSRequest smsRequest) throws Exception { } @Override + @Transactional(rollbackFor = Exception.class) public String saveSMSTemplate(CreateSMSRequest smsRequest) throws Exception { + // Sanitize inputs before processing + sanitizeInputs(smsRequest); + // Validate template syntax + if (!InputSanitizer.isValidTemplateParameter(smsRequest.getSmsTemplate())) { + throw new IllegalArgumentException("Template contains invalid parameter syntax"); + } SMSTemplate smsTemplate; SMSTemplate request = smsMapper.createRequestToSMSTemplate(smsRequest); smsTemplate = smsTemplateRepository.save(request); @@ -214,6 +223,45 @@ public String saveSMSTemplate(CreateSMSRequest smsRequest) throws Exception { smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplate.getSmsTemplateID()); return OutputMapper.gsonWithoutExposeRestriction().toJson(smsMapper.smsTemplateToResponse(smsTemplate)); } + + /** + * Sanitize all inputs to prevent XSS, SQL injection, and command injection + */ + private void sanitizeInputs(CreateSMSRequest smsRequest) { + logger.debug("Sanitizing SMS template request inputs"); + + // Sanitize template name + if (smsRequest.getSmsTemplateName() != null) { + smsRequest.setSmsTemplateName( + InputSanitizer.sanitize(smsRequest.getSmsTemplateName()) + ); + } + + // Sanitize template content (preserve ${} but remove dangerous chars) + if (smsRequest.getSmsTemplate() != null) { + smsRequest.setSmsTemplate( + InputSanitizer.sanitizeForXSS(smsRequest.getSmsTemplate()) + ); + } + + // Sanitize parameter maps + if (smsRequest.getSmsParameterMaps() != null) { + for (SMSParameterMapModel param : smsRequest.getSmsParameterMaps()) { + if (param.getSmsParameterName() != null) { + param.setSmsParameterName( + InputSanitizer.sanitize(param.getSmsParameterName()) + ); + } + if (param.getSmsParameterValue() != null) { + param.setSmsParameterValue( + InputSanitizer.sanitize(param.getSmsParameterValue()) + ); + } + } + } + + logger.debug("Input sanitization completed"); + } private void saveSMSParameterMaps(CreateSMSRequest smsRequest, Integer smsTemplateID) { List smsParameterMapModels = smsRequest.getSmsParameterMaps(); diff --git a/src/main/java/com/iemr/common/utils/InputSanitizer.java b/src/main/java/com/iemr/common/utils/InputSanitizer.java new file mode 100644 index 00000000..8c67f4fb --- /dev/null +++ b/src/main/java/com/iemr/common/utils/InputSanitizer.java @@ -0,0 +1,110 @@ +package com.iemr.common.utils; + +import org.springframework.web.util.HtmlUtils; + +/** + * Utility class for sanitizing user inputs to prevent XSS, SQL Injection, and Command Injection + */ +public class InputSanitizer { + + // Characters that are dangerous for XSS + private static final String[] XSS_PATTERNS = { + "", "javascript:", "onerror=", "onload=", + "", "<", "\\", "\n", "\r" + }; + + /** + * Sanitize input to prevent XSS attacks + * @param input User input string + * @return Sanitized string with HTML entities encoded + */ + public static String sanitizeForXSS(String input) { + if (input == null || input.trim().isEmpty()) { + return input; + } + + // HTML encode to neutralize XSS + String sanitized = HtmlUtils.htmlEscape(input); + + // Additional check for common XSS patterns (case-insensitive) + String lowerInput = sanitized.toLowerCase(); + for (String pattern : XSS_PATTERNS) { + if (lowerInput.contains(pattern.toLowerCase())) { + // Remove the dangerous pattern + sanitized = sanitized.replaceAll("(?i)" + pattern, ""); + } + } + + return sanitized; + } + + /** + * Sanitize input to prevent command injection + * Removes shell metacharacters + * @param input User input string + * @return Sanitized string + */ + public static String sanitizeForCommandInjection(String input) { + if (input == null || input.trim().isEmpty()) { + return input; + } + + String sanitized = input; + + // Remove dangerous command injection characters + for (String dangerChar : COMMAND_INJECTION_CHARS) { + sanitized = sanitized.replace(dangerChar, ""); + } + + return sanitized; + } + + /** + * Comprehensive sanitization for general text input + * Combines XSS and command injection protection + * @param input User input string + * @return Sanitized string + */ + public static String sanitize(String input) { + if (input == null) { + return null; + } + + // First remove command injection chars, then sanitize XSS + String sanitized = sanitizeForCommandInjection(input); + sanitized = sanitizeForXSS(sanitized); + + return sanitized.trim(); + } + + /** + * Validate that template parameter syntax is safe + * Allows ${paramName} but prevents ${`command`} style injections + * @param template Template string + * @return true if template is safe + */ + public static boolean isValidTemplateParameter(String template) { + if (template == null || template.trim().isEmpty()) { + return false; + } + + // Check for command injection attempts in template parameters + // Valid: ${userName}, ${age} + // Invalid: ${`ls`}, ${$(whoami)}, ${;rm -rf} + + if (template.contains("${`") || template.contains("$(`") || + template.contains("${$(") || template.contains("${;")) { + return false; + } + + return true; + } +} + + From 19239f845eae4f33cea5aab7a7eee472a928024d Mon Sep 17 00:00:00 2001 From: SnehaRH Date: Tue, 11 Nov 2025 13:05:37 +0530 Subject: [PATCH 295/318] fix: amm-1931 JWT token reduced expiry timing --- src/main/java/com/iemr/common/utils/CookieUtil.java | 4 ++-- src/main/resources/application.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/CookieUtil.java b/src/main/java/com/iemr/common/utils/CookieUtil.java index 12da4137..92c071c5 100644 --- a/src/main/java/com/iemr/common/utils/CookieUtil.java +++ b/src/main/java/com/iemr/common/utils/CookieUtil.java @@ -35,8 +35,8 @@ public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response, H // Make the cookie HttpOnly to prevent JavaScript access for security cookie.setHttpOnly(true); - // Set the Max-Age (expiry time) in seconds (1 day) - cookie.setMaxAge(60 * 60 * 24); // 1 day expiration + // Set the Max-Age (expiry time) in seconds (8 hours) + cookie.setMaxAge(60 * 60 * 8); // 8 hours expiration // Set the path to "/" so the cookie is available across the entire application cookie.setPath("/"); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 886eb969..d57801bd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -170,7 +170,7 @@ quality-Audit-PageSize=5 failedLoginAttempt=5 #Jwt Token configuration -jwt.access.expiration=86400000 +jwt.access.expiration=28800000 jwt.refresh.expiration=604800000 # local env From ddee5bd1515f9b273ee51cc460916c9783b591b8 Mon Sep 17 00:00:00 2001 From: Amoghavarsh <93114621+5Amogh@users.noreply.github.com> Date: Wed, 12 Nov 2025 12:52:19 +0530 Subject: [PATCH 296/318] Bump version from 3.6.0 to 3.6.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 18b50f33..25b8da59 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.6.0 + 3.6.1 war Common-API From e41a47e5aeaec2dd38930a31aadc0813f87374a6 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Wed, 12 Nov 2025 17:47:05 +0530 Subject: [PATCH 297/318] fix: amm-1927 http options vulnerability fixed through cors --- .../com/iemr/common/config/CorsConfig.java | 15 ++- .../utils/JwtUserIdValidationFilter.java | 113 ++++++++++++++++-- .../utils/http/HTTPRequestInterceptor.java | 37 +++++- 3 files changed, 151 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index 2e226b79..f711eb49 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -12,6 +12,19 @@ public class CorsConfig implements WebMvcConfigurer { @Value("${cors.allowed-origins}") private String allowedOrigins; + /** + * Spring MVC CORS configuration (framework level). + * + * NOTE: This configuration is permissive at the Spring framework level. + * Actual granular CORS enforcement (origin validation, endpoint-specific method control) + * is handled by JwtUserIdValidationFilter, which implements a two-layer security approach: + * + * 1. Spring CORS config: Permissive at framework level (allows PUT/DELETE for all endpoints) + * 2. JwtUserIdValidationFilter: Enforces strict origin validation and endpoint-specific method restrictions + * + * This design allows Spring to handle CORS preflight requests, while the filter enforces + * security policies before requests reach controllers. + */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") @@ -20,7 +33,7 @@ public void addCorsMappings(CorsRegistry registry) { .map(String::trim) .toArray(String[]::new)) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") - .allowedHeaders("*") + .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken") .exposedHeaders("Authorization", "Jwttoken") .allowCredentials(true) .maxAge(3600); diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 16466ee5..f708c633 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -2,6 +2,10 @@ import java.io.IOException; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,6 +27,21 @@ public class JwtUserIdValidationFilter implements Filter { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private final String allowedOrigins; + // Default allowed methods for unconfigured endpoints + private static final Set DEFAULT_ALLOWED_METHODS = Set.of("GET", "POST", "OPTIONS"); + + // Endpoint-specific method control map + // Key = endpoint path pattern (supports wildcards), Value = Set of allowed HTTP methods + private static final Map> ENDPOINT_ALLOWED_METHODS = new HashMap<>(); + + static { + Set dynamicFormMethods = new HashSet<>(); + dynamicFormMethods.add("GET"); + dynamicFormMethods.add("POST"); + dynamicFormMethods.add("DELETE"); + ENDPOINT_ALLOWED_METHODS.put("/dynamicForm/delete/*/field", dynamicFormMethods); + } + public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil, String allowedOrigins) { this.jwtAuthenticationUtil = jwtAuthenticationUtil; @@ -36,27 +55,68 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo HttpServletResponse response = (HttpServletResponse) servletResponse; String origin = request.getHeader("Origin"); + String method = request.getMethod(); + String uri = request.getRequestURI(); logger.debug("Incoming Origin: {}", origin); + logger.debug("Request Method: {}", method); + logger.debug("Request URI: {}", uri); logger.debug("Allowed Origins Configured: {}", allowedOrigins); - logger.info("Add server authorization header to response"); + + // STEP 1: STRICT Origin Validation - Block unauthorized origins immediately + // For OPTIONS requests, Origin header is required (CORS preflight) + if ("OPTIONS".equalsIgnoreCase(method)) { + if (origin == null) { + logger.warn("BLOCKED - OPTIONS request without Origin header | Method: {} | URI: {}", method, uri); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "OPTIONS request requires Origin header"); + return; + } + if (!isOriginAllowed(origin)) { + logger.warn("BLOCKED - Unauthorized Origin | Origin: {} | Method: {} | URI: {}", origin, method, uri); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Origin not allowed"); + return; + } + } else { + // For non-OPTIONS requests, validate origin if present + if (origin != null && !isOriginAllowed(origin)) { + logger.warn("BLOCKED - Unauthorized Origin | Origin: {} | Method: {} | URI: {}", origin, method, uri); + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Origin not allowed"); + return; + } + } + + // STEP 2: Endpoint-Specific Method Validation + String path = request.getRequestURI(); + String contextPath = request.getContextPath(); + String relativePath = path.startsWith(contextPath) ? path.substring(contextPath.length()) : path; + + Set allowedMethods = getAllowedMethodsForEndpoint(relativePath); + if (!allowedMethods.contains(method.toUpperCase())) { + logger.warn("BLOCKED - Method Not Allowed | Method: {} | URI: {} | Allowed Methods: {}", + method, uri, allowedMethods); + response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, + "Method " + method + " not allowed for this endpoint"); + return; + } + + // STEP 3: Add CORS Headers (only for validated origins) if (origin != null && isOriginAllowed(origin)) { - response.setHeader("Access-Control-Allow-Origin", origin); - response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); - response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, Jwttoken, serverAuthorization, ServerAuthorization, serverauthorization, Serverauthorization"); + response.setHeader("Access-Control-Allow-Origin", origin); // Never use wildcard + response.setHeader("Access-Control-Allow-Methods", String.join(", ", allowedMethods) + ", OPTIONS"); + response.setHeader("Access-Control-Allow-Headers", + "Authorization, Content-Type, Accept, Jwttoken, serverAuthorization, ServerAuthorization, serverauthorization, Serverauthorization"); response.setHeader("Access-Control-Allow-Credentials", "true"); - } else { - logger.warn("Origin [{}] is NOT allowed. CORS headers NOT added.", origin); + response.setHeader("Access-Control-Max-Age", "3600"); + logger.info("Origin Validated | Origin: {} | Method: {} | URI: {}", origin, method, uri); } - if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { - logger.info("OPTIONS request - skipping JWT validation"); + // STEP 4: Handle OPTIONS Preflight Request + if ("OPTIONS".equalsIgnoreCase(method)) { + logger.info("OPTIONS preflight request - skipping JWT validation"); response.setStatus(HttpServletResponse.SC_OK); return; } - String path = request.getRequestURI(); - String contextPath = request.getContextPath(); logger.info("JwtUserIdValidationFilter invoked for path: " + path); // Log cookies for debugging @@ -73,8 +133,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo } // Log headers for debugging - String jwtTokenFromHeader = request.getHeader("Jwttoken"); - logger.info("JWT token from header: "); + logger.debug("JWT token from header: {}", request.getHeader("Jwttoken") != null ? "present" : "not present"); // Skip authentication for public endpoints if (shouldSkipAuthentication(path, contextPath)) { @@ -146,6 +205,36 @@ private boolean isOriginAllowed(String origin) { }); } + /** + * Get allowed HTTP methods for a given endpoint path. + * Checks against ENDPOINT_ALLOWED_METHODS map with wildcard support. + * Returns DEFAULT_ALLOWED_METHODS if endpoint is not configured. + * + * @param endpointPath The endpoint path (relative, without context path) + * @return Set of allowed HTTP methods for this endpoint + */ + private Set getAllowedMethodsForEndpoint(String endpointPath) { + // Check exact match first + if (ENDPOINT_ALLOWED_METHODS.containsKey(endpointPath)) { + return ENDPOINT_ALLOWED_METHODS.get(endpointPath); + } + + // Check wildcard patterns (e.g., /dynamicForm/delete/*/field) + for (Map.Entry> entry : ENDPOINT_ALLOWED_METHODS.entrySet()) { + String pattern = entry.getKey(); + // Convert wildcard pattern to regex: escape special chars, then replace * with [^/]+ + String regex = pattern + .replace(".", "\\.") + .replace("*", "[^/]+"); // * matches one or more non-slash characters + if (endpointPath.matches(regex)) { + return entry.getValue(); + } + } + + // Default: only GET, POST, OPTIONS allowed + return DEFAULT_ALLOWED_METHODS; + } + private boolean isMobileClient(String userAgent) { if (userAgent == null) return false; diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 1c322dc4..375f02a8 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -22,11 +22,13 @@ package com.iemr.common.utils.http; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import javax.ws.rs.core.MediaType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; @@ -45,6 +47,9 @@ public class HTTPRequestInterceptor implements HandlerInterceptor { Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + @Value("${cors.allowed-origins}") + private String allowedOrigins; + @Autowired public void setValidator(Validator validator) { this.validator = validator; @@ -140,7 +145,14 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 response.setContentType(MediaType.APPLICATION_JSON); - response.setHeader("Access-Control-Allow-Origin", "*"); + + String origin = request.getHeader("Origin"); + if (origin != null && isOriginAllowed(origin)) { + response.setHeader("Access-Control-Allow-Origin", origin); + response.setHeader("Access-Control-Allow-Credentials", "true"); + } else if (origin != null) { + logger.warn("CORS headers NOT added for error response | Unauthorized origin: {}", origin); + } // Better to use getBytes().length for accurate byte size byte[] responseBytes = jsonErrorResponse.getBytes(StandardCharsets.UTF_8); @@ -182,4 +194,27 @@ public void afterCompletion(HttpServletRequest request, HttpServletResponse resp throws Exception { logger.debug("In afterCompletion Request Completed"); } + + /** + * Check if the given origin is allowed based on configured allowedOrigins. + * Uses the same logic as JwtUserIdValidationFilter for consistency. + * + * @param origin The origin to validate + * @return true if origin is allowed, false otherwise + */ + private boolean isOriginAllowed(String origin) { + if (origin == null || allowedOrigins == null || allowedOrigins.trim().isEmpty()) { + return false; + } + + return Arrays.stream(allowedOrigins.split(",")) + .map(String::trim) + .anyMatch(pattern -> { + String regex = pattern + .replace(".", "\\.") + .replace("*", ".*") + .replace("http://localhost:.*", "http://localhost:\\d+"); // special case for wildcard port + return origin.matches(regex); + }); + } } From 4081825fdac5fe81c3fdc54e4500c8b743781d0f Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 13 Nov 2025 10:13:27 +0530 Subject: [PATCH 298/318] fix: amm 1927 implementing suggested code fixes by coderabbit --- src/main/java/com/iemr/common/config/CorsConfig.java | 3 ++- .../com/iemr/common/utils/JwtUserIdValidationFilter.java | 8 ++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index f711eb49..fea2cc04 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -33,7 +33,8 @@ public void addCorsMappings(CorsRegistry registry) { .map(String::trim) .toArray(String[]::new)) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") - .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken") + .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken", + "serverAuthorization", "ServerAuthorization", "serverauthorization", "Serverauthorization") .exposedHeaders("Authorization", "Jwttoken") .allowCredentials(true) .maxAge(3600); diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index f708c633..8a8cb453 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -35,11 +34,8 @@ public class JwtUserIdValidationFilter implements Filter { private static final Map> ENDPOINT_ALLOWED_METHODS = new HashMap<>(); static { - Set dynamicFormMethods = new HashSet<>(); - dynamicFormMethods.add("GET"); - dynamicFormMethods.add("POST"); - dynamicFormMethods.add("DELETE"); - ENDPOINT_ALLOWED_METHODS.put("/dynamicForm/delete/*/field", dynamicFormMethods); + ENDPOINT_ALLOWED_METHODS.put("/dynamicForm/delete/*/field", + Set.of("GET", "POST", "DELETE")); } public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil, From 6112133c36ba9b6a20bc10a69b64248b1a9c07e6 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 13 Nov 2025 10:46:17 +0530 Subject: [PATCH 299/318] fix: amm 1927 removal of hardcoded localhost part --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 3 +-- .../com/iemr/common/utils/http/HTTPRequestInterceptor.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 8a8cb453..71688e4d 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -193,8 +193,7 @@ private boolean isOriginAllowed(String origin) { .anyMatch(pattern -> { String regex = pattern .replace(".", "\\.") - .replace("*", ".*") - .replace("http://localhost:.*", "http://localhost:\\d+"); // special case for wildcard port + .replace("*", ".*"); boolean matched = origin.matches(regex); return matched; diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 375f02a8..0c609839 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -212,8 +212,7 @@ private boolean isOriginAllowed(String origin) { .anyMatch(pattern -> { String regex = pattern .replace(".", "\\.") - .replace("*", ".*") - .replace("http://localhost:.*", "http://localhost:\\d+"); // special case for wildcard port + .replace("*", ".*"); return origin.matches(regex); }); } From 106515c424606b6086b212560fe61dfd3bd983c6 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 13 Nov 2025 12:37:56 +0530 Subject: [PATCH 300/318] fix: amm 1927 removal of restrictive pattern for options & sticking REST API standards --- .../com/iemr/common/config/CorsConfig.java | 20 +------ .../utils/JwtUserIdValidationFilter.java | 60 +++---------------- 2 files changed, 11 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index fea2cc04..fdd9b494 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -11,20 +11,6 @@ public class CorsConfig implements WebMvcConfigurer { @Value("${cors.allowed-origins}") private String allowedOrigins; - - /** - * Spring MVC CORS configuration (framework level). - * - * NOTE: This configuration is permissive at the Spring framework level. - * Actual granular CORS enforcement (origin validation, endpoint-specific method control) - * is handled by JwtUserIdValidationFilter, which implements a two-layer security approach: - * - * 1. Spring CORS config: Permissive at framework level (allows PUT/DELETE for all endpoints) - * 2. JwtUserIdValidationFilter: Enforces strict origin validation and endpoint-specific method restrictions - * - * This design allows Spring to handle CORS preflight requests, while the filter enforces - * security policies before requests reach controllers. - */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") @@ -32,9 +18,9 @@ public void addCorsMappings(CorsRegistry registry) { Arrays.stream(allowedOrigins.split(",")) .map(String::trim) .toArray(String[]::new)) - .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") - .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken", - "serverAuthorization", "ServerAuthorization", "serverauthorization", "Serverauthorization") + .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS") + .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken", + "serverAuthorization", "ServerAuthorization", "serverauthorization", "Serverauthorization") .exposedHeaders("Authorization", "Jwttoken") .allowCredentials(true) .maxAge(3600); diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 71688e4d..412352fc 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -26,17 +26,6 @@ public class JwtUserIdValidationFilter implements Filter { private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private final String allowedOrigins; - // Default allowed methods for unconfigured endpoints - private static final Set DEFAULT_ALLOWED_METHODS = Set.of("GET", "POST", "OPTIONS"); - - // Endpoint-specific method control map - // Key = endpoint path pattern (supports wildcards), Value = Set of allowed HTTP methods - private static final Map> ENDPOINT_ALLOWED_METHODS = new HashMap<>(); - - static { - ENDPOINT_ALLOWED_METHODS.put("/dynamicForm/delete/*/field", - Set.of("GET", "POST", "DELETE")); - } public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil, String allowedOrigins) { @@ -81,24 +70,14 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo } } - // STEP 2: Endpoint-Specific Method Validation + // Determine request path/context for later checks String path = request.getRequestURI(); String contextPath = request.getContextPath(); - String relativePath = path.startsWith(contextPath) ? path.substring(contextPath.length()) : path; - - Set allowedMethods = getAllowedMethodsForEndpoint(relativePath); - if (!allowedMethods.contains(method.toUpperCase())) { - logger.warn("BLOCKED - Method Not Allowed | Method: {} | URI: {} | Allowed Methods: {}", - method, uri, allowedMethods); - response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, - "Method " + method + " not allowed for this endpoint"); - return; - } // STEP 3: Add CORS Headers (only for validated origins) if (origin != null && isOriginAllowed(origin)) { response.setHeader("Access-Control-Allow-Origin", origin); // Never use wildcard - response.setHeader("Access-Control-Allow-Methods", String.join(", ", allowedMethods) + ", OPTIONS"); + response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, Jwttoken, serverAuthorization, ServerAuthorization, serverauthorization, Serverauthorization"); response.setHeader("Access-Control-Allow-Credentials", "true"); @@ -108,7 +87,12 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo // STEP 4: Handle OPTIONS Preflight Request if ("OPTIONS".equalsIgnoreCase(method)) { - logger.info("OPTIONS preflight request - skipping JWT validation"); + // OPTIONS (preflight) - respond with full allowed methods + response.setHeader("Access-Control-Allow-Origin", origin); + response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS"); + response.setHeader("Access-Control-Allow-Headers", + "Authorization, Content-Type, Accept, Jwttoken, serverAuthorization, ServerAuthorization, serverauthorization, Serverauthorization"); + response.setHeader("Access-Control-Allow-Credentials", "true"); response.setStatus(HttpServletResponse.SC_OK); return; } @@ -200,35 +184,7 @@ private boolean isOriginAllowed(String origin) { }); } - /** - * Get allowed HTTP methods for a given endpoint path. - * Checks against ENDPOINT_ALLOWED_METHODS map with wildcard support. - * Returns DEFAULT_ALLOWED_METHODS if endpoint is not configured. - * - * @param endpointPath The endpoint path (relative, without context path) - * @return Set of allowed HTTP methods for this endpoint - */ - private Set getAllowedMethodsForEndpoint(String endpointPath) { - // Check exact match first - if (ENDPOINT_ALLOWED_METHODS.containsKey(endpointPath)) { - return ENDPOINT_ALLOWED_METHODS.get(endpointPath); - } - - // Check wildcard patterns (e.g., /dynamicForm/delete/*/field) - for (Map.Entry> entry : ENDPOINT_ALLOWED_METHODS.entrySet()) { - String pattern = entry.getKey(); - // Convert wildcard pattern to regex: escape special chars, then replace * with [^/]+ - String regex = pattern - .replace(".", "\\.") - .replace("*", "[^/]+"); // * matches one or more non-slash characters - if (endpointPath.matches(regex)) { - return entry.getValue(); - } - } - // Default: only GET, POST, OPTIONS allowed - return DEFAULT_ALLOWED_METHODS; - } private boolean isMobileClient(String userAgent) { if (userAgent == null) From 8a9569407a97168014acb38349dcecc7479ffe9f Mon Sep 17 00:00:00 2001 From: SnehaRH Date: Thu, 13 Nov 2025 16:37:35 +0530 Subject: [PATCH 301/318] fix: amm-1929 username and passwords are passed plain --- .../java/com/iemr/common/service/cti/CTIServiceImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java index 9a792699..5a69abdd 100644 --- a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java +++ b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java @@ -56,6 +56,7 @@ import com.iemr.common.repository.callhandling.BeneficiaryCallRepository; import com.iemr.common.repository.callhandling.IEMRCalltypeRepositoryImplCustom; import com.iemr.common.utils.config.ConfigProperties; +import com.iemr.common.utils.encryption.AESUtil; import com.iemr.common.utils.exception.IEMRException; import com.iemr.common.utils.http.HttpUtils; import com.iemr.common.utils.mapper.InputMapper; @@ -81,6 +82,9 @@ public class CTIServiceImpl implements CTIService { private static final String CUSTOM_API_FAILURE = "0"; private static final String DEFAULT_IP = "0.0.0.0"; + + private AESUtil aesUtil; + @Autowired private BeneficiaryCallRepository beneficiaryCallRepository; @@ -290,9 +294,12 @@ public OutputResponse getLoginKey(String request, String ipAddress) throws IEMRE String serverURL = ConfigProperties.getPropertyByName("cti-server-ip"); AgentLoginKey agentState = objectMapper.readValue(request, AgentLoginKey.class); + String decryptPassword = aesUtil.decrypt("Piramal12Piramal", agentState.getPassword()); + + ctiURI = ctiURI.replace("CTI_SERVER", serverURL); ctiURI = ctiURI.replace("USERNAME", (agentState.getUsername() != null) ? agentState.getUsername() : ""); - ctiURI = ctiURI.replace("PASSWORD", (agentState.getPassword() != null) ? agentState.getPassword() : ""); + ctiURI = ctiURI.replace("PASSWORD", (decryptPassword != null) ? decryptPassword : ""); logger.info("calling URL " + ctiURI); ctiURI = ctiURI.replace("AGENT_IP", ipAddress); String response = this.callUrl(ctiURI);// httpUtils.get(ctiURI); From a51d44198080b80e108d40db601cca3ee00bac72 Mon Sep 17 00:00:00 2001 From: SnehaRH Date: Thu, 13 Nov 2025 20:40:51 +0530 Subject: [PATCH 302/318] fix: amm-1929 removed hardcoded decrypted value --- .../com/iemr/common/service/cti/CTIServiceImpl.java | 11 ++++++++--- src/main/resources/application.properties | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java index 5a69abdd..81d8953a 100644 --- a/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java +++ b/src/main/java/com/iemr/common/service/cti/CTIServiceImpl.java @@ -83,6 +83,7 @@ public class CTIServiceImpl implements CTIService { private static final String DEFAULT_IP = "0.0.0.0"; + @Autowired private AESUtil aesUtil; @@ -294,9 +295,13 @@ public OutputResponse getLoginKey(String request, String ipAddress) throws IEMRE String serverURL = ConfigProperties.getPropertyByName("cti-server-ip"); AgentLoginKey agentState = objectMapper.readValue(request, AgentLoginKey.class); - String decryptPassword = aesUtil.decrypt("Piramal12Piramal", agentState.getPassword()); - - + String decryptPassword = null; + + String passphrase = ConfigProperties.getPropertyByName("encryption.passphrase"); + + decryptPassword = aesUtil.decrypt(passphrase, agentState.getPassword()); + + ctiURI = ctiURI.replace("CTI_SERVER", serverURL); ctiURI = ctiURI.replace("USERNAME", (agentState.getUsername() != null) ? agentState.getUsername() : ""); ctiURI = ctiURI.replace("PASSWORD", (decryptPassword != null) ? decryptPassword : ""); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d57801bd..427754c5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -193,6 +193,9 @@ cti-server-ip=10.208.122.99 cti-logger_base_url=http://10.208.122.99/logger sms-gateway-url = +#Encryption passphrase used by AESUtil for decrypting CTI passwords. +encryption.passphrase=Piramal12Piramal + # Identity Config identity-api-url = http://localhost:8094/ #Verify whether 1097 and identity are same? From f45361195453adf7851433c4a1a5a51149ed8bd3 Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:40:37 +0530 Subject: [PATCH 303/318] fix: internal url disclosure (#308) --- .../com/iemr/common/service/scheme/SchemeServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java b/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java index 327c46ba..44e1efaa 100644 --- a/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java +++ b/src/main/java/com/iemr/common/service/scheme/SchemeServiceImpl.java @@ -111,7 +111,9 @@ public String getFilePath(KMFileManager kmFileManager) { fileUIDAsURI = dmsProtocol + "://" + userName + ":" + userPassword + "@" + dmsPath + "/Download?uuid=" + fileUID; } - return fileUIDAsURI; + // return fileUIDAsURI; + String message = kmFileManager.getFileUID() ; + return message; } @Override From ca7bc2e192ba98b40552b7ad9ccbc0876e8e4d7c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 21 Nov 2025 14:08:02 +0530 Subject: [PATCH 304/318] fix strict-origin-when-cross-origin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7e7b29d8..171ab162 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.iemr.common-API common-api - 3.7.0 + 3.6.1 war Common-API From 5b195cfd3bbbde4690e1ceda103b115ba8162a2d Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Fri, 21 Nov 2025 14:36:27 +0530 Subject: [PATCH 305/318] fix strict-origin-when-cross-origin --- .../iemr/common/service/dynamicForm/FormMasterServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java index 8e4d4707..df019de7 100644 --- a/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java +++ b/src/main/java/com/iemr/common/service/dynamicForm/FormMasterServiceImpl.java @@ -170,7 +170,8 @@ public FormResponseDTO getStructuredFormByFormId(String formId,String lang) { } else { dto.setConditional(null); } - } catch (JsonProcessingException e) { + } catch (Exception e) { + System.err.println("JSON Parsing Error in field: " + field.getFieldId()); throw new RuntimeException("Failed to parse JSON for field: " + field.getFieldId(), e); } From e7828c2825bf15e919493f228da460dc7ec616ff Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 24 Nov 2025 17:53:58 +0530 Subject: [PATCH 306/318] fix strict-origin-when-cross-origin --- .../common/controller/dynamicForm/DynamicFormController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java index 4c7f30a8..30a1bc3f 100644 --- a/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java +++ b/src/main/java/com/iemr/common/controller/dynamicForm/DynamicFormController.java @@ -90,8 +90,9 @@ public ResponseEntity> getStructuredForm(@PathVariable String for return ResponseEntity.status(HttpStatus.OK) .body(ApiResponse.success("Form structure fetched successfully", HttpStatus.OK.value(), result)); } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(ApiResponse.error("Failed to fetch form structure:"+e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value(), null)); + .body(ApiResponse.error("Failed to fetch form structure:"+e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value(), e)); } } From 543b022b847c746c4ad924b8d0567bcf5ba16a7f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 26 Nov 2025 10:22:08 +0530 Subject: [PATCH 307/318] add column in create BeneficiaryModel --- .../model/beneficiary/BeneficiaryModel.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java index d61659f0..e7a7a3de 100644 --- a/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java +++ b/src/main/java/com/iemr/common/model/beneficiary/BeneficiaryModel.java @@ -108,6 +108,21 @@ public class BeneficiaryModel implements Comparable { @Expose private String otherPlaceOfDeath; + @Expose + private Boolean isSpouseAdded; + + @Expose + private Boolean isChildrenAdded; + + @Expose + private Boolean isMarried; + + @Expose + private Integer doYouHavechildren; + + @Expose + private Integer noofAlivechildren; + @Expose private String beneficiaryID; @Expose From 19a52910b6e6b8696273a821707b12bc513753b6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 26 Nov 2025 16:19:23 +0530 Subject: [PATCH 308/318] Add UAT domain to allowed CORS origins --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3b400682..d15e828a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901 +cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901,https://uatamrit.piramalswasthya.org video-call-url = From cb2ac7f74bd0d98de1e306c1a549a88dcbd5cf9e Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 26 Nov 2025 16:32:24 +0530 Subject: [PATCH 309/318] Update application.properties --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d15e828a..4c658a0f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,7 +366,7 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origin= http://localhost:*,https://amritdemo.piramalswasthya.org,http://devbox.bizbrolly.com:4901,https://uatamrit.piramalswasthya.org +cors.allowed-origin= https://uatamrit.piramalswasthya.org video-call-url = From a49f09bcaf5228e27a387db81c28d7cdcb3173a6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Wed, 26 Nov 2025 16:33:08 +0530 Subject: [PATCH 310/318] Remove CORS allowed origin from properties Removed allowed origin for CORS configuration. --- src/main/resources/application.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4c658a0f..18723465 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -366,9 +366,6 @@ captcha.secret-key= captcha.verify-url= https://challenges.cloudflare.com/turnstile/v0/siteverify captcha.enable-captcha=false -cors.allowed-origin= https://uatamrit.piramalswasthya.org - - video-call-url = allowed.file.extensions=msg,pdf,png,jpeg,doc,docx,xlsx,xls,csv,txt From 948d72cbebf4dbbf23248abd27e936fba337d818 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 26 Nov 2025 19:29:57 +0530 Subject: [PATCH 311/318] add column in create BeneficiaryModel --- .../beneficiary/RegisterBenificiaryServiceImpl.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java index 54637a4c..7d5f1de0 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/RegisterBenificiaryServiceImpl.java @@ -140,18 +140,7 @@ public Integer updateBenificiary(BeneficiaryModel benificiaryDetails, String aut //updateDeathOfBenificiary(benificiaryDetails); return updatedRows; } - private void updateDeathOfBenificiary(BeneficiaryModel beneficiaryModel){ - RMNCHBeneficiaryDetailsRmnch rmnchBeneficiaryDetailsRmnch = new RMNCHBeneficiaryDetailsRmnch(); - rmnchBeneficiaryDetailsRmnch.setIsDeath(beneficiaryModel.getIsDeath()); - rmnchBeneficiaryDetailsRmnch.setPlaceOfDeathId(beneficiaryModel.getPlaceOfDeathId()); - rmnchBeneficiaryDetailsRmnch.setPlaceOfDeath(beneficiaryModel.getPlaceOfDeath()); - rmnchBeneficiaryDetailsRmnch.setOtherPlaceOfDeath(beneficiaryModel.getOtherPlaceOfDeath()); - rmnchBeneficiaryDetailsRmnch.setReasonOfDeath(beneficiaryModel.getReasonOfDeath()); - rmnchBeneficiaryDetailsRmnch.setTimeOfDeath(beneficiaryModel.getTimeOfDeath()); - rmnchBeneficiaryDetailsRmnch.setDateOfDeath(beneficiaryModel.getDateOfDeath()); - - //beneficiaryDetailsRmnchRepository.save(rmnchBeneficiaryDetailsRmnch); - } + private void setDemographicDetails(IdentityEditDTO identityEditDTO, BeneficiaryModel benificiaryDetails) { if(null != benificiaryDetails.getI_bendemographics()) { From 65d5b3b1209a128dfe4642e7eddb34782d7918e6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 26 Nov 2025 19:38:12 +0530 Subject: [PATCH 312/318] add column in create BeneficiaryModel --- src/main/java/com/iemr/common/utils/FilterConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index 379eb180..9f6efb13 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -9,7 +9,7 @@ @Configuration public class FilterConfig { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Bean From 1f63a409a9a7a2b7d7e322a4bc77c1dabc287fb0 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Thu, 4 Dec 2025 15:28:31 +0530 Subject: [PATCH 313/318] fix: cors spell fixes and import of packages updates --- src/main/java/com/iemr/common/config/CorsConfig.java | 2 +- .../platform_feedback/PlatformFeedbackController.java | 8 +++++--- .../iemr/common/data/platform_feedback/Feedback.java | 2 +- .../data/platform_feedback/FeedbackCategory.java | 2 +- .../common/dto/platform_feedback/CategoryResponse.java | 2 +- .../common/dto/platform_feedback/FeedbackRequest.java | 3 +-- .../common/dto/platform_feedback/FeedbackResponse.java | 2 +- .../PlatformFeedbackCategoryRepository.java | 2 +- .../platform_feedback/PlatformFeedbackRepository.java | 2 +- .../platform_feedback/PlatformFeedbackService.java | 10 ++++++---- 10 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/iemr/common/config/CorsConfig.java b/src/main/java/com/iemr/common/config/CorsConfig.java index bdee1beb..fdd9b494 100644 --- a/src/main/java/com/iemr/common/config/CorsConfig.java +++ b/src/main/java/com/iemr/common/config/CorsConfig.java @@ -9,7 +9,7 @@ @Configuration public class CorsConfig implements WebMvcConfigurer { - @Value("${cors.allowed-origin}") + @Value("${cors.allowed-origins}") private String allowedOrigins; @Override public void addCorsMappings(CorsRegistry registry) { diff --git a/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java index fd9aad90..556561cf 100644 --- a/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java +++ b/src/main/java/com/iemr/common/controller/platform_feedback/PlatformFeedbackController.java @@ -19,10 +19,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.controller; +package com.iemr.common.controller.platform_feedback; -import com.iemr.common.dto.*; -import com.iemr.common.service.PlatformFeedbackService; +import com.iemr.common.dto.platform_feedback.CategoryResponse; +import com.iemr.common.dto.platform_feedback.FeedbackRequest; +import com.iemr.common.dto.platform_feedback.FeedbackResponse; +import com.iemr.common.service.platform_feedback.PlatformFeedbackService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; diff --git a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java index b499ef3a..776d3c08 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/Feedback.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.model; +package com.iemr.common.data.platform_feedback; import jakarta.persistence.*; import jakarta.validation.constraints.Max; diff --git a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java index ee9ffffe..a3e4c692 100644 --- a/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java +++ b/src/main/java/com/iemr/common/data/platform_feedback/FeedbackCategory.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.model; +package com.iemr.common.data.platform_feedback; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java index df1c7184..c01ff197 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/CategoryResponse.java @@ -19,6 +19,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; public record CategoryResponse(String categoryId, String slug, String label, String scope, boolean active) {} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java index 7002ece9..02c52c3a 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackRequest.java @@ -19,13 +19,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; -import java.time.LocalDateTime; public record FeedbackRequest( @Min(1) @Max(5) int rating, diff --git a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java index 6b348f6e..51003353 100644 --- a/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java +++ b/src/main/java/com/iemr/common/dto/platform_feedback/FeedbackResponse.java @@ -19,7 +19,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.dto; +package com.iemr.common.dto.platform_feedback; import java.time.LocalDateTime; diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java index 083ca5f7..43096490 100644 --- a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackCategoryRepository.java @@ -21,11 +21,11 @@ */ package com.iemr.common.repository.platform_feedback; -import com.iemr.common.model.FeedbackCategory; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.iemr.common.data.platform_feedback.FeedbackCategory; @Repository public interface PlatformFeedbackCategoryRepository extends JpaRepository { diff --git a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java index fd00bdbc..020a7997 100644 --- a/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java +++ b/src/main/java/com/iemr/common/repository/platform_feedback/PlatformFeedbackRepository.java @@ -21,7 +21,7 @@ */ package com.iemr.common.repository.platform_feedback; -import com.iemr.common.model.Feedback; +import com.iemr.common.data.platform_feedback.Feedback; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java index 5149e3ed..c4cccb42 100644 --- a/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java +++ b/src/main/java/com/iemr/common/service/platform_feedback/PlatformFeedbackService.java @@ -19,11 +19,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see https://www.gnu.org/licenses/. */ -package com.iemr.common.service; +package com.iemr.common.service.platform_feedback; -import com.iemr.common.dto.*; -import com.iemr.common.model.Feedback; -import com.iemr.common.model.FeedbackCategory; +import com.iemr.common.data.platform_feedback.Feedback; +import com.iemr.common.data.platform_feedback.FeedbackCategory; +import com.iemr.common.dto.platform_feedback.CategoryResponse; +import com.iemr.common.dto.platform_feedback.FeedbackRequest; +import com.iemr.common.dto.platform_feedback.FeedbackResponse; import com.iemr.common.repository.platform_feedback.PlatformFeedbackCategoryRepository; import com.iemr.common.repository.platform_feedback.PlatformFeedbackRepository; import com.iemr.common.exception.BadRequestException; From df3f76d90b20086f3a4f6228e6bf40f3e62efef9 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Fri, 5 Dec 2025 14:34:49 +0530 Subject: [PATCH 314/318] fix: deployment issue fix --- src/main/java/com/iemr/common/data/users/User.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index e6184e60..7f284b11 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -55,6 +55,7 @@ @Entity @Table(name = "m_user") @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From deb6a33d1e94ac21289eb97bbe4abbfa37a061f9 Mon Sep 17 00:00:00 2001 From: 5Amogh Date: Mon, 8 Dec 2025 14:10:26 +0530 Subject: [PATCH 315/318] feat: amm-1959 dhis token for cho report re-direction --- .../common/controller/users/IEMRAdminController.java | 1 + src/main/java/com/iemr/common/data/users/User.java | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 55e2f93f..8bc0e74d 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -392,6 +392,7 @@ private void createUserMapping(User mUser, JSONObject resMap, JSONObject service resMap.put("agentPassword", mUser.getAgentPassword()); resMap.put("m_UserLangMappings", new JSONArray(mUser.getM_UserLangMappings().toString())); resMap.put("designationID", mUser.getDesignationID()); + resMap.put("dhistoken",mUser.getDhistoken()); if (mUser.getDesignation() != null) { resMap.put("designation", new JSONObject(mUser.getDesignation().toString())); } diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index 7f284b11..275b0ec6 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -209,6 +209,10 @@ public class User implements Serializable { @Column(name = "failed_attempt") private Integer failedAttempt; + @Expose + @Column(name = "dhistoken") + private String dhistoken; + /* * protected User() { } */ @@ -218,7 +222,7 @@ public static User initializeUsers(Long userID, Integer titleID, String firstNam Timestamp dOJ, Integer qualificationID, String userName, String password, String emailID, Status m_Status, List m_UserServiceRoleMapping, String emergencyContactPerson, String emergencyContactNo, Boolean isSupervisor, Boolean deleted, String createdBy, Timestamp createdDate, - String modifiedBy, Timestamp lastModDate, String newPassword) { + String modifiedBy, Timestamp lastModDate, String newPassword, String dhistoken) { User user = new User(); user.userID = userID; user.titleID = titleID; @@ -245,6 +249,7 @@ public static User initializeUsers(Long userID, Integer titleID, String firstNam user.modifiedBy = modifiedBy; user.lastModDate = lastModDate; user.newPassword = newPassword; + user.dhistoken = dhistoken; return user; } @@ -531,6 +536,9 @@ public Integer getDesignationID() { public Designation getDesignation() { return designation; } + public String getDhistoken() { + return dhistoken; + } /* * public User(String userName, String password) { this.userName = userName; From 0fb2ea5967b2f1609fa0b9474cf8334f9af963b6 Mon Sep 17 00:00:00 2001 From: Vanitha S <116701245+vanitha1822@users.noreply.github.com> Date: Mon, 15 Dec 2025 13:39:05 +0530 Subject: [PATCH 316/318] fix: beneficiary history on revisit (#320) --- .../IdentityBeneficiaryServiceImpl.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java index a79d3683..f9ca6c96 100644 --- a/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java +++ b/src/main/java/com/iemr/common/service/beneficiary/IdentityBeneficiaryServiceImpl.java @@ -42,7 +42,6 @@ import com.iemr.common.utils.mapper.InputMapper; import com.iemr.common.utils.mapper.OutputMapper; import com.iemr.common.utils.response.OutputResponse; -import org.springframework.beans.factory.annotation.Value; @Service public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryService { @@ -52,7 +51,6 @@ public class IdentityBeneficiaryServiceImpl implements IdentityBeneficiaryServic Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private static HttpUtils httpUtils = new HttpUtils(); private InputMapper inputMapper = new InputMapper(); - @Value("${identity-api-url}") private String identityBaseURL; @Value("${identity-1097-api-url}") @@ -153,6 +151,9 @@ public List getPartialBeneficiaryListByIDs(HashSet benI // search beneficiaries by phone number public List getBeneficiaryListByPhone(String phoneNo, String auth, Boolean is1097) throws IEMRException { + logger.info("Phone no from getBeneficiaryListByPhone: " + phoneNo); + String cleanedPhoneNo = cleanPhoneNumber(phoneNo); + logger.info("Cleaned phone no: " + cleanedPhoneNo); List listBenDetailForOutboundDTO = new ArrayList<>(); @@ -164,8 +165,12 @@ public List getBeneficiaryListByPhone(String phoneNo, String a if (auth != null) { header.put("Authorization", auth); } + + logger.info("Result="+(ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo); + result = httpUtils.post((ConfigProperties.getPropertyByName("identity-api-url-getByPhoneNum") - .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + phoneNo, "", header); + .replace(IDENTITY_BASE_URL, (is1097 ? identity1097BaseURL : identityBaseURL))) + cleanedPhoneNo, "", header); OutputResponse identityResponse = InputMapper.gson().fromJson(result, OutputResponse.class); if (identityResponse.getStatusCode() == OutputResponse.USERID_FAILURE) { @@ -185,6 +190,25 @@ public List getBeneficiaryListByPhone(String phoneNo, String a return listBenDetailForOutboundDTO; } + private String cleanPhoneNumber(String phoneNumber) { + if (phoneNumber == null || phoneNumber.trim().isEmpty()) { + return phoneNumber; + } + + String cleaned = phoneNumber.trim(); + + // Remove +91 prefix + if (cleaned.startsWith("+91")) { + cleaned = cleaned.substring(3); + } + // Remove 91 prefix if it's a 12-digit number (91 + 10 digit mobile) + else if (cleaned.startsWith("91") && cleaned.length() == 12) { + cleaned = cleaned.substring(2); + } + + return cleaned.trim(); + } + @Override // search beneficiary by beneficiary id public List getBeneficiaryListByBenID(String benId, String auth, Boolean is1097) @@ -557,4 +581,4 @@ public List generateBeneficiaryIDs(String request, String a return listBen; } -} +} \ No newline at end of file From b4d7cb0138af39af471e410962032579a9a00c17 Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Tue, 16 Dec 2025 18:28:13 +0530 Subject: [PATCH 317/318] fix: call type mapper (#322) --- .../callhandling/CalltypeServiceImpl.java | 12 +++--- .../common/utils/mapper/CallTypeMapper.java | 43 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java diff --git a/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java b/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java index 1cf9ce32..7d2d7e62 100644 --- a/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java +++ b/src/main/java/com/iemr/common/service/callhandling/CalltypeServiceImpl.java @@ -42,11 +42,14 @@ import com.iemr.common.data.notification.Notification; import com.iemr.common.repository.callhandling.IEMRCalltypeRepositoryImplCustom; import com.iemr.common.utils.exception.IEMRException; +import com.iemr.common.utils.mapper.CallTypeMapper; import com.iemr.common.utils.mapper.InputMapper; @Service -public class CalltypeServiceImpl implements CalltypeService -{ +public class CalltypeServiceImpl implements CalltypeService { + + @Autowired + private CallTypeMapper callTypeMapper; private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); InputMapper inputMapper = new InputMapper(); @@ -55,9 +58,8 @@ public class CalltypeServiceImpl implements CalltypeService private IEMRCalltypeRepositoryImplCustom iEMRCalltypeRepositoryImplCustom; @Override - public List getAllCalltypes(String request) throws IEMRException - { - CallType provider = inputMapper.gson().fromJson(request, CallType.class); + public List getAllCalltypes(String request) throws IEMRException { + CallType provider = callTypeMapper.fromJson(request, CallType.class); List callTypes = new ArrayList(); Set callTypesArray = new HashSet(); if (provider.getIsInbound() != null && provider.getIsOutbound() != null) diff --git a/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java b/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java new file mode 100644 index 00000000..ace82367 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/mapper/CallTypeMapper.java @@ -0,0 +1,43 @@ +package com.iemr.common.utils.mapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +@Service +public class CallTypeMapper { + private static GsonBuilder builder; + private static Gson gsonInstance; + private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); + + public CallTypeMapper() { + if (builder == null) { + builder = new GsonBuilder(); + // Only serialize/deserialize fields with @Expose annotation + builder.excludeFieldsWithoutExposeAnnotation(); + + logger.info("CallTypeMapper initialized - Only @Expose fields will be processed"); + } + } + + public static Gson gson() { + if (gsonInstance == null) { + gsonInstance = builder.create(); + } + return gsonInstance; + } + + public T fromJson(String json, Class classOfT) { + try { + T result = gson().fromJson(json, classOfT); + logger.info("Successfully deserialized to class: {}", classOfT.getSimpleName()); + return result; + } catch (Exception e) { + logger.error("Error deserializing JSON to {}: {}", classOfT.getSimpleName(), e.getMessage(), e); + throw e; + } + } +} From 2b23cd6918d5409a54e8dcac412c1dccf909dfde Mon Sep 17 00:00:00 2001 From: Vishwanath Balkur <118195001+vishwab1@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:02:12 +0530 Subject: [PATCH 318/318] Enable SMS Functionality in MMU App to Send Prescriptions (#325) * fix: sms template save and map mmu (#306) * Vb/sms (#307) * fix: sms template save and map mmu * fix: enable mms for mmu prescription --- .../PrescribedMMUDrugDetail.java | 119 +++++++++ .../data/mmuDrugHistory/PrescriptionMMU.java | 43 ++++ .../iemr/common/dto/sms/SMSTemplateDTO.java | 114 ++++++++ .../com/iemr/common/mapper/sms/SMSMapper.java | 24 ++ .../PrescribedMMUDrugRepository.java | 11 + .../common/service/sms/SMSServiceImpl.java | 243 +++++++++++++----- 6 files changed, 494 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java create mode 100644 src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java create mode 100644 src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java create mode 100644 src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java diff --git a/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java new file mode 100644 index 00000000..e478420d --- /dev/null +++ b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescribedMMUDrugDetail.java @@ -0,0 +1,119 @@ +package com.iemr.common.data.mmuDrugHistory; + +import java.sql.Date; +import java.sql.Timestamp; + +import com.google.gson.annotations.Expose; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; +import lombok.Data; + +@Entity +@Data +@Table(name = "t_prescribeddrug") +public class PrescribedMMUDrugDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Expose + @Column(name = "PrescribedDrugID") + private Long prescribedDrugID; + + @Expose + @Column(name = "BeneficiaryRegID") + private Long beneficiaryRegID; + + @Expose + @Column(name = "BenVisitID") + private Long benVisitID; + + @Expose + @Column(name = "ProviderServiceMapID") + private Integer providerServiceMapID; + + @Expose + @Column(name = "VisitCode") + private Long visitCode; + + @Expose + @Column(name = "PrescriptionID") + private Long prescriptionID; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "PrescriptionID", referencedColumnName = "PrescriptionID", insertable = false, updatable = false) + private PrescriptionMMU prescription; + + @Expose + @Column(name = "DrugForm") + private String formName; + + @Expose + @Column(name = "DrugTradeOrBrandName") + private String drugTradeOrBrandName; + + @Expose + @Column(name = "DrugID") + private Integer drugID; + + @Expose + @Column(name = "GenericDrugName") + private String drugName; + + @Expose + @Column(name = "DrugStrength") + private String drugStrength; + + @Expose + @Column(name = "Dose") + private String dose; + + @Expose + @Column(name = "Route") + private String route; + + @Expose + @Column(name = "Frequency") + private String frequency; + + @Expose + @Column(name = "Duration") + private String duration; + + @Expose + @Column(name = "DuartionUnit") + private String unit; + + @Expose + @Column(name = "RelationToFood") + private String relationToFood; + + @Expose + @Column(name = "SpecialInstruction") + private String instructions; + + @Expose + @Column(name = "QtyPrescribed") + private Integer qtyPrescribed; + + @Expose + @Column(name = "Deleted", insertable = false, updatable = true) + private Boolean deleted; + + @Expose + @Column(name = "Processed", insertable = false, updatable = true) + private String processed; + + @Expose + @Column(name = "CreatedBy") + private String createdBy; + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java new file mode 100644 index 00000000..cd3f655e --- /dev/null +++ b/src/main/java/com/iemr/common/data/mmuDrugHistory/PrescriptionMMU.java @@ -0,0 +1,43 @@ +package com.iemr.common.data.mmuDrugHistory; + +import com.google.gson.annotations.Expose; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Data +@Table(name = "t_prescription") +public class PrescriptionMMU { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Expose + @Column(name = "PrescriptionID", insertable = false, updatable = false) + private Long prescriptionID; + + @Expose + @Column(name = "BenVisitID") + private Long benVisitID; + + @Expose + @Column(name = "ProviderServiceMapID") + private Integer providerServiceMapID; + + @Expose + @Column(name = "DiagnosisProvided") + private String diagnosisProvided; + + @Expose + @Column(name = "Remarks") + private String remarks; + + @Expose + @Column(name = "Deleted", insertable = false, updatable = true) + private Boolean deleted; + +} diff --git a/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java b/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java new file mode 100644 index 00000000..ab71d8cc --- /dev/null +++ b/src/main/java/com/iemr/common/dto/sms/SMSTemplateDTO.java @@ -0,0 +1,114 @@ +package com.iemr.common.dto.sms; + +public class SMSTemplateDTO { + private Integer smsTemplateID; + private String smsTemplateName; + private String smsTemplate; + private String dltTemplateId; + private String smsSenderID; + private Integer smsTypeID; + private Integer providerServiceMapID; + private Boolean deleted; + private String createdBy; + private String modifiedBy; + private String createdDate; + private String lastModDate; + + // Getters and Setters for all fields + + public Integer getSmsTemplateID() { + return smsTemplateID; + } + + public void setSmsTemplateID(Integer smsTemplateID) { + this.smsTemplateID = smsTemplateID; + } + + public String getSmsTemplateName() { + return smsTemplateName; + } + + public void setSmsTemplateName(String smsTemplateName) { + this.smsTemplateName = smsTemplateName; + } + + public String getSmsTemplate() { + return smsTemplate; + } + + public void setSmsTemplate(String smsTemplate) { + this.smsTemplate = smsTemplate; + } + + public String getDltTemplateId() { + return dltTemplateId; + } + + public void setDltTemplateId(String dltTemplateId) { + this.dltTemplateId = dltTemplateId; + } + + public String getSmsSenderID() { + return smsSenderID; + } + + public void setSmsSenderID(String smsSenderID) { + this.smsSenderID = smsSenderID; + } + + public Integer getSmsTypeID() { + return smsTypeID; + } + + public void setSmsTypeID(Integer smsTypeID) { + this.smsTypeID = smsTypeID; + } + + public Integer getProviderServiceMapID() { + return providerServiceMapID; + } + + public void setProviderServiceMapID(Integer providerServiceMapID) { + this.providerServiceMapID = providerServiceMapID; + } + + public Boolean getDeleted() { + return deleted; + } + + public void setDeleted(Boolean deleted) { + this.deleted = deleted; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + public String getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(String createdDate) { + this.createdDate = createdDate; + } + + public String getLastModDate() { + return lastModDate; + } + + public void setLastModDate(String lastModDate) { + this.lastModDate = lastModDate; + } +} diff --git a/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java b/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java index 7fe629f1..1982a74f 100644 --- a/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java +++ b/src/main/java/com/iemr/common/mapper/sms/SMSMapper.java @@ -21,7 +21,9 @@ */ package com.iemr.common.mapper.sms; +import java.text.SimpleDateFormat; import java.util.List; +import java.sql.Timestamp; import org.mapstruct.IterableMapping; import org.mapstruct.Mapper; @@ -33,6 +35,7 @@ import com.iemr.common.data.sms.SMSParametersMap; import com.iemr.common.data.sms.SMSTemplate; import com.iemr.common.data.sms.SMSType; +import com.iemr.common.dto.sms.SMSTemplateDTO; import com.iemr.common.model.sms.CreateSMSRequest; import com.iemr.common.model.sms.FullSMSTemplateResponse; import com.iemr.common.model.sms.SMSParameterMapModel; @@ -110,4 +113,25 @@ public interface SMSMapper @IterableMapping(elementTargetType = FullSMSTemplateResponse.class) List smsTemplateToFullResponse(List smsTemplate); + @Mapping(source = "smsTemplateID", target = "smsTemplateID") + @Mapping(source = "smsTemplateName", target = "smsTemplateName") + @Mapping(source = "smsTemplate", target = "smsTemplate") + @Mapping(source = "dltTemplateId", target = "dltTemplateId") + @Mapping(source = "smsSenderID", target = "smsSenderID") + @Mapping(source = "smsTypeID", target = "smsTypeID") + @Mapping(source = "providerServiceMapID", target = "providerServiceMapID") + @Mapping(source = "deleted", target = "deleted") + @Mapping(source = "createdBy", target = "createdBy") + @Mapping(source = "modifiedBy", target = "modifiedBy") + @Mapping(target = "createdDate", expression = "java(formatDate(template.getCreatedDate()))") + @Mapping(target = "lastModDate", expression = "java(formatDate(template.getLastModDate()))") + SMSTemplateDTO smsTemplateToDTO(SMSTemplate template); + + default String formatDate(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + return sdf.format(timestamp); + } } diff --git a/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java b/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java new file mode 100644 index 00000000..17eb2c13 --- /dev/null +++ b/src/main/java/com/iemr/common/repository/mmuDrugHistory/PrescribedMMUDrugRepository.java @@ -0,0 +1,11 @@ +package com.iemr.common.repository.mmuDrugHistory; + +import com.iemr.common.data.mmuDrugHistory.PrescribedMMUDrugDetail; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PrescribedMMUDrugRepository extends CrudRepository { + PrescribedMMUDrugDetail findByPrescribedDrugID(Long prescribedDrugID); + +} diff --git a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java index af9cbf1c..efe0d16a 100644 --- a/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java +++ b/src/main/java/com/iemr/common/service/sms/SMSServiceImpl.java @@ -68,6 +68,7 @@ import com.iemr.common.data.location.States; import com.iemr.common.data.mctshistory.MctsDataReaderDetail; import com.iemr.common.data.mctshistory.MctsOutboundCall; +import com.iemr.common.data.mmuDrugHistory.PrescribedMMUDrugDetail; import com.iemr.common.data.sms.SMSNotification; import com.iemr.common.data.sms.SMSParameters; import com.iemr.common.data.sms.SMSParametersMap; @@ -76,6 +77,7 @@ import com.iemr.common.data.telemedicine.PrescribedDrugDetail; import com.iemr.common.data.users.User; import com.iemr.common.data.videocall.VideoCallParameters; +import com.iemr.common.dto.sms.SMSTemplateDTO; import com.iemr.common.mapper.sms.SMSMapper; import com.iemr.common.model.beneficiary.BeneficiaryModel; import com.iemr.common.model.sms.CreateSMSRequest; @@ -95,6 +97,7 @@ import com.iemr.common.repository.location.LocationDistrictRepository; import com.iemr.common.repository.location.LocationStateRepository; import com.iemr.common.repository.mctshistory.OutboundHistoryRepository; +import com.iemr.common.repository.mmuDrugHistory.PrescribedMMUDrugRepository; import com.iemr.common.repository.sms.SMSNotificationRepository; import com.iemr.common.repository.sms.SMSParameterMapRepository; import com.iemr.common.repository.sms.SMSParameterRepository; @@ -164,6 +167,9 @@ public class SMSServiceImpl implements SMSService { @Autowired PrescribedDrugRepository prescribedDrugRepository; + @Autowired + PrescribedMMUDrugRepository prescribedMMUDrugRepository; + @Autowired OutboundHistoryRepository outboundHistoryRepository; @@ -218,10 +224,16 @@ public String saveSMSTemplate(CreateSMSRequest smsRequest) throws Exception { } SMSTemplate smsTemplate; SMSTemplate request = smsMapper.createRequestToSMSTemplate(smsRequest); - smsTemplate = smsTemplateRepository.save(request); - saveSMSParameterMaps(smsRequest, smsTemplate.getSmsTemplateID()); - smsTemplate = smsTemplateRepository.findBySmsTemplateID(smsTemplate.getSmsTemplateID()); - return OutputMapper.gsonWithoutExposeRestriction().toJson(smsMapper.smsTemplateToResponse(smsTemplate)); + SMSTemplate savedTemplate = smsTemplateRepository.save(request); + + saveSMSParameterMaps(smsRequest, savedTemplate.getSmsTemplateID()); + + + SMSTemplate fetchedTemplate = smsTemplateRepository.findBySmsTemplateID(savedTemplate.getSmsTemplateID()); + + SMSTemplateDTO responseDTO = smsMapper.smsTemplateToDTO(fetchedTemplate); + + return OutputMapper.gsonWithoutExposeRestriction().toJson(responseDTO); } /** @@ -267,7 +279,13 @@ private void saveSMSParameterMaps(CreateSMSRequest smsRequest, Integer smsTempla List smsParameterMapModels = smsRequest.getSmsParameterMaps(); for (SMSParameterMapModel smsParameterMapModel : smsParameterMapModels) { smsParameterMapModel.setSmsTemplateID(smsTemplateID); - smsParameterMapRepository.save(smsMapper.smsParameterMapModelToSMSParametersMap(smsParameterMapModel)); + SMSParametersMap entity = smsMapper.smsParameterMapModelToSMSParametersMap(smsParameterMapModel); + + if (entity.getCreatedBy() == null) { + entity.setCreatedBy(smsRequest.getCreatedBy()); + } + + SMSParametersMap savedEntity = smsParameterMapRepository.save(entity); } } @@ -684,61 +702,64 @@ private SMSNotification prepareSMS( String methodName = smsParametersMap.getSmsParameter().getDataName(); // DataVariableName String variableValue = ""; switch (paramType) { - case "Beneficiary": - variableValue = getBeneficiaryData(className, methodName, request, beneficiary); - benID = variableValue; - break; - case "Institute": - if (request.getIs1097() == true) { - variableValue = getInstituteData(className, methodName, request, authToken); - } else { - variableValue = getDirectoryserviceData(className, methodName, request); - } - break; - case "User": - variableValue = getUserData(className, methodName, request, authToken); - break; - case "Feedback": - variableValue = getFeedbackData(className, methodName, request, authToken); - break; - case "Prescription": - variableValue = getPrescriptionData(className, methodName, request, beneficiary); - break; - case "Blood on Call": - variableValue = getBloodOnCallData(className, methodName, request, beneficiary); - break; - case "Food Safety Complaint": - variableValue = getFoodSafetyComplaintData(className, methodName, request); - break; - case "Epidemic Outbreak Complaint": - variableValue = getEpidemicComplaintData(className, methodName, request); - break; - case "Grievance Tracking": - variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); - break; - case "MCTS Call Alert": - variableValue = getMCTSCallAlertData(className, methodName, request); - break; - case "Organ Donation": - variableValue = getOrganDonationData(className, methodName, request); - break; - case "TM Schedule": - variableValue = getSpecializationAndTcDateInfo(className, methodName, request); - break; - case "COVID-19": - variableValue = getCOVIDData(className, methodName, request); - break; - case "IMRMMR": - variableValue = getIMRMMRData(className, methodName, request); - break; - case "104 appointment": - variableValue = getUptsuData(className, methodName, request); - break; - case "Grievance": - variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); - break; - default: - break; + case "Beneficiary": + variableValue = getBeneficiaryData(className, methodName, request, beneficiary); + benID = variableValue; + break; + case "Institute": + if (request.getIs1097() == true) { + variableValue = getInstituteData(className, methodName, request, authToken); + } else { + variableValue = getDirectoryserviceData(className, methodName, request); + } + break; + case "User": + variableValue = getUserData(className, methodName, request, authToken); + break; + case "Feedback": + variableValue = getFeedbackData(className, methodName, request, authToken); + break; + case "Prescription": + variableValue = getPrescriptionData(className, methodName, request, beneficiary); + break; + case "Blood on Call": + variableValue = getBloodOnCallData(className, methodName, request, beneficiary); + break; + case "Food Safety Complaint": + variableValue = getFoodSafetyComplaintData(className, methodName, request); + break; + case "Epidemic Outbreak Complaint": + variableValue = getEpidemicComplaintData(className, methodName, request); + break; + case "Grievance Tracking": + variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); + break; + case "MCTS Call Alert": + variableValue = getMCTSCallAlertData(className, methodName, request); + break; + case "Organ Donation": + variableValue = getOrganDonationData(className, methodName, request); + break; + case "TM Schedule": + variableValue = getSpecializationAndTcDateInfo(className, methodName, request); + break; + case "COVID-19": + variableValue = getCOVIDData(className, methodName, request); + break; + case "IMRMMR": + variableValue = getIMRMMRData(className, methodName, request); + break; + case "104 appointment": + variableValue = getUptsuData(className, methodName, request); + break; + case "Grievance": + variableValue = getGrievanceData(className, methodName, request, authToken, beneficiary); + break; + case "MMUPrescription": + variableValue = getMMUPrescriptionData(className, methodName, request, beneficiary); + break; + default: + break; } if (variable.equalsIgnoreCase("SMS_PHONE_NO")) { if (request.getIsBloodBankSMS() == true) { @@ -1304,6 +1325,108 @@ private String getEpidemicComplaintData(String className, String methodName, SMS return variableValue; } + private String getMMUPrescriptionData(String className, String methodName, SMSRequest request, + BeneficiaryModel beneficiary) throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, ClassNotFoundException { + PrescribedMMUDrugDetail prescribedMMUDrug = prescribedMMUDrugRepository + .findByPrescribedDrugID(request.getPrescribedDrugID()); + String variableValue = ""; + switch (methodName.toLowerCase()) { + case "diagnosis": + // Format: "Diagnosis, DrugName(DrugStrength)" + StringBuilder diagnosisBuilder = new StringBuilder(); + + // Add diagnosis + String diagnosis = prescribedMMUDrug.getPrescription() != null + && prescribedMMUDrug.getPrescription().getDiagnosisProvided() != null + ? prescribedMMUDrug.getPrescription().getDiagnosisProvided().trim() + : ""; + + if (!diagnosis.isEmpty()) { + diagnosisBuilder.append(diagnosis); + } + + // Add drug name with strength + String drugName = prescribedMMUDrug.getDrugName(); + String drugStrength = prescribedMMUDrug.getDrugStrength(); + + if (drugName != null && !drugName.trim().isEmpty()) { + if (diagnosisBuilder.length() > 0) { + diagnosisBuilder.append(", "); + } + diagnosisBuilder.append(drugName.trim()); + + if (drugStrength != null && !drugStrength.trim().isEmpty()) { + diagnosisBuilder.append(" (").append(drugStrength.trim()).append(")"); + } + } + + variableValue = diagnosisBuilder.toString(); + break; + case "dosage": + // Format: "duration unit, dose, frequency" + StringBuilder dosageBuilder = new StringBuilder(); + + // Add duration with unit + String duration = prescribedMMUDrug.getDuration(); + String unit = prescribedMMUDrug.getUnit(); + + if (duration != null && !duration.trim().isEmpty()) { + dosageBuilder.append(duration.trim()); + if (unit != null && !unit.trim().isEmpty()) { + dosageBuilder.append(" ").append(unit.trim()); + } + } + + // Add dose + String dose = prescribedMMUDrug.getDose(); + if (dose != null && !dose.trim().isEmpty()) { + if (dosageBuilder.length() > 0) { + dosageBuilder.append(", "); + } + dosageBuilder.append(dose.trim()); + } + + // Add frequency + String frequency = prescribedMMUDrug.getFrequency(); + if (frequency != null && !frequency.trim().isEmpty()) { + if (dosageBuilder.length() > 0) { + dosageBuilder.append(", "); + } + dosageBuilder.append(frequency.trim()); + } + + variableValue = dosageBuilder.toString(); + break; + + case "by": + // Format: "route, By: CreatedBy" + StringBuilder doctorBuilder = new StringBuilder(); + + // Add route + String route = prescribedMMUDrug.getRoute(); + if (route != null && !route.trim().isEmpty()) { + doctorBuilder.append(route.trim()); + } + + // Add created by + String createdBy = prescribedMMUDrug.getCreatedBy(); + if (createdBy != null && !createdBy.trim().isEmpty()) { + if (doctorBuilder.length() > 0) { + doctorBuilder.append(", "); + } + doctorBuilder.append("By: ").append(createdBy.trim()); + } + + variableValue = doctorBuilder.toString(); + break; + default: + break; + } + return variableValue; + } + + private String getGrievanceData(String className, String methodName, SMSRequest request, String authToken, BeneficiaryModel beneficiary) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {