diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 83dc88da..71150aa4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [ "7.1", "7.2", "7.3", "7.4", "8.0", "8.1"] + php: [ "7.4", "8.0", "8.1"] name: PHP ${{matrix.php }} Unit Test steps: - uses: actions/checkout@v2 diff --git a/composer.json b/composer.json index 2a3cb2df..5551d316 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ ], "license": "BSD-3-Clause", "require": { - "php": "^7.1||^8.0" + "php": "^7.4||^8.0" }, "suggest": { "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" @@ -31,9 +31,9 @@ } }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", - "phpspec/prophecy-phpunit": "^1.1", - "phpunit/phpunit": "^7.5||^9.5", + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "psr/cache": "^1.0||^2.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" diff --git a/src/CachedKeySet.php b/src/CachedKeySet.php index 87f470d7..cf833ba4 100644 --- a/src/CachedKeySet.php +++ b/src/CachedKeySet.php @@ -16,62 +16,33 @@ */ class CachedKeySet implements ArrayAccess { - /** - * @var string - */ - private $jwksUri; - /** - * @var ClientInterface - */ - private $httpClient; - /** - * @var RequestFactoryInterface - */ - private $httpFactory; - /** - * @var CacheItemPoolInterface - */ - private $cache; - /** - * @var ?int - */ - private $expiresAfter; - /** - * @var ?CacheItemInterface - */ - private $cacheItem; - /** - * @var array - */ - private $keySet; - /** - * @var string - */ - private $cacheKey; - /** - * @var string - */ - private $cacheKeyPrefix = 'jwks'; - /** - * @var int - */ - private $maxKeyLength = 64; - /** - * @var bool - */ - private $rateLimit; - /** - * @var string - */ - private $rateLimitCacheKey; - /** - * @var int - */ - private $maxCallsPerMinute = 10; - /** - * @var string|null - */ - private $defaultAlg; + private string $jwksUri; + + private ClientInterface $httpClient; + + private RequestFactoryInterface $httpFactory; + + private CacheItemPoolInterface $cache; + + private ?int $expiresAfter; + + private ?CacheItemInterface $cacheItem = null; + + private ?array $keySet = null; + + private string $cacheKey; + + private string $cacheKeyPrefix = 'jwks'; + + private int $maxKeyLength = 64; + + private bool $rateLimit; + + private string $rateLimitCacheKey; + + private int $maxCallsPerMinute = 10; + + private ?string $defaultAlg; public function __construct( string $jwksUri, diff --git a/src/JWK.php b/src/JWK.php index 15631ecc..8ddd28c7 100644 --- a/src/JWK.php +++ b/src/JWK.php @@ -34,7 +34,7 @@ class JWK * Parse a set of JWK keys * * @param array $jwks The JSON Web Key Set as an associative array - * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * @param string|null $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return array An associative array of key IDs (kid) to Key objects @@ -75,7 +75,7 @@ public static function parseKeySet(array $jwks, string $defaultAlg = null): arra * Parse a JWK key * * @param array $jwk An individual JWK - * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * @param string|null $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return Key The key object for the JWK diff --git a/src/JWT.php b/src/JWT.php index 977d7fbd..821eea22 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -35,24 +35,20 @@ class JWT * When checking nbf, iat or expiration times, * we want to provide some extra leeway time to * account for clock skew. - * - * @var int */ - public static $leeway = 0; + public static int $leeway = 0; /** * Allow the current timestamp to be specified. * Useful for fixing a value within unit testing. * Will default to PHP time() value if null. - * - * @var ?int */ - public static $timestamp = null; + public static ?int $timestamp = null; /** * @var array */ - public static $supported_algs = [ + public static array $supported_algs = [ 'ES384' => ['openssl', 'SHA384'], 'ES256' => ['openssl', 'SHA256'], 'HS256' => ['hash_hmac', 'SHA256'], @@ -172,7 +168,7 @@ public static function decode( * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', * 'HS512', 'RS256', 'RS384', and 'RS512' - * @param string $keyId + * @param string|null $keyId * @param array $head An array with header elements to attach * * @return string A signed JWT @@ -480,9 +476,7 @@ private static function handleJsonError(int $errno): void JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 ]; throw new DomainException( - isset($messages[$errno]) - ? $messages[$errno] - : 'Unknown JSON error: ' . $errno + $messages[$errno] ?? 'Unknown JSON error: ' . $errno ); } diff --git a/src/Key.php b/src/Key.php index 00cf7f2e..42a12ee6 100644 --- a/src/Key.php +++ b/src/Key.php @@ -12,7 +12,7 @@ class Key /** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */ private $keyMaterial; /** @var string */ - private $algorithm; + private string $algorithm; /** * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial diff --git a/tests/CachedKeySetTest.php b/tests/CachedKeySetTest.php index 73b1213d..9eced110 100644 --- a/tests/CachedKeySetTest.php +++ b/tests/CachedKeySetTest.php @@ -6,6 +6,7 @@ use OutOfBoundsException; use PHPUnit\Framework\TestCase; use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; use Psr\Http\Client\ClientInterface; @@ -14,16 +15,18 @@ class CachedKeySetTest extends TestCase { - private $testJwksUri = 'https://jwk.uri'; - private $testJwksUriKey = 'jwkshttpsjwk.uri'; - private $testJwks1 = '{"keys": [{"kid":"foo","kty":"RSA","alg":"foo","n":"","e":""}]}'; - private $testJwks2 = '{"keys": [{"kid":"bar","kty":"RSA","alg":"bar","n":"","e":""}]}'; - private $testJwks3 = '{"keys": [{"kid":"baz","kty":"RSA","n":"","e":""}]}'; + use ProphecyTrait; - private $googleRsaUri = 'https://www.googleapis.com/oauth2/v3/certs'; + private string $testJwksUri = 'https://jwk.uri'; + private string $testJwksUriKey = 'jwkshttpsjwk.uri'; + private string $testJwks1 = '{"keys": [{"kid":"foo","kty":"RSA","alg":"foo","n":"","e":""}]}'; + private string $testJwks2 = '{"keys": [{"kid":"bar","kty":"RSA","alg":"bar","n":"","e":""}]}'; + private string $testJwks3 = '{"keys": [{"kid":"baz","kty":"RSA","n":"","e":""}]}'; + + private string $googleRsaUri = 'https://www.googleapis.com/oauth2/v3/certs'; // private $googleEcUri = 'https://www.gstatic.com/iap/verify/public_key-jwk'; - public function testEmptyUriThrowsException() + public function testEmptyUriThrowsException(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('JWKS URI is empty'); @@ -38,7 +41,7 @@ public function testEmptyUriThrowsException() $cachedKeySet['foo']; } - public function testOffsetSetThrowsException() + public function testOffsetSetThrowsException(): void { $this->expectException(LogicException::class); $this->expectExceptionMessage('Method not implemented'); @@ -53,7 +56,7 @@ public function testOffsetSetThrowsException() $cachedKeySet['foo'] = 'bar'; } - public function testOffsetUnsetThrowsException() + public function testOffsetUnsetThrowsException(): void { $this->expectException(LogicException::class); $this->expectExceptionMessage('Method not implemented'); @@ -68,7 +71,7 @@ public function testOffsetUnsetThrowsException() unset($cachedKeySet['foo']); } - public function testOutOfBoundsThrowsException() + public function testOutOfBoundsThrowsException(): void { $this->expectException(OutOfBoundsException::class); $this->expectExceptionMessage('Key ID not found'); @@ -84,7 +87,7 @@ public function testOutOfBoundsThrowsException() $cachedKeySet['bar']; } - public function testWithExistingKeyId() + public function testWithExistingKeyId(): void { $cachedKeySet = new CachedKeySet( $this->testJwksUri, @@ -96,7 +99,7 @@ public function testWithExistingKeyId() $this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm()); } - public function testWithDefaultAlg() + public function testWithDefaultAlg(): void { $cachedKeySet = new CachedKeySet( $this->testJwksUri, @@ -111,7 +114,7 @@ public function testWithDefaultAlg() $this->assertEquals('baz256', $cachedKeySet['baz']->getAlgorithm()); } - public function testKeyIdIsCached() + public function testKeyIdIsCached(): void { $cacheItem = $this->prophesize(CacheItemInterface::class); $cacheItem->isHit() @@ -135,7 +138,7 @@ public function testKeyIdIsCached() $this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm()); } - public function testCachedKeyIdRefresh() + public function testCachedKeyIdRefresh(): void { $cacheItem = $this->prophesize(CacheItemInterface::class); $cacheItem->isHit() @@ -171,7 +174,7 @@ public function testCachedKeyIdRefresh() $this->assertEquals('bar', $cachedKeySet['bar']->getAlgorithm()); } - public function testCacheItemWithExpiresAfter() + public function testCacheItemWithExpiresAfter(): void { $expiresAfter = 10; $cacheItem = $this->prophesize(CacheItemInterface::class); @@ -207,7 +210,7 @@ public function testCacheItemWithExpiresAfter() $this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm()); } - public function testJwtVerify() + public function testJwtVerify(): void { $privKey1 = file_get_contents(__DIR__ . '/data/rsa1-private.pem'); $payload = ['sub' => 'foo', 'exp' => strtotime('+10 seconds')]; @@ -236,7 +239,7 @@ public function testJwtVerify() $this->assertEquals('foo', $result->sub); } - public function testRateLimit() + public function testRateLimit(): void { // We request the key 11 times, HTTP should only be called 10 times $shouldBeCalledTimes = 10; @@ -293,7 +296,7 @@ public function testFullIntegration(string $jwkUri): void $this->assertEquals($keys['keys'][0]['alg'], $key->getAlgorithm()); } - public function provideFullIntegration() + public function provideFullIntegration(): array { return [ [$this->googleRsaUri], @@ -301,7 +304,7 @@ public function provideFullIntegration() ]; } - private function getMockHttpClient($testJwks, int $timesCalled = 1) + private function getMockHttpClient($testJwks, int $timesCalled = 1): object { $body = $this->prophesize('Psr\Http\Message\StreamInterface'); $body->__toString() @@ -321,7 +324,7 @@ private function getMockHttpClient($testJwks, int $timesCalled = 1) return $http->reveal(); } - private function getMockHttpFactory(int $timesCalled = 1) + private function getMockHttpFactory(int $timesCalled = 1): object { $request = $this->prophesize('Psr\Http\Message\RequestInterface'); $factory = $this->prophesize(RequestFactoryInterface::class); @@ -332,7 +335,7 @@ private function getMockHttpFactory(int $timesCalled = 1) return $factory->reveal(); } - private function getMockEmptyCache() + private function getMockEmptyCache(): object { $cacheItem = $this->prophesize(CacheItemInterface::class); $cacheItem->isHit() diff --git a/tests/JWKTest.php b/tests/JWKTest.php index b8c24f98..8691b7df 100644 --- a/tests/JWKTest.php +++ b/tests/JWKTest.php @@ -12,7 +12,7 @@ class JWKTest extends TestCase private static $privKey1; private static $privKey2; - public function testMissingKty() + public function testMissingKty(): void { $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('JWK must contain a "kty" parameter'); @@ -21,7 +21,7 @@ public function testMissingKty() $keys = JWK::parseKeySet(['keys' => [$badJwk]]); } - public function testInvalidAlgorithm() + public function testInvalidAlgorithm(): void { $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('No supported algorithms found in JWK Set'); @@ -30,7 +30,7 @@ public function testInvalidAlgorithm() $keys = JWK::parseKeySet(['keys' => [$badJwk]]); } - public function testParsePrivateKey() + public function testParsePrivateKey(): void { $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('RSA private keys are not supported'); @@ -44,7 +44,7 @@ public function testParsePrivateKey() JWK::parseKeySet($jwkSet); } - public function testParsePrivateKeyWithoutAlg() + public function testParsePrivateKeyWithoutAlg(): void { $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('JWK must contain an "alg" parameter'); @@ -58,7 +58,7 @@ public function testParsePrivateKeyWithoutAlg() JWK::parseKeySet($jwkSet); } - public function testParsePrivateKeyWithoutAlgWithDefaultAlgParameter() + public function testParsePrivateKeyWithoutAlgWithDefaultAlgParameter(): void { $jwkSet = json_decode( file_get_contents(__DIR__ . '/data/rsa-jwkset.json'), @@ -70,7 +70,7 @@ public function testParsePrivateKeyWithoutAlgWithDefaultAlgParameter() $this->assertEquals('foo', $jwks['jwk1']->getAlgorithm()); } - public function testParseKeyWithEmptyDValue() + public function testParseKeyWithEmptyDValue(): void { $jwkSet = json_decode( file_get_contents(__DIR__ . '/data/rsa-jwkset.json'), @@ -84,7 +84,7 @@ public function testParseKeyWithEmptyDValue() $this->assertTrue(\is_array($keys)); } - public function testParseJwkKeySet() + public function testParseJwkKeySet(): void { $jwkSet = json_decode( file_get_contents(__DIR__ . '/data/rsa-jwkset.json'), @@ -96,7 +96,7 @@ public function testParseJwkKeySet() self::$keys = $keys; } - public function testParseJwkKey_empty() + public function testParseJwkKey_empty(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('JWK must not be empty'); @@ -104,7 +104,7 @@ public function testParseJwkKey_empty() JWK::parseKeySet(['keys' => [[]]]); } - public function testParseJwkKeySet_empty() + public function testParseJwkKeySet_empty(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('JWK Set did not contain any keys'); @@ -115,7 +115,7 @@ public function testParseJwkKeySet_empty() /** * @depends testParseJwkKeySet */ - public function testDecodeByJwkKeySetTokenExpired() + public function testDecodeByJwkKeySetTokenExpired(): void { $privKey1 = file_get_contents(__DIR__ . '/data/rsa1-private.pem'); $payload = ['exp' => strtotime('-1 hour')]; @@ -129,7 +129,7 @@ public function testDecodeByJwkKeySetTokenExpired() /** * @dataProvider provideDecodeByJwkKeySet */ - public function testDecodeByJwkKeySet($pemFile, $jwkFile, $alg) + public function testDecodeByJwkKeySet($pemFile, $jwkFile, $alg): void { $privKey1 = file_get_contents(__DIR__ . '/data/' . $pemFile); $payload = ['sub' => 'foo', 'exp' => strtotime('+10 seconds')]; @@ -146,7 +146,7 @@ public function testDecodeByJwkKeySet($pemFile, $jwkFile, $alg) $this->assertEquals('foo', $result->sub); } - public function provideDecodeByJwkKeySet() + public function provideDecodeByJwkKeySet(): array { return [ ['rsa1-private.pem', 'rsa-jwkset.json', 'RS256'], @@ -157,7 +157,7 @@ public function provideDecodeByJwkKeySet() /** * @depends testParseJwkKeySet */ - public function testDecodeByMultiJwkKeySet() + public function testDecodeByMultiJwkKeySet(): void { $privKey2 = file_get_contents(__DIR__ . '/data/rsa2-private.pem'); $payload = ['sub' => 'bar', 'exp' => strtotime('+10 seconds')]; diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 58c334ed..040e73c2 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -12,7 +12,7 @@ class JWTTest extends TestCase { - public function testUrlSafeCharacters() + public function testUrlSafeCharacters(): void { $encoded = JWT::encode(['message' => 'f?'], 'a', 'HS256'); $expected = new stdClass(); @@ -20,19 +20,19 @@ public function testUrlSafeCharacters() $this->assertEquals($expected, JWT::decode($encoded, new Key('a', 'HS256'))); } - public function testMalformedUtf8StringsFail() + public function testMalformedUtf8StringsFail(): void { $this->expectException(DomainException::class); JWT::encode(['message' => pack('c', 128)], 'a', 'HS256'); } - public function testMalformedJsonThrowsException() + public function testMalformedJsonThrowsException(): void { $this->expectException(DomainException::class); JWT::jsonDecode('this is not valid JSON string'); } - public function testExpiredToken() + public function testExpiredToken(): void { $this->expectException(ExpiredException::class); $payload = [ @@ -43,7 +43,7 @@ public function testExpiredToken() JWT::decode($encoded, new Key('my_key', 'HS256')); } - public function testBeforeValidTokenWithNbf() + public function testBeforeValidTokenWithNbf(): void { $this->expectException(BeforeValidException::class); $payload = [ @@ -54,7 +54,7 @@ public function testBeforeValidTokenWithNbf() JWT::decode($encoded, new Key('my_key', 'HS256')); } - public function testBeforeValidTokenWithIat() + public function testBeforeValidTokenWithIat(): void { $this->expectException(BeforeValidException::class); $payload = [ @@ -65,7 +65,7 @@ public function testBeforeValidTokenWithIat() JWT::decode($encoded, new Key('my_key', 'HS256')); } - public function testValidToken() + public function testValidToken(): void { $payload = [ 'message' => 'abc', @@ -73,10 +73,10 @@ public function testValidToken() ]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); } - public function testValidTokenWithLeeway() + public function testValidTokenWithLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -85,11 +85,11 @@ public function testValidTokenWithLeeway() ]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); JWT::$leeway = 0; } - public function testExpiredTokenWithLeeway() + public function testExpiredTokenWithLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -99,11 +99,11 @@ public function testExpiredTokenWithLeeway() $this->expectException(ExpiredException::class); $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); JWT::$leeway = 0; } - public function testValidTokenWithNbf() + public function testValidTokenWithNbf(): void { $payload = [ 'message' => 'abc', @@ -113,10 +113,10 @@ public function testValidTokenWithNbf() ]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); } - public function testValidTokenWithNbfLeeway() + public function testValidTokenWithNbfLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -125,11 +125,11 @@ public function testValidTokenWithNbfLeeway() ]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); JWT::$leeway = 0; } - public function testInvalidTokenWithNbfLeeway() + public function testInvalidTokenWithNbfLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -142,7 +142,7 @@ public function testInvalidTokenWithNbfLeeway() JWT::$leeway = 0; } - public function testValidTokenWithIatLeeway() + public function testValidTokenWithIatLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -151,11 +151,11 @@ public function testValidTokenWithIatLeeway() ]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); - $this->assertEquals($decoded->message, 'abc'); + $this->assertEquals('abc', $decoded->message); JWT::$leeway = 0; } - public function testInvalidTokenWithIatLeeway() + public function testInvalidTokenWithIatLeeway(): void { JWT::$leeway = 60; $payload = [ @@ -168,7 +168,7 @@ public function testInvalidTokenWithIatLeeway() JWT::$leeway = 0; } - public function testInvalidToken() + public function testInvalidToken(): void { $payload = [ 'message' => 'abc', @@ -179,7 +179,7 @@ public function testInvalidToken() JWT::decode($encoded, new Key('my_key2', 'HS256')); } - public function testNullKeyFails() + public function testNullKeyFails(): void { $payload = [ 'message' => 'abc', @@ -190,7 +190,7 @@ public function testNullKeyFails() JWT::decode($encoded, new Key(null, 'HS256')); } - public function testEmptyKeyFails() + public function testEmptyKeyFails(): void { $payload = [ 'message' => 'abc', @@ -201,7 +201,7 @@ public function testEmptyKeyFails() JWT::decode($encoded, new Key('', 'HS256')); } - public function testKIDChooser() + public function testKIDChooser(): void { $keys = [ '1' => new Key('my_key', 'HS256'), @@ -214,7 +214,7 @@ public function testKIDChooser() $this->assertEquals($decoded, $expected); } - public function testArrayAccessKIDChooser() + public function testArrayAccessKIDChooser(): void { $keys = new ArrayObject([ '1' => new Key('my_key', 'HS256'), @@ -227,28 +227,28 @@ public function testArrayAccessKIDChooser() $this->assertEquals($decoded, $expected); } - public function testNoneAlgorithm() + public function testNoneAlgorithm(): void { $msg = JWT::encode(['message' => 'abc'], 'my_key', 'HS256'); $this->expectException(UnexpectedValueException::class); JWT::decode($msg, new Key('my_key', 'none')); } - public function testIncorrectAlgorithm() + public function testIncorrectAlgorithm(): void { $msg = JWT::encode(['message' => 'abc'], 'my_key', 'HS256'); $this->expectException(UnexpectedValueException::class); JWT::decode($msg, new Key('my_key', 'RS256')); } - public function testEmptyAlgorithm() + public function testEmptyAlgorithm(): void { $msg = JWT::encode(['message' => 'abc'], 'my_key', 'HS256'); $this->expectException(InvalidArgumentException::class); JWT::decode($msg, new Key('my_key', '')); } - public function testAdditionalHeaders() + public function testAdditionalHeaders(): void { $msg = JWT::encode(['message' => 'abc'], 'my_key', 'HS256', null, ['cty' => 'test-eit;v=1']); $expected = new stdClass(); @@ -256,20 +256,20 @@ public function testAdditionalHeaders() $this->assertEquals(JWT::decode($msg, new Key('my_key', 'HS256')), $expected); } - public function testInvalidSegmentCount() + public function testInvalidSegmentCount(): void { $this->expectException(UnexpectedValueException::class); JWT::decode('brokenheader.brokenbody', new Key('my_key', 'HS256')); } - public function testInvalidSignatureEncoding() + public function testInvalidSignatureEncoding(): void { $msg = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlUxx'; $this->expectException(UnexpectedValueException::class); JWT::decode($msg, new Key('secret', 'HS256')); } - public function testHSEncodeDecode() + public function testHSEncodeDecode(): void { $msg = JWT::encode(['message' => 'abc'], 'my_key', 'HS256'); $expected = new stdClass(); @@ -277,7 +277,7 @@ public function testHSEncodeDecode() $this->assertEquals(JWT::decode($msg, new Key('my_key', 'HS256')), $expected); } - public function testRSEncodeDecode() + public function testRSEncodeDecode(): void { $privKey = openssl_pkey_new(['digest_alg' => 'sha256', 'private_key_bits' => 1024,