diff --git a/lib/php-jwt/CHANGELOG.md b/lib/php-jwt/CHANGELOG.md
index 644fa0beafa..01fcc077414 100644
--- a/lib/php-jwt/CHANGELOG.md
+++ b/lib/php-jwt/CHANGELOG.md
@@ -1,5 +1,33 @@
# Changelog
+## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23)
+
+
+### Features
+
+* support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad))
+
+
+### Bug Fixes
+
+* refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca))
+
+## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24)
+
+
+### Bug Fixes
+
+* Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5))
+* support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e))
+
+## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18)
+
+
+### Bug Fixes
+
+* ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648))
+* ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae))
+
## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28)
diff --git a/lib/php-jwt/README.md b/lib/php-jwt/README.md
index 701de23a828..04252693ca9 100644
--- a/lib/php-jwt/README.md
+++ b/lib/php-jwt/README.md
@@ -17,7 +17,7 @@ composer require firebase/php-jwt
```
Optionally, install the `paragonie/sodium_compat` package from composer if your
-php is < 7.2 or does not have libsodium installed:
+php env does not have libsodium installed:
```bash
composer require paragonie/sodium_compat
@@ -48,7 +48,8 @@ $decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);
// Pass a stdClass in as the third parameter to get the decoded header values
-$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass());
+$headers = new stdClass();
+$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers);
print_r($headers);
/*
diff --git a/lib/php-jwt/composer.json b/lib/php-jwt/composer.json
index e23dfe378d8..816cfd0bd9a 100644
--- a/lib/php-jwt/composer.json
+++ b/lib/php-jwt/composer.json
@@ -20,7 +20,7 @@
],
"license": "BSD-3-Clause",
"require": {
- "php": "^7.4||^8.0"
+ "php": "^8.0"
},
"suggest": {
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present",
@@ -32,10 +32,10 @@
}
},
"require-dev": {
- "guzzlehttp/guzzle": "^6.5||^7.4",
+ "guzzlehttp/guzzle": "^7.4",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
- "psr/cache": "^1.0||^2.0",
+ "psr/cache": "^2.0||^3.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
}
diff --git a/lib/php-jwt/readme_moodle.txt b/lib/php-jwt/readme_moodle.txt
index f454f109324..e12cdcc6e92 100644
--- a/lib/php-jwt/readme_moodle.txt
+++ b/lib/php-jwt/readme_moodle.txt
@@ -7,10 +7,11 @@ Dependencies
Instructions
------------
-1. Check dependencies to confirm suitability of the new version of the library (see above).
-2. Visit [https://github.com/firebase/php-jwt].
-3. Click on 'X releases'.
-4. Download the latest release.
-5. Unzip it in lib as php-jwt.
-6. Update entry for this library in lib/thirdpartylibs.xml.
+1. Check dependencies to confirm suitability of the new version of the library (see above).
+2. Visit [https://github.com/firebase/php-jwt].
+3. Click on 'X releases'.
+4. Download the latest release.
+5. Remove everything under lib/php-jwt/ except this file (readme_moodle.txt).
+6. Unzip the release and put its content as into lib/php-jwt.
+7. Update entry for this library in lib/thirdpartylibs.xml.
diff --git a/lib/php-jwt/src/CachedKeySet.php b/lib/php-jwt/src/CachedKeySet.php
index ee529f9f50a..8e8e8d68cae 100644
--- a/lib/php-jwt/src/CachedKeySet.php
+++ b/lib/php-jwt/src/CachedKeySet.php
@@ -80,9 +80,9 @@ class CachedKeySet implements ArrayAccess
ClientInterface $httpClient,
RequestFactoryInterface $httpFactory,
CacheItemPoolInterface $cache,
- int $expiresAfter = null,
+ ?int $expiresAfter = null,
bool $rateLimit = false,
- string $defaultAlg = null
+ ?string $defaultAlg = null
) {
$this->jwksUri = $jwksUri;
$this->httpClient = $httpClient;
@@ -180,7 +180,7 @@ class CachedKeySet implements ArrayAccess
$jwksResponse = $this->httpClient->sendRequest($request);
if ($jwksResponse->getStatusCode() !== 200) {
throw new UnexpectedValueException(
- sprintf('HTTP Error: %d %s for URI "%s"',
+ \sprintf('HTTP Error: %d %s for URI "%s"',
$jwksResponse->getStatusCode(),
$jwksResponse->getReasonPhrase(),
$this->jwksUri,
@@ -212,15 +212,21 @@ class CachedKeySet implements ArrayAccess
}
$cacheItem = $this->cache->getItem($this->rateLimitCacheKey);
- if (!$cacheItem->isHit()) {
- $cacheItem->expiresAfter(1); // # of calls are cached each minute
+
+ $cacheItemData = [];
+ if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) {
+ $cacheItemData = $data;
}
- $callsPerMinute = (int) $cacheItem->get();
+ $callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0;
+ $expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC'));
+
if (++$callsPerMinute > $this->maxCallsPerMinute) {
return true;
}
- $cacheItem->set($callsPerMinute);
+
+ $cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]);
+ $cacheItem->expiresAt($expiry);
$this->cache->save($cacheItem);
return false;
}
diff --git a/lib/php-jwt/src/JWK.php b/lib/php-jwt/src/JWK.php
index 63fb2484b32..405dcc49b70 100644
--- a/lib/php-jwt/src/JWK.php
+++ b/lib/php-jwt/src/JWK.php
@@ -52,7 +52,7 @@ class JWK
*
* @uses parseKey
*/
- public static function parseKeySet(array $jwks, string $defaultAlg = null): array
+ public static function parseKeySet(array $jwks, ?string $defaultAlg = null): array
{
$keys = [];
@@ -93,7 +93,7 @@ class JWK
*
* @uses createPemFromModulusAndExponent
*/
- public static function parseKey(array $jwk, string $defaultAlg = null): ?Key
+ public static function parseKey(array $jwk, ?string $defaultAlg = null): ?Key
{
if (empty($jwk)) {
throw new InvalidArgumentException('JWK must not be empty');
@@ -172,6 +172,12 @@ class JWK
// This library works internally with EdDSA keys (Ed25519) encoded in standard base64.
$publicKey = JWT::convertBase64urlToBase64($jwk['x']);
return new Key($publicKey, $jwk['alg']);
+ case 'oct':
+ if (!isset($jwk['k'])) {
+ throw new UnexpectedValueException('k not set');
+ }
+
+ return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']);
default:
break;
}
@@ -212,7 +218,7 @@ class JWK
)
);
- return sprintf(
+ return \sprintf(
"-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n",
wordwrap(base64_encode($pem), 64, "\n", true)
);
diff --git a/lib/php-jwt/src/JWT.php b/lib/php-jwt/src/JWT.php
index 263492068cb..dd9292a4314 100644
--- a/lib/php-jwt/src/JWT.php
+++ b/lib/php-jwt/src/JWT.php
@@ -96,7 +96,7 @@ class JWT
public static function decode(
string $jwt,
$keyOrKeyArray,
- stdClass &$headers = null
+ ?stdClass &$headers = null
): stdClass {
// Validate JWT
$timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp;
@@ -200,11 +200,11 @@ class JWT
array $payload,
$key,
string $alg,
- string $keyId = null,
- array $head = null
+ ?string $keyId = null,
+ ?array $head = null
): string {
$header = ['typ' => 'JWT'];
- if (isset($head) && \is_array($head)) {
+ if (isset($head)) {
$header = \array_merge($header, $head);
}
$header['alg'] = $alg;
@@ -251,6 +251,9 @@ class JWT
return \hash_hmac($algorithm, $msg, $key, true);
case 'openssl':
$signature = '';
+ if (!\is_resource($key) && !openssl_pkey_get_private($key)) {
+ throw new DomainException('OpenSSL unable to validate key');
+ }
$success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line
if (!$success) {
throw new DomainException('OpenSSL unable to sign data');
@@ -384,12 +387,7 @@ class JWT
*/
public static function jsonEncode(array $input): string
{
- if (PHP_VERSION_ID >= 50400) {
- $json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
- } else {
- // PHP 5.3 only
- $json = \json_encode($input);
- }
+ $json = \json_encode($input, \JSON_UNESCAPED_SLASHES);
if ($errno = \json_last_error()) {
self::handleJsonError($errno);
} elseif ($json === 'null') {
diff --git a/lib/php-jwt/src/Key.php b/lib/php-jwt/src/Key.php
index 00cf7f2edf3..b34eae25858 100644
--- a/lib/php-jwt/src/Key.php
+++ b/lib/php-jwt/src/Key.php
@@ -9,18 +9,13 @@ use TypeError;
class Key
{
- /** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */
- private $keyMaterial;
- /** @var string */
- private $algorithm;
-
/**
* @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial
* @param string $algorithm
*/
public function __construct(
- $keyMaterial,
- string $algorithm
+ private $keyMaterial,
+ private string $algorithm
) {
if (
!\is_string($keyMaterial)
@@ -38,10 +33,6 @@ class Key
if (empty($algorithm)) {
throw new InvalidArgumentException('Algorithm must not be empty');
}
-
- // TODO: Remove in PHP 8.0 in favor of class constructor property promotion
- $this->keyMaterial = $keyMaterial;
- $this->algorithm = $algorithm;
}
/**
diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml
index 56cc1e89214..349c0603c81 100644
--- a/lib/thirdpartylibs.xml
+++ b/lib/thirdpartylibs.xml
@@ -515,7 +515,7 @@ All rights reserved.
php-jwt
PHP-JWT
A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to RFC 7519
- 6.10.0
+ 6.11.0
BSD
3-Clause
https://github.com/firebase/php-jwt