diff --git a/app/Http/Middleware/JwtAuthMiddleware.php b/app/Http/Middleware/JwtAuthMiddleware.php index 3321393..dac309f 100644 --- a/app/Http/Middleware/JwtAuthMiddleware.php +++ b/app/Http/Middleware/JwtAuthMiddleware.php @@ -28,14 +28,24 @@ class JwtAuthMiddleware return response()->json(['message' => 'Invalid token algorithm'], 401); } - if ( - !$this->signatureIsValid($token, $signature) || - ($payload['iss'] ?? null) !== config('jwt.issuer') || - !$this->audienceIsValid($payload['aud'] ?? null) || - empty($payload['sub']) || - $this->tokenIsExpired($payload) - ) { - return response()->json(['message' => 'Invalid token'], 401); + if (!$this->signatureIsValid($token, $signature)) { + return response()->json(['message' => 'Invalid token signature'], 401); + } + + if (($payload['iss'] ?? null) !== config('jwt.issuer')) { + return response()->json(['message' => 'Invalid token issuer'], 401); + } + + if (!$this->audienceIsValid($payload['aud'] ?? null)) { + return response()->json(['message' => 'Invalid token audience'], 401); + } + + if (empty($payload['sub'])) { + return response()->json(['message' => 'Invalid token subject'], 401); + } + + if ($this->tokenIsExpired($payload)) { + return response()->json(['message' => 'Invalid or expired token'], 401); } $request->attributes->set('auth', [ @@ -105,12 +115,18 @@ class JwtAuthMiddleware throw new \RuntimeException(openssl_error_string() ?: 'OpenSSL could not read JWT public key'); } - return openssl_verify( + $result = openssl_verify( $header . '.' . $payload, $signature, $keyResource, OPENSSL_ALGO_SHA256 - ) === 1; + ); + + if ($result === false) { + throw new \RuntimeException(openssl_error_string() ?: 'OpenSSL could not verify JWT signature'); + } + + return $result === 1; } private function tokenIsExpired(array $payload): bool diff --git a/routes/api.php b/routes/api.php index 90b58a5..a1a9557 100644 --- a/routes/api.php +++ b/routes/api.php @@ -21,6 +21,10 @@ Route::prefix('v1')->middleware(['jwt.auth'])->group(function () { Route::get('/games/most-played', [GameController::class, 'mostPlayed']); }); +Route::get('/health', function () { + return response()->json(['status' => 'ok']); +}); + Route::get('/health-check-key', function () { $rawPublicKey = (string) config('jwt.public_key'); $formattedPublicKey = str_replace('\\n', "\n", $rawPublicKey); diff --git a/routes/web.php b/routes/web.php index b3d9bbc..1c715bc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1 +1,20 @@ json(['status' => 'ok']); +}); + +Route::get('/health-check-key', function () { + $rawPublicKey = (string) config('jwt.public_key'); + $formattedPublicKey = str_replace('\\n', "\n", $rawPublicKey); + $publicKeyResource = openssl_pkey_get_public($formattedPublicKey); + + return response()->json([ + 'raw_key_empty' => $rawPublicKey === '', + 'key_length' => strlen($formattedPublicKey), + 'openssl_accepted' => $publicKeyResource !== false, + 'openssl_error' => openssl_error_string(), + ]); +});