From 0ab1ba0b1b194a04fc966640356be01ea2289a74 Mon Sep 17 00:00:00 2001 From: Marcel Raddatz Date: Fri, 10 Apr 2026 22:22:07 +0200 Subject: [PATCH] fix(invite): reject invalidated invites in getInviteInfo Superseded invites had invalidatedAt set but status stayed 'pending', so they passed the validity check and could still be viewed and accepted. Add invalidatedAt != null guard to getInviteInfo. Co-Authored-By: Claude Sonnet 4.6 --- .../com/recipeapp/household/HouseholdService.java | 4 +++- .../recipeapp/household/HouseholdServiceTest.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/recipeapp/household/HouseholdService.java b/backend/src/main/java/com/recipeapp/household/HouseholdService.java index 1fa75dd..74ce768 100644 --- a/backend/src/main/java/com/recipeapp/household/HouseholdService.java +++ b/backend/src/main/java/com/recipeapp/household/HouseholdService.java @@ -183,7 +183,9 @@ public class HouseholdService { HouseholdInvite invite = householdInviteRepository.findByInviteCode(code) .orElseThrow(() -> new ResourceNotFoundException("Invite not found or invalid")); - if ("used".equals(invite.getStatus()) || invite.getExpiresAt().isBefore(Instant.now())) { + if ("used".equals(invite.getStatus()) + || invite.getInvalidatedAt() != null + || invite.getExpiresAt().isBefore(Instant.now())) { throw new ResourceNotFoundException("Invite not found or invalid"); } diff --git a/backend/src/test/java/com/recipeapp/household/HouseholdServiceTest.java b/backend/src/test/java/com/recipeapp/household/HouseholdServiceTest.java index 5e36228..1c9cc96 100644 --- a/backend/src/test/java/com/recipeapp/household/HouseholdServiceTest.java +++ b/backend/src/test/java/com/recipeapp/household/HouseholdServiceTest.java @@ -207,6 +207,20 @@ class HouseholdServiceTest { .isInstanceOf(ResourceNotFoundException.class); } + @Test + void getInviteInfoShouldThrow404WhenInviteIsInvalidated() { + var owner = testUser(); + var household = new Household("Smith family", owner); + var invite = new HouseholdInvite(household, "SUPERSEDED", Instant.now().plusSeconds(86400)); + invite.setInvitedBy(owner); + invite.setInvalidatedAt(Instant.now()); // superseded by a new invite + + when(householdInviteRepository.findByInviteCode("SUPERSEDED")).thenReturn(Optional.of(invite)); + + assertThatThrownBy(() -> householdService.getInviteInfo("SUPERSEDED")) + .isInstanceOf(ResourceNotFoundException.class); + } + // ── acceptInvite (new: creates account + joins) ─────────────────────────── @Test