From 381fc515cdf1a4f9029bc232f94673b819d9a58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=C3=A1n=20L=2E?= Date: Mon, 6 Apr 2026 19:55:44 +0100 Subject: [PATCH] push --- app/Providers/AppServiceProvider.php | 9 +++++++++ package.json | 2 +- readme/changelog/2026-04-06.md | 3 +++ routes/api.php | 4 ++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7a90f8747..683081ec9 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -11,6 +11,7 @@ use App\Services\Clustering\ClusteringService; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Facades\Gate; +use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; use Laravel\Cashier\Cashier; use Illuminate\Cache\RateLimiting\Limit; @@ -52,5 +53,13 @@ public function boot() RateLimiter::for('ses-emails', function () { return Limit::perSecond(12); }); + + RateLimiter::for('login', function (Request $request) { + return Limit::perMinute(5)->by($request->ip()); + }); + + RateLimiter::for('login-token', function (Request $request) { + return Limit::perMinute(10)->by($request->ip()); + }); } } diff --git a/package.json b/package.json index 0f371bed5..4f5600259 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openlittermap-web", - "version": "5.8.2", + "version": "5.8.3", "type": "module", "author": "Seán Lynch", "license": "GPL v3", diff --git a/readme/changelog/2026-04-06.md b/readme/changelog/2026-04-06.md index 063daeb87..e25dce3d6 100644 --- a/readme/changelog/2026-04-06.md +++ b/readme/changelog/2026-04-06.md @@ -4,3 +4,6 @@ - fix(photos): add shared `resolvePhotoUrl()` composable for S3/MinIO URL handling — fixes broken images in TeamPhotoList, TeamPhotoEdit, TeamApprovalQueue, ParticipantWorkspace; refactors Uploads.vue, PhotoPreview.vue, and PhotoViewer.vue to use same helper (covers FacilitatorQueue, AdminQueue, AddTags automatically) - feat(teams): team map popup now matches global map — shows photo image, tag summary, user attribution, picked-up status, and date via `popupHelper`; images load directly via `resolvePhotoUrl` (bypasses signed-url endpoint for pending private photos) - fix(teams): improve text readability across 14 team Vue components — bump `text-white/30`→`/50`, `text-white/40`→`/60`, `text-white/50`→`/60` (section headers), `placeholder-white/30`→`/50`, `text-slate-400`→`slate-500` (light theme), `text-gray-400`→`gray-300` (facilitator queue); skip disabled button states + +## v5.8.3 +- fix(auth): resolve 429 Too Many Requests on production login — double throttle middleware (global `throttle:60,1` + route `throttle:5,1`) shared same cache key, halving effective limit to ~2 req/min; switched to named rate limiters (`login`, `login-token`) with independent keys diff --git a/routes/api.php b/routes/api.php index 63c87cf0a..a38cc4730 100644 --- a/routes/api.php +++ b/routes/api.php @@ -156,10 +156,10 @@ Route::post('/password/reset', [ResetPasswordController::class, 'reset']); Route::post('/auth/login', [LoginController::class, 'login']) - ->middleware(app()->isLocal() ? ['web'] : ['web', 'throttle:5,1']); + ->middleware(app()->isLocal() ? ['web'] : ['web', 'throttle:login']); Route::post('/auth/token', [AuthTokenController::class, 'login']) - ->middleware('throttle:10,1'); + ->middleware('throttle:login-token'); Route::post('/auth/logout', [LoginController::class, 'logout']) ->middleware(['web', 'auth:web']);