diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 4791ade25..90ead050e 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -229,6 +229,52 @@ class ApiV1Controller extends Controller return $this->json($res); } + /** + * GET /api/v1/accounts/lookup + * + * @param int $id + * @return \App\Transformer\Api\AccountTransformer + */ + public function accountLookupById(Request $request) + { + $request->validate([ + 'acct' => 'required|string|min:3|max:100', + ]); + + $acct = $request->acct; + + if (str_contains($acct, '@')) { + $count = mb_substr_count($acct, '@'); + + if ($count === 1) { + if (str_starts_with($acct, '@')) { + $acct = substr($acct, 1); + } else { + $acct = '@'.$acct; + } + } + if ($count > 2) { + return $this->json(['error' => 'Record not found'], 400); + } + } + $profile = Profile::whereUsername($acct)->first(); + + if (! $profile) { + return $this->json(['error' => 'Record not found'], 400); + } + + $res = $request->has(self::PF_API_ENTITY_KEY) ? AccountService::get($profile->id, true) : AccountService::getMastodon($profile->id, true); + if (! $res) { + return response()->json(['error' => 'Record not found'], 404); + } + if ($res && strpos($res['acct'], '@') != -1) { + $domain = parse_url($res['url'], PHP_URL_HOST); + abort_if(in_array($domain, InstanceService::getBannedDomains()), 404); + } + + return $this->json($res); + } + /** * PATCH /api/v1/accounts/update_credentials * diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index e62b3557b..2d3f80e6f 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -103,6 +103,10 @@ class AppServiceProvider extends ServiceProvider return Limit::perHour(10)->by($request->ip()); }); + RateLimiter::for('account-lookup', function (Request $request) { + return Limit::perDay(50)->by($request->ip()); + }); + // Model::preventLazyLoading(true); } diff --git a/routes/api.php b/routes/api.php index 8133db7a4..c056168df 100644 --- a/routes/api.php +++ b/routes/api.php @@ -100,6 +100,7 @@ Route::group(['prefix' => 'api'], function () use ($middleware) { Route::get('accounts/verify_credentials', 'Api\ApiV1Controller@verifyCredentials')->middleware($middleware); Route::match(['post', 'patch'], 'accounts/update_credentials', 'Api\ApiV1Controller@accountUpdateCredentials')->middleware($middleware); Route::get('accounts/relationships', 'Api\ApiV1Controller@accountRelationshipsById')->middleware($middleware); + Route::get('accounts/lookup', 'Api\ApiV1Controller@accountLookupById')->middleware('throttle:account-lookup'); Route::get('accounts/search', 'Api\ApiV1Controller@accountSearch')->middleware($middleware); Route::get('accounts/{id}/statuses', 'Api\ApiV1Controller@accountStatusesById')->middleware($middleware); Route::get('accounts/{id}/following', 'Api\ApiV1Controller@accountFollowingById')->middleware($middleware);