diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc9a99..440b5e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ v1.5 - Fix FLEXIAPI-156 Disable the Phone change web form when PHONE_AUTHENTICATION is disabled - Fix FLEXIAPI-155 Add a new accountServiceAccountUpdatedHook and accountServiceAccountDeletedHook - Fix FLEXIAPI-153 Add phone and email to be changed in the Activity panel +- Fix FLEXIAPI-152 API Key usage clarification - Fix FLEXIAPI-151 Migrate to hCaptcha - Fix FLEXIAPI-150 Use the same account_id parameter for both API and Web routes - Fix FLEXIAPI-149 Add a toggle to disable phone check on username for admin endpoints and forms diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index 895ff56..68d0fd5 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -356,7 +356,7 @@ class Account extends Authenticatable return ($this->activationExpiration && $this->activationExpiration->isExpired()); } - public function generateApiKey(): ApiKey + public function generateApiKey(?Request $request = null): ApiKey { $this->apiKey()->delete(); @@ -364,6 +364,7 @@ class Account extends Authenticatable $apiKey->account_id = $this->id; $apiKey->last_used_at = Carbon::now(); $apiKey->key = Str::random(40); + $apiKey->ip = $request ? $request->ip() : '127.0.0.1'; $apiKey->save(); return $apiKey; diff --git a/flexiapi/app/Console/Commands/CreateAdminAccount.php b/flexiapi/app/Console/Commands/CreateAdminAccount.php index 55954f5..a1e12de 100644 --- a/flexiapi/app/Console/Commands/CreateAdminAccount.php +++ b/flexiapi/app/Console/Commands/CreateAdminAccount.php @@ -83,12 +83,7 @@ class CreateAdminAccount extends Command $account->created_at = Carbon::now()->subYears(3); $account->save(); - $apiKey = new ApiKey; - $apiKey->account_id = $account->id; - $apiKey->last_used_at = Carbon::now(); - $apiKey->key = Str::random(10); - $apiKey->save(); - + $account->generateApiKey(); $account->updatePassword($password); $this->info('Admin test account created: "' . $username . '@' . $domain . '" | Password: "' . $password . '" | API Key: "' . $apiKey->key . '"'); diff --git a/flexiapi/app/Http/Controllers/Account/ApiKeyController.php b/flexiapi/app/Http/Controllers/Account/ApiKeyController.php index b80ef80..700f182 100644 --- a/flexiapi/app/Http/Controllers/Account/ApiKeyController.php +++ b/flexiapi/app/Http/Controllers/Account/ApiKeyController.php @@ -34,7 +34,7 @@ class ApiKeyController extends Controller public function update(Request $request) { $account = $request->user(); - $account->generateApiKey(); + $account->generateApiKey($request); return redirect()->back(); } diff --git a/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php b/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php index f4406d0..0dbab97 100644 --- a/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php +++ b/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php @@ -29,7 +29,7 @@ class ApiKeyController extends Controller public function generate(Request $request) { $account = $request->user(); - $account->generateApiKey(); + $account->generateApiKey($request); $account->refresh(); Cookie::queue('x-api-key', $account->apiKey->key, config('app.api_key_expiration_minutes')); @@ -37,12 +37,12 @@ class ApiKeyController extends Controller return $account->apiKey->key; } - public function generateFromToken(string $token) + public function generateFromToken(Request $request, string $token) { $authToken = AuthToken::where('token', $token)->valid()->firstOrFail(); if ($authToken->account) { - $authToken->account->generateApiKey(); + $authToken->account->generateApiKey($request); $authToken->account->refresh(); Cookie::queue('x-api-key', $authToken->account->apiKey->key, config('app.api_key_expiration_minutes')); diff --git a/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php b/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php index 32b27d4..0930b2c 100644 --- a/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php +++ b/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php @@ -26,6 +26,7 @@ use Illuminate\Validation\Rule; use Illuminate\Support\Facades\Auth; use Illuminate\Http\Response; use Closure; +use Illuminate\Http\Request; use Validator; class AuthenticateDigestOrKey @@ -37,7 +38,7 @@ class AuthenticateDigestOrKey * @param \Closure $next * @return mixed */ - public function handle($request, Closure $next) + public function handle(Request $request, Closure $next) { if ($request->bearerToken() && Auth::check()) { return $next($request); @@ -50,8 +51,9 @@ class AuthenticateDigestOrKey $query->withoutGlobalScopes(); }])->where('key', $request->header('x-api-key') ?? $request->cookie('x-api-key'))->first(); - if ($apiKey) { + if ($apiKey && ($apiKey->ip == null || $apiKey->ip == $request->ip())) { $apiKey->last_used_at = Carbon::now(); + $apiKey->requests = $apiKey->requests + 1; $apiKey->save(); Auth::login($apiKey->account); diff --git a/flexiapi/database/migrations/2024_04_08_144054_add_request_counter_and_ip_to_api_keys_table.php b/flexiapi/database/migrations/2024_04_08_144054_add_request_counter_and_ip_to_api_keys_table.php new file mode 100644 index 0000000..47ddf92 --- /dev/null +++ b/flexiapi/database/migrations/2024_04_08_144054_add_request_counter_and_ip_to_api_keys_table.php @@ -0,0 +1,25 @@ +string('ip')->nullable(); + $table->integer('requests')->default(0); + }); + } + + public function down() + { + Schema::table('api_keys', function (Blueprint $table) { + $table->dropColumn('ip'); + $table->dropColumn('requests'); + }); + } +}; diff --git a/flexiapi/public/css/style.css b/flexiapi/public/css/style.css index 9aefbe7..29bc1b4 100644 --- a/flexiapi/public/css/style.css +++ b/flexiapi/public/css/style.css @@ -116,7 +116,7 @@ pre { color: var(--second-7); } -b { +b, strong { font-weight: bold; } diff --git a/flexiapi/resources/views/account/api_key.blade.php b/flexiapi/resources/views/account/api_key.blade.php index 29dbae6..450e7a6 100644 --- a/flexiapi/resources/views/account/api_key.blade.php +++ b/flexiapi/resources/views/account/api_key.blade.php @@ -7,7 +7,6 @@ @endsection @section('content') -
An unused key will expires after some times.
+ @if ($account->apiKey) +| Code | +Created | +Last usage | +IP | +Requests | +
|---|---|---|---|---|
| + {{ $account->apiKey->key }} + | ++ {{ $account->apiKey->created_at }} + | ++ {{ $account->apiKey->last_used_at }} + | ++ {{ $account->apiKey->ip ?? '-' }} + | ++ {{ $account->apiKey->requests }} + | +