From 6db5c2d1c4b4a6eabf05f7e886a8abbf7cc4bf14 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 18 May 2026 22:26:42 +0200 Subject: [PATCH] test(user): add CSRF failure tests for changePassword and forceLogout endpoints Adds two @WebMvcTest assertions verifying that POST /api/users/me/password and POST /api/users/{id}/force-logout without an XSRF-TOKEN header return 403 with code CSRF_TOKEN_MISSING. Addresses Nora Concern 9 from PR #617 review. Co-Authored-By: Claude Sonnet 4.6 --- .../user/UserControllerTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/backend/src/test/java/org/raddatz/familienarchiv/user/UserControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/user/UserControllerTest.java index a31fa4af..80f26119 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/user/UserControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/user/UserControllerTest.java @@ -191,6 +191,16 @@ class UserControllerTest { .andExpect(status().isUnauthorized()); } + @Test + @WithMockUser(username = "user@example.com") + void changePassword_without_csrf_returns_403_CSRF_TOKEN_MISSING() throws Exception { + mockMvc.perform(post("/api/users/me/password") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"currentPassword\":\"old\",\"newPassword\":\"new123!\"}")) + .andExpect(status().isForbidden()) + .andExpect(jsonPath("$.code").value("CSRF_TOKEN_MISSING")); + } + // ─── POST /api/users/{id}/force-logout ──────────────────────────────────── @Test @@ -232,4 +242,12 @@ class UserControllerTest { mockMvc.perform(post("/api/users/" + targetId + "/force-logout").with(csrf())) .andExpect(status().isNotFound()); } + + @Test + @WithMockUser(username = "admin@example.com", authorities = "ADMIN_USER") + void forceLogout_without_csrf_returns_403_CSRF_TOKEN_MISSING() throws Exception { + mockMvc.perform(post("/api/users/" + UUID.randomUUID() + "/force-logout")) + .andExpect(status().isForbidden()) + .andExpect(jsonPath("$.code").value("CSRF_TOKEN_MISSING")); + } }