From 91ded93833ede2535ac69e1cc3036ab78f51f39c Mon Sep 17 00:00:00 2001 From: Bennett Date: Sun, 16 Aug 2026 19:40:30 +0300 Subject: [PATCH 1/2] release: Silence 404s --- .../core/exceptions/GlobalExceptionHandler.java | 6 ++++-- .../app/controllers/FrontendController.java | 14 +++++++++++--- .../app/controllers/FrontendControllerTest.java | 15 ++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/flexcodelabs/flextuma/core/exceptions/GlobalExceptionHandler.java b/src/main/java/com/flexcodelabs/flextuma/core/exceptions/GlobalExceptionHandler.java index 703edef..455fd85 100644 --- a/src/main/java/com/flexcodelabs/flextuma/core/exceptions/GlobalExceptionHandler.java +++ b/src/main/java/com/flexcodelabs/flextuma/core/exceptions/GlobalExceptionHandler.java @@ -168,7 +168,9 @@ public ResponseEntity handleAccessDenied(AccessDeniedException ex) { public ResponseEntity handleNotFound(HttpServletRequest request) { String requestUri = request.getRequestURI(); String method = request.getMethod(); - if ("GET".equals(method) && !requestUri.startsWith("/api/")) { + String accept = request.getHeader("Accept"); + boolean acceptsHtml = accept != null && accept.contains(MediaType.TEXT_HTML_VALUE); + if ("GET".equals(method) && acceptsHtml && !requestUri.startsWith("/api/")) { try { Path filePath = Paths.get(frontendDirectory, "index.html"); Resource resource = new FileSystemResource(filePath.toString()); @@ -360,4 +362,4 @@ private HttpStatus getResponseStatus(String message, HttpStatus defaultStatus) { return HttpStatus.NOT_FOUND; return defaultStatus; } -} \ No newline at end of file +} diff --git a/src/main/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendController.java b/src/main/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendController.java index 42c879d..fd21ac2 100644 --- a/src/main/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendController.java +++ b/src/main/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendController.java @@ -52,11 +52,19 @@ public ResponseEntity serveCatchAll(HttpServletRequest request) { return serveStatic(path); } - if (path.startsWith(".well-known/")) { + if (path.startsWith(".well-known/") && acceptsHtml(request)) { return serveStatic(indexFile); } - return serveStatic(indexFile); + // Only browser document navigations should receive the SPA shell. Requests + // from vulnerability scanners (for example /wp-login.php) normally accept + // any content type and must remain a 404 instead of appearing to be routes. + return acceptsHtml(request) ? serveStatic(indexFile) : ResponseEntity.notFound().build(); + } + + private boolean acceptsHtml(HttpServletRequest request) { + String accept = request.getHeader("Accept"); + return accept != null && accept.contains(MediaType.TEXT_HTML_VALUE); } private ResponseEntity serveStatic(String path) { @@ -64,7 +72,7 @@ private ResponseEntity serveStatic(String path) { Path filePath = Paths.get(frontendDirectory, path); Resource resource = new FileSystemResource(filePath.toString()); - if (resource.exists() || resource.isReadable()) { + if (resource.exists() && resource.isReadable()) { String contentType = getContentType(path); return ResponseEntity.ok() diff --git a/src/test/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendControllerTest.java b/src/test/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendControllerTest.java index 9577cca..5376a8a 100644 --- a/src/test/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendControllerTest.java +++ b/src/test/java/com/flexcodelabs/flextuma/modules/app/controllers/FrontendControllerTest.java @@ -4,6 +4,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import org.springframework.http.MediaType; + import java.nio.file.Files; import java.nio.file.Path; @@ -33,24 +35,23 @@ void setUp() throws Exception { } @Test - void serveCatchAll_shouldReturnIndexForNonApiRoutes() throws Exception { - mockMvc.perform(get("/dashboard/overview")) + void serveCatchAll_shouldReturnIndexForBrowserNavigation() throws Exception { + mockMvc.perform(get("/dashboard/overview").header("Accept", MediaType.TEXT_HTML_VALUE)) .andExpect(status().isOk()) .andExpect(content().string("app")); } @Test void serveCatchAll_shouldReturnIndexForLoginRoute() throws Exception { - mockMvc.perform(get("/login")) + mockMvc.perform(get("/login").header("Accept", MediaType.TEXT_HTML_VALUE)) .andExpect(status().isOk()) .andExpect(content().string("app")); } @Test - void serveCatchAll_shouldReturnIndexForDottedNonApiRoutes() throws Exception { - mockMvc.perform(get("/foo.bar")) - .andExpect(status().isOk()) - .andExpect(content().string("app")); + void serveCatchAll_shouldReturnNotFoundForNonBrowserRequests() throws Exception { + mockMvc.perform(get("/wp-login.php").header("Accept", "*/*")) + .andExpect(status().isNotFound()); } @Test From 57f8fff083e4ae9f1f7f19efbd2207fcb783b139 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 16 Aug 2026 16:41:11 +0000 Subject: [PATCH 2/2] Release v0.0.43 [skip ci] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 25ba3e0..7d550e7 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { } group = 'com.flexcodelabs' -version = '0.0.42' +version = '0.0.43' description = 'Flextuma App' java {