From 4a9d1f4ada50d0ca9471a04f3ab1543dd0c1c05e Mon Sep 17 00:00:00 2001 From: AliceDarkest Date: Wed, 22 Jul 2026 14:18:57 +0200 Subject: [PATCH] Add Neural browser favicon --- CHANGELOG.md | 2 ++ .../mindflux/config/SecurityConfig.java | 2 +- .../controller/FaviconController.java | 23 +++++++++++++++++++ .../example/mindflux/SecurityRulesTest.java | 11 ++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/mindflux/controller/FaviconController.java diff --git a/CHANGELOG.md b/CHANGELOG.md index c44bda2..3b53a19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Versionierung [semantisch](https://semver.org/lang/de/). ## [Unreleased] – 2026-07-21 · Gesamt-Audit: Light Mode, Barrierefreiheit, AP2-Inhalte, DSGVO ### Light Mode & Design +- **Browser-Icon:** Das Neural-Emblem wird unter `/favicon.ico` ausgeliefert und + ersetzt damit das Standard-Globus-Symbol im Browser-Tab. - **Preismodell offen formuliert:** Die öffentliche Einstiegsseite verspricht keine kostenlose Nutzung mehr; Beschreibung, Registrierungs-Teaser und Account-Hinweis bleiben bewusst preisneutral. diff --git a/src/main/java/com/example/mindflux/config/SecurityConfig.java b/src/main/java/com/example/mindflux/config/SecurityConfig.java index 6fa97c8..6566699 100644 --- a/src/main/java/com/example/mindflux/config/SecurityConfig.java +++ b/src/main/java/com/example/mindflux/config/SecurityConfig.java @@ -21,7 +21,7 @@ public class SecurityConfig { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth - .requestMatchers("/", "/login", "/register", "/forgot-password", "/reset-password", "/verify-email", "/verification/resend", "/impressum", "/nutzungsbedingungen", "/datenschutz", "/richtlinien", "/css/**", "/js/**", "/img/**").permitAll() + .requestMatchers("/", "/login", "/register", "/forgot-password", "/reset-password", "/verify-email", "/verification/resend", "/impressum", "/nutzungsbedingungen", "/datenschutz", "/richtlinien", "/favicon.ico", "/css/**", "/js/**", "/img/**").permitAll() .requestMatchers("/actuator/health").permitAll() // Container-Healthcheck .requestMatchers("/admin/**").hasRole("ADMIN") .requestMatchers("/api/users/**").hasRole("ADMIN") diff --git a/src/main/java/com/example/mindflux/controller/FaviconController.java b/src/main/java/com/example/mindflux/controller/FaviconController.java new file mode 100644 index 0000000..a7d7964 --- /dev/null +++ b/src/main/java/com/example/mindflux/controller/FaviconController.java @@ -0,0 +1,23 @@ +package com.example.mindflux.controller; + +import java.time.Duration; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.http.CacheControl; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class FaviconController { + + @GetMapping(value = "/favicon.ico", produces = MediaType.IMAGE_PNG_VALUE) + public ResponseEntity favicon() { + Resource emblem = new ClassPathResource("static/img/mindflux-emblem.png"); + return ResponseEntity.ok() + .cacheControl(CacheControl.maxAge(Duration.ofDays(30)).cachePublic()) + .body(emblem); + } +} diff --git a/src/test/java/com/example/mindflux/SecurityRulesTest.java b/src/test/java/com/example/mindflux/SecurityRulesTest.java index 7ed064a..6434d34 100644 --- a/src/test/java/com/example/mindflux/SecurityRulesTest.java +++ b/src/test/java/com/example/mindflux/SecurityRulesTest.java @@ -3,6 +3,7 @@ package com.example.mindflux; import com.example.mindflux.config.SecurityConfig; import com.example.mindflux.controller.AdminUserController; import com.example.mindflux.controller.DashboardController; +import com.example.mindflux.controller.FaviconController; import com.example.mindflux.controller.ProgressController; import com.example.mindflux.controller.PlatformStatusController; import com.example.mindflux.dto.ProgressData; @@ -28,9 +29,10 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; /** Absichert die zentralen Security-Regeln: Login-Zwang, Admin-Schutz, gelöschter Legacy-Endpunkt. */ -@WebMvcTest(controllers = {DashboardController.class, ProgressController.class, PlatformStatusController.class, AdminUserController.class}) +@WebMvcTest(controllers = {DashboardController.class, ProgressController.class, PlatformStatusController.class, AdminUserController.class, FaviconController.class}) @Import(SecurityConfig.class) class SecurityRulesTest { @@ -58,6 +60,13 @@ class SecurityRulesTest { .andExpect(status().is3xxRedirection()); } + @Test + void faviconIstOhneAnmeldungErreichbar() throws Exception { + mockMvc.perform(get("/favicon.ico")) + .andExpect(status().isOk()) + .andExpect(content().contentType("image/png")); + } + @Test @WithMockUser(username = "alice") void eingeloggteNutzerSehenDasDashboard() throws Exception {