From 52251cf71125d95499be424c443b13f1a6cf8948 Mon Sep 17 00:00:00 2001 From: Patrick Plate Date: Sat, 13 Jun 2026 10:52:43 +0200 Subject: [PATCH] =?UTF-8?q?fix(api):=20resolve=20consent/dsgvo=20'User=20n?= =?UTF-8?q?ot=20found'=20=E2=80=94=20principal=20is=20userId=20not=20email?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConsentController.resolveUserId() and DsgvoController.resolveUserId() read auth.getName() as an email and did findByEmailAndTenantId(...), but JwtAuthFilter sets the Authentication principal to the userId (UUID) — the JWT subject is the userId, not the email. So auth.getName() returns a UUID string, the email lookup never matched, and every consent/dsgvo call threw 'User not found' (404/500). This made the DSGVO consent banner unusable: /consent/check 404'd (banner always shown) and clicking Accept POSTed /consent which 500'd with no UI feedback — the button appeared to 'not react'. Fix: parse auth.getName() as the userId UUID directly and verify existsById. --- .../api/controller/ConsentController.java | 19 +++++++++++++++---- .../api/controller/DsgvoController.java | 16 ++++++++++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/cannamanage-api/src/main/java/de/cannamanage/api/controller/ConsentController.java b/cannamanage-api/src/main/java/de/cannamanage/api/controller/ConsentController.java index d327764..1362df8 100644 --- a/cannamanage-api/src/main/java/de/cannamanage/api/controller/ConsentController.java +++ b/cannamanage-api/src/main/java/de/cannamanage/api/controller/ConsentController.java @@ -78,10 +78,21 @@ public class ConsentController { } private UUID resolveUserId(Authentication auth) { - String email = auth.getName(); - return userRepository.findByEmailAndTenantId(email, TenantContext.getCurrentTenant()) - .map(User::getId) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "User not found")); + // JwtAuthFilter sets the Authentication principal to the userId (the JWT subject), + // so auth.getName() is the userId UUID — NOT an email. Parse it directly and verify + // the user exists in the current tenant. (Previously this did findByEmailAndTenantId + // on auth.getName(), which searched the email column for a UUID → always "User not + // found" → 404/500 on every consent call.) + UUID userId; + try { + userId = UUID.fromString(auth.getName()); + } catch (IllegalArgumentException e) { + throw new ResponseStatusException(NOT_FOUND, "User not found"); + } + if (!userRepository.existsById(userId)) { + throw new ResponseStatusException(NOT_FOUND, "User not found"); + } + return userId; } private ConsentResponse toResponse(Consent consent) { diff --git a/cannamanage-api/src/main/java/de/cannamanage/api/controller/DsgvoController.java b/cannamanage-api/src/main/java/de/cannamanage/api/controller/DsgvoController.java index 345c582..1ffee39 100644 --- a/cannamanage-api/src/main/java/de/cannamanage/api/controller/DsgvoController.java +++ b/cannamanage-api/src/main/java/de/cannamanage/api/controller/DsgvoController.java @@ -54,9 +54,17 @@ public class DsgvoController { } private UUID resolveUserId(Authentication auth) { - String email = auth.getName(); - return userRepository.findByEmailAndTenantId(email, TenantContext.getCurrentTenant()) - .map(User::getId) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "User not found")); + // JwtAuthFilter sets the Authentication principal to the userId (the JWT subject), + // so auth.getName() is the userId UUID — NOT an email. Parse it directly. + UUID userId; + try { + userId = UUID.fromString(auth.getName()); + } catch (IllegalArgumentException e) { + throw new ResponseStatusException(NOT_FOUND, "User not found"); + } + if (!userRepository.existsById(userId)) { + throw new ResponseStatusException(NOT_FOUND, "User not found"); + } + return userId; } }