From d1a13058a647456d50e3ea606451bdb33da7f35a Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 4 Sep 2026 20:02:15 +0200 Subject: [PATCH] fix(roadtrip): make the addon gate on the REST routes actually run @RequireAddon has sat on the controller since the domain was written and did nothing: it is metadata, AddonGuard was not in the chain, and it is not one of the three global guards either. The addon ships disabled (seeds sets enabled 0), so on any instance that never switched it on, all six via routes answered anyway. Two doc comments in this repo already describe the behaviour this commit creates rather than the one it replaces. AddonGuard leads the chain, the way reservation-import and collections do it, because a disabled addon owes an anonymous caller a 404 rather than a 401. --- server/src/nest/roadtrip/roadtrip.controller.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/src/nest/roadtrip/roadtrip.controller.ts b/server/src/nest/roadtrip/roadtrip.controller.ts index a706ff10c..b135687a7 100644 --- a/server/src/nest/roadtrip/roadtrip.controller.ts +++ b/server/src/nest/roadtrip/roadtrip.controller.ts @@ -5,6 +5,7 @@ import { RoadtripViaCreateDto, RoadtripViaReanchorDto, RoadtripViaUpdateDto } fr import { JwtAuthGuard } from '../auth/jwt-auth.guard'; import { RequirePermission, TripAccessGuard } from '../permissions/trip-access.guard'; import { RequireAddon } from '../addons/require-addon.decorator'; +import { AddonGuard } from '../addons/addon.guard'; import { ADDON_IDS } from '../../addons'; /** @@ -20,7 +21,11 @@ import { ADDON_IDS } from '../../addons'; * become shared editing rather than route shaping. */ @Controller('api/trips/:tripId/roadtrip') -@UseGuards(JwtAuthGuard, TripAccessGuard) +// AddonGuard FIRST: @RequireAddon is metadata and does nothing on its own, and the guard +// is not registered globally either, so without it here the decorator below was inert and +// all six routes answered on an instance that had the addon switched off. It leads the +// chain because a disabled addon owes an anonymous caller a 404, not a 401. +@UseGuards(AddonGuard, JwtAuthGuard, TripAccessGuard) @RequireAddon(ADDON_IDS.ROADTRIP, 'Road trip') export class RoadtripController { constructor(private readonly roadtrip: RoadtripService) {}