diff --git a/pom.xml b/pom.xml
index 8027e14..ac49436 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.iemr.common
helpline-104-api
- 3.1.0
+ 3.6.0
war
Helpline-104-API
Piramal Helpline 104 API
@@ -437,4 +437,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/java/com/iemr/helpline104/config/CorsConfig.java b/src/main/java/com/iemr/helpline104/config/CorsConfig.java
index 520f113..2642605 100644
--- a/src/main/java/com/iemr/helpline104/config/CorsConfig.java
+++ b/src/main/java/com/iemr/helpline104/config/CorsConfig.java
@@ -19,8 +19,9 @@ public void addCorsMappings(CorsRegistry registry) {
Arrays.stream(allowedOrigins.split(","))
.map(String::trim)
.toArray(String[]::new))
- .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
- .allowedHeaders("Content-Type", "Authorization")
+ .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
+ .allowedHeaders("Authorization", "Content-Type", "Accept", "Jwttoken",
+ "serverAuthorization", "ServerAuthorization", "serverauthorization", "Serverauthorization")
.exposedHeaders("Authorization")
.allowCredentials(true)
.maxAge(3600);
diff --git a/src/main/java/com/iemr/helpline104/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/helpline104/utils/JwtUserIdValidationFilter.java
index fe90b2c..779980d 100644
--- a/src/main/java/com/iemr/helpline104/utils/JwtUserIdValidationFilter.java
+++ b/src/main/java/com/iemr/helpline104/utils/JwtUserIdValidationFilter.java
@@ -37,24 +37,52 @@ 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);
+ 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;
+ }
+ }
+
+ // Set CORS headers and handle OPTIONS request only if origin is valid and
+ // allowed
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("Vary", "Origin");
- response.setHeader("Access-Control-Allow-Credentials", "true");
+ addCorsHeaders(response, origin);
+ logger.info("Origin Validated | Origin: {} | Method: {} | URI: {}", origin, method, uri);
+
+ if ("OPTIONS".equalsIgnoreCase(method)) {
+ // OPTIONS (preflight) - respond with full allowed methods
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }
} else {
logger.warn("Origin [{}] is NOT allowed. CORS headers NOT added.", origin);
- }
- if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
- logger.info("OPTIONS request - skipping JWT validation");
- response.setStatus(HttpServletResponse.SC_OK);
- return;
+ if ("OPTIONS".equalsIgnoreCase(method)) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "Origin not allowed for OPTIONS request");
+ return;
+ }
}
String path = request.getRequestURI();
@@ -180,4 +208,13 @@ private void clearUserIdCookie(HttpServletResponse response) {
cookie.setMaxAge(0); // Invalidate the cookie
response.addCookie(cookie);
}
+
+ private void addCorsHeaders(HttpServletResponse response, String origin) {
+ response.setHeader("Access-Control-Allow-Origin", origin); // Never use wildcard
+ 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.setHeader("Access-Control-Max-Age", "3600");
+ }
}
diff --git a/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
index 6512c11..693170a 100644
--- a/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
+++ b/src/main/java/com/iemr/helpline104/utils/http/HTTPRequestInterceptor.java
@@ -22,9 +22,12 @@
package com.iemr.helpline104.utils.http;
+import java.util.Arrays;
+
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.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@@ -43,6 +46,9 @@ public class HTTPRequestInterceptor implements HandlerInterceptor {
private final Validator validator;
Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
+
+ @Value("${cors.allowed-origins}")
+ private String allowedOrigins;
@Autowired
public HTTPRequestInterceptor(Validator validator) {
@@ -96,6 +102,13 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
response.getOutputStream().print(output.toString());
response.setContentType(MediaType.APPLICATION_JSON);
response.setContentLength(output.toString().length());
+ 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);
+ }
status = false;
}
}
@@ -123,6 +136,20 @@ public void afterCompletion(HttpServletRequest request, HttpServletResponse resp
logger.debug("In afterCompletion Request Completed");
}
-
+ 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+");
+ return origin.matches(regex);
+ });
+ }
}
\ No newline at end of file