From a17de8cd0389c6fbc55b97b4c126af644303c59f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Jul 2026 23:43:17 +0000 Subject: [PATCH] Stop Cachet API routes inheriting the host application rate limiter The API routes were registered with both the "cachet:api" middleware group and "throttle:cachet-api". The "cachet:api" group defaulted to the host application's "api" middleware group, which typically registers its own "throttle:api" limiter (Laravel's default is 60 requests a minute). Both throttles were applied, so the more restrictive host limiter capped requests at 60 and its value was reported in the X-RateLimit-Limit header, ignoring both the CACHET_API_RATE_LIMIT setting and the intended default of 300. Default "cachet.api_middleware" to SubstituteBindings only, so Cachet's API relies solely on its own "throttle:cachet-api" limiter while keeping route model binding working. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01TKAFhcTL68GptC9YTU2qi9 --- config/cachet.php | 14 +++++++++++++- tests/Feature/RateLimitTest.php | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/config/cachet.php b/config/cachet.php index f185ec5d..adeded5a 100644 --- a/config/cachet.php +++ b/config/cachet.php @@ -75,8 +75,20 @@ // \Cachet\Http\Middleware\AuthenticateRemoteUser::class, ], + /* + |-------------------------------------------------------------------------- + | Cachet API Middleware + |-------------------------------------------------------------------------- + | + | This is the middleware that will be applied to the Cachet API routes. + | Cachet manages its own rate limiting via the "cachet.api_rate_limit" + | option, so the host application's "api" middleware group (which may + | register its own, more restrictive "throttle:api" limiter) is + | intentionally not included here. + | + */ 'api_middleware' => [ - 'api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'trusted_proxies' => env('CACHET_TRUSTED_PROXIES', ''), diff --git a/tests/Feature/RateLimitTest.php b/tests/Feature/RateLimitTest.php index 0decd259..1dd5fbaf 100644 --- a/tests/Feature/RateLimitTest.php +++ b/tests/Feature/RateLimitTest.php @@ -1,5 +1,7 @@ Limit::perMinute(60)); + Route::middlewareGroup('api', ['throttle:api']); + + Route::get('/cachet-api-test', fn () => response()->json()) + ->middleware(['cachet:api', 'throttle:cachet-api']); + + $response = getJson('/cachet-api-test'); + + expect($response->status())->toBe(200) + ->and($response->headers->get('X-RateLimit-Limit'))->toBe('300'); +});