From 4e6cd1ae7bd1ac7f13fbee9c52a611c18bd3bb5f Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 16 Apr 2026 10:07:10 +0200 Subject: [PATCH 01/14] Create GlobalExceptionHandler and error code --- .../exceptions/GlobalExceptionHandler.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java diff --git a/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000..d210dca --- /dev/null +++ b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,29 @@ +package org.example.alfs.exceptions; + +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.server.ResponseStatusException; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(ResponseStatusException.class) + public String handleResponseStatusException(ResponseStatusException ex, Model model) { + + model.addAttribute("status", ex.getStatusCode()); + model.addAttribute("error", ex.getReason()); + + return "error"; + } + + @ExceptionHandler(Exception.class) + public String handleException(Exception ex, Model model) { + + model.addAttribute("status", 500); + model.addAttribute("error", "Something went wrong"); + + return "error"; + } + +} From 3d8597eac22f15d1dc7c974dc06e857c8b2adfbd Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 16 Apr 2026 20:33:45 +0200 Subject: [PATCH 02/14] fix: status code handling in GlobalExceptionHandler --- .../org/example/alfs/exceptions/GlobalExceptionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java index d210dca..8598297 100644 --- a/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java +++ b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java @@ -11,7 +11,7 @@ public class GlobalExceptionHandler { @ExceptionHandler(ResponseStatusException.class) public String handleResponseStatusException(ResponseStatusException ex, Model model) { - model.addAttribute("status", ex.getStatusCode()); + model.addAttribute("status", ex.getStatusCode().value()); model.addAttribute("error", ex.getReason()); return "error"; From a2b178b267510513be201acfec5767572546cf6f Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 16 Apr 2026 20:34:34 +0200 Subject: [PATCH 03/14] Create error page --- src/main/jte/error.jte | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/jte/error.jte diff --git a/src/main/jte/error.jte b/src/main/jte/error.jte new file mode 100644 index 0000000..e34841f --- /dev/null +++ b/src/main/jte/error.jte @@ -0,0 +1,26 @@ +@param org.example.alfs.exceptions.GlobalExceptionHandler ex +@param String error +@param Integer status + + +@template.layout(title = "Error", content = @` +
+ +

+ Something went wrong +

+ +

+ Status: ${status} +

+ +

+ ${error} +

+ + + Back to start page + + +
+`) \ No newline at end of file From 248e2506ccda5c0447c94b953a15ca5adcac72a4 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Thu, 16 Apr 2026 20:51:23 +0200 Subject: [PATCH 04/14] Disable whitelabel --- src/main/resources/application.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e2145af..2d41565 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,9 @@ gg.jte.development-mode=true spring.application.name=alfs +#Disable whitelabel +spring.web.error.whitelabel.enabled=false + # Storage (MinIO/S3) ? default local dev values; override via env in andra milj�er storage.s3.endpoint=http://localhost:9000 storage.s3.accessKey=minioadmin From c0c718e873153fce08c26b33609dbee2f8ab2ed4 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Fri, 17 Apr 2026 11:50:09 +0200 Subject: [PATCH 05/14] Create ErrorController and initial code --- .../alfs/controllers/ErrorController.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/org/example/alfs/controllers/ErrorController.java diff --git a/src/main/java/org/example/alfs/controllers/ErrorController.java b/src/main/java/org/example/alfs/controllers/ErrorController.java new file mode 100644 index 0000000..0825500 --- /dev/null +++ b/src/main/java/org/example/alfs/controllers/ErrorController.java @@ -0,0 +1,18 @@ +package org.example.alfs.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping +public class ErrorController { + + @GetMapping("/403") + public String forbidden(Model model) { + model.addAttribute("status", 403); + model.addAttribute("error", "Access denied"); + return "error"; + } +} From f3f97f98bc5cc1a707caa38471c0e82b25807b61 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Fri, 17 Apr 2026 11:51:04 +0200 Subject: [PATCH 06/14] Allow custom error page for 403 --- .../java/org/example/alfs/config/SecurityConfig.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/example/alfs/config/SecurityConfig.java b/src/main/java/org/example/alfs/config/SecurityConfig.java index 0b61490..1823178 100644 --- a/src/main/java/org/example/alfs/config/SecurityConfig.java +++ b/src/main/java/org/example/alfs/config/SecurityConfig.java @@ -52,6 +52,16 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .anyRequest().authenticated() ) + // Use custom error page for 403 (Spring Security access denied) + .exceptionHandling(exception -> exception + .accessDeniedHandler(( + request, + response, + ex) -> { + request.getRequestDispatcher("/error/403") + .forward(request, response); }) + ) + // disable DEFAULT LOGIN .formLogin(form -> form.disable()) .httpBasic(basic -> basic.disable()) From ad5a0d417f800608706024bc408b971b6313267d Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 10:56:35 +0200 Subject: [PATCH 07/14] Add endpoint matchers --- src/main/java/org/example/alfs/config/SecurityConfig.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/config/SecurityConfig.java b/src/main/java/org/example/alfs/config/SecurityConfig.java index 1823178..2910bbb 100644 --- a/src/main/java/org/example/alfs/config/SecurityConfig.java +++ b/src/main/java/org/example/alfs/config/SecurityConfig.java @@ -3,6 +3,7 @@ import org.example.alfs.security.JwtAuthenticationFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; @@ -43,9 +44,11 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/auth/signup").permitAll() .requestMatchers("/auth/hash").permitAll() .requestMatchers("/h2-console/**").permitAll() + .requestMatchers("/", "/startPage").permitAll() + .requestMatchers(HttpMethod.GET,"/tickets/create").permitAll() + .requestMatchers("/error/**").permitAll() //allow access to endpoints during development - .requestMatchers("/create", "/tickets/**", "/view/**").permitAll() .requestMatchers("/css/**", "/js/**", "/images/**", "/static/**").permitAll() .requestMatchers("/login", "/login-form").permitAll() .requestMatchers("/signup", "/signup-form").permitAll() From 2f5f8f7218ba1ee56bf65b659087e417b9badac2 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 10:58:12 +0200 Subject: [PATCH 08/14] Add base path "error" --- src/main/java/org/example/alfs/controllers/ErrorController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/alfs/controllers/ErrorController.java b/src/main/java/org/example/alfs/controllers/ErrorController.java index 0825500..5747a39 100644 --- a/src/main/java/org/example/alfs/controllers/ErrorController.java +++ b/src/main/java/org/example/alfs/controllers/ErrorController.java @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @Controller -@RequestMapping +@RequestMapping("/error") public class ErrorController { @GetMapping("/403") From 3c05df104b612fc3ccda63dbda00bed661537952 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 11:28:35 +0200 Subject: [PATCH 09/14] add: 401 unauthorized --- .../java/org/example/alfs/controllers/ErrorController.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/example/alfs/controllers/ErrorController.java b/src/main/java/org/example/alfs/controllers/ErrorController.java index 5747a39..6341cc8 100644 --- a/src/main/java/org/example/alfs/controllers/ErrorController.java +++ b/src/main/java/org/example/alfs/controllers/ErrorController.java @@ -15,4 +15,11 @@ public String forbidden(Model model) { model.addAttribute("error", "Access denied"); return "error"; } + + @GetMapping("/401") + public String unauthorized(Model model) { + model.addAttribute("status", 401); + model.addAttribute("error", "You need to log in to access this page"); + return "error"; + } } From 95346b3db077ba8acb70715ad90620977e403ded Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 11:29:16 +0200 Subject: [PATCH 10/14] use custom error page for 401 --- .../example/alfs/config/SecurityConfig.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/example/alfs/config/SecurityConfig.java b/src/main/java/org/example/alfs/config/SecurityConfig.java index 2910bbb..cc3a5cf 100644 --- a/src/main/java/org/example/alfs/config/SecurityConfig.java +++ b/src/main/java/org/example/alfs/config/SecurityConfig.java @@ -55,16 +55,22 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .anyRequest().authenticated() ) - // Use custom error page for 403 (Spring Security access denied) .exceptionHandling(exception -> exception - .accessDeniedHandler(( - request, - response, - ex) -> { + + // Use custom error page for 403 (Spring Security access denied) + .accessDeniedHandler((request, response, ex) -> { request.getRequestDispatcher("/error/403") - .forward(request, response); }) + .forward(request, response); + }) + + // Use custom error page for 401 (unauthorized) + .authenticationEntryPoint((request, response, ex) -> { + request.getRequestDispatcher("/error/401") + .forward(request, response); + }) ) + // disable DEFAULT LOGIN .formLogin(form -> form.disable()) .httpBasic(basic -> basic.disable()) From b9d476561541ca499613fd1d6dc99ab5d3122195 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 11:55:34 +0200 Subject: [PATCH 11/14] cleanup unused param --- src/main/jte/error.jte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/jte/error.jte b/src/main/jte/error.jte index e34841f..0d101b3 100644 --- a/src/main/jte/error.jte +++ b/src/main/jte/error.jte @@ -1,4 +1,3 @@ -@param org.example.alfs.exceptions.GlobalExceptionHandler ex @param String error @param Integer status From 6bb037a7e7b1ac00cce090b287d862c112e4cb38 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 12:05:57 +0200 Subject: [PATCH 12/14] fix: proper HTTP status handling --- .../exceptions/GlobalExceptionHandler.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java index 8598297..9a92124 100644 --- a/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java +++ b/src/main/java/org/example/alfs/exceptions/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package org.example.alfs.exceptions; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -9,21 +10,33 @@ public class GlobalExceptionHandler { @ExceptionHandler(ResponseStatusException.class) - public String handleResponseStatusException(ResponseStatusException ex, Model model) { + public String handleResponseStatusException( + ResponseStatusException ex, + Model model, + HttpServletResponse response + ) { - model.addAttribute("status", ex.getStatusCode().value()); + int status = ex.getStatusCode().value(); + response.setStatus(status); + + model.addAttribute("status", status); model.addAttribute("error", ex.getReason()); return "error"; } @ExceptionHandler(Exception.class) - public String handleException(Exception ex, Model model) { + public String handleException( + Exception ex, + Model model, + HttpServletResponse response + ) { + + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); model.addAttribute("status", 500); model.addAttribute("error", "Something went wrong"); return "error"; } - -} +} \ No newline at end of file From 82123df31d90618cb803b822da02153d3f6bdd59 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Mon, 20 Apr 2026 12:08:59 +0200 Subject: [PATCH 13/14] fix: correct HTTP status codes --- .../org/example/alfs/controllers/ErrorController.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/example/alfs/controllers/ErrorController.java b/src/main/java/org/example/alfs/controllers/ErrorController.java index 6341cc8..d78b9c4 100644 --- a/src/main/java/org/example/alfs/controllers/ErrorController.java +++ b/src/main/java/org/example/alfs/controllers/ErrorController.java @@ -1,22 +1,25 @@ package org.example.alfs.controllers; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; @Controller @RequestMapping("/error") public class ErrorController { - @GetMapping("/403") + @RequestMapping("/403") + @ResponseStatus(HttpStatus.FORBIDDEN) public String forbidden(Model model) { model.addAttribute("status", 403); model.addAttribute("error", "Access denied"); return "error"; } - @GetMapping("/401") + @RequestMapping("/401") + @ResponseStatus(HttpStatus.UNAUTHORIZED) public String unauthorized(Model model) { model.addAttribute("status", 401); model.addAttribute("error", "You need to log in to access this page"); From 708f9fbe6b95a3348ea16bdf70ed67d3397c9895 Mon Sep 17 00:00:00 2001 From: Fiona Friberg Date: Tue, 21 Apr 2026 12:12:10 +0200 Subject: [PATCH 14/14] fix: resolve JTE layout parameter mismatch in error template --- src/main/jte/error.jte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/jte/error.jte b/src/main/jte/error.jte index 0d101b3..e025087 100644 --- a/src/main/jte/error.jte +++ b/src/main/jte/error.jte @@ -1,5 +1,6 @@ @param String error @param Integer status +@param String success @template.layout(title = "Error", content = @` @@ -22,4 +23,4 @@ -`) \ No newline at end of file +` , success = null) \ No newline at end of file