Skip to content

Commit a71eaee

Browse files
authored
fix: cors error removed in all api (#60)
1 parent 5f3f2b3 commit a71eaee

File tree

7 files changed

+65
-23
lines changed

7 files changed

+65
-23
lines changed

src/main/environment/common_ci.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ logging.file.name=@env.SCHEDULER_API_LOGGING_FILE_NAME@
2525
springdoc.api-docs.enabled=@env.SWAGGER_DOC_ENABLED@
2626
springdoc.swagger-ui.enabled=@env.SWAGGER_DOC_ENABLED@
2727

28+
cors.allowed-origins=@env.CORS_ALLOWED_ORIGINS@
29+

src/main/environment/common_example.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ jwt.secret=my-32-character-ultra-secure-and-ultra-long-secret
2222
logging.path=logs/
2323
logging.file.name=logs/scheduler-api.log
2424

25+
cors.allowed-origins=http://localhost:*
26+

src/main/java/com/iemr/tm/controller/schedule/SchedulingController.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.slf4j.Logger;
2727
import org.slf4j.LoggerFactory;
2828
import org.springframework.beans.factory.annotation.Autowired;
29-
import org.springframework.web.bind.annotation.CrossOrigin;
29+
3030
import org.springframework.web.bind.annotation.PathVariable;
3131
import org.springframework.web.bind.annotation.RequestBody;
3232
import org.springframework.web.bind.annotation.RequestMapping;
@@ -43,7 +43,6 @@
4343

4444
import io.swagger.v3.oas.annotations.Operation;
4545

46-
4746
@RestController
4847
@RequestMapping(value = "/schedule", headers = "Authorization")
4948
public class SchedulingController {
@@ -52,7 +51,6 @@ public class SchedulingController {
5251
@Autowired
5352
private SchedulingService schedulingService;
5453

55-
@CrossOrigin()
5654
@Operation(summary = "Mark availability of specialist")
5755
@RequestMapping(value = "markavailability", method = RequestMethod.POST)
5856
public String markavailability(@RequestBody String specialistInput1) {
@@ -72,7 +70,6 @@ public String markavailability(@RequestBody String specialistInput1) {
7270
return response.toString();
7371
}
7472

75-
@CrossOrigin()
7673
@Operation(summary = "Mark unavailability of specialist")
7774
@RequestMapping(value = "unmarkavailability", method = RequestMethod.POST)
7875
public String unmarkavailability(@RequestBody String specialistInput1) {
@@ -91,7 +88,6 @@ public String unmarkavailability(@RequestBody String specialistInput1) {
9188
return response.toString();
9289
}
9390

94-
@CrossOrigin()
9591
@Operation(summary = "Get available slots of specialist for a particular day")
9692
@RequestMapping(value = "getavailableSlot", method = RequestMethod.POST)
9793
public String getavailableSlot(@RequestBody String specialistInput1) {
@@ -109,7 +105,6 @@ public String getavailableSlot(@RequestBody String specialistInput1) {
109105
return response.toString();
110106
}
111107

112-
@CrossOrigin()
113108
@Operation(summary = "Get available slots of specialist for a particular month")
114109
@RequestMapping(value = { "/monthview/{year}", "/monthview/{year}/{month}",
115110
"/monthview/{year}/{month}/{day}" }, method = RequestMethod.POST)
@@ -131,7 +126,6 @@ public String view(@RequestBody String specialistInput1, @PathVariable("year") I
131126
return response.toString();
132127
}
133128

134-
@CrossOrigin()
135129
@Operation(summary = "Book available slots of specialist of a particular day")
136130
@RequestMapping(value = "bookSlot", method = RequestMethod.POST)
137131
public String bookSlot(@RequestBody String specialistInput1) {
@@ -149,7 +143,6 @@ public String bookSlot(@RequestBody String specialistInput1) {
149143
return response.toString();
150144
}
151145

152-
@CrossOrigin()
153146
@Operation(summary = "Cancel booked slots of specialist of a particular day")
154147
@RequestMapping(value = "cancelBookedSlot", method = RequestMethod.POST)
155148
public String cancelBookedSlot(@RequestBody String specialistInput1) {
@@ -167,7 +160,6 @@ public String cancelBookedSlot(@RequestBody String specialistInput1) {
167160
return response.toString();
168161
}
169162

170-
@CrossOrigin()
171163
@Operation(summary = "Get day view of particular specialization")
172164
@RequestMapping(value = "getdayview", method = RequestMethod.POST)
173165
public String getdayview(@RequestBody String specialistInput1) {

src/main/java/com/iemr/tm/controller/specialist/SpecialistController.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.slf4j.Logger;
2727
import org.slf4j.LoggerFactory;
2828
import org.springframework.beans.factory.annotation.Autowired;
29-
import org.springframework.web.bind.annotation.CrossOrigin;
29+
3030
import org.springframework.web.bind.annotation.PathVariable;
3131
import org.springframework.web.bind.annotation.RequestBody;
3232
import org.springframework.web.bind.annotation.RequestMapping;
@@ -41,7 +41,6 @@
4141

4242
import io.swagger.v3.oas.annotations.Operation;
4343

44-
4544
@RestController
4645
@RequestMapping(value = "/specialist", headers = "Authorization")
4746
public class SpecialistController {
@@ -50,7 +49,6 @@ public class SpecialistController {
5049
@Autowired
5150
private SpecialistService specialistService;
5251

53-
@CrossOrigin()
5452
@Operation(summary = "Fetch master specialization")
5553
@RequestMapping(value = "masterspecialization", method = RequestMethod.POST)
5654
public String markavailability() {
@@ -66,7 +64,6 @@ public String markavailability() {
6664
return response.toString();
6765
}
6866

69-
@CrossOrigin()
7067
@Operation(summary = "Fetch list of specialists")
7168
@RequestMapping(value = "getSpecialist", method = RequestMethod.POST)
7269
public String getSpecialist(@RequestBody Specialist specialist) {
@@ -83,7 +80,6 @@ public String getSpecialist(@RequestBody Specialist specialist) {
8380
return response.toString();
8481
}
8582

86-
@CrossOrigin()
8783
@Operation(summary = "Fetch user specialist")
8884
@RequestMapping(value = "info/{userID}", method = RequestMethod.GET)
8985
public String info(@PathVariable("userID") Long userID) {
@@ -101,7 +97,6 @@ public String info(@PathVariable("userID") Long userID) {
10197
return response.toString();
10298
}
10399

104-
@CrossOrigin()
105100
@Operation(summary = "Fetch all specialists")
106101
@RequestMapping(value = "getSpecialistAll", method = RequestMethod.POST)
107102
public String getSpecialistAll(@RequestBody Specialist specialist) {

src/main/java/com/iemr/tm/controller/van/VanController.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.slf4j.Logger;
2525
import org.slf4j.LoggerFactory;
2626
import org.springframework.beans.factory.annotation.Autowired;
27-
import org.springframework.web.bind.annotation.CrossOrigin;
27+
2828
import org.springframework.web.bind.annotation.PathVariable;
2929
import org.springframework.web.bind.annotation.RequestMapping;
3030
import org.springframework.web.bind.annotation.RequestMethod;
@@ -36,8 +36,6 @@
3636

3737
import io.swagger.v3.oas.annotations.Operation;
3838

39-
40-
4139
@RestController
4240
@RequestMapping(value = "/van", headers = "Authorization")
4341
public class VanController {
@@ -46,7 +44,6 @@ public class VanController {
4644
@Autowired
4745
private VanService vanService;
4846

49-
@CrossOrigin()
5047
@Operation(summary = "Fetch specialization by van id")
5148
@RequestMapping(value = "getvan/{vanid}", method = RequestMethod.GET)
5249
public String markavailability(@PathVariable("vanid") Integer vanid) {

src/main/java/com/iemr/tm/utils/FilterConfig.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,26 @@
33
import org.springframework.boot.web.servlet.FilterRegistrationBean;
44
import org.springframework.context.annotation.Bean;
55
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.core.Ordered;
7+
import org.springframework.beans.factory.annotation.Value;
68

79
@Configuration
810
public class FilterConfig {
911

12+
@Value("${cors.allowed-origins}")
13+
private String allowedOrigins;
14+
1015
@Bean
1116
public FilterRegistrationBean<JwtUserIdValidationFilter> jwtUserIdValidationFilter(
1217
JwtAuthenticationUtil jwtAuthenticationUtil) {
1318
FilterRegistrationBean<JwtUserIdValidationFilter> registrationBean = new FilterRegistrationBean<>();
14-
registrationBean.setFilter(new JwtUserIdValidationFilter(jwtAuthenticationUtil));
19+
20+
// Pass allowedOrigins explicitly to the filter constructor
21+
JwtUserIdValidationFilter filter = new JwtUserIdValidationFilter(jwtAuthenticationUtil, allowedOrigins);
22+
23+
registrationBean.setFilter(filter);
24+
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
1525
registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints
1626
return registrationBean;
1727
}
18-
1928
}

src/main/java/com/iemr/tm/utils/JwtUserIdValidationFilter.java

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.iemr.tm.utils;
22

33
import java.io.IOException;
4+
import java.util.Arrays;
45

56
import org.slf4j.Logger;
67
import org.slf4j.LoggerFactory;
@@ -17,14 +18,16 @@
1718
import jakarta.servlet.http.HttpServletRequest;
1819
import jakarta.servlet.http.HttpServletResponse;
1920

20-
@Component
2121
public class JwtUserIdValidationFilter implements Filter {
2222

2323
private final JwtAuthenticationUtil jwtAuthenticationUtil;
2424
private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
25+
private final String allowedOrigins;
2526

26-
public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) {
27+
public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil,
28+
String allowedOrigins) {
2729
this.jwtAuthenticationUtil = jwtAuthenticationUtil;
30+
this.allowedOrigins = allowedOrigins;
2831
}
2932

3033
@Override
@@ -33,6 +36,27 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
3336
HttpServletRequest request = (HttpServletRequest) servletRequest;
3437
HttpServletResponse response = (HttpServletResponse) servletResponse;
3538

39+
String origin = request.getHeader("Origin");
40+
41+
logger.debug("Incoming Origin: {}", origin);
42+
logger.debug("Allowed Origins Configured: {}", allowedOrigins);
43+
44+
if (origin != null && isOriginAllowed(origin)) {
45+
response.setHeader("Access-Control-Allow-Origin", origin);
46+
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
47+
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, Jwttoken");
48+
response.setHeader("Vary", "Origin");
49+
response.setHeader("Access-Control-Allow-Credentials", "true");
50+
} else {
51+
logger.warn("Origin [{}] is NOT allowed. CORS headers NOT added.", origin);
52+
}
53+
54+
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
55+
logger.info("OPTIONS request - skipping JWT validation");
56+
response.setStatus(HttpServletResponse.SC_OK);
57+
return;
58+
}
59+
3660
String path = request.getRequestURI();
3761
String contextPath = request.getContextPath();
3862
logger.info("JwtUserIdValidationFilter invoked for path: " + path);
@@ -110,12 +134,33 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
110134
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization error: " + e.getMessage());
111135
}
112136
}
137+
138+
private boolean isOriginAllowed(String origin) {
139+
if (origin == null || allowedOrigins == null || allowedOrigins.trim().isEmpty()) {
140+
logger.warn("No allowed origins configured or origin is null");
141+
return false;
142+
}
143+
144+
return Arrays.stream(allowedOrigins.split(","))
145+
.map(String::trim)
146+
.anyMatch(pattern -> {
147+
String regex = pattern
148+
.replace(".", "\\.")
149+
.replace("*", ".*")
150+
.replace("http://localhost:.*", "http://localhost:\\d+"); // special case for wildcard port
151+
152+
boolean matched = origin.matches(regex);
153+
return matched;
154+
});
155+
}
156+
113157
private boolean isMobileClient(String userAgent) {
114158
if (userAgent == null)
115159
return false;
116160
userAgent = userAgent.toLowerCase();
117161
return userAgent.contains("okhttp");
118162
}
163+
119164
private String getJwtTokenFromCookies(HttpServletRequest request) {
120165
Cookie[] cookies = request.getCookies();
121166
if (cookies != null) {

0 commit comments

Comments
 (0)