diff --git a/app/Http/Controllers/FollowController.php b/app/Http/Controllers/FollowController.php index d11ea56..6515c8a 100644 --- a/app/Http/Controllers/FollowController.php +++ b/app/Http/Controllers/FollowController.php @@ -64,6 +64,8 @@ class FollowController extends Controller public function followers(Request $request, User $user): AnonymousResourceCollection { + abort_unless($request->user()->id === $user->id, 403); + $perPage = max(1, min($request->integer('per_page', 15), 100)); $followers = $user->followers() @@ -75,6 +77,8 @@ class FollowController extends Controller public function following(Request $request, User $user): AnonymousResourceCollection { + abort_unless($request->user()->id === $user->id, 403); + $perPage = max(1, min($request->integer('per_page', 15), 100)); $following = $user->following() diff --git a/app/Http/Controllers/PublicUserProfileController.php b/app/Http/Controllers/PublicUserProfileController.php index 2f6c372..384ffb1 100644 --- a/app/Http/Controllers/PublicUserProfileController.php +++ b/app/Http/Controllers/PublicUserProfileController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Enums\FollowStatus; use App\Enums\MealPostVisibility; use App\Http\Resources\MealPostsResource; use App\Models\User; @@ -39,6 +40,12 @@ class PublicUserProfileController extends Controller ->where('visibility', MealPostVisibility::Public->value) ->whereNull('hidden_at') ->count(), + 'followersCount' => $user->followers() + ->wherePivot('status', FollowStatus::Accepted) + ->count(), + 'followingCount' => $user->following() + ->wherePivot('status', FollowStatus::Accepted) + ->count(), ], 'meals' => MealPostsResource::collection($meals)->resolve($request), ], diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index cf79923..78de90d 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -7,6 +7,9 @@ use App\Listeners\GrantCreditsFromStripeWebhook; use App\Mail\ResetPasswordMail; use App\Mail\VerifyAccount; use App\Models\User; +use Dedoc\Scramble\Scramble; +use Dedoc\Scramble\Support\Generator\OpenApi; +use Dedoc\Scramble\Support\Generator\SecurityScheme; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Auth\Notifications\VerifyEmail; use Illuminate\Cache\RateLimiting\Limit; @@ -45,6 +48,12 @@ class AppServiceProvider extends ServiceProvider { $this->configureRateLimiting(); + Scramble::afterOpenApiGenerated(function (OpenApi $openApi) { + $openApi->secure( + SecurityScheme::http('bearer') + ); + }); + if ($this->app->environment('production')) { URL::forceScheme('https'); } diff --git a/routes/api.php b/routes/api.php index aaae7a4..4b092b5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,6 +3,7 @@ use App\Http\Controllers\AuthController; use App\Http\Controllers\BillingController; use App\Http\Controllers\DeviceTokenController; +use App\Http\Controllers\FollowController; use App\Http\Controllers\LegalDocumentController; use App\Http\Controllers\MealImageAnalysisController; use App\Http\Controllers\MealPostController; @@ -79,6 +80,12 @@ Route::middleware(['auth:sanctum', 'verified', 'not_suspended'])->group(function // Meals Route::middleware(['auth:sanctum', 'verified', 'not_suspended'])->group(function (): void { Route::get('users/{user}', [PublicUserProfileController::class, 'show'])->name('users.show'); + Route::post('users/{user}/follow', [FollowController::class, 'follow'])->middleware('throttle:engagement')->name('users.follow'); + Route::delete('users/{user}/follow', [FollowController::class, 'unfollow'])->middleware('throttle:engagement')->name('users.unfollow'); + Route::post('users/{user}/accept', [FollowController::class, 'accept'])->middleware('throttle:engagement')->name('users.accept'); + Route::post('users/{user}/reject', [FollowController::class, 'reject'])->middleware('throttle:engagement')->name('users.reject'); + Route::get('users/{user}/followers', [FollowController::class, 'followers'])->name('users.followers'); + Route::get('users/{user}/following', [FollowController::class, 'following'])->name('users.following'); Route::post('users/{user}/reports', [ReportController::class, 'storeUser']) ->middleware('throttle:reports') ->name('users.reports.store');