diff --git a/pom.xml b/pom.xml
index c41d078a..e1f121cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -220,6 +220,40 @@
spring-web
6.1.12
+
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-processing
+ 2.30.1
+
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 2.3.1
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.12.6
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.12.6
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.12.6
+ runtime
+
diff --git a/src/main/environment/1097_ci.properties b/src/main/environment/1097_ci.properties
index ea60930f..953a9b47 100644
--- a/src/main/environment/1097_ci.properties
+++ b/src/main/environment/1097_ci.properties
@@ -18,3 +18,6 @@ tm-url=@TM_API@
# FHIR Config
fhir-url=@FHIR_API@
+logging.file.name=@env.IDENTITY_API_1097_LOGGING_FILE_NAME@
+
+cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS
diff --git a/src/main/environment/1097_example.properties b/src/main/environment/1097_example.properties
index 6a7d8b0f..ebd80ecf 100644
--- a/src/main/environment/1097_example.properties
+++ b/src/main/environment/1097_example.properties
@@ -14,4 +14,5 @@ logging.file.name=logs/1097identity-api.log
tm-url=http://localhost:8089/
# FHIR Config
-fhir-url=http://localhost:8093/
\ No newline at end of file
+fhir-url=http://localhost:8093/
+cors.allowed-origins=
diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties
index d6b426ef..56485871 100644
--- a/src/main/environment/common_ci.properties
+++ b/src/main/environment/common_ci.properties
@@ -18,3 +18,6 @@ tm-url=@TM_API@
# FHIR Config
fhir-url=@FHIR_API@
+logging.file.name=@env.IDENTITY_API_LOGGING_FILE_NAME@
+
+cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS
diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties
index 79dfeb12..92ccd6a4 100644
--- a/src/main/environment/common_example.properties
+++ b/src/main/environment/common_example.properties
@@ -13,4 +13,5 @@ logging.file.name=logs/identity-api.log
tm-url=http://localhost:8089/
# FHIR Config
-fhir-url=http://localhost:8093/
\ No newline at end of file
+fhir-url=http://localhost:8093/
+cors.allowed-origins=*
diff --git a/src/main/java/com/iemr/common/identity/config/CorsConfig.java b/src/main/java/com/iemr/common/identity/config/CorsConfig.java
new file mode 100644
index 00000000..ed306e04
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/config/CorsConfig.java
@@ -0,0 +1,25 @@
+package com.iemr.common.identity.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+ @Value("${cors.allowed-origins}")
+ private String allowedOrigins;
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOriginPatterns(allowedOrigins.split(","))
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+ .allowedHeaders("*")
+ .exposedHeaders("Authorization", "Jwttoken") // Explicitly expose headers if needed
+ .allowCredentials(true)
+ .maxAge(3600)
+ ;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/controller/IdentityController.java b/src/main/java/com/iemr/common/identity/controller/IdentityController.java
index c3658c66..d9bd308d 100644
--- a/src/main/java/com/iemr/common/identity/controller/IdentityController.java
+++ b/src/main/java/com/iemr/common/identity/controller/IdentityController.java
@@ -33,7 +33,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -83,7 +82,7 @@ public class IdentityController {
@Autowired
IdentityMapper mapper;
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Get beneficiaries by advance search")
@PostMapping(path = "/advanceSearch", headers = "Authorization")
public String getBeneficiaries(
@@ -112,7 +111,7 @@ public String getBeneficiaries(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on beneficiary registration id")
@PostMapping(path = "/getByBenRegId", headers = "Authorization")
public String getBeneficiariesByBeneficiaryRegId(
@@ -137,7 +136,7 @@ public String getBeneficiariesByBeneficiaryRegId(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search identity based on beneficiary registration id")
@PostMapping(path = "/getByBenId", headers = "Authorization")
public String getBeneficiariesByBeneficiaryId(
@@ -172,7 +171,7 @@ public String getBeneficiariesByBeneficiaryId(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on phone number")
@PostMapping(path = "/getByPhoneNum", headers = "Authorization")
public String getBeneficiariesByPhoneNum(
@@ -203,7 +202,7 @@ public String getBeneficiariesByPhoneNum(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on health ID / ABHA Address")
@PostMapping(path = "/getByAbhaAddress", headers = "Authorization")
public String searhBeneficiaryByABHAAddress(
@@ -235,7 +234,7 @@ public String searhBeneficiaryByABHAAddress(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on health ID number / ABHA ID number")
@PostMapping(path = "/getByAbhaIdNo", headers = "Authorization")
public String searhBeneficiaryByABHAIdNo(
@@ -267,7 +266,7 @@ public String searhBeneficiaryByABHAIdNo(
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on family id")
@PostMapping(path = "/searchByFamilyId", headers = "Authorization")
public String searhBeneficiaryByFamilyId(
@@ -297,7 +296,7 @@ public String searhBeneficiaryByFamilyId(
}
// search beneficiary by lastModDate and districtID
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary ="Search beneficiary by villageId and last modified date-time")
@PostMapping(path = "/searchByVillageIdAndLastModifiedDate")
public String searchBeneficiaryByVillageIdAndLastModDate(
@@ -322,7 +321,7 @@ public String searchBeneficiaryByVillageIdAndLastModDate(
return response;
}
// search beneficiary by lastModDate and districtID
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary ="Get count of beneficiary by villageId and last modified date-time")
@PostMapping(path = "/countBenByVillageIdAndLastModifiedDate")
public String countBeneficiaryByVillageIdAndLastModDate(
@@ -342,7 +341,7 @@ public String countBeneficiaryByVillageIdAndLastModDate(
}
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Search beneficiary based on government identity number")
@PostMapping(path = "/searhByGovIdentity", headers = "Authorization")
public String searhBeneficiaryByGovIdentity(
@@ -376,7 +375,7 @@ public String searhBeneficiaryByGovIdentity(
* @param identityEditData
* @return
*/
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Edit identity by agent")
@PostMapping(path = "/edit", headers = "Authorization")
public String editIdentity(@Param(value = "{\r\n" + " \"eventTypeName\": \"String\",\r\n"
@@ -508,7 +507,7 @@ public String editIdentity(@Param(value = "{\r\n" + " \"eventTypeName\": \"Stri
* @param identityData
* @return
*/
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Create identity by agent")
@PostMapping(path = "/create", headers = "Authorization")
public String createIdentity(@Param(value = "{\r\n" + " \"eventTypeName\": \"String\",\r\n"
@@ -615,7 +614,7 @@ public String createIdentity(@Param(value = "{\r\n" + " \"eventTypeName\": \"St
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Reserve identity by agent")
@PostMapping(path = "/reserve", headers = "Authorization")
public String reserveIdentity(@RequestBody String reserveIdentity) {
@@ -635,7 +634,7 @@ public String reserveIdentity(@RequestBody String reserveIdentity) {
return response;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Unreserve identity by agent")
@PostMapping(path = "/unreserve", headers = "Authorization")
public String unreserveIdentity(@RequestBody String unreserve) {
@@ -661,7 +660,7 @@ public String unreserveIdentity(@RequestBody String unreserve) {
* @param benRegIds
* @return
*/
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Get beneficiaries partial details by beneficiary registration id list")
@PostMapping(path = "/getByPartialBenRegIdList", headers = "Authorization")
public String getPartialBeneficiariesByBenRegIds(
@@ -693,7 +692,7 @@ public String getPartialBeneficiariesByBenRegIds(
* @param benRegIds
* @return
*/
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Get beneficiaries by beneficiary registration id")
@PostMapping(path = "/getByBenRegIdList", headers = "Authorization")
public String getBeneficiariesByBenRegIds(
@@ -792,7 +791,7 @@ public String getJsonAsString(Object obj) {
return sb.toString();
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Get finite beneficiaries")
@PostMapping(path = "/finiteSearch", headers = "Authorization")
public String getFiniteBeneficiaries(@RequestBody String searchFilter) {
@@ -816,7 +815,7 @@ public String getFiniteBeneficiaries(@RequestBody String searchFilter) {
}
// New API for getting beneficiary image only.
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Get beneficiary image by beneficiary registration id")
@PostMapping(path = "/benImageByBenRegID", headers = "Authorization")
public String getBeneficiaryImageByBenRegID(@RequestBody String identityData) {
@@ -830,7 +829,7 @@ public String getBeneficiaryImageByBenRegID(@RequestBody String identityData) {
return benImage;
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Edit education or community by agent")
@PostMapping(path = "/editEducationOrCommunity", headers = "Authorization")
public String editIdentityEducationOrCommunity(@Param(value = "{\r\n"
@@ -957,7 +956,7 @@ public String editIdentityEducationOrCommunity(@Param(value = "{\r\n"
}
}
- @CrossOrigin()
+
@Operation(summary = "Check available beneficary id in local server")
@GetMapping(path = "/checkAvailablBenIDLocalServer", headers = "Authorization")
public String checkAvailablBenIDLocalServer() {
@@ -972,7 +971,7 @@ public String checkAvailablBenIDLocalServer() {
return response.toString();
}
- @CrossOrigin(origins = { "*commonapi*" })
+
@Operation(summary = "Save server generated beneficiary ID & beneficiary registration ID to local server")
@PostMapping(path = "/saveGeneratedBenIDToLocalServer", headers = "Authorization", consumes = "application/json", produces = "application/json")
public String saveGeneratedBenIDToLocalServer(
diff --git a/src/main/java/com/iemr/common/identity/controller/familyTagging/FamilyTaggingController.java b/src/main/java/com/iemr/common/identity/controller/familyTagging/FamilyTaggingController.java
index b1f117c7..69074128 100644
--- a/src/main/java/com/iemr/common/identity/controller/familyTagging/FamilyTaggingController.java
+++ b/src/main/java/com/iemr/common/identity/controller/familyTagging/FamilyTaggingController.java
@@ -35,7 +35,7 @@
import io.swagger.v3.oas.annotations.Operation;
-@CrossOrigin
+
@RestController
@RequestMapping({ "/family" })
public class FamilyTaggingController {
@@ -43,7 +43,7 @@ public class FamilyTaggingController {
@Autowired
private FamilyTagService familyTagService;
- @CrossOrigin()
+
@Operation(summary = "Create and modify family tagging")
@PostMapping(value = { "/addTag" }, consumes = "application/json", produces = "application/json")
public String saveFamilyTagging(@RequestBody String comingReq) {
@@ -59,7 +59,7 @@ public String saveFamilyTagging(@RequestBody String comingReq) {
return response.toString();
}
- @CrossOrigin()
+
@Operation(summary = "Create family")
@PostMapping(value = { "/createFamily" }, consumes = "application/json", produces = "application/json")
public String createFamily(@RequestBody String comingReq) {
@@ -75,7 +75,7 @@ public String createFamily(@RequestBody String comingReq) {
return response.toString();
}
- @CrossOrigin()
+
@Operation(summary = "Search family")
@PostMapping(value = { "/searchFamily" }, consumes = "application/json", produces = "application/json")
public String searchFamily(@RequestBody String comingReq) {
@@ -91,7 +91,7 @@ public String searchFamily(@RequestBody String comingReq) {
return response.toString();
}
- @CrossOrigin()
+
@Operation(summary = "Get family members details")
@PostMapping(value = { "/getFamilyDetails" }, consumes = "application/json", produces = "application/json")
public String getFamilyDatails(@RequestBody String comingReq) {
@@ -107,7 +107,7 @@ public String getFamilyDatails(@RequestBody String comingReq) {
return response.toString();
}
- @CrossOrigin()
+
@Operation(summary = "Untag beneficiary from a family")
@PostMapping(value = { "/untag" }, consumes = "application/json", produces = "application/json")
public String untagFamily(@RequestBody String comingReq) {
@@ -123,7 +123,7 @@ public String untagFamily(@RequestBody String comingReq) {
return response.toString();
}
- @CrossOrigin()
+
@Operation(summary = "Edit beneficiary family details")
@PostMapping(value = { "/editFamilyTagging" }, consumes = "application/json", produces = "application/json")
public String editFamilyDetails(@RequestBody String comingReq) {
diff --git a/src/main/java/com/iemr/common/identity/controller/version/VersionController.java b/src/main/java/com/iemr/common/identity/controller/version/VersionController.java
index fdf973cd..28980e42 100644
--- a/src/main/java/com/iemr/common/identity/controller/version/VersionController.java
+++ b/src/main/java/com/iemr/common/identity/controller/version/VersionController.java
@@ -41,7 +41,7 @@ public class VersionController {
private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
- @CrossOrigin()
+
@Operation(summary = "Get version information")
@GetMapping(value = "/version",consumes = "application/json", produces = "application/json")
public String versionInformation() {
diff --git a/src/main/java/com/iemr/common/identity/domain/iemr/M_User.java b/src/main/java/com/iemr/common/identity/domain/iemr/M_User.java
new file mode 100644
index 00000000..fa9a8281
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/domain/iemr/M_User.java
@@ -0,0 +1,142 @@
+package com.iemr.common.identity.domain.iemr;
+
+import com.google.gson.annotations.Expose;
+import jakarta.persistence.*;
+import lombok.Data;
+import java.sql.Date;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+
+@Entity
+@Table(name = "m_User",schema = "db_iemr")
+@Data
+public class M_User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Expose
+ @Column(name="UserID")
+ private Integer userID;
+ @Expose
+ @Column(name="TitleID")
+ private Integer titleID;
+ @Expose
+ @Column(name="FirstName")
+ private String firstName;
+ @Expose
+ @Column(name="MiddleName")
+ private String middleName;
+ @Expose
+ @Column(name="LastName")
+ private String lastName;
+ @Expose
+ @Column(name="GenderID")
+ private Short genderID;
+
+ @Expose
+ @Column(name="MaritalStatusID")
+ private Integer maritalStatusID;
+ @Expose
+ @Column(name="DesignationID")
+ private Integer designationID;
+
+ @Expose
+ @Column(name="AadhaarNo")
+ private String aadhaarNo;
+ @Expose
+ @Column(name="PAN")
+ private String pAN;
+ @Expose
+ @Column(name="DOB")
+ private LocalDate dOB;
+ @Expose
+ @Column(name="DOJ")
+ private LocalDate dOJ;
+ @Expose
+ @Column(name="QualificationID")
+ private Integer qualificationID;
+ @Expose
+ @Column(name="HealthProfessionalID")
+ private String healthProfessionalID;
+ @Expose
+ @Column(name="UserName")
+ private String userName;
+ @Expose
+ @Column(name="Password")
+ private String password;
+ @Expose
+ @Column(name="IsExternal")
+ private Boolean isExternal;
+ @Expose
+ @Column(name="AgentID")
+ private String agentID;
+ @Expose
+ @Column(name="AgentPassword")
+ private String agentPassword;
+ @Expose
+ @Column(name="EmailID")
+ private String emailID;
+ @Expose
+ @Column(name="StatusID")
+ private Integer statusID;
+ @Expose
+ @Column(name="EmergencyContactPerson")
+ private String emergencyContactPerson;
+ @Expose
+ @Column(name="EmergencyContactNo")
+ private String emergencyContactNo;
+ @Expose
+ @Column(name="IsSupervisor")
+ private Boolean isSupervisor;
+ @Expose
+ @Column(name="Deleted",insertable = false, updatable = true)
+ private Boolean deleted;
+ @Expose
+ @Column(name="CreatedBy")
+ private String createdBy;
+ @Expose
+ @Column(name="EmployeeID")
+ private String employeeID;
+ @Expose
+ @Column(name="CreatedDate",insertable = false, updatable = false)
+ private Timestamp createdDate;
+ @Expose
+ @Column(name="ModifiedBy")
+ private String modifiedBy;
+ @Expose
+ @Column(name="LastModDate",insertable = false, updatable = false)
+ private Timestamp lastModDate;
+
+ @Expose
+ @Column(name="Remarks")
+ private String remarks;
+
+ @Expose
+ @Column(name="ContactNo")
+ private String contactNo;
+
+
+ @Expose
+ @Column(name="IsProviderAdmin")
+ private Boolean isProviderAdmin;
+
+ @Expose
+ @Column(name="ServiceProviderID")
+ private Integer serviceProviderID;
+
+
+
+ @Expose
+ @Column(name = "failed_attempt", insertable = false)
+ private Integer failedAttempt;
+ public M_User() {
+ // TODO Auto-generated constructor stub
+ }
+
+ public M_User(Integer userID, String userName) {
+ // TODO Auto-generated constructor stub
+ this.userID=userID;
+ this.userName=userName;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/repo/iemr/EmployeeMasterRepo.java b/src/main/java/com/iemr/common/identity/repo/iemr/EmployeeMasterRepo.java
new file mode 100644
index 00000000..4bea5680
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/repo/iemr/EmployeeMasterRepo.java
@@ -0,0 +1,12 @@
+package com.iemr.common.identity.repo.iemr;
+
+import com.iemr.common.identity.domain.iemr.M_User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface EmployeeMasterRepo extends JpaRepository {
+ M_User findByUserID(Integer userID);
+
+ M_User getUserByUserID(Integer parseLong);
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/utils/CookieUtil.java b/src/main/java/com/iemr/common/identity/utils/CookieUtil.java
new file mode 100644
index 00000000..67ee952c
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/CookieUtil.java
@@ -0,0 +1,41 @@
+package com.iemr.common.identity.utils;
+
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.stereotype.Service;
+import java.util.Arrays;
+import java.util.Optional;
+
+@Service
+public class CookieUtil {
+
+ public Optional getCookieValue(HttpServletRequest request, String cookieName) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (cookieName.equals(cookie.getName())) {
+ return Optional.of(cookie.getValue());
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response, HttpServletRequest request) {
+ // Create a new cookie with the JWT token
+ Cookie cookie = new Cookie("Jwttoken", Jwttoken);
+ cookie.setHttpOnly(true); // Prevent JavaScript access for security
+ cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time
+ cookie.setPath("/"); // Make the cookie available for the entire application
+ if ("https".equalsIgnoreCase(request.getScheme())) {
+ cookie.setSecure(true); // Secure flag only on HTTPS
+ }
+ response.addCookie(cookie); // Add the cookie to the response
+ }
+
+ public String getJwtTokenFromCookie(HttpServletRequest request) {
+ return Arrays.stream(request.getCookies()).filter(cookie -> "Jwttoken".equals(cookie.getName()))
+ .map(Cookie::getValue).findFirst().orElse(null);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/utils/DynamicCorsFilter.java b/src/main/java/com/iemr/common/identity/utils/DynamicCorsFilter.java
new file mode 100644
index 00000000..9d018511
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/DynamicCorsFilter.java
@@ -0,0 +1,37 @@
+package com.iemr.common.identity.utils;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+@Component
+public class DynamicCorsFilter extends OncePerRequestFilter {
+
+ @Value("${cors.allowed-origins}")
+ private String[] allowedOrigins;
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain filterChain)
+ throws ServletException, IOException {
+
+ String origin = request.getHeader("Origin");
+ if (origin != null && Arrays.asList(allowedOrigins).contains(origin)) {
+ response.setHeader("Access-Control-Allow-Origin", origin);
+ }
+
+ if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+ response.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ filterChain.doFilter(request, response);
+ }
+ }
+}
diff --git a/src/main/java/com/iemr/common/identity/utils/FilterConfig.java b/src/main/java/com/iemr/common/identity/utils/FilterConfig.java
new file mode 100644
index 00000000..1404b043
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/FilterConfig.java
@@ -0,0 +1,25 @@
+package com.iemr.common.identity.utils;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FilterConfig {
+
+ @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.addUrlPatterns("/*"); // Apply filter to all API endpoints
+ return registrationBean;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/identity/utils/JwtAuthenticationUtil.java
new file mode 100644
index 00000000..aa1fefab
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/JwtAuthenticationUtil.java
@@ -0,0 +1,124 @@
+package com.iemr.common.identity.utils;
+
+import com.iemr.common.identity.domain.iemr.M_User;
+import com.iemr.common.identity.repo.iemr.EmployeeMasterRepo;
+import com.iemr.common.identity.utils.exception.IEMRException;
+import io.jsonwebtoken.Claims;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class JwtAuthenticationUtil {
+
+ @Autowired
+ private CookieUtil cookieUtil;
+ @Autowired
+ private JwtUtil jwtUtil;
+ @Autowired
+ private RedisTemplate redisTemplate;
+ @Autowired
+ private EmployeeMasterRepo userLoginRepo;
+ private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
+
+ public JwtAuthenticationUtil(CookieUtil cookieUtil, JwtUtil jwtUtil) {
+ this.cookieUtil = cookieUtil;
+ this.jwtUtil = jwtUtil;
+ }
+
+ public ResponseEntity validateJwtToken(HttpServletRequest request) {
+ Optional jwtTokenOpt = cookieUtil.getCookieValue(request, "Jwttoken");
+
+ if (jwtTokenOpt.isEmpty()) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
+ .body("Error 401: Unauthorized - JWT Token is not set!");
+ }
+
+ String jwtToken = jwtTokenOpt.get();
+
+ // Validate the token
+ Claims claims = jwtUtil.validateToken(jwtToken);
+ if (claims == null) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Invalid JWT Token!");
+ }
+
+ // Extract username from token
+ String usernameFromToken = claims.getSubject();
+ if (usernameFromToken == null || usernameFromToken.isEmpty()) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
+ .body("Error 401: Unauthorized - Username is missing!");
+ }
+
+ // Return the username if valid
+ return ResponseEntity.ok(usernameFromToken);
+ }
+
+ public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException {
+ try {
+ // Validate JWT token and extract claims
+ Claims claims = jwtUtil.validateToken(jwtToken);
+
+ if (claims == null) {
+ throw new IEMRException("Invalid JWT token.");
+ }
+
+ String userId = claims.get("userId", String.class);
+
+ // Check if user data is present in Redis
+ M_User user = getUserFromCache(userId);
+ if (user == null) {
+ // If not in Redis, fetch from DB and cache the result
+ user = fetchUserFromDB(userId);
+ }
+ if (user == null) {
+ throw new IEMRException("Invalid User ID.");
+ }
+
+ return true; // Valid userId and JWT token
+ } catch (Exception e) {
+ logger.error("Validation failed: " + e.getMessage(), e);
+ throw new IEMRException("Validation error: " + e.getMessage(), e);
+ }
+ }
+
+ private M_User getUserFromCache(String userId) {
+ String redisKey = "user_" + userId; // The Redis key format
+ M_User user = (M_User) redisTemplate.opsForValue().get(redisKey);
+
+ if (user == null) {
+ logger.warn("User not found in Redis. Will try to fetch from DB.");
+ } else {
+ logger.info("User fetched successfully from Redis.");
+ }
+
+ return user; // Returns null if not found
+ }
+
+ private M_User fetchUserFromDB(String userId) {
+ // This method will only be called if the user is not found in Redis.
+ String redisKey = "user_" + userId; // Redis key format
+
+ // Fetch user from DB
+ M_User user = userLoginRepo.getUserByUserID(Integer.parseInt(userId));
+
+ if (user != null) {
+ // Cache the user in Redis for future requests (cache for 30 minutes)
+ redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES);
+
+ // Log that the user has been stored in Redis
+ logger.info("User stored in Redis with key: " + redisKey);
+ } else {
+ logger.warn("User not found for userId: " + userId);
+ }
+
+ return user;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/identity/utils/JwtUserIdValidationFilter.java
new file mode 100644
index 00000000..c27778d8
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/JwtUserIdValidationFilter.java
@@ -0,0 +1,141 @@
+package com.iemr.common.identity.utils;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@Component
+public class JwtUserIdValidationFilter implements Filter {
+
+ private final JwtAuthenticationUtil jwtAuthenticationUtil;
+ private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
+
+ private final String allowedOrigins;
+
+ public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil,
+ @Value("${cors.allowed-origins}") String allowedOrigins) {
+ this.jwtAuthenticationUtil = jwtAuthenticationUtil;
+ this.allowedOrigins = allowedOrigins;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ HttpServletResponse response = (HttpServletResponse) servletResponse;
+
+ String path = request.getRequestURI();
+ String contextPath = request.getContextPath();
+ logger.info("JwtUserIdValidationFilter invoked for path: " + path);
+
+ String origin = request.getHeader("Origin");
+ 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");
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ }
+
+ if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+ logger.info("OPTIONS request - skipping JWT validation");
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }
+
+ // Log cookies for debugging
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if ("userId".equals(cookie.getName())) {
+ logger.warn("userId found in cookies! Clearing it...");
+ clearUserIdCookie(response); // Explicitly remove userId cookie
+ }
+ }
+ } else {
+ logger.info("No cookies found in the request");
+ }
+
+ // Log headers for debugging
+ String jwtTokenFromHeader = request.getHeader("Jwttoken");
+ logger.info("JWT token from header: ");
+
+ // Skip login and public endpoints
+ if (path.equals(contextPath + "/user/userAuthenticate")
+ || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession")
+ || path.startsWith(contextPath + "/public")) {
+ logger.info("Skipping filter for path: " + path);
+ filterChain.doFilter(servletRequest, servletResponse);
+ return;
+ }
+
+ try {
+ // Retrieve JWT token from cookies
+ String jwtTokenFromCookie = getJwtTokenFromCookies(request);
+ logger.info("JWT token from cookie: ");
+
+ // Determine which token (cookie or header) to validate
+ String jwtToken = jwtTokenFromCookie != null ? jwtTokenFromCookie : jwtTokenFromHeader;
+ if (jwtToken == null) {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "JWT token not found in cookies or headers");
+ return;
+ }
+
+ // Validate JWT token and userId
+ boolean isValid = jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtToken);
+
+ if (isValid) {
+ // If token is valid, allow the request to proceed
+ filterChain.doFilter(servletRequest, servletResponse);
+ } else {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token");
+ }
+ } catch (Exception e) {
+ logger.error("Authorization error: ", e);
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization error: ");
+ }
+ }
+
+ private boolean isOriginAllowed(String origin) {
+ if (origin == null || allowedOrigins == null || allowedOrigins.trim().isEmpty()) {
+ logger.warn("No allowed origins configured or origin is null");
+ return false;
+ }
+
+ return Arrays.stream(allowedOrigins.split(",")).map(String::trim)
+ .anyMatch(pattern -> origin.matches(pattern.replace(".", "\\.").replace("*", ".*")));
+ }
+
+ private String getJwtTokenFromCookies(HttpServletRequest request) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals("Jwttoken")) {
+ return cookie.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ private void clearUserIdCookie(HttpServletResponse response) {
+ Cookie cookie = new Cookie("userId", null);
+ cookie.setPath("/");
+ cookie.setHttpOnly(true);
+ cookie.setSecure(true);
+ cookie.setMaxAge(0); // Invalidate the cookie
+ response.addCookie(cookie);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/iemr/common/identity/utils/JwtUtil.java b/src/main/java/com/iemr/common/identity/utils/JwtUtil.java
new file mode 100644
index 00000000..de2f5864
--- /dev/null
+++ b/src/main/java/com/iemr/common/identity/utils/JwtUtil.java
@@ -0,0 +1,85 @@
+package com.iemr.common.identity.utils;
+
+import com.iemr.common.identity.utils.exception.IEMRException;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.Keys;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.security.Key;
+import java.util.Date;
+import java.util.function.Function;
+
+@Component
+public class JwtUtil {
+
+ @Value("${jwt.secret}")
+ private String SECRET_KEY;
+
+ private static final long EXPIRATION_TIME = 24L * 60 * 60 * 1000; // 1 day in milliseconds
+
+ // Generate a key using the secret
+ private Key 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 JWT Token
+ public String generateToken(String username, String userId) {
+ Date now = new Date();
+ Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME);
+
+ // Include the userId in the JWT claims
+ return Jwts.builder().setSubject(username).claim("userId", userId) // Add userId as a claim
+ .setIssuedAt(now).setExpiration(expiryDate).signWith(getSigningKey(), SignatureAlgorithm.HS256)
+ .compact();
+ }
+
+ // Validate and parse JWT Token
+ public Claims validateToken(String token) {
+ try {
+ return Jwts.parser().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody();
+ } catch (Exception e) {
+ return null; // Handle token parsing/validation errors
+ }
+ }
+
+
+ public String extractUsername(String token) {
+ return extractClaim(token, Claims::getSubject);
+ }
+
+ public Integer extractUserId(String jwtToken) throws IEMRException {
+ try {
+ // Validate JWT token and extract claims
+ Claims claims = validateToken(jwtToken);
+
+ if (claims == null) {
+ throw new IEMRException("Invalid JWT token.");
+ }
+
+ String userId = claims.get("userId", String.class);
+
+ return Integer.parseInt(userId);
+
+ } catch (Exception e) {
+ throw new IEMRException("Validation error: " + e.getMessage(), e);
+ }
+
+
+ }
+
+
+ public T extractClaim(String token, Function claimsResolver) {
+ final Claims claims = extractAllClaims(token);
+ return claimsResolver.apply(claims);
+ }
+
+ private Claims extractAllClaims(String token) {
+ return Jwts.parser().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody();
+ }
+}
\ No newline at end of file