diff --git a/src/HttpClient/AuthenticatedClient.php b/src/HttpClient/AuthenticatedClient.php index c2b6bc3..fe88863 100644 --- a/src/HttpClient/AuthenticatedClient.php +++ b/src/HttpClient/AuthenticatedClient.php @@ -43,12 +43,24 @@ private function fetchAccessToken(): string throw new AuthenticationFailedException($this->shop->getShopId(), $response); } - /** @var array{access_token: string, expires_in: int} $token */ - $token = json_decode($response->getBody()->getContents(), true); + $body = $response->getBody()->getContents(); + + try { + $token = json_decode($body, true, 512, JSON_THROW_ON_ERROR); + } catch (\JsonException) { + throw new AuthenticationFailedException($this->shop->getShopId(), $response); + } + + if (!is_array($token) || !isset($token['access_token'], $token['expires_in'])) { + throw new AuthenticationFailedException( + $this->shop->getShopId(), + $response, + ); + } $this->cache->set($cacheKey, $token['access_token'], $token['expires_in'] - self::TOKEN_EXPIRE_DIFF); - return $token['access_token']; + return (string) $token['access_token']; } /** diff --git a/tests/HttpClient/AuthenticatedClientTest.php b/tests/HttpClient/AuthenticatedClientTest.php index 8e6e028..ebdd85a 100644 --- a/tests/HttpClient/AuthenticatedClientTest.php +++ b/tests/HttpClient/AuthenticatedClientTest.php @@ -172,4 +172,28 @@ public function getAuthenticatedClient(MockClient $mockClient, CacheInterface $c $cache ); } + + public function testInvalidJsonTokenResponseThrowsException(): void + { + $mockClient = new MockClient([ + new Response(200, [], 'not-a-json'), + ]); + + $client = $this->getAuthenticatedClient($mockClient); + + static::expectException(AuthenticationFailedException::class); + $client->sendRequest(new Request('GET', 'https://example.com')); + } + + public function testMissingTokenFieldsThrowsException(): void + { + $mockClient = new MockClient([ + new Response(200, [], '{"foo":"bar"}'), + ]); + + $client = $this->getAuthenticatedClient($mockClient); + static::expectException(AuthenticationFailedException::class); + + $client->sendRequest(new Request('GET', 'https://example.com')); + } }