mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-10-29 04:33:25 +00:00
Merge pull request #7568 from mailcow/feat/compose-update
[Web] Update composer libraries
This commit is contained in:
1296 files changed
+69434
-22307
No files matched your search
@@ -1604,7 +1604,9 @@ function init_db_schema()
|
|||||||
"redirect_uri" => "VARCHAR(2000)",
|
"redirect_uri" => "VARCHAR(2000)",
|
||||||
"expires" => "TIMESTAMP NOT NULL",
|
"expires" => "TIMESTAMP NOT NULL",
|
||||||
"scope" => "VARCHAR(4000)",
|
"scope" => "VARCHAR(4000)",
|
||||||
"id_token" => "VARCHAR(1000)"
|
"id_token" => "VARCHAR(1000)",
|
||||||
|
"code_challenge" => "VARCHAR(1000)",
|
||||||
|
"code_challenge_method" => "VARCHAR(20)"
|
||||||
),
|
),
|
||||||
"keys" => array(
|
"keys" => array(
|
||||||
"primary" => array(
|
"primary" => array(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"mustangostang/spyc": "^0.6.3",
|
"mustangostang/spyc": "^0.6.3",
|
||||||
"directorytree/ldaprecord": "^3.3",
|
"directorytree/ldaprecord": "^3.3",
|
||||||
"twig/twig": "^3.0",
|
"twig/twig": "^3.0",
|
||||||
"stevenmaguire/oauth2-keycloak": "^4.0",
|
"stevenmaguire/oauth2-keycloak": "^6.1",
|
||||||
"league/oauth2-client": "^2.7",
|
"league/oauth2-client": "^2.7",
|
||||||
"bacon/bacon-qr-code": "^2.0"
|
"bacon/bacon-qr-code": "^2.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+825
-472
File diff suppressed because it is too large.
Load diff
Vendored
+1
-4
@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
|
|||||||
echo $err;
|
echo $err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trigger_error(
|
throw new RuntimeException($err);
|
||||||
$err,
|
|
||||||
E_USER_ERROR
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|||||||
+34
-12
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
namespace Composer;
|
namespace Composer;
|
||||||
|
|
||||||
|
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
if (PHP_VERSION_ID < 80000) {
|
||||||
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
{
|
{
|
||||||
private $handle;
|
private $handle;
|
||||||
private $position;
|
private $position;
|
||||||
|
private $realpath;
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open($path, $mode, $options, &$opened_path)
|
||||||
{
|
{
|
||||||
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
|
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||||
$opened_path = substr($path, 21);
|
$opened_path = substr($path, 17);
|
||||||
$opened_path = realpath($opened_path) ?: $opened_path;
|
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||||
$this->handle = fopen($opened_path, $mode);
|
$opened_path = $this->realpath;
|
||||||
|
$this->handle = fopen($this->realpath, $mode);
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
|
|
||||||
// remove all traces of this stream wrapper once it has been used
|
|
||||||
stream_wrapper_unregister('composer-bin-proxy');
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
return (bool) $this->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
return $operation ? flock($this->handle, $operation) : true;
|
return $operation ? flock($this->handle, $operation) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function stream_seek($offset, $whence)
|
||||||
|
{
|
||||||
|
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||||
|
$this->position = ftell($this->handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function stream_tell()
|
public function stream_tell()
|
||||||
{
|
{
|
||||||
return $this->position;
|
return $this->position;
|
||||||
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
|
|
||||||
public function stream_stat()
|
public function stream_stat()
|
||||||
{
|
{
|
||||||
return fstat($this->handle);
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
public function stream_set_option($option, $arg1, $arg2)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function url_stat($path, $flags)
|
||||||
|
{
|
||||||
|
$path = substr($path, 17);
|
||||||
|
if (file_exists($path)) {
|
||||||
|
return stat($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
|
if (
|
||||||
include("composer-bin-proxy://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss');
|
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||||
exit(0);
|
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||||
|
) {
|
||||||
|
return include("phpvfscomposer://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss';
|
return include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifycss';
|
||||||
Vendored
+34
-12
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
namespace Composer;
|
namespace Composer;
|
||||||
|
|
||||||
|
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
if (PHP_VERSION_ID < 80000) {
|
||||||
@@ -23,18 +24,17 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
{
|
{
|
||||||
private $handle;
|
private $handle;
|
||||||
private $position;
|
private $position;
|
||||||
|
private $realpath;
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
public function stream_open($path, $mode, $options, &$opened_path)
|
||||||
{
|
{
|
||||||
// get rid of composer-bin-proxy:// prefix for __FILE__ & __DIR__ resolution
|
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||||
$opened_path = substr($path, 21);
|
$opened_path = substr($path, 17);
|
||||||
$opened_path = realpath($opened_path) ?: $opened_path;
|
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||||
$this->handle = fopen($opened_path, $mode);
|
$opened_path = $this->realpath;
|
||||||
|
$this->handle = fopen($this->realpath, $mode);
|
||||||
$this->position = 0;
|
$this->position = 0;
|
||||||
|
|
||||||
// remove all traces of this stream wrapper once it has been used
|
|
||||||
stream_wrapper_unregister('composer-bin-proxy');
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
return (bool) $this->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
return $operation ? flock($this->handle, $operation) : true;
|
return $operation ? flock($this->handle, $operation) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function stream_seek($offset, $whence)
|
||||||
|
{
|
||||||
|
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||||
|
$this->position = ftell($this->handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function stream_tell()
|
public function stream_tell()
|
||||||
{
|
{
|
||||||
return $this->position;
|
return $this->position;
|
||||||
@@ -78,20 +88,32 @@ if (PHP_VERSION_ID < 80000) {
|
|||||||
|
|
||||||
public function stream_stat()
|
public function stream_stat()
|
||||||
{
|
{
|
||||||
return fstat($this->handle);
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
public function stream_set_option($option, $arg1, $arg2)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function url_stat($path, $flags)
|
||||||
|
{
|
||||||
|
$path = substr($path, 17);
|
||||||
|
if (file_exists($path)) {
|
||||||
|
return stat($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('composer-bin-proxy', 'Composer\BinProxyWrapper')) {
|
if (
|
||||||
include("composer-bin-proxy://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs');
|
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
||||||
exit(0);
|
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
||||||
|
) {
|
||||||
|
return include("phpvfscomposer://" . __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs';
|
return include __DIR__ . '/..'.'/matthiasmullie/minify/bin/minifyjs';
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
name: Test Suite
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis
|
||||||
|
ports:
|
||||||
|
- 6379:6379
|
||||||
|
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||||
|
mongodb:
|
||||||
|
image: mongo
|
||||||
|
ports:
|
||||||
|
- 27017:27017
|
||||||
|
myriadb:
|
||||||
|
image: mariadb
|
||||||
|
env:
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
ports:
|
||||||
|
- 3808:3808
|
||||||
|
- 3306:3306
|
||||||
|
postgres:
|
||||||
|
image: postgres
|
||||||
|
env:
|
||||||
|
POSTGRES_DB: oauth2_server_php
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
options: --health-cmd="pg_isready -h localhost" --health-interval=10s --health-timeout=5s --health-retries=5
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php: [ 7.2, 7.3, 7.4, "8.0", 8.1, 8.2 ]
|
||||||
|
name: "PHP ${{ matrix.php }} Unit Test"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: codecov/codecov-action@v1
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
extensions: mongodb, mbstring, intl, redis, pdo_mysql
|
||||||
|
- name: Install composer dependencies
|
||||||
|
uses: nick-invision/retry@v1
|
||||||
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
command: composer install
|
||||||
|
- name: Run PHPUnit
|
||||||
|
run: vendor/bin/phpunit -v
|
||||||
|
phpstan:
|
||||||
|
name: "PHPStan"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: 8.1
|
||||||
|
- name: Install composer dependencies
|
||||||
|
uses: nick-invision/retry@v1
|
||||||
|
with:
|
||||||
|
timeout_minutes: 10
|
||||||
|
max_attempts: 3
|
||||||
|
command: composer install
|
||||||
|
- name: Run PHPStan
|
||||||
|
run: |
|
||||||
|
composer require phpstan/phpstan
|
||||||
|
vendor/bin/phpstan analyse --level=0 src/
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
oauth2-server-php
|
oauth2-server-php
|
||||||
=================
|
=================
|
||||||
|
|
||||||
[](https://travis-ci.org/bshaffer/oauth2-server-php)
|
[](https://packagist.org/packages/bshaffer/oauth2-server-php)
|
||||||
|
|
||||||
[](https://packagist.org/packages/bshaffer/oauth2-server-php)
|
|
||||||
|
|
||||||
View the [complete documentation](https://bshaffer.github.io/oauth2-server-php-docs/)
|
View the [complete documentation](https://bshaffer.github.io/oauth2-server-php-docs/)
|
||||||
@@ -16,21 +16,21 @@
|
|||||||
"psr-0": { "OAuth2": "src/" }
|
"psr-0": { "OAuth2": "src/" }
|
||||||
},
|
},
|
||||||
"require":{
|
"require":{
|
||||||
"php":">=5.3.9"
|
"php":">=7.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.0",
|
"phpunit/phpunit": "^7.5||^8.0",
|
||||||
"aws/aws-sdk-php": "~2.8",
|
"aws/aws-sdk-php": "^2.8",
|
||||||
"firebase/php-jwt": "~2.2",
|
"firebase/php-jwt": "^6.4",
|
||||||
"predis/predis": "dev-master",
|
"predis/predis": "^1.1",
|
||||||
"thobbs/phpcassa": "dev-master",
|
"thobbs/phpcassa": "dev-master",
|
||||||
"mongodb/mongodb": "^1.1"
|
"yoast/phpunit-polyfills": "^1.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"predis/predis": "Required to use Redis storage",
|
"predis/predis": "Required to use Redis storage",
|
||||||
"thobbs/phpcassa": "Required to use Cassandra storage",
|
"thobbs/phpcassa": "Required to use Cassandra storage",
|
||||||
"aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
|
"aws/aws-sdk-php": "~2.8 is required to use DynamoDB storage",
|
||||||
"firebase/php-jwt": "~2.2 is required to use JWT features",
|
"firebase/php-jwt": "~v6.4 is required to use JWT features",
|
||||||
"mongodb/mongodb": "^1.1 is required to use MongoDB storage"
|
"mongodb/mongodb": "^1.1 is required to use MongoDB storage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -39,7 +39,7 @@ class Autoloader
|
|||||||
* Handles autoloading of classes.
|
* Handles autoloading of classes.
|
||||||
*
|
*
|
||||||
* @param string $class - A class name.
|
* @param string $class - A class name.
|
||||||
* @return boolean - Returns true if the class has been loaded
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function autoload($class)
|
public function autoload($class)
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
+1
-1
@@ -112,7 +112,7 @@ class HttpBasic implements ClientAssertionTypeInterface
|
|||||||
*
|
*
|
||||||
* @ingroup oauth2_section_2
|
* @ingroup oauth2_section_2
|
||||||
*/
|
*/
|
||||||
public function getClientCredentials(RequestInterface $request, ResponseInterface $response = null)
|
public function getClientCredentials(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
|
if (!is_null($request->headers('PHP_AUTH_USER')) && !is_null($request->headers('PHP_AUTH_PW'))) {
|
||||||
return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
|
return array('client_id' => $request->headers('PHP_AUTH_USER'), 'client_secret' => $request->headers('PHP_AUTH_PW'));
|
||||||
|
|||||||
Vendored
+2
-1
@@ -78,7 +78,7 @@ class AuthorizeController implements AuthorizeControllerInterface
|
|||||||
* );
|
* );
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ScopeInterface $scopeUtil = null)
|
public function __construct(ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), ?ScopeInterface $scopeUtil = null)
|
||||||
{
|
{
|
||||||
$this->clientStorage = $clientStorage;
|
$this->clientStorage = $clientStorage;
|
||||||
$this->responseTypes = $responseTypes;
|
$this->responseTypes = $responseTypes;
|
||||||
@@ -87,6 +87,7 @@ class AuthorizeController implements AuthorizeControllerInterface
|
|||||||
'enforce_state' => true,
|
'enforce_state' => true,
|
||||||
'require_exact_redirect_uri' => true,
|
'require_exact_redirect_uri' => true,
|
||||||
'redirect_status_code' => 302,
|
'redirect_status_code' => 302,
|
||||||
|
'enforce_pkce' => false,
|
||||||
), $config);
|
), $config);
|
||||||
|
|
||||||
if (is_null($scopeUtil)) {
|
if (is_null($scopeUtil)) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -47,7 +47,7 @@ class ResourceController implements ResourceControllerInterface
|
|||||||
* @param array $config
|
* @param array $config
|
||||||
* @param ScopeInterface $scopeUtil
|
* @param ScopeInterface $scopeUtil
|
||||||
*/
|
*/
|
||||||
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ScopeInterface $scopeUtil = null)
|
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ?ScopeInterface $scopeUtil = null)
|
||||||
{
|
{
|
||||||
$this->tokenType = $tokenType;
|
$this->tokenType = $tokenType;
|
||||||
$this->tokenStorage = $tokenStorage;
|
$this->tokenStorage = $tokenStorage;
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ use OAuth2\ResponseInterface;
|
|||||||
* @code
|
* @code
|
||||||
* if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
|
* if (!$resourceController->verifyResourceRequest(OAuth2\Request::createFromGlobals(), $response = new OAuth2\Response())) {
|
||||||
* $response->send(); // authorization failed
|
* $response->send(); // authorization failed
|
||||||
* exit();
|
* die();
|
||||||
* }
|
* }
|
||||||
* return json_encode($resource); // valid token! Send the stuff!
|
* return json_encode($resource); // valid token! Send the stuff!
|
||||||
* @endcode
|
* @endcode
|
||||||
|
|||||||
Vendored
+1
-1
@@ -54,7 +54,7 @@ class TokenController implements TokenControllerInterface
|
|||||||
* @param ScopeInterface $scopeUtil
|
* @param ScopeInterface $scopeUtil
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function __construct(AccessTokenInterface $accessToken, ClientInterface $clientStorage, array $grantTypes = array(), ClientAssertionTypeInterface $clientAssertionType = null, ScopeInterface $scopeUtil = null)
|
public function __construct(AccessTokenInterface $accessToken, ClientInterface $clientStorage, array $grantTypes = array(), ?ClientAssertionTypeInterface $clientAssertionType = null, ?ScopeInterface $scopeUtil = null)
|
||||||
{
|
{
|
||||||
if (is_null($clientAssertionType)) {
|
if (is_null($clientAssertionType)) {
|
||||||
foreach ($grantTypes as $grantType) {
|
foreach ($grantTypes as $grantType) {
|
||||||
|
|||||||
+20
-7
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace OAuth2\Encryption;
|
namespace OAuth2\Encryption;
|
||||||
|
|
||||||
|
use Firebase\JWT\JWT;
|
||||||
|
use Firebase\JWT\Key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bridge file to use the firebase/php-jwt package for JWT encoding and decoding.
|
* Bridge file to use the firebase/php-jwt package for JWT encoding and decoding.
|
||||||
* @author Francis Chuang <francis.chuang@gmail.com>
|
* @author Francis Chuang <francis.chuang@gmail.com>
|
||||||
@@ -10,26 +13,36 @@ class FirebaseJwt implements EncryptionInterface
|
|||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (!class_exists('\JWT')) {
|
if (!class_exists(JWT::class)) {
|
||||||
throw new \ErrorException('firebase/php-jwt must be installed to use this feature. You can do this by running "composer require firebase/php-jwt"');
|
throw new \ErrorException('firebase/php-jwt must be installed to use this feature. You can do this by running "composer require firebase/php-jwt"');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function encode($payload, $key, $alg = 'HS256', $keyId = null)
|
public function encode($payload, $key, $alg = 'HS256', $keyId = null)
|
||||||
{
|
{
|
||||||
return \JWT::encode($payload, $key, $alg, $keyId);
|
return JWT::encode($payload, $key, $alg, $keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decode($jwt, $key = null, $allowedAlgorithms = null)
|
public function decode($jwt, $key = null, $allowedAlgorithms = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
//Maintain BC: Do not verify if no algorithms are passed in.
|
//Maintain BC: Do not verify if no algorithms are passed in.
|
||||||
if (!$allowedAlgorithms) {
|
if (!$allowedAlgorithms) {
|
||||||
$key = null;
|
$tks = \explode('.', $jwt);
|
||||||
|
if (\count($tks) === 3) {
|
||||||
|
[$headb64] = $tks;
|
||||||
|
$headerRaw = JWT::urlsafeB64Decode($headb64);
|
||||||
|
if (($header = JWT::jsonDecode($headerRaw))) {
|
||||||
|
$key = new Key($key, $header->alg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif(is_array($allowedAlgorithms)) {
|
||||||
|
$key = new Key($key, $allowedAlgorithms[0]);
|
||||||
|
} else {
|
||||||
|
$key = new Key($key, $allowedAlgorithms);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (array)\JWT::decode($jwt, $key, $allowedAlgorithms);
|
return (array) JWT::decode($jwt, $key);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -37,11 +50,11 @@ class FirebaseJwt implements EncryptionInterface
|
|||||||
|
|
||||||
public function urlSafeB64Encode($data)
|
public function urlSafeB64Encode($data)
|
||||||
{
|
{
|
||||||
return \JWT::urlsafeB64Encode($data);
|
return JWT::urlsafeB64Encode($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function urlSafeB64Decode($b64)
|
public function urlSafeB64Decode($b64)
|
||||||
{
|
{
|
||||||
return \JWT::urlsafeB64Decode($b64);
|
return JWT::urlsafeB64Decode($b64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
+35
@@ -84,6 +84,41 @@ class AuthorizationCode implements GrantTypeInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($authCode['code_challenge']) && $authCode['code_challenge']) {
|
||||||
|
if (!($code_verifier = $request->request('code_verifier'))) {
|
||||||
|
$response->setError(400, 'code_verifier_missing', "The PKCE code verifier parameter is required.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Validate code_verifier according to RFC-7636
|
||||||
|
// @see: https://tools.ietf.org/html/rfc7636#section-4.1
|
||||||
|
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $code_verifier) !== 1) {
|
||||||
|
$response->setError(400, 'code_verifier_invalid', "The PKCE code verifier parameter is invalid.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$code_verifier = $request->request('code_verifier');
|
||||||
|
switch ($authCode['code_challenge_method']) {
|
||||||
|
case 'S256':
|
||||||
|
$code_verifier_hashed = strtr(rtrim(base64_encode(hash('sha256', $code_verifier, true)), '='), '+/', '-_');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'plain':
|
||||||
|
$code_verifier_hashed = $code_verifier;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$response->setError(400, 'code_challenge_method_invalid', "Unknown PKCE code challenge method.");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if ($code_verifier_hashed !== $authCode['code_challenge']) {
|
||||||
|
$response->setError(400, 'code_verifier_mismatch', "The PKCE code verifier parameter does not match the code challenge.");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($authCode['code'])) {
|
if (!isset($authCode['code'])) {
|
||||||
$authCode['code'] = $code; // used to expire the code after the access token is granted
|
$authCode['code'] = $code; // used to expire the code after the access token is granted
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -37,7 +37,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
|||||||
* @param EncryptionInterface|JWT $jwtUtil - OPTONAL The class used to decode, encode and verify JWTs.
|
* @param EncryptionInterface|JWT $jwtUtil - OPTONAL The class used to decode, encode and verify JWTs.
|
||||||
* @param array $config
|
* @param array $config
|
||||||
*/
|
*/
|
||||||
public function __construct(JwtBearerInterface $storage, $audience, EncryptionInterface $jwtUtil = null, array $config = array())
|
public function __construct(JwtBearerInterface $storage, $audience, ?EncryptionInterface $jwtUtil = null, array $config = array())
|
||||||
{
|
{
|
||||||
$this->storage = $storage;
|
$this->storage = $storage;
|
||||||
$this->audience = $audience;
|
$this->audience = $audience;
|
||||||
@@ -46,13 +46,13 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
|||||||
$jwtUtil = new Jwt();
|
$jwtUtil = new Jwt();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->config = array_merge(array(
|
$config = array_merge(array(
|
||||||
'allowed_algorithms' => array('RS256', 'RS384', 'RS512')
|
'allowed_algorithms' => array('RS256', 'RS384', 'RS512')
|
||||||
), $config);
|
), $config);
|
||||||
|
|
||||||
$this->jwtUtil = $jwtUtil;
|
$this->jwtUtil = $jwtUtil;
|
||||||
|
|
||||||
$this->allowedAlgorithms = $this->config['allowed_algorithms'];
|
$this->allowedAlgorithms = $config['allowed_algorithms'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,7 +127,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check expiration
|
// Check expiration
|
||||||
if (ctype_digit($jwt['exp'])) {
|
if (ctype_digit((string)$jwt['exp'])) {
|
||||||
if ($jwt['exp'] <= time()) {
|
if ($jwt['exp'] <= time()) {
|
||||||
$response->setError(400, 'invalid_grant', "JWT has expired");
|
$response->setError(400, 'invalid_grant', "JWT has expired");
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class JwtBearer implements GrantTypeInterface, ClientAssertionTypeInterface
|
|||||||
|
|
||||||
// Check the not before time
|
// Check the not before time
|
||||||
if ($notBefore = $jwt['nbf']) {
|
if ($notBefore = $jwt['nbf']) {
|
||||||
if (ctype_digit($notBefore)) {
|
if (ctype_digit((string)$notBefore)) {
|
||||||
if ($notBefore > time()) {
|
if ($notBefore > time()) {
|
||||||
$response->setError(400, 'invalid_grant', "JWT cannot be used before the Not Before (nbf) time");
|
$response->setError(400, 'invalid_grant', "JWT cannot be used before the Not Before (nbf) time");
|
||||||
|
|
||||||
|
|||||||
+40
@@ -16,6 +16,16 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
|||||||
*/
|
*/
|
||||||
private $nonce;
|
private $nonce;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $code_challenge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $code_challenge_method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set not authorized response
|
* Set not authorized response
|
||||||
*
|
*
|
||||||
@@ -65,6 +75,10 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
|||||||
// add the nonce to return with the redirect URI
|
// add the nonce to return with the redirect URI
|
||||||
$params['nonce'] = $this->nonce;
|
$params['nonce'] = $this->nonce;
|
||||||
|
|
||||||
|
// Add PKCE code challenge.
|
||||||
|
$params['code_challenge'] = $this->code_challenge;
|
||||||
|
$params['code_challenge_method'] = $this->code_challenge_method;
|
||||||
|
|
||||||
return $params;
|
return $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +104,32 @@ class AuthorizeController extends BaseAuthorizeController implements AuthorizeCo
|
|||||||
|
|
||||||
$this->nonce = $nonce;
|
$this->nonce = $nonce;
|
||||||
|
|
||||||
|
$code_challenge = $request->query('code_challenge');
|
||||||
|
$code_challenge_method = $request->query('code_challenge_method');
|
||||||
|
|
||||||
|
if ($this->config['enforce_pkce']) {
|
||||||
|
if (!$code_challenge) {
|
||||||
|
$response->setError(400, 'missing_code_challenge', 'This application requires you provide a PKCE code challenge');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $code_challenge) !== 1) {
|
||||||
|
$response->setError(400, 'invalid_code_challenge', 'The PKCE code challenge supplied is invalid');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($code_challenge_method, array('plain', 'S256'), true)) {
|
||||||
|
$response->setError(400, 'missing_code_challenge_method', 'This application requires you specify a PKCE code challenge method');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->code_challenge = $code_challenge;
|
||||||
|
$this->code_challenge_method = $code_challenge_method;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ class UserInfoController extends ResourceController implements UserInfoControlle
|
|||||||
* @param array $config
|
* @param array $config
|
||||||
* @param ScopeInterface $scopeUtil
|
* @param ScopeInterface $scopeUtil
|
||||||
*/
|
*/
|
||||||
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ScopeInterface $scopeUtil = null)
|
public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, UserClaimsInterface $userClaimsStorage, $config = array(), ?ScopeInterface $scopeUtil = null)
|
||||||
{
|
{
|
||||||
parent::__construct($tokenType, $tokenStorage, $config, $scopeUtil);
|
parent::__construct($tokenType, $tokenStorage, $config, $scopeUtil);
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -31,9 +31,9 @@ class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCo
|
|||||||
// build the URL to redirect to
|
// build the URL to redirect to
|
||||||
$result = array('query' => array());
|
$result = array('query' => array());
|
||||||
|
|
||||||
$params += array('scope' => null, 'state' => null, 'id_token' => null);
|
$params += array('scope' => null, 'state' => null, 'id_token' => null, 'code_challenge' => null, 'code_challenge_method' => null);
|
||||||
|
|
||||||
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token']);
|
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['id_token'], $params['code_challenge'], $params['code_challenge_method']);
|
||||||
|
|
||||||
if (isset($params['state'])) {
|
if (isset($params['state'])) {
|
||||||
$result['query']['state'] = $params['state'];
|
$result['query']['state'] = $params['state'];
|
||||||
@@ -56,10 +56,10 @@ class AuthorizationCode extends BaseAuthorizationCode implements AuthorizationCo
|
|||||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||||
* @ingroup oauth2_section_4
|
* @ingroup oauth2_section_4
|
||||||
*/
|
*/
|
||||||
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null)
|
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
$code = $this->generateAuthorizationCode();
|
$code = $this->generateAuthorizationCode();
|
||||||
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token);
|
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, $id_token, $code_challenge, $code_challenge_method);
|
||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -38,7 +38,7 @@ class IdToken implements IdTokenInterface
|
|||||||
* @param EncryptionInterface $encryptionUtil
|
* @param EncryptionInterface $encryptionUtil
|
||||||
* @throws LogicException
|
* @throws LogicException
|
||||||
*/
|
*/
|
||||||
public function __construct(UserClaimsInterface $userClaimsStorage, PublicKeyInterface $publicKeyStorage, array $config = array(), EncryptionInterface $encryptionUtil = null)
|
public function __construct(UserClaimsInterface $userClaimsStorage, PublicKeyInterface $publicKeyStorage, array $config = array(), ?EncryptionInterface $encryptionUtil = null)
|
||||||
{
|
{
|
||||||
$this->userClaimsStorage = $userClaimsStorage;
|
$this->userClaimsStorage = $userClaimsStorage;
|
||||||
$this->publicKeyStorage = $publicKeyStorage;
|
$this->publicKeyStorage = $publicKeyStorage;
|
||||||
|
|||||||
+1
-1
@@ -33,5 +33,5 @@ interface AuthorizationCodeInterface extends BaseAuthorizationCodeInterface
|
|||||||
*
|
*
|
||||||
* @ingroup oauth2_section_4
|
* @ingroup oauth2_section_4
|
||||||
*/
|
*/
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null);
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null);
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ class Request implements RequestInterface
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
|
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, ?array $headers = null)
|
||||||
{
|
{
|
||||||
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content, $headers);
|
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content, $headers);
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ class Request implements RequestInterface
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, array $headers = null)
|
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null, ?array $headers = null)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->query = $query;
|
$this->query = $query;
|
||||||
|
|||||||
@@ -140,11 +140,10 @@ class Response implements ResponseInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $statusCode
|
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function setStatusCode($statusCode, $text = null)
|
public function setStatusCode(int $statusCode, $text = null)
|
||||||
{
|
{
|
||||||
$this->statusCode = (int) $statusCode;
|
$this->statusCode = (int) $statusCode;
|
||||||
if ($this->isInvalid()) {
|
if ($this->isInvalid()) {
|
||||||
|
|||||||
+1
-4
@@ -20,10 +20,7 @@ interface ResponseInterface
|
|||||||
*/
|
*/
|
||||||
public function addHttpHeaders(array $httpHeaders);
|
public function addHttpHeaders(array $httpHeaders);
|
||||||
|
|
||||||
/**
|
public function setStatusCode(int $statusCode);
|
||||||
* @param int $statusCode
|
|
||||||
*/
|
|
||||||
public function setStatusCode($statusCode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $statusCode
|
* @param int $statusCode
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class AccessToken implements AccessTokenInterface
|
|||||||
* );
|
* );
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
public function __construct(AccessTokenStorageInterface $tokenStorage, RefreshTokenInterface $refreshStorage = null, array $config = array())
|
public function __construct(AccessTokenStorageInterface $tokenStorage, ?RefreshTokenInterface $refreshStorage = null, array $config = array())
|
||||||
{
|
{
|
||||||
$this->tokenStorage = $tokenStorage;
|
$this->tokenStorage = $tokenStorage;
|
||||||
$this->refreshStorage = $refreshStorage;
|
$this->refreshStorage = $refreshStorage;
|
||||||
|
|||||||
Vendored
+4
-4
@@ -26,9 +26,9 @@ class AuthorizationCode implements AuthorizationCodeInterface
|
|||||||
// build the URL to redirect to
|
// build the URL to redirect to
|
||||||
$result = array('query' => array());
|
$result = array('query' => array());
|
||||||
|
|
||||||
$params += array('scope' => null, 'state' => null);
|
$params += array('scope' => null, 'state' => null, 'code_challenge' => null, 'code_challenge_method' => null);
|
||||||
|
|
||||||
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope']);
|
$result['query']['code'] = $this->createAuthorizationCode($params['client_id'], $user_id, $params['redirect_uri'], $params['scope'], $params['code_challenge'], $params['code_challenge_method']);
|
||||||
|
|
||||||
if (isset($params['state'])) {
|
if (isset($params['state'])) {
|
||||||
$result['query']['state'] = $params['state'];
|
$result['query']['state'] = $params['state'];
|
||||||
@@ -53,10 +53,10 @@ class AuthorizationCode implements AuthorizationCodeInterface
|
|||||||
* @see http://tools.ietf.org/html/rfc6749#section-4
|
* @see http://tools.ietf.org/html/rfc6749#section-4
|
||||||
* @ingroup oauth2_section_4
|
* @ingroup oauth2_section_4
|
||||||
*/
|
*/
|
||||||
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null)
|
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
$code = $this->generateAuthorizationCode();
|
$code = $this->generateAuthorizationCode();
|
||||||
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope);
|
$this->storage->setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, time() + $this->config['auth_code_lifetime'], $scope, null, $code_challenge, $code_challenge_method);
|
||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -26,7 +26,7 @@ class JwtAccessToken extends AccessToken
|
|||||||
* or just the token ID is stored
|
* or just the token ID is stored
|
||||||
* @param EncryptionInterface $encryptionUtil -
|
* @param EncryptionInterface $encryptionUtil -
|
||||||
*/
|
*/
|
||||||
public function __construct(PublicKeyInterface $publicKeyStorage = null, AccessTokenStorageInterface $tokenStorage = null, RefreshTokenInterface $refreshStorage = null, array $config = array(), EncryptionInterface $encryptionUtil = null)
|
public function __construct(?PublicKeyInterface $publicKeyStorage = null, ?AccessTokenStorageInterface $tokenStorage = null, ?RefreshTokenInterface $refreshStorage = null, array $config = array(), ?EncryptionInterface $encryptionUtil = null)
|
||||||
{
|
{
|
||||||
$this->publicKeyStorage = $publicKeyStorage;
|
$this->publicKeyStorage = $publicKeyStorage;
|
||||||
$config = array_merge(array(
|
$config = array_merge(array(
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
*
|
*
|
||||||
* @ingroup oauth2_section_7
|
* @ingroup oauth2_section_7
|
||||||
*/
|
*/
|
||||||
public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), TokenTypeInterface $tokenType = null, ScopeInterface $scopeUtil = null, ClientAssertionTypeInterface $clientAssertionType = null)
|
public function __construct($storage = array(), array $config = array(), array $grantTypes = array(), array $responseTypes = array(), ?TokenTypeInterface $tokenType = null, ?ScopeInterface $scopeUtil = null, ?ClientAssertionTypeInterface $clientAssertionType = null)
|
||||||
{
|
{
|
||||||
$storage = is_array($storage) ? $storage : array($storage);
|
$storage = is_array($storage) ? $storage : array($storage);
|
||||||
$this->storages = array();
|
$this->storages = array();
|
||||||
@@ -172,6 +172,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
'enforce_state' => true,
|
'enforce_state' => true,
|
||||||
'require_exact_redirect_uri' => true,
|
'require_exact_redirect_uri' => true,
|
||||||
'allow_implicit' => false,
|
'allow_implicit' => false,
|
||||||
|
'enforce_pkce' => false,
|
||||||
'allow_credentials_in_request_body' => true,
|
'allow_credentials_in_request_body' => true,
|
||||||
'allow_public_clients' => true,
|
'allow_public_clients' => true,
|
||||||
'always_issue_new_refresh_token' => false,
|
'always_issue_new_refresh_token' => false,
|
||||||
@@ -288,7 +289,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
*
|
*
|
||||||
* @see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
|
* @see http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
|
||||||
*/
|
*/
|
||||||
public function handleUserInfoRequest(RequestInterface $request, ResponseInterface $response = null)
|
public function handleUserInfoRequest(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
|
$this->getUserInfoController()->handleUserInfoRequest($request, $this->response);
|
||||||
@@ -314,7 +315,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
*
|
*
|
||||||
* @ingroup oauth2_section_4
|
* @ingroup oauth2_section_4
|
||||||
*/
|
*/
|
||||||
public function handleTokenRequest(RequestInterface $request, ResponseInterface $response = null)
|
public function handleTokenRequest(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$this->getTokenController()->handleTokenRequest($request, $this->response);
|
$this->getTokenController()->handleTokenRequest($request, $this->response);
|
||||||
@@ -327,7 +328,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
* @param ResponseInterface $response - Response object
|
* @param ResponseInterface $response - Response object
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function grantAccessToken(RequestInterface $request, ResponseInterface $response = null)
|
public function grantAccessToken(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$value = $this->getTokenController()->grantAccessToken($request, $this->response);
|
$value = $this->getTokenController()->grantAccessToken($request, $this->response);
|
||||||
@@ -345,7 +346,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
* @param ResponseInterface $response
|
* @param ResponseInterface $response
|
||||||
* @return Response|ResponseInterface
|
* @return Response|ResponseInterface
|
||||||
*/
|
*/
|
||||||
public function handleRevokeRequest(RequestInterface $request, ResponseInterface $response = null)
|
public function handleRevokeRequest(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$this->getTokenController()->handleRevokeRequest($request, $this->response);
|
$this->getTokenController()->handleRevokeRequest($request, $this->response);
|
||||||
@@ -407,7 +408,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
*
|
*
|
||||||
* @ingroup oauth2_section_3
|
* @ingroup oauth2_section_3
|
||||||
*/
|
*/
|
||||||
public function validateAuthorizeRequest(RequestInterface $request, ResponseInterface $response = null)
|
public function validateAuthorizeRequest(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
|
$value = $this->getAuthorizeController()->validateAuthorizeRequest($request, $this->response);
|
||||||
@@ -421,7 +422,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
* @param string $scope - Scope
|
* @param string $scope - Scope
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response = null, $scope = null)
|
public function verifyResourceRequest(RequestInterface $request, ?ResponseInterface $response = null, $scope = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
|
$value = $this->getResourceController()->verifyResourceRequest($request, $this->response, $scope);
|
||||||
@@ -434,7 +435,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
* @param ResponseInterface $response - Response object
|
* @param ResponseInterface $response - Response object
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getAccessTokenData(RequestInterface $request, ResponseInterface $response = null)
|
public function getAccessTokenData(RequestInterface $request, ?ResponseInterface $response = null)
|
||||||
{
|
{
|
||||||
$this->response = is_null($response) ? new Response() : $response;
|
$this->response = is_null($response) ? new Response() : $response;
|
||||||
$value = $this->getResourceController()->getAccessTokenData($request, $this->response);
|
$value = $this->getResourceController()->getAccessTokenData($request, $this->response);
|
||||||
@@ -577,7 +578,7 @@ class Server implements ResourceControllerInterface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri')));
|
$config = array_intersect_key($this->config, array_flip(explode(' ', 'allow_implicit enforce_state require_exact_redirect_uri enforce_pkce')));
|
||||||
|
|
||||||
if ($this->config['use_openid_connect']) {
|
if ($this->config['use_openid_connect']) {
|
||||||
return new OpenIDAuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
|
return new OpenIDAuthorizeController($this->storages['client'], $this->responseTypes, $config, $this->getScopeUtil());
|
||||||
|
|||||||
+2
-2
@@ -191,11 +191,11 @@ class Cassandra implements AuthorizationCodeInterface,
|
|||||||
* @param string $id_token
|
* @param string $id_token
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
return $this->setValue(
|
return $this->setValue(
|
||||||
$this->config['code_key'] . $authorization_code,
|
$this->config['code_key'] . $authorization_code,
|
||||||
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
|
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'),
|
||||||
$expires
|
$expires
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-3
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace OAuth2\Storage;
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
use Couchbase;
|
||||||
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
use OAuth2\OpenID\Storage\AuthorizationCodeInterface as OpenIDAuthorizationCodeInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,14 +28,18 @@ class CouchbaseDB implements AuthorizationCodeInterface,
|
|||||||
|
|
||||||
public function __construct($connection, $config = array())
|
public function __construct($connection, $config = array())
|
||||||
{
|
{
|
||||||
if ($connection instanceof \Couchbase) {
|
if (!class_exists(Couchbase::class)) {
|
||||||
|
throw new \RuntimeException('Missing Couchbase');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($connection instanceof Couchbase) {
|
||||||
$this->db = $connection;
|
$this->db = $connection;
|
||||||
} else {
|
} else {
|
||||||
if (!is_array($connection) || !is_array($connection['servers'])) {
|
if (!is_array($connection) || !is_array($connection['servers'])) {
|
||||||
throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
|
throw new \InvalidArgumentException('First argument to OAuth2\Storage\CouchbaseDB must be an instance of Couchbase or a configuration array containing a server array');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->db = new \Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
|
$this->db = new Couchbase($connection['servers'], (!isset($connection['username'])) ? '' : $connection['username'], (!isset($connection['password'])) ? '' : $connection['password'], $connection['bucket'], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->config = array_merge(array(
|
$this->config = array_merge(array(
|
||||||
@@ -173,7 +178,7 @@ class CouchbaseDB implements AuthorizationCodeInterface,
|
|||||||
return is_null($code) ? false : $code;
|
return is_null($code) ? false : $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
// if it exists, update it.
|
// if it exists, update it.
|
||||||
if ($this->getAuthorizationCode($code)) {
|
if ($this->getAuthorizationCode($code)) {
|
||||||
@@ -185,6 +190,8 @@ class CouchbaseDB implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
$this->setObjectByType('code_table',$code,array(
|
$this->setObjectByType('code_table',$code,array(
|
||||||
@@ -195,6 +202,8 @@ class CouchbaseDB implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -213,12 +213,12 @@ class DynamoDB implements
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
// convert expires to datestring
|
// convert expires to datestring
|
||||||
$expires = date('Y-m-d H:i:s', $expires);
|
$expires = date('Y-m-d H:i:s', $expires);
|
||||||
|
|
||||||
$clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'id_token', 'scope');
|
$clientData = compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method');
|
||||||
$clientData = array_filter($clientData, 'self::isNotEmpty');
|
$clientData = array_filter($clientData, 'self::isNotEmpty');
|
||||||
|
|
||||||
$result = $this->client->putItem(array(
|
$result = $this->client->putItem(array(
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ class JwtAccessToken implements JwtAccessTokenInterface
|
|||||||
* is not necessary when using this grant type.
|
* is not necessary when using this grant type.
|
||||||
* @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
|
* @param OAuth2\Encryption\EncryptionInterface $encryptionUtil OPTIONAL class to use for "encode" and "decode" functions.
|
||||||
*/
|
*/
|
||||||
public function __construct(PublicKeyInterface $publicKeyStorage, AccessTokenInterface $tokenStorage = null, EncryptionInterface $encryptionUtil = null)
|
public function __construct(PublicKeyInterface $publicKeyStorage, ?AccessTokenInterface $tokenStorage = null, ?EncryptionInterface $encryptionUtil = null)
|
||||||
{
|
{
|
||||||
$this->publicKeyStorage = $publicKeyStorage;
|
$this->publicKeyStorage = $publicKeyStorage;
|
||||||
$this->tokenStorage = $tokenStorage;
|
$this->tokenStorage = $tokenStorage;
|
||||||
|
|||||||
+2
-2
@@ -74,9 +74,9 @@ class Memory implements AuthorizationCodeInterface,
|
|||||||
), $this->authorizationCodes[$code]);
|
), $this->authorizationCodes[$code]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
$this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token');
|
$this->authorizationCodes[$code] = compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -179,7 +179,7 @@ class Mongo implements AuthorizationCodeInterface,
|
|||||||
return is_null($code) ? false : $code;
|
return is_null($code) ? false : $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
// if it exists, update it.
|
// if it exists, update it.
|
||||||
if ($this->getAuthorizationCode($code)) {
|
if ($this->getAuthorizationCode($code)) {
|
||||||
@@ -192,6 +192,8 @@ class Mongo implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -203,6 +205,8 @@ class Mongo implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
);
|
);
|
||||||
$this->collection('code_table')->insert($token);
|
$this->collection('code_table')->insert($token);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -32,6 +32,9 @@ class MongoDB implements AuthorizationCodeInterface,
|
|||||||
|
|
||||||
public function __construct($connection, $config = array())
|
public function __construct($connection, $config = array())
|
||||||
{
|
{
|
||||||
|
if (!class_exists(Database::class) || !class_exists(Client::class)) {
|
||||||
|
throw new \LogicException('Missing MongoDB php extension. Please install mongodb.so');
|
||||||
|
}
|
||||||
if ($connection instanceof Database) {
|
if ($connection instanceof Database) {
|
||||||
$this->db = $connection;
|
$this->db = $connection;
|
||||||
} else {
|
} else {
|
||||||
@@ -167,7 +170,7 @@ class MongoDB implements AuthorizationCodeInterface,
|
|||||||
return is_null($code) ? false : $code;
|
return is_null($code) ? false : $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
// if it exists, update it.
|
// if it exists, update it.
|
||||||
if ($this->getAuthorizationCode($code)) {
|
if ($this->getAuthorizationCode($code)) {
|
||||||
@@ -180,6 +183,8 @@ class MongoDB implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
return $result->getMatchedCount() > 0;
|
return $result->getMatchedCount() > 0;
|
||||||
@@ -192,6 +197,8 @@ class MongoDB implements AuthorizationCodeInterface,
|
|||||||
'expires' => $expires,
|
'expires' => $expires,
|
||||||
'scope' => $scope,
|
'scope' => $scope,
|
||||||
'id_token' => $id_token,
|
'id_token' => $id_token,
|
||||||
|
'code_challenge' => $code_challenge,
|
||||||
|
'code_challenge_method' => $code_challenge_method,
|
||||||
);
|
);
|
||||||
$result = $this->collection('code_table')->insertOne($token);
|
$result = $this->collection('code_table')->insertOne($token);
|
||||||
return $result->getInsertedCount() > 0;
|
return $result->getInsertedCount() > 0;
|
||||||
|
|||||||
+10
-8
@@ -247,7 +247,7 @@ class Pdo implements
|
|||||||
* @param string $id_token
|
* @param string $id_token
|
||||||
* @return bool|mixed
|
* @return bool|mixed
|
||||||
*/
|
*/
|
||||||
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
if (func_num_args() > 6) {
|
if (func_num_args() > 6) {
|
||||||
// we are calling with an id token
|
// we are calling with an id token
|
||||||
@@ -259,12 +259,12 @@ class Pdo implements
|
|||||||
|
|
||||||
// if it exists, update it.
|
// if it exists, update it.
|
||||||
if ($this->getAuthorizationCode($code)) {
|
if ($this->getAuthorizationCode($code)) {
|
||||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope where authorization_code=:code', $this->config['code_table']));
|
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, code_challenge=:code_challenge, code_challenge_method=:code_challenge_method where authorization_code=:code', $this->config['code_table']));
|
||||||
} else {
|
} else {
|
||||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope)', $this->config['code_table']));
|
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, code_challenge, code_challenge_method) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :code_challenge, :code_challenge_method)', $this->config['code_table']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
|
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'code_challenge', 'code_challenge_method'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -277,19 +277,19 @@ class Pdo implements
|
|||||||
* @param string $id_token
|
* @param string $id_token
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
private function setAuthorizationCodeWithIdToken($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
// convert expires to datestring
|
// convert expires to datestring
|
||||||
$expires = date('Y-m-d H:i:s', $expires);
|
$expires = date('Y-m-d H:i:s', $expires);
|
||||||
|
|
||||||
// if it exists, update it.
|
// if it exists, update it.
|
||||||
if ($this->getAuthorizationCode($code)) {
|
if ($this->getAuthorizationCode($code)) {
|
||||||
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token where authorization_code=:code', $this->config['code_table']));
|
$stmt = $this->db->prepare($sql = sprintf('UPDATE %s SET client_id=:client_id, user_id=:user_id, redirect_uri=:redirect_uri, expires=:expires, scope=:scope, id_token =:id_token, code_challenge=:code_challenge, code_challenge_method=:code_challenge_method where authorization_code=:code', $this->config['code_table']));
|
||||||
} else {
|
} else {
|
||||||
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token)', $this->config['code_table']));
|
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (authorization_code, client_id, user_id, redirect_uri, expires, scope, id_token, code_challenge, code_challenge_method) VALUES (:code, :client_id, :user_id, :redirect_uri, :expires, :scope, :id_token, :code_challenge, :code_challenge_method)', $this->config['code_table']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'));
|
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -676,6 +676,8 @@ class Pdo implements
|
|||||||
expires TIMESTAMP NOT NULL,
|
expires TIMESTAMP NOT NULL,
|
||||||
scope VARCHAR(4000),
|
scope VARCHAR(4000),
|
||||||
id_token VARCHAR(1000),
|
id_token VARCHAR(1000),
|
||||||
|
code_challenge VARCHAR(1000),
|
||||||
|
code_challenge_method VARCHAR(20),
|
||||||
PRIMARY KEY (authorization_code)
|
PRIMARY KEY (authorization_code)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -95,11 +95,11 @@ class Redis implements AuthorizationCodeInterface,
|
|||||||
return $this->getValue($this->config['code_key'] . $code);
|
return $this->getValue($this->config['code_key'] . $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
|
public function setAuthorizationCode($authorization_code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null, $code_challenge = null, $code_challenge_method = null)
|
||||||
{
|
{
|
||||||
return $this->setValue(
|
return $this->setValue(
|
||||||
$this->config['code_key'] . $authorization_code,
|
$this->config['code_key'] . $authorization_code,
|
||||||
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token'),
|
compact('authorization_code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope', 'id_token', 'code_challenge', 'code_challenge_method'),
|
||||||
$expires
|
$expires
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -109,7 +109,7 @@ class Bearer implements TokenTypeInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$contentType = $request->server('CONTENT_TYPE');
|
$contentType = $request->server('CONTENT_TYPE');
|
||||||
if (false !== $pos = strpos($contentType, ';')) {
|
if (false !== $pos = strpos((string) $contentType, ';')) {
|
||||||
$contentType = substr($contentType, 0, $pos);
|
$contentType = substr($contentType, 0, $pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -133,7 +133,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertNotContains('error', $response->getHttpHeader('Location'));
|
$this->assertStringNotContainsString('error', $response->getHttpHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEnforceScope()
|
public function testEnforceScope()
|
||||||
@@ -161,7 +161,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertNotContains('error', $response->getHttpHeader('Location'));
|
$this->assertStringNotContainsString('error', $response->getHttpHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidRedirectUri()
|
public function testInvalidRedirectUri()
|
||||||
@@ -227,7 +227,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertContains('code', $response->getHttpHeader('Location'));
|
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
|
public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
|
||||||
@@ -263,7 +263,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertContains('code', $response->getHttpHeader('Location'));
|
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMultipleRedirectUris()
|
public function testMultipleRedirectUris()
|
||||||
@@ -278,14 +278,14 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
|
|
||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertContains('code', $response->getHttpHeader('Location'));
|
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
|
||||||
|
|
||||||
// call again with different (but still valid) redirect URI
|
// call again with different (but still valid) redirect URI
|
||||||
$request->query['redirect_uri'] = 'http://morehazards.com';
|
$request->query['redirect_uri'] = 'http://morehazards.com';
|
||||||
|
|
||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertContains('code', $response->getHttpHeader('Location'));
|
$this->assertStringContainsString('code', $response->getHttpHeader('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,7 +303,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
|
|
||||||
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
$server->handleAuthorizeRequest($request, $response = new Response(), true);
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$this->assertContains('state', $response->getHttpHeader('Location'));
|
$this->assertStringContainsString('state', $response->getHttpHeader('Location'));
|
||||||
$this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
|
$this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
|
||||||
|
|
||||||
$parts = parse_url($response->getHttpHeader('Location'));
|
$parts = parse_url($response->getHttpHeader('Location'));
|
||||||
@@ -421,7 +421,7 @@ class AuthorizeControllerTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertFalse(isset($parts['fake']));
|
$this->assertFalse(isset($parts['fake']));
|
||||||
|
|||||||
Vendored
+1
-1
@@ -9,7 +9,7 @@ class FirebaseJwtTest extends TestCase
|
|||||||
{
|
{
|
||||||
private $privateKey;
|
private $privateKey;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->privateKey = <<<EOD
|
$this->privateKey = <<<EOD
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ class JwtTest extends TestCase
|
|||||||
{
|
{
|
||||||
private $privateKey;
|
private $privateKey;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->privateKey = <<<EOD
|
$this->privateKey = <<<EOD
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ class JwtBearerTest extends TestCase
|
|||||||
{
|
{
|
||||||
private $privateKey;
|
private $privateKey;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->privateKey = <<<EOD
|
$this->privateKey = <<<EOD
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
|||||||
+3
-3
@@ -29,7 +29,7 @@ class CodeIdTokenTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('query', $parts);
|
$this->assertArrayHasKey('query', $parts);
|
||||||
@@ -87,7 +87,7 @@ class CodeIdTokenTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('query', $parts);
|
$this->assertArrayHasKey('query', $parts);
|
||||||
@@ -133,7 +133,7 @@ class CodeIdTokenTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('query', $parts);
|
$this->assertArrayHasKey('query', $parts);
|
||||||
|
|||||||
Vendored
+2
-2
@@ -52,7 +52,7 @@ class IdTokenTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('fragment', $parts);
|
$this->assertArrayHasKey('fragment', $parts);
|
||||||
@@ -110,7 +110,7 @@ class IdTokenTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('fragment', $parts);
|
$this->assertArrayHasKey('fragment', $parts);
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ class IdTokenTokenTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals($response->getStatusCode(), 302);
|
$this->assertEquals($response->getStatusCode(), 302);
|
||||||
$location = $response->getHttpHeader('Location');
|
$location = $response->getHttpHeader('Location');
|
||||||
$this->assertNotContains('error', $location);
|
$this->assertStringNotContainsString('error', $location);
|
||||||
|
|
||||||
$parts = parse_url($location);
|
$parts = parse_url($location);
|
||||||
$this->assertArrayHasKey('fragment', $parts);
|
$this->assertArrayHasKey('fragment', $parts);
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ class ResponseTest extends TestCase
|
|||||||
));
|
));
|
||||||
|
|
||||||
$string = $response->getResponseBody('xml');
|
$string = $response->getResponseBody('xml');
|
||||||
$this->assertContains('<response><foo>bar</foo><halland>oates</halland></response>', $string);
|
$this->assertStringContainsString('<response><foo>bar</foo><halland>oates</halland></response>', $string);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetRedirect()
|
public function testSetRedirect()
|
||||||
|
|||||||
Vendored
+1
-1
@@ -162,7 +162,7 @@ class JwtAccessTokenTest extends TestCase
|
|||||||
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
|
$memoryStorage = Bootstrap::getInstance()->getMemoryStorage();
|
||||||
|
|
||||||
$storage = array(
|
$storage = array(
|
||||||
'access_token' => new JwtAccessTokenStorage($memoryStorage),
|
'access_token' => new JwtAccessTokenStorage($memoryStorage, $memoryStorage),
|
||||||
'client' => $memoryStorage,
|
'client' => $memoryStorage,
|
||||||
'client_credentials' => $memoryStorage,
|
'client_credentials' => $memoryStorage,
|
||||||
);
|
);
|
||||||
|
|||||||
+99
-135
@@ -6,27 +6,26 @@ use OAuth2\Request\TestRequest;
|
|||||||
use OAuth2\ResponseType\AuthorizationCode;
|
use OAuth2\ResponseType\AuthorizationCode;
|
||||||
use OAuth2\Storage\Bootstrap;
|
use OAuth2\Storage\Bootstrap;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
|
||||||
|
|
||||||
class ServerTest extends TestCase
|
class ServerTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
use ExpectPHPException;
|
||||||
* @expectedException LogicException OAuth2\Storage\ClientInterface
|
|
||||||
**/
|
|
||||||
public function testGetAuthorizeControllerWithNoClientStorageThrowsException()
|
public function testGetAuthorizeControllerWithNoClientStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\ClientInterface');
|
||||||
// must set Client Storage
|
// must set Client Storage
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
|
|
||||||
**/
|
|
||||||
public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
|
public function testGetAuthorizeControllerWithNoAccessTokenStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
|
||||||
// must set AccessToken or AuthorizationCode
|
// must set AccessToken or AuthorizationCode
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,8 +33,8 @@ class ServerTest extends TestCase
|
|||||||
{
|
{
|
||||||
// must set AccessToken or AuthorizationCode
|
// must set AccessToken or AuthorizationCode
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->addResponseType($this->getMock('OAuth2\ResponseType\AccessTokenInterface'));
|
$server->addResponseType($this->createMock('OAuth2\ResponseType\AccessTokenInterface'));
|
||||||
|
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
@@ -44,21 +43,19 @@ class ServerTest extends TestCase
|
|||||||
{
|
{
|
||||||
// must set AccessToken or AuthorizationCode
|
// must set AccessToken or AuthorizationCode
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->addResponseType($this->getMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
|
$server->addResponseType($this->createMock('OAuth2\ResponseType\AuthorizationCodeInterface'));
|
||||||
|
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException allow_implicit
|
|
||||||
**/
|
|
||||||
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
|
public function testGetAuthorizeControllerWithClientStorageAndAccessTokenStorageThrowsException()
|
||||||
{
|
{
|
||||||
// must set AuthorizationCode or AccessToken / implicit
|
// must set AuthorizationCode or AccessToken / implicit
|
||||||
|
$this->expectExceptionMessage('allow_implicit');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
|
||||||
|
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
@@ -67,8 +64,8 @@ class ServerTest extends TestCase
|
|||||||
{
|
{
|
||||||
// must set AuthorizationCode or AccessToken / implicit
|
// must set AuthorizationCode or AccessToken / implicit
|
||||||
$server = new Server(array(), array('allow_implicit' => true));
|
$server = new Server(array(), array('allow_implicit' => true));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
|
||||||
|
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
@@ -77,63 +74,55 @@ class ServerTest extends TestCase
|
|||||||
{
|
{
|
||||||
// must set AccessToken or AuthorizationCode
|
// must set AccessToken or AuthorizationCode
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AuthorizationCodeInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AuthorizationCodeInterface'));
|
||||||
|
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException grant_types
|
|
||||||
**/
|
|
||||||
public function testGetTokenControllerWithGrantTypeStorageThrowsException()
|
public function testGetTokenControllerWithGrantTypeStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('grant_types');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\ClientCredentialsInterface
|
|
||||||
**/
|
|
||||||
public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
|
public function testGetTokenControllerWithNoClientCredentialsStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\ClientCredentialsInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\UserCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\UserCredentialsInterface'));
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
|
|
||||||
**/
|
|
||||||
public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
|
public function testGetTokenControllerWithNoAccessTokenStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
|
public function testGetTokenControllerWithAccessTokenAndClientCredentialsStorage()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
|
public function testGetTokenControllerAccessTokenStorageAndClientCredentialsStorageAndGrantTypes()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
|
||||||
$server->addGrantType($this->getMockBuilder('OAuth2\GrantType\AuthorizationCode')->disableOriginalConstructor()->getMock());
|
$server->addGrantType($this->createMock('OAuth2\GrantType\AuthorizationCode'));
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\AccessTokenInterface
|
|
||||||
**/
|
|
||||||
public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
|
public function testGetResourceControllerWithNoAccessTokenStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->getResourceController();
|
$server->getResourceController();
|
||||||
}
|
}
|
||||||
@@ -141,41 +130,35 @@ class ServerTest extends TestCase
|
|||||||
public function testGetResourceControllerWithAccessTokenStorage()
|
public function testGetResourceControllerWithAccessTokenStorage()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'));
|
||||||
$server->getResourceController();
|
$server->getResourceController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException InvalidArgumentException OAuth2\Storage\AccessTokenInterface
|
|
||||||
**/
|
|
||||||
public function testAddingStorageWithInvalidClass()
|
public function testAddingStorageWithInvalidClass()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\AccessTokenInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage(new \StdClass());
|
$server->addStorage(new \StdClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException InvalidArgumentException access_token
|
|
||||||
**/
|
|
||||||
public function testAddingStorageWithInvalidKey()
|
public function testAddingStorageWithInvalidKey()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('access_token');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'), 'nonexistant_storage');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException InvalidArgumentException OAuth2\Storage\AuthorizationCodeInterface
|
|
||||||
**/
|
|
||||||
public function testAddingStorageWithInvalidKeyStorageCombination()
|
public function testAddingStorageWithInvalidKeyStorageCombination()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\AuthorizationCodeInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
|
$server->addStorage($this->createMock('OAuth2\Storage\AccessTokenInterface'), 'authorization_code');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddingStorageWithValidKeyOnlySetsThatKey()
|
public function testAddingStorageWithValidKeyOnlySetsThatKey()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\Memory'), 'access_token');
|
$server->addStorage($this->createMock('OAuth2\Storage\Memory'), 'access_token');
|
||||||
|
|
||||||
$reflection = new \ReflectionClass($server);
|
$reflection = new \ReflectionClass($server);
|
||||||
$prop = $reflection->getProperty('storages');
|
$prop = $reflection->getProperty('storages');
|
||||||
@@ -191,7 +174,7 @@ class ServerTest extends TestCase
|
|||||||
public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
|
public function testAddingClientStorageSetsClientCredentialsStorageByDefault()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$memory = $this->getMock('OAuth2\Storage\Memory');
|
$memory = $this->createMock('OAuth2\Storage\Memory');
|
||||||
$server->addStorage($memory, 'client');
|
$server->addStorage($memory, 'client');
|
||||||
|
|
||||||
$client_credentials = $server->getStorage('client_credentials');
|
$client_credentials = $server->getStorage('client_credentials');
|
||||||
@@ -202,7 +185,7 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testAddStorageWithNullValue()
|
public function testAddStorageWithNullValue()
|
||||||
{
|
{
|
||||||
$memory = $this->getMock('OAuth2\Storage\Memory');
|
$memory = $this->createMock('OAuth2\Storage\Memory');
|
||||||
$server = new Server($memory);
|
$server = new Server($memory);
|
||||||
$server->addStorage(null, 'refresh_token');
|
$server->addStorage(null, 'refresh_token');
|
||||||
|
|
||||||
@@ -218,7 +201,7 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testNewServerWithNullStorageValue()
|
public function testNewServerWithNullStorageValue()
|
||||||
{
|
{
|
||||||
$memory = $this->getMock('OAuth2\Storage\Memory');
|
$memory = $this->createMock('OAuth2\Storage\Memory');
|
||||||
$server = new Server(array(
|
$server = new Server(array(
|
||||||
'client_credentials' => $memory,
|
'client_credentials' => $memory,
|
||||||
'refresh_token' => null,
|
'refresh_token' => null,
|
||||||
@@ -237,7 +220,7 @@ class ServerTest extends TestCase
|
|||||||
public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
|
public function testAddingClientCredentialsStorageSetsClientStorageByDefault()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$memory = $this->getMock('OAuth2\Storage\Memory');
|
$memory = $this->createMock('OAuth2\Storage\Memory');
|
||||||
$server->addStorage($memory, 'client_credentials');
|
$server->addStorage($memory, 'client_credentials');
|
||||||
|
|
||||||
$client = $server->getStorage('client');
|
$client = $server->getStorage('client');
|
||||||
@@ -249,10 +232,9 @@ class ServerTest extends TestCase
|
|||||||
public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
|
public function testSettingClientStorageByDefaultDoesNotOverrideSetStorage()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$pdo = $this->getMockBuilder('OAuth2\Storage\Pdo')
|
$pdo = $this->createMock('OAuth2\Storage\Pdo');
|
||||||
->disableOriginalConstructor()->getMock();
|
|
||||||
|
|
||||||
$memory = $this->getMock('OAuth2\Storage\Memory');
|
$memory = $this->createMock('OAuth2\Storage\Memory');
|
||||||
|
|
||||||
$server->addStorage($pdo, 'client');
|
$server->addStorage($pdo, 'client');
|
||||||
$server->addStorage($memory, 'client_credentials');
|
$server->addStorage($memory, 'client_credentials');
|
||||||
@@ -266,7 +248,7 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testAddingResponseType()
|
public function testAddingResponseType()
|
||||||
{
|
{
|
||||||
$storage = $this->getMock('OAuth2\Storage\Memory');
|
$storage = $this->createMock('OAuth2\Storage\Memory');
|
||||||
$storage
|
$storage
|
||||||
->expects($this->any())
|
->expects($this->any())
|
||||||
->method('getClientDetails')
|
->method('getClientDetails')
|
||||||
@@ -323,7 +305,7 @@ class ServerTest extends TestCase
|
|||||||
'code' => 'testcode',
|
'code' => 'testcode',
|
||||||
));
|
));
|
||||||
// verify the mock clientAssertionType was called as expected
|
// verify the mock clientAssertionType was called as expected
|
||||||
$clientAssertionType = $this->getMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface', array('validateRequest', 'getClientId'));
|
$clientAssertionType = $this->createMock('OAuth2\ClientAssertionType\ClientAssertionTypeInterface');
|
||||||
$clientAssertionType
|
$clientAssertionType
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('validateRequest')
|
->method('validateRequest')
|
||||||
@@ -420,98 +402,84 @@ class ServerTest extends TestCase
|
|||||||
$this->assertFalse($used_token, 'the refresh token used is no longer valid');
|
$this->assertFalse($used_token, 'the refresh token used is no longer valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException InvalidArgumentException OAuth2\ResponseType\AuthorizationCodeInterface
|
|
||||||
**/
|
|
||||||
public function testAddingUnknownResponseTypeThrowsException()
|
public function testAddingUnknownResponseTypeThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\ResponseType\AuthorizationCodeInterface');
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addResponseType($this->getMock('OAuth2\ResponseType\ResponseTypeInterface'));
|
$server->addResponseType($this->createMock('OAuth2\ResponseType\ResponseTypeInterface'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\PublicKeyInterface
|
|
||||||
**/
|
|
||||||
public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
|
public function testUsingJwtAccessTokensWithoutPublicKeyStorageThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectExceptionMessage('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array(), array('use_jwt_access_tokens' => true));
|
$server = new Server(array(), array('use_jwt_access_tokens' => true));
|
||||||
$server->addGrantType($this->getMock('OAuth2\GrantType\GrantTypeInterface'));
|
$server->addGrantType($this->createMock('OAuth2\GrantType\GrantTypeInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
|
||||||
$server->addStorage($this->getMock('OAuth2\Storage\ClientCredentialsInterface'));
|
$server->addStorage($this->createMock('OAuth2\Storage\ClientCredentialsInterface'));
|
||||||
|
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
|
public function testUsingJustJwtAccessTokenStorageWithResourceControllerIsOkay()
|
||||||
{
|
{
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
||||||
|
|
||||||
$this->assertNotNull($server->getResourceController());
|
$this->assertNotNull($server->getResourceController());
|
||||||
$this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
|
$this->assertInstanceOf('OAuth2\Storage\PublicKeyInterface', $server->getStorage('public_key'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\Storage\ClientInterface
|
|
||||||
**/
|
|
||||||
public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
|
public function testUsingJustJwtAccessTokenStorageWithAuthorizeControllerThrowsException()
|
||||||
{
|
{
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$this->expectExceptionMessage('OAuth2\Storage\ClientInterface');
|
||||||
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException grant_types
|
|
||||||
**/
|
|
||||||
public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
|
public function testUsingJustJwtAccessTokenStorageWithTokenControllerThrowsException()
|
||||||
{
|
{
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$this->expectExceptionMessage('grant_types');
|
||||||
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
$server = new Server(array($pubkey), array('use_jwt_access_tokens' => true));
|
||||||
$server->getTokenController();
|
$server->getTokenController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
|
public function testUsingJwtAccessTokenAndClientStorageWithAuthorizeControllerIsOkay()
|
||||||
{
|
{
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
|
$server = new Server(array($pubkey, $client), array('use_jwt_access_tokens' => true, 'allow_implicit' => true));
|
||||||
$this->assertNotNull($server->getAuthorizeController());
|
$this->assertNotNull($server->getAuthorizeController());
|
||||||
|
|
||||||
$this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
|
$this->assertInstanceOf('OAuth2\ResponseType\JwtAccessToken', $server->getResponseType('token'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException UserClaims
|
|
||||||
**/
|
|
||||||
public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
|
public function testUsingOpenIDConnectWithoutUserClaimsThrowsException()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$this->expectExceptionMessage('UserClaims');
|
||||||
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$server = new Server($client, array('use_openid_connect' => true));
|
$server = new Server($client, array('use_openid_connect' => true));
|
||||||
|
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException PublicKeyInterface
|
|
||||||
**/
|
|
||||||
public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
|
public function testUsingOpenIDConnectWithoutPublicKeyThrowsException()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$this->expectExceptionMessage('PublicKeyInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OPenID\Storage\UserClaimsInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
|
$userclaims = $this->createMock('OAuth2\OPenID\Storage\UserClaimsInterface');
|
||||||
$server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
|
$server = new Server(array($client, $userclaims), array('use_openid_connect' => true));
|
||||||
|
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException issuer
|
|
||||||
**/
|
|
||||||
public function testUsingOpenIDConnectWithoutIssuerThrowsException()
|
public function testUsingOpenIDConnectWithoutIssuerThrowsException()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$this->expectExceptionMessage('issuer');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
|
$server = new Server(array($client, $userclaims, $pubkey), array('use_openid_connect' => true));
|
||||||
|
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
@@ -519,9 +487,9 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
|
public function testUsingOpenIDConnectWithIssuerPublicKeyAndUserClaimsIsOkay()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey), array(
|
$server = new Server(array($client, $userclaims, $pubkey), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy',
|
'issuer' => 'someguy',
|
||||||
@@ -533,14 +501,12 @@ class ServerTest extends TestCase
|
|||||||
$this->assertNull($server->getResponseType('id_token token'));
|
$this->assertNull($server->getResponseType('id_token token'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\ResponseType\AccessTokenInterface
|
|
||||||
**/
|
|
||||||
public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
|
public function testUsingOpenIDConnectWithAllowImplicitWithoutTokenStorageThrowsException()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$this->expectErrorMessage('OAuth2\ResponseType\AccessTokenInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey), array(
|
$server = new Server(array($client, $userclaims, $pubkey), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy',
|
'issuer' => 'someguy',
|
||||||
@@ -552,9 +518,9 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
|
public function testUsingOpenIDConnectWithAllowImplicitAndUseJwtAccessTokensIsOkay()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey), array(
|
$server = new Server(array($client, $userclaims, $pubkey), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy',
|
'issuer' => 'someguy',
|
||||||
@@ -570,10 +536,10 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
|
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenStorageIsOkay()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
|
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey, $token), array(
|
$server = new Server(array($client, $userclaims, $pubkey, $token), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy',
|
'issuer' => 'someguy',
|
||||||
@@ -588,17 +554,17 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
|
public function testUsingOpenIDConnectWithAllowImplicitAndAccessTokenResponseTypeIsOkay()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
// $token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
|
// $token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey), array(
|
$server = new Server(array($client, $userclaims, $pubkey), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy',
|
'issuer' => 'someguy',
|
||||||
'allow_implicit' => true,
|
'allow_implicit' => true,
|
||||||
));
|
));
|
||||||
|
|
||||||
$token = $this->getMock('OAuth2\ResponseType\AccessTokenInterface');
|
$token = $this->createMock('OAuth2\ResponseType\AccessTokenInterface');
|
||||||
$server->addResponseType($token, 'token');
|
$server->addResponseType($token, 'token');
|
||||||
|
|
||||||
$server->getAuthorizeController();
|
$server->getAuthorizeController();
|
||||||
@@ -607,17 +573,15 @@ class ServerTest extends TestCase
|
|||||||
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
|
$this->assertInstanceOf('OAuth2\OpenID\ResponseType\IdTokenTokenInterface', $server->getResponseType('id_token token'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException LogicException OAuth2\OpenID\Storage\AuthorizationCodeInterface
|
|
||||||
**/
|
|
||||||
public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
|
public function testUsingOpenIDConnectWithAuthorizationCodeStorageThrowsException()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientCredentialsInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
|
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
|
||||||
$authcode = $this->getMock('OAuth2\Storage\AuthorizationCodeInterface');
|
$authcode = $this->createMock('OAuth2\Storage\AuthorizationCodeInterface');
|
||||||
|
|
||||||
|
$this->expectErrorMessage('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
|
||||||
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
|
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
'issuer' => 'someguy'
|
'issuer' => 'someguy'
|
||||||
@@ -630,11 +594,11 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
|
public function testUsingOpenIDConnectWithOpenIDAuthorizationCodeStorageCreatesOpenIDAuthorizationCodeGrantType()
|
||||||
{
|
{
|
||||||
$client = $this->getMock('OAuth2\Storage\ClientCredentialsInterface');
|
$client = $this->createMock('OAuth2\Storage\ClientCredentialsInterface');
|
||||||
$userclaims = $this->getMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
$userclaims = $this->createMock('OAuth2\OpenID\Storage\UserClaimsInterface');
|
||||||
$pubkey = $this->getMock('OAuth2\Storage\PublicKeyInterface');
|
$pubkey = $this->createMock('OAuth2\Storage\PublicKeyInterface');
|
||||||
$token = $this->getMock('OAuth2\Storage\AccessTokenInterface');
|
$token = $this->createMock('OAuth2\Storage\AccessTokenInterface');
|
||||||
$authcode = $this->getMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
|
$authcode = $this->createMock('OAuth2\OpenID\Storage\AuthorizationCodeInterface');
|
||||||
|
|
||||||
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
|
$server = new Server(array($client, $userclaims, $pubkey, $token, $authcode), array(
|
||||||
'use_openid_connect' => true,
|
'use_openid_connect' => true,
|
||||||
@@ -648,7 +612,7 @@ class ServerTest extends TestCase
|
|||||||
|
|
||||||
public function testMultipleValuedResponseTypeOrderDoesntMatter()
|
public function testMultipleValuedResponseTypeOrderDoesntMatter()
|
||||||
{
|
{
|
||||||
$responseType = $this->getMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
|
$responseType = $this->createMock('OAuth2\OpenID\ResponseType\IdTokenTokenInterface');
|
||||||
$server = new Server(array(), array(), array(), array(
|
$server = new Server(array(), array(), array(), array(
|
||||||
'token id_token' => $responseType,
|
'token id_token' => $responseType,
|
||||||
));
|
));
|
||||||
@@ -659,7 +623,7 @@ class ServerTest extends TestCase
|
|||||||
public function testAddGrantTypeWithoutKey()
|
public function testAddGrantTypeWithoutKey()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')));
|
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')));
|
||||||
|
|
||||||
$grantTypes = $server->getGrantTypes();
|
$grantTypes = $server->getGrantTypes();
|
||||||
$this->assertEquals('authorization_code', key($grantTypes));
|
$this->assertEquals('authorization_code', key($grantTypes));
|
||||||
@@ -668,7 +632,7 @@ class ServerTest extends TestCase
|
|||||||
public function testAddGrantTypeWithKey()
|
public function testAddGrantTypeWithKey()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
|
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')), 'ac');
|
||||||
|
|
||||||
$grantTypes = $server->getGrantTypes();
|
$grantTypes = $server->getGrantTypes();
|
||||||
$this->assertEquals('ac', key($grantTypes));
|
$this->assertEquals('ac', key($grantTypes));
|
||||||
@@ -677,7 +641,7 @@ class ServerTest extends TestCase
|
|||||||
public function testAddGrantTypeWithKeyNotString()
|
public function testAddGrantTypeWithKeyNotString()
|
||||||
{
|
{
|
||||||
$server = new Server();
|
$server = new Server();
|
||||||
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->getMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
|
$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($this->createMock('OAuth2\Storage\AuthorizationCodeInterface')), 42);
|
||||||
|
|
||||||
$grantTypes = $server->getGrantTypes();
|
$grantTypes = $server->getGrantTypes();
|
||||||
$this->assertEquals('authorization_code', key($grantTypes));
|
$this->assertEquals('authorization_code', key($grantTypes));
|
||||||
|
|||||||
+5
-3
@@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
namespace OAuth2\Storage;
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException;
|
||||||
|
|
||||||
class PdoTest extends BaseTest
|
class PdoTest extends BaseTest
|
||||||
{
|
{
|
||||||
|
use ExpectPHPException;
|
||||||
|
|
||||||
public function testCreatePdoStorageUsingPdoClass()
|
public function testCreatePdoStorageUsingPdoClass()
|
||||||
{
|
{
|
||||||
$dsn = sprintf('sqlite:%s', Bootstrap::getInstance()->getSqliteDir());
|
$dsn = sprintf('sqlite:%s', Bootstrap::getInstance()->getSqliteDir());
|
||||||
@@ -30,11 +34,9 @@ class PdoTest extends BaseTest
|
|||||||
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
|
$this->assertNotNull($storage->getClientDetails('oauth_test_client'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException InvalidArgumentException dsn
|
|
||||||
*/
|
|
||||||
public function testCreatePdoStorageWithoutDSNThrowsException()
|
public function testCreatePdoStorageWithoutDSNThrowsException()
|
||||||
{
|
{
|
||||||
|
$this->expectErrorMessage('dsn');
|
||||||
$config = array('username' => 'brent', 'password' => 'brentisaballer');
|
$config = array('username' => 'brent', 'password' => 'brentisaballer');
|
||||||
$storage = new Pdo($config);
|
$storage = new Pdo($config);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -35,6 +35,17 @@ class BearerTest extends TestCase
|
|||||||
$this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
|
$this->assertEquals($response->getParameter('error_description'), 'The content type for POST requests must be "application/x-www-form-urlencoded"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMissingContentTypeExpectsToBeCorrectContent()
|
||||||
|
{
|
||||||
|
$bearer = new Bearer();
|
||||||
|
$request = TestRequest::createPost(array(
|
||||||
|
'access_token' => 'ThisIsMyAccessToken'
|
||||||
|
));
|
||||||
|
|
||||||
|
$param = $bearer->getAccessTokenParameter($request, $response = new Response());
|
||||||
|
$this->assertEquals($param, 'ThisIsMyAccessToken');
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidRequestUsingAuthorizationHeader()
|
public function testValidRequestUsingAuthorizationHeader()
|
||||||
{
|
{
|
||||||
$bearer = new Bearer();
|
$bearer = new Bearer();
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once(dirname(__FILE__).'/../src/OAuth2/Autoloader.php');
|
|
||||||
OAuth2\Autoloader::register();
|
|
||||||
|
|
||||||
// register test classes
|
|
||||||
OAuth2\Autoloader::register(dirname(__FILE__).'/lib');
|
|
||||||
|
|
||||||
// register vendors if possible
|
|
||||||
if (file_exists(__DIR__.'/../vendor/autoload.php')) {
|
|
||||||
require_once(__DIR__.'/../vendor/autoload.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the dynamoDB database that was created for this build
|
|
||||||
OAuth2\Storage\Bootstrap::getInstance()->cleanupTravisDynamoDb();
|
|
||||||
+7
-22
@@ -68,7 +68,7 @@ class Bootstrap
|
|||||||
public function getPostgresDriver()
|
public function getPostgresDriver()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres');
|
$pdo = new \PDO('pgsql:host=localhost;dbname=oauth2_server_php', 'postgres', 'postgres');
|
||||||
|
|
||||||
return $pdo;
|
return $pdo;
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
@@ -118,7 +118,7 @@ class Bootstrap
|
|||||||
if (!$this->mysql) {
|
if (!$this->mysql) {
|
||||||
$pdo = null;
|
$pdo = null;
|
||||||
try {
|
try {
|
||||||
$pdo = new \PDO('mysql:host=localhost;', 'root');
|
$pdo = new \PDO('mysql:host=localhost;', 'root', 'root');
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
$this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
|
$this->mysql = new NullStorage('MySQL', 'Unable to connect to MySQL on root@localhost');
|
||||||
}
|
}
|
||||||
@@ -352,11 +352,11 @@ class Bootstrap
|
|||||||
|
|
||||||
private function createPostgresDb()
|
private function createPostgresDb()
|
||||||
{
|
{
|
||||||
if (!`psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'"`) {
|
if (!`PGPASSWORD=postgres psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='postgres'" -h localhost -U postgres`) {
|
||||||
`createuser -s -r postgres`;
|
`PGPASSWORD=postgres createuser -s -r postgres -h localhost -U postgres`;
|
||||||
}
|
}
|
||||||
|
|
||||||
`createdb -O postgres oauth2_server_php`;
|
`PGPASSWORD=postgres createdb -O postgres oauth2_server_php -h localhost -U postgres`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function populatePostgresDb(\PDO $pdo)
|
private function populatePostgresDb(\PDO $pdo)
|
||||||
@@ -366,8 +366,8 @@ class Bootstrap
|
|||||||
|
|
||||||
private function removePostgresDb()
|
private function removePostgresDb()
|
||||||
{
|
{
|
||||||
if (trim(`psql -l | grep oauth2_server_php | wc -l`)) {
|
if (trim(`PGPASSWORD=postgres psql -l -h localhost -U postgres | grep oauth2_server_php | wc -l`)) {
|
||||||
`dropdb oauth2_server_php`;
|
`PGPASSWORD=postgres dropdb oauth2_server_php -h localhost -U postgres`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,21 +945,6 @@ class Bootstrap
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cleanupTravisDynamoDb($prefix = null)
|
|
||||||
{
|
|
||||||
if (is_null($prefix)) {
|
|
||||||
// skip this when not applicable
|
|
||||||
if (!$this->getEnvVar('TRAVIS') || self::DYNAMODB_PHP_VERSION != $this->getEnvVar('TRAVIS_PHP_VERSION')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$prefix = sprintf('build_%s_', $this->getEnvVar('TRAVIS_JOB_NUMBER'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$client = $this->getDynamoDbClient();
|
|
||||||
$this->deleteDynamoDb($client, $prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getEnvVar($var, $default = null)
|
private function getEnvVar($var, $default = null)
|
||||||
{
|
{
|
||||||
return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
|
return isset($_SERVER[$var]) ? $_SERVER[$var] : (getenv($var) ?: $default);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Types to use Carbon in Doctrine
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/symfony/)
|
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/guide/getting-started/symfony.html)
|
||||||
|
|
||||||
This package is an externalization of [src/Carbon/Doctrine](https://github.com/briannesbitt/Carbon/tree/2.71.0/src/Carbon/Doctrine)
|
This package is an externalization of [src/Carbon/Doctrine](https://github.com/briannesbitt/Carbon/tree/2.71.0/src/Carbon/Doctrine)
|
||||||
from `nestbot/carbon` package.
|
from `nestbot/carbon` package.
|
||||||
|
|||||||
@@ -32,5 +32,10 @@
|
|||||||
"email": "kylekatarnls@gmail.com"
|
"email": "kylekatarnls@gmail.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minimum-stability": "dev"
|
"minimum-stability": "dev",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Vendored
+4
-3
@@ -4,13 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Carbon\Doctrine;
|
namespace Carbon\Doctrine;
|
||||||
|
|
||||||
|
use Carbon\CarbonInterface;
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
|
||||||
interface CarbonDoctrineType
|
interface CarbonDoctrineType
|
||||||
{
|
{
|
||||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
|
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string;
|
||||||
|
|
||||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform);
|
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?CarbonInterface;
|
||||||
|
|
||||||
public function convertToDatabaseValue($value, AbstractPlatform $platform);
|
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string;
|
||||||
}
|
}
|
||||||
Vendored
+3
-3
@@ -62,7 +62,7 @@ trait CarbonTypeConverter
|
|||||||
/**
|
/**
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||||
*/
|
*/
|
||||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
|
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
|
||||||
{
|
{
|
||||||
if ($value === null) {
|
if ($value === null) {
|
||||||
return $value;
|
return $value;
|
||||||
@@ -79,11 +79,11 @@ trait CarbonTypeConverter
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function doConvertToPHPValue(mixed $value)
|
private function doConvertToPHPValue(mixed $value): ?CarbonInterface
|
||||||
{
|
{
|
||||||
$class = $this->getCarbonClassName();
|
$class = $this->getCarbonClassName();
|
||||||
|
|
||||||
if ($value === null || is_a($value, $class)) {
|
if ($value === null || (is_object($value) && is_a($value, $class))) {
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-1
@@ -26,6 +26,12 @@ use Composer\Semver\VersionParser;
|
|||||||
*/
|
*/
|
||||||
class InstalledVersions
|
class InstalledVersions
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private static $selfDir = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var mixed[]|null
|
* @var mixed[]|null
|
||||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||||
@@ -322,6 +328,18 @@ class InstalledVersions
|
|||||||
self::$installedIsLocalDir = false;
|
self::$installedIsLocalDir = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function getSelfDir()
|
||||||
|
{
|
||||||
|
if (self::$selfDir === null) {
|
||||||
|
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$selfDir;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array[]
|
* @return array[]
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
@@ -336,7 +354,7 @@ class InstalledVersions
|
|||||||
$copiedLocalDir = false;
|
$copiedLocalDir = false;
|
||||||
|
|
||||||
if (self::$canGetVendors) {
|
if (self::$canGetVendors) {
|
||||||
$selfDir = strtr(__DIR__, '\\', '/');
|
$selfDir = self::getSelfDir();
|
||||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
$vendorDir = strtr($vendorDir, '\\', '/');
|
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||||
|
|||||||
+35
-2
@@ -6,12 +6,45 @@ $vendorDir = dirname(__DIR__);
|
|||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'AllowDynamicProperties' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/AllowDynamicProperties.php',
|
||||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||||
'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
|
||||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
|
'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||||
|
'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||||
|
'DateInvalidOperationException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
|
||||||
|
'DateInvalidTimeZoneException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
|
||||||
|
'DateMalformedIntervalStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
|
||||||
|
'DateMalformedPeriodStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
|
||||||
|
'DateMalformedStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
|
||||||
|
'DateObjectError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
|
||||||
|
'DateRangeError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
|
||||||
|
'DelayedTargetValidation' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/DelayedTargetValidation.php',
|
||||||
|
'Deprecated' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Deprecated.php',
|
||||||
|
'Filter\\FilterException' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterException.php',
|
||||||
|
'Filter\\FilterFailedException' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterFailedException.php',
|
||||||
|
'NoDiscard' => $vendorDir . '/symfony/polyfill-php85/Resources/stubs/NoDiscard.php',
|
||||||
|
'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||||
|
'Pdo\\Dblib' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Dblib.php',
|
||||||
|
'Pdo\\Firebird' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Firebird.php',
|
||||||
|
'Pdo\\Mysql' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php',
|
||||||
|
'Pdo\\Odbc' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Odbc.php',
|
||||||
|
'Pdo\\Pgsql' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Pgsql.php',
|
||||||
|
'Pdo\\Sqlite' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/Pdo/Sqlite.php',
|
||||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||||
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
'Random\\BrokenRandomEngineError' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/BrokenRandomEngineError.php',
|
||||||
|
'Random\\CryptoSafeEngine' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/CryptoSafeEngine.php',
|
||||||
|
'Random\\Engine' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/Engine.php',
|
||||||
|
'Random\\Engine\\Secure' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/Engine/Secure.php',
|
||||||
|
'Random\\RandomError' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/RandomError.php',
|
||||||
|
'Random\\RandomException' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/Random/RandomException.php',
|
||||||
|
'ReflectionConstant' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php',
|
||||||
|
'RoundingMode' => $vendorDir . '/symfony/polyfill-php84/Resources/stubs/RoundingMode.php',
|
||||||
|
'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
|
||||||
|
'SensitiveParameter' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameter.php',
|
||||||
|
'SensitiveParameterValue' => $vendorDir . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameterValue.php',
|
||||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||||
|
'Time\\Duration' => $vendorDir . '/symfony/polyfill-time/Resources/stubs/Time/Duration.php',
|
||||||
|
'Time\\TimeException' => $vendorDir . '/symfony/polyfill-time/Resources/stubs/Time/TimeException.php',
|
||||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||||
);
|
);
|
||||||
+7
-5
@@ -6,16 +6,18 @@ $vendorDir = dirname(__DIR__);
|
|||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||||
|
'5897ea0ac4cccf14d323035e65887801' => $vendorDir . '/symfony/polyfill-php82/bootstrap.php',
|
||||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
'662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php',
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
'2203a247e6fda86070a5e4e07aed533a' => $vendorDir . '/symfony/clock/Resources/now.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
'9d2b9fc6db0f153a0a149fefb182415e' => $vendorDir . '/symfony/polyfill-php84/bootstrap.php',
|
||||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
'606a39d89246991a373564698c2d8383' => $vendorDir . '/symfony/polyfill-php85/bootstrap.php',
|
||||||
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
|
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
|
||||||
|
'23f09fe3194f8c2f70923f90d6702129' => $vendorDir . '/illuminate/collections/functions.php',
|
||||||
'60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
|
'60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
|
||||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||||
'23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
|
|
||||||
'04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php',
|
'04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php',
|
||||||
'89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php',
|
'89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php',
|
||||||
'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php',
|
'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php',
|
||||||
|
|||||||
+6
-1
@@ -7,12 +7,17 @@ $baseDir = dirname($vendorDir);
|
|||||||
|
|
||||||
return array(
|
return array(
|
||||||
'Twig\\' => array($vendorDir . '/twig/twig/src'),
|
'Twig\\' => array($vendorDir . '/twig/twig/src'),
|
||||||
'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
|
'Symfony\\Polyfill\\Time\\' => array($vendorDir . '/symfony/polyfill-time'),
|
||||||
|
'Symfony\\Polyfill\\Php85\\' => array($vendorDir . '/symfony/polyfill-php85'),
|
||||||
|
'Symfony\\Polyfill\\Php84\\' => array($vendorDir . '/symfony/polyfill-php84'),
|
||||||
|
'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'),
|
||||||
|
'Symfony\\Polyfill\\Php82\\' => array($vendorDir . '/symfony/polyfill-php82'),
|
||||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||||
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
|
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
|
||||||
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
|
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
|
||||||
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
|
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
|
||||||
|
'Symfony\\Component\\Clock\\' => array($vendorDir . '/symfony/clock'),
|
||||||
'Stevenmaguire\\OAuth2\\Client\\' => array($vendorDir . '/stevenmaguire/oauth2-keycloak/src'),
|
'Stevenmaguire\\OAuth2\\Client\\' => array($vendorDir . '/stevenmaguire/oauth2-keycloak/src'),
|
||||||
'RobThree\\Auth\\' => array($vendorDir . '/robthree/twofactorauth/lib'),
|
'RobThree\\Auth\\' => array($vendorDir . '/robthree/twofactorauth/lib'),
|
||||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||||
|
|||||||
+70
-10
@@ -7,16 +7,18 @@ namespace Composer\Autoload;
|
|||||||
class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
||||||
{
|
{
|
||||||
public static $files = array (
|
public static $files = array (
|
||||||
|
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||||
|
'5897ea0ac4cccf14d323035e65887801' => __DIR__ . '/..' . '/symfony/polyfill-php82/bootstrap.php',
|
||||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
'662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php',
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
'2203a247e6fda86070a5e4e07aed533a' => __DIR__ . '/..' . '/symfony/clock/Resources/now.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
'9d2b9fc6db0f153a0a149fefb182415e' => __DIR__ . '/..' . '/symfony/polyfill-php84/bootstrap.php',
|
||||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
'606a39d89246991a373564698c2d8383' => __DIR__ . '/..' . '/symfony/polyfill-php85/bootstrap.php',
|
||||||
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
|
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
|
||||||
|
'23f09fe3194f8c2f70923f90d6702129' => __DIR__ . '/..' . '/illuminate/collections/functions.php',
|
||||||
'60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
|
'60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
|
||||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||||
'23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
|
|
||||||
'04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php',
|
'04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php',
|
||||||
'89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php',
|
'89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php',
|
||||||
'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php',
|
'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php',
|
||||||
@@ -31,12 +33,17 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
|||||||
),
|
),
|
||||||
'S' =>
|
'S' =>
|
||||||
array (
|
array (
|
||||||
'Symfony\\Polyfill\\Php81\\' => 23,
|
'Symfony\\Polyfill\\Time\\' => 22,
|
||||||
|
'Symfony\\Polyfill\\Php85\\' => 23,
|
||||||
|
'Symfony\\Polyfill\\Php84\\' => 23,
|
||||||
|
'Symfony\\Polyfill\\Php83\\' => 23,
|
||||||
|
'Symfony\\Polyfill\\Php82\\' => 23,
|
||||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||||
'Symfony\\Polyfill\\Ctype\\' => 23,
|
'Symfony\\Polyfill\\Ctype\\' => 23,
|
||||||
'Symfony\\Contracts\\Translation\\' => 30,
|
'Symfony\\Contracts\\Translation\\' => 30,
|
||||||
'Symfony\\Component\\Translation\\' => 30,
|
'Symfony\\Component\\Translation\\' => 30,
|
||||||
|
'Symfony\\Component\\Clock\\' => 24,
|
||||||
'Stevenmaguire\\OAuth2\\Client\\' => 28,
|
'Stevenmaguire\\OAuth2\\Client\\' => 28,
|
||||||
),
|
),
|
||||||
'R' =>
|
'R' =>
|
||||||
@@ -105,9 +112,25 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
|||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/twig/twig/src',
|
0 => __DIR__ . '/..' . '/twig/twig/src',
|
||||||
),
|
),
|
||||||
'Symfony\\Polyfill\\Php81\\' =>
|
'Symfony\\Polyfill\\Time\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php81',
|
0 => __DIR__ . '/..' . '/symfony/polyfill-time',
|
||||||
|
),
|
||||||
|
'Symfony\\Polyfill\\Php85\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/symfony/polyfill-php85',
|
||||||
|
),
|
||||||
|
'Symfony\\Polyfill\\Php84\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/symfony/polyfill-php84',
|
||||||
|
),
|
||||||
|
'Symfony\\Polyfill\\Php83\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
|
||||||
|
),
|
||||||
|
'Symfony\\Polyfill\\Php82\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/symfony/polyfill-php82',
|
||||||
),
|
),
|
||||||
'Symfony\\Polyfill\\Php80\\' =>
|
'Symfony\\Polyfill\\Php80\\' =>
|
||||||
array (
|
array (
|
||||||
@@ -129,6 +152,10 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
|||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/symfony/translation',
|
0 => __DIR__ . '/..' . '/symfony/translation',
|
||||||
),
|
),
|
||||||
|
'Symfony\\Component\\Clock\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/symfony/clock',
|
||||||
|
),
|
||||||
'Stevenmaguire\\OAuth2\\Client\\' =>
|
'Stevenmaguire\\OAuth2\\Client\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/stevenmaguire/oauth2-keycloak/src',
|
0 => __DIR__ . '/..' . '/stevenmaguire/oauth2-keycloak/src',
|
||||||
@@ -253,12 +280,45 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static $classMap = array (
|
public static $classMap = array (
|
||||||
|
'AllowDynamicProperties' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/AllowDynamicProperties.php',
|
||||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||||
'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
|
|
||||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||||
|
'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||||
|
'DateInvalidOperationException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php',
|
||||||
|
'DateInvalidTimeZoneException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php',
|
||||||
|
'DateMalformedIntervalStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php',
|
||||||
|
'DateMalformedPeriodStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php',
|
||||||
|
'DateMalformedStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php',
|
||||||
|
'DateObjectError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php',
|
||||||
|
'DateRangeError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php',
|
||||||
|
'DelayedTargetValidation' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/DelayedTargetValidation.php',
|
||||||
|
'Deprecated' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Deprecated.php',
|
||||||
|
'Filter\\FilterException' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterException.php',
|
||||||
|
'Filter\\FilterFailedException' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/Filter/FilterFailedException.php',
|
||||||
|
'NoDiscard' => __DIR__ . '/..' . '/symfony/polyfill-php85/Resources/stubs/NoDiscard.php',
|
||||||
|
'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php',
|
||||||
|
'Pdo\\Dblib' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Dblib.php',
|
||||||
|
'Pdo\\Firebird' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Firebird.php',
|
||||||
|
'Pdo\\Mysql' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Mysql.php',
|
||||||
|
'Pdo\\Odbc' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Odbc.php',
|
||||||
|
'Pdo\\Pgsql' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Pgsql.php',
|
||||||
|
'Pdo\\Sqlite' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/Pdo/Sqlite.php',
|
||||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||||
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
|
'Random\\BrokenRandomEngineError' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/BrokenRandomEngineError.php',
|
||||||
|
'Random\\CryptoSafeEngine' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/CryptoSafeEngine.php',
|
||||||
|
'Random\\Engine' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/Engine.php',
|
||||||
|
'Random\\Engine\\Secure' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/Engine/Secure.php',
|
||||||
|
'Random\\RandomError' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/RandomError.php',
|
||||||
|
'Random\\RandomException' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/Random/RandomException.php',
|
||||||
|
'ReflectionConstant' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php',
|
||||||
|
'RoundingMode' => __DIR__ . '/..' . '/symfony/polyfill-php84/Resources/stubs/RoundingMode.php',
|
||||||
|
'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php',
|
||||||
|
'SensitiveParameter' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameter.php',
|
||||||
|
'SensitiveParameterValue' => __DIR__ . '/..' . '/symfony/polyfill-php82/Resources/stubs/SensitiveParameterValue.php',
|
||||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||||
|
'Time\\Duration' => __DIR__ . '/..' . '/symfony/polyfill-time/Resources/stubs/Time/Duration.php',
|
||||||
|
'Time\\TimeException' => __DIR__ . '/..' . '/symfony/polyfill-time/Resources/stubs/Time/TimeException.php',
|
||||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||||
);
|
);
|
||||||
|
|||||||
+869
-507
File diff suppressed because it is too large.
Load diff
+145
-118
@@ -29,18 +29,18 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'bshaffer/oauth2-server-php' => array(
|
'bshaffer/oauth2-server-php' => array(
|
||||||
'pretty_version' => 'v1.11.1',
|
'pretty_version' => 'v1.14.2',
|
||||||
'version' => '1.11.1.0',
|
'version' => '1.14.2.0',
|
||||||
'reference' => '5a0c8000d4763b276919e2106f54eddda6bc50fa',
|
'reference' => '1c715c2d2f71254d1c683b8c89a0f16b61ccd0d6',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../bshaffer/oauth2-server-php',
|
'install_path' => __DIR__ . '/../bshaffer/oauth2-server-php',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'carbonphp/carbon-doctrine-types' => array(
|
'carbonphp/carbon-doctrine-types' => array(
|
||||||
'pretty_version' => '3.2.0',
|
'pretty_version' => '3.2.1',
|
||||||
'version' => '3.2.0.0',
|
'version' => '3.2.1.0',
|
||||||
'reference' => '18ba5ddfec8976260ead6e866180bd5d2f71aa1d',
|
'reference' => '5fa5eacafd9ef47c8c6ab9143fc901ba0194d3dc',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../carbonphp/carbon-doctrine-types',
|
'install_path' => __DIR__ . '/../carbonphp/carbon-doctrine-types',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -56,18 +56,18 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'ddeboer/imap' => array(
|
'ddeboer/imap' => array(
|
||||||
'pretty_version' => '1.13.1',
|
'pretty_version' => '1.19.0',
|
||||||
'version' => '1.13.1.0',
|
'version' => '1.19.0.0',
|
||||||
'reference' => '8b772d04b1deadb5df13782fb78c4b648f77496e',
|
'reference' => '30800b1cfeacc4add5bb418e40a8b6e95a8a04ac',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../ddeboer/imap',
|
'install_path' => __DIR__ . '/../ddeboer/imap',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'directorytree/ldaprecord' => array(
|
'directorytree/ldaprecord' => array(
|
||||||
'pretty_version' => 'v3.8.5',
|
'pretty_version' => 'v3.8.6',
|
||||||
'version' => '3.8.5.0',
|
'version' => '3.8.6.0',
|
||||||
'reference' => '00e5f088f8c4028d5f398783cccc2e8119a27a65',
|
'reference' => 'a1cab9f078eb4756fc6fad58caea1e3d11cad0ec',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../directorytree/ldaprecord',
|
'install_path' => __DIR__ . '/../directorytree/ldaprecord',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -80,90 +80,90 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'firebase/php-jwt' => array(
|
'firebase/php-jwt' => array(
|
||||||
'pretty_version' => 'v6.5.0',
|
'pretty_version' => 'v7.2.1',
|
||||||
'version' => '6.5.0.0',
|
'version' => '7.2.1.0',
|
||||||
'reference' => 'e94e7353302b0c11ec3cfff7180cd0b1743975d2',
|
'reference' => '0501f5729b9e2448516674aff07c7d1727869b8e',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/guzzle' => array(
|
'guzzlehttp/guzzle' => array(
|
||||||
'pretty_version' => '7.5.0',
|
'pretty_version' => '8.3.1',
|
||||||
'version' => '7.5.0.0',
|
'version' => '8.3.1.0',
|
||||||
'reference' => 'b50a2a1251152e43f6a37f0fa053e730a67d25ba',
|
'reference' => '7d9b1f430bb65ac664e120af227bf9a795ad6333',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/promises' => array(
|
'guzzlehttp/promises' => array(
|
||||||
'pretty_version' => '1.5.2',
|
'pretty_version' => '3.1.0',
|
||||||
'version' => '1.5.2.0',
|
'version' => '3.1.0.0',
|
||||||
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598',
|
'reference' => '094d0ec418eb3b1411ea271a180ec95cae6ae933',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'guzzlehttp/psr7' => array(
|
'guzzlehttp/psr7' => array(
|
||||||
'pretty_version' => '2.4.5',
|
'pretty_version' => '3.2.0',
|
||||||
'version' => '2.4.5.0',
|
'version' => '3.2.0.0',
|
||||||
'reference' => '0454e12ef0cd597ccd2adb036f7bda4e7fface66',
|
'reference' => 'cdc139396207a5eba10c242d241fb014cb098390',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'illuminate/collections' => array(
|
'illuminate/collections' => array(
|
||||||
'pretty_version' => 'v10.49.0',
|
'pretty_version' => 'v12.70.2',
|
||||||
'version' => '10.49.0.0',
|
'version' => '12.70.2.0',
|
||||||
'reference' => '6ae9c74fa92d4e1824d1b346cd435e8eacdc3232',
|
'reference' => '83313b009c4afb6f02dbc090bdb67809756eefa2',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../illuminate/collections',
|
'install_path' => __DIR__ . '/../illuminate/collections',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'illuminate/conditionable' => array(
|
'illuminate/conditionable' => array(
|
||||||
'pretty_version' => 'v10.49.0',
|
'pretty_version' => 'v12.70.2',
|
||||||
'version' => '10.49.0.0',
|
'version' => '12.70.2.0',
|
||||||
'reference' => '47c700320b7a419f0d188d111f3bbed978fcbd3f',
|
'reference' => 'ec677967c1f2faf90b8428919124d2184a4c9b49',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../illuminate/conditionable',
|
'install_path' => __DIR__ . '/../illuminate/conditionable',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'illuminate/contracts' => array(
|
'illuminate/contracts' => array(
|
||||||
'pretty_version' => 'v10.44.0',
|
'pretty_version' => 'v12.70.2',
|
||||||
'version' => '10.44.0.0',
|
'version' => '12.70.2.0',
|
||||||
'reference' => '8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac',
|
'reference' => 'c16fd7ba7d8e6b8f336639ceb6b7e1ff6ed0efb5',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../illuminate/contracts',
|
'install_path' => __DIR__ . '/../illuminate/contracts',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'illuminate/macroable' => array(
|
'illuminate/macroable' => array(
|
||||||
'pretty_version' => 'v10.49.0',
|
'pretty_version' => 'v12.70.2',
|
||||||
'version' => '10.49.0.0',
|
'version' => '12.70.2.0',
|
||||||
'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27',
|
'reference' => 'e295d62d89dcdb87e2b1bd70dd14d074a0ed73cc',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../illuminate/macroable',
|
'install_path' => __DIR__ . '/../illuminate/macroable',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'league/oauth2-client' => array(
|
'league/oauth2-client' => array(
|
||||||
'pretty_version' => '2.7.0',
|
'pretty_version' => '2.9.1',
|
||||||
'version' => '2.7.0.0',
|
'version' => '2.9.1.0',
|
||||||
'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8',
|
'reference' => '8cedfef9d01a8d1fd2ecfabb41734b17592c4b71',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../league/oauth2-client',
|
'install_path' => __DIR__ . '/../league/oauth2-client',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'matthiasmullie/minify' => array(
|
'matthiasmullie/minify' => array(
|
||||||
'pretty_version' => '1.3.66',
|
'pretty_version' => '1.3.75',
|
||||||
'version' => '1.3.66.0',
|
'version' => '1.3.75.0',
|
||||||
'reference' => '45fd3b0f1dfa2c965857c6d4a470bea52adc31a6',
|
'reference' => '76ba4a5f555fd7bf4aa408af608e991569076671',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../matthiasmullie/minify',
|
'install_path' => __DIR__ . '/../matthiasmullie/minify',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -194,36 +194,27 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'nesbot/carbon' => array(
|
'nesbot/carbon' => array(
|
||||||
'pretty_version' => '2.72.3',
|
'pretty_version' => '3.15.1',
|
||||||
'version' => '2.72.3.0',
|
'version' => '3.15.1.0',
|
||||||
'reference' => '0c6fd108360c562f6e4fd1dedb8233b423e91c83',
|
'reference' => 'ce0e5636fae7d1e99856eb70cae4c719a284aa08',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../nesbot/carbon',
|
'install_path' => __DIR__ . '/../nesbot/carbon',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'paragonie/random_compat' => array(
|
|
||||||
'pretty_version' => 'v9.99.100',
|
|
||||||
'version' => '9.99.100.0',
|
|
||||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
|
||||||
'type' => 'library',
|
|
||||||
'install_path' => __DIR__ . '/../paragonie/random_compat',
|
|
||||||
'aliases' => array(),
|
|
||||||
'dev_requirement' => false,
|
|
||||||
),
|
|
||||||
'php-mime-mail-parser/php-mime-mail-parser' => array(
|
'php-mime-mail-parser/php-mime-mail-parser' => array(
|
||||||
'pretty_version' => '7.0.0',
|
'pretty_version' => '7.1.2',
|
||||||
'version' => '7.0.0.0',
|
'version' => '7.1.2.0',
|
||||||
'reference' => '9d09a017f3f103fec8456211a4a538b80e0eca0d',
|
'reference' => '81d84bbc6a73b913110e155e98059526825c7ee3',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../php-mime-mail-parser/php-mime-mail-parser',
|
'install_path' => __DIR__ . '/../php-mime-mail-parser/php-mime-mail-parser',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'phpmailer/phpmailer' => array(
|
'phpmailer/phpmailer' => array(
|
||||||
'pretty_version' => 'v6.6.0',
|
'pretty_version' => 'v6.12.0',
|
||||||
'version' => '6.6.0.0',
|
'version' => '6.12.0.0',
|
||||||
'reference' => 'e43bac82edc26ca04b36143a48bde1c051cfd5b1',
|
'reference' => 'd1ac35d784bf9f5e61b424901d5a014967f15b12',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -254,9 +245,9 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'psr/http-client' => array(
|
'psr/http-client' => array(
|
||||||
'pretty_version' => '1.0.1',
|
'pretty_version' => '1.0.3',
|
||||||
'version' => '1.0.1.0',
|
'version' => '1.0.3.0',
|
||||||
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
|
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/http-client',
|
'install_path' => __DIR__ . '/../psr/http-client',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -269,9 +260,9 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/http-factory' => array(
|
'psr/http-factory' => array(
|
||||||
'pretty_version' => '1.0.1',
|
'pretty_version' => '1.1.0',
|
||||||
'version' => '1.0.1.0',
|
'version' => '1.1.0.0',
|
||||||
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
|
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -280,13 +271,13 @@
|
|||||||
'psr/http-factory-implementation' => array(
|
'psr/http-factory-implementation' => array(
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
'provided' => array(
|
'provided' => array(
|
||||||
0 => '1.0',
|
0 => '1.1',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/http-message' => array(
|
'psr/http-message' => array(
|
||||||
'pretty_version' => '1.0.1',
|
'pretty_version' => '2.0',
|
||||||
'version' => '1.0.1.0',
|
'version' => '2.0.0.0',
|
||||||
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
|
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/http-message',
|
'install_path' => __DIR__ . '/../psr/http-message',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -295,40 +286,31 @@
|
|||||||
'psr/http-message-implementation' => array(
|
'psr/http-message-implementation' => array(
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
'provided' => array(
|
'provided' => array(
|
||||||
0 => '1.0',
|
0 => '2.0',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/log' => array(
|
'psr/log' => array(
|
||||||
'pretty_version' => '3.0.0',
|
'pretty_version' => '3.0.2',
|
||||||
'version' => '3.0.0.0',
|
'version' => '3.0.2.0',
|
||||||
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/log',
|
'install_path' => __DIR__ . '/../psr/log',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'psr/simple-cache' => array(
|
'psr/simple-cache' => array(
|
||||||
'pretty_version' => '2.0.0',
|
'pretty_version' => '3.0.0',
|
||||||
'version' => '2.0.0.0',
|
'version' => '3.0.0.0',
|
||||||
'reference' => '8707bf3cea6f710bf6ef05491234e3ab06f6432a',
|
'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../psr/simple-cache',
|
'install_path' => __DIR__ . '/../psr/simple-cache',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'ralouphie/getallheaders' => array(
|
|
||||||
'pretty_version' => '3.0.3',
|
|
||||||
'version' => '3.0.3.0',
|
|
||||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
|
||||||
'type' => 'library',
|
|
||||||
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
|
|
||||||
'aliases' => array(),
|
|
||||||
'dev_requirement' => false,
|
|
||||||
),
|
|
||||||
'robthree/twofactorauth' => array(
|
'robthree/twofactorauth' => array(
|
||||||
'pretty_version' => '1.8.1',
|
'pretty_version' => '1.8.2',
|
||||||
'version' => '1.8.1.0',
|
'version' => '1.8.2.0',
|
||||||
'reference' => '5afcb45282f1c75562a48d479ecd1732c9bdb11b',
|
'reference' => '65681de5a324eae05140ac58b08648a60212afc0',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../robthree/twofactorauth',
|
'install_path' => __DIR__ . '/../robthree/twofactorauth',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -344,72 +326,117 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'stevenmaguire/oauth2-keycloak' => array(
|
'stevenmaguire/oauth2-keycloak' => array(
|
||||||
'pretty_version' => '4.0.0',
|
'pretty_version' => '6.1.1',
|
||||||
'version' => '4.0.0.0',
|
'version' => '6.1.1.0',
|
||||||
'reference' => '05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d',
|
'reference' => '31bb3b1fa15b444212ed43facc898fafc7c2707a',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../stevenmaguire/oauth2-keycloak',
|
'install_path' => __DIR__ . '/../stevenmaguire/oauth2-keycloak',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
|
'symfony/clock' => array(
|
||||||
|
'pretty_version' => 'v7.4.21',
|
||||||
|
'version' => '7.4.21.0',
|
||||||
|
'reference' => '07437f612dca89c1894c1db04491002b1e798f03',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../symfony/clock',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
'symfony/deprecation-contracts' => array(
|
'symfony/deprecation-contracts' => array(
|
||||||
'pretty_version' => 'v3.5.0',
|
'pretty_version' => 'v3.7.1',
|
||||||
'version' => '3.5.0.0',
|
'version' => '3.7.1.0',
|
||||||
'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1',
|
'reference' => 'f3202fa1b5097b0af062dc978b32ecf63404e31d',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
|
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/polyfill-ctype' => array(
|
'symfony/polyfill-ctype' => array(
|
||||||
'pretty_version' => 'v1.24.0',
|
'pretty_version' => 'v1.37.0',
|
||||||
'version' => '1.24.0.0',
|
'version' => '1.37.0.0',
|
||||||
'reference' => '30885182c981ab175d4d034db0f6f469898070ab',
|
'reference' => '141046a8f9477948ff284fa65be2095baafb94f2',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/polyfill-mbstring' => array(
|
'symfony/polyfill-mbstring' => array(
|
||||||
'pretty_version' => 'v1.29.0',
|
'pretty_version' => 'v1.43.3',
|
||||||
'version' => '1.29.0.0',
|
'version' => '1.43.3.0',
|
||||||
'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec',
|
'reference' => '122889ed24dc000165bcbfd77ec412f15cbdfc6a',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/polyfill-php80' => array(
|
'symfony/polyfill-php80' => array(
|
||||||
'pretty_version' => 'v1.29.0',
|
'pretty_version' => 'v1.43.0',
|
||||||
'version' => '1.29.0.0',
|
'version' => '1.43.0.0',
|
||||||
'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b',
|
'reference' => '9c6a5d6b01ca51d486c813e9a9c0ed55f208bb74',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/polyfill-php81' => array(
|
'symfony/polyfill-php82' => array(
|
||||||
'pretty_version' => 'v1.31.0',
|
'pretty_version' => 'v1.43.0',
|
||||||
'version' => '1.31.0.0',
|
'version' => '1.43.0.0',
|
||||||
'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c',
|
'reference' => '843bbe8b2a7934307b749751eede0f111f5d1cfc',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/polyfill-php81',
|
'install_path' => __DIR__ . '/../symfony/polyfill-php82',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'symfony/polyfill-php83' => array(
|
||||||
|
'pretty_version' => 'v1.43.0',
|
||||||
|
'version' => '1.43.0.0',
|
||||||
|
'reference' => '80ccff923a8d61f73ebe9da0aa94e25232f004ce',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../symfony/polyfill-php83',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'symfony/polyfill-php84' => array(
|
||||||
|
'pretty_version' => 'v1.43.0',
|
||||||
|
'version' => '1.43.0.0',
|
||||||
|
'reference' => '22c6548499cbe5c5bb072fc0c42312dff062a015',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../symfony/polyfill-php84',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'symfony/polyfill-php85' => array(
|
||||||
|
'pretty_version' => 'v1.43.0',
|
||||||
|
'version' => '1.43.0.0',
|
||||||
|
'reference' => '86a42cbcc07adc331481a5ab310a4024bfc227f6',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../symfony/polyfill-php85',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'symfony/polyfill-time' => array(
|
||||||
|
'pretty_version' => 'v1.42.0',
|
||||||
|
'version' => '1.42.0.0',
|
||||||
|
'reference' => 'ac9f1ed802dd58f37e720388130c088434aa09fc',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../symfony/polyfill-time',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/translation' => array(
|
'symfony/translation' => array(
|
||||||
'pretty_version' => 'v6.4.3',
|
'pretty_version' => 'v7.4.17',
|
||||||
'version' => '6.4.3.0',
|
'version' => '7.4.17.0',
|
||||||
'reference' => '637c51191b6b184184bbf98937702bcf554f7d04',
|
'reference' => '2ee1e4a3b32a528a642babe041ff7c440b213b4b',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/translation',
|
'install_path' => __DIR__ . '/../symfony/translation',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'symfony/translation-contracts' => array(
|
'symfony/translation-contracts' => array(
|
||||||
'pretty_version' => 'v3.4.1',
|
'pretty_version' => 'v3.7.1',
|
||||||
'version' => '3.4.1.0',
|
'version' => '3.7.1.0',
|
||||||
'reference' => '06450585bf65e978026bda220cdebca3f867fde7',
|
'reference' => 'ccb206b98faccc511ebae8e5fad50f2dc0b30621',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../symfony/translation-contracts',
|
'install_path' => __DIR__ . '/../symfony/translation-contracts',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -422,9 +449,9 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
'twig/twig' => array(
|
'twig/twig' => array(
|
||||||
'pretty_version' => 'v3.14.0',
|
'pretty_version' => 'v3.30.0',
|
||||||
'version' => '3.14.0.0',
|
'version' => '3.30.0.0',
|
||||||
'reference' => '126b2c97818dbff0cdf3fbfc881aedb3d40aae72',
|
'reference' => '8c737079b726af72ff8ef3c595be9f6a810ea1ef',
|
||||||
'type' => 'library',
|
'type' => 'library',
|
||||||
'install_path' => __DIR__ . '/../twig/twig',
|
'install_path' => __DIR__ . '/../twig/twig',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
|||||||
+4
-5
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
$issues = array();
|
$issues = array();
|
||||||
|
|
||||||
if (!(PHP_VERSION_ID >= 80100)) {
|
if (!(PHP_VERSION_ID >= 80200)) {
|
||||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
|
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($issues) {
|
if ($issues) {
|
||||||
@@ -19,8 +19,7 @@ if ($issues) {
|
|||||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trigger_error(
|
throw new \RuntimeException(
|
||||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||||
E_USER_ERROR
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+3
-3
@@ -17,7 +17,7 @@ return (new PhpCsFixer\Config())
|
|||||||
'binary_operator_spaces' => ['default' => 'align_single_space'],
|
'binary_operator_spaces' => ['default' => 'align_single_space'],
|
||||||
'blank_line_before_statement' => true,
|
'blank_line_before_statement' => true,
|
||||||
'class_definition' => ['single_item_single_line' => true],
|
'class_definition' => ['single_item_single_line' => true],
|
||||||
'compact_nullable_typehint' => true,
|
'compact_nullable_type_declaration' => true,
|
||||||
'concat_space' => ['spacing' => 'one'],
|
'concat_space' => ['spacing' => 'one'],
|
||||||
'echo_tag_syntax' => ['format' => 'long'],
|
'echo_tag_syntax' => ['format' => 'long'],
|
||||||
'error_suppression' => false,
|
'error_suppression' => false,
|
||||||
@@ -39,7 +39,7 @@ return (new PhpCsFixer\Config())
|
|||||||
'no_null_property_initialization' => true,
|
'no_null_property_initialization' => true,
|
||||||
'no_php4_constructor' => true,
|
'no_php4_constructor' => true,
|
||||||
'no_superfluous_elseif' => true,
|
'no_superfluous_elseif' => true,
|
||||||
'no_unneeded_curly_braces' => true,
|
'no_unneeded_braces' => true,
|
||||||
'no_unneeded_final_method' => true,
|
'no_unneeded_final_method' => true,
|
||||||
'no_unreachable_default_argument_value' => true,
|
'no_unreachable_default_argument_value' => true,
|
||||||
'no_useless_else' => true,
|
'no_useless_else' => true,
|
||||||
@@ -49,7 +49,7 @@ return (new PhpCsFixer\Config())
|
|||||||
'php_unit_set_up_tear_down_visibility' => true,
|
'php_unit_set_up_tear_down_visibility' => true,
|
||||||
'php_unit_strict' => true,
|
'php_unit_strict' => true,
|
||||||
'php_unit_test_annotation' => true,
|
'php_unit_test_annotation' => true,
|
||||||
'php_unit_test_case_static_method_calls' => true,
|
'php_unit_test_case_static_method_calls' => false,
|
||||||
'php_unit_test_class_requires_covers' => false,
|
'php_unit_test_class_requires_covers' => false,
|
||||||
'phpdoc_add_missing_param_annotation' => true,
|
'phpdoc_add_missing_param_annotation' => true,
|
||||||
'phpdoc_order' => true,
|
'phpdoc_order' => true,
|
||||||
|
|||||||
+20
-22
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
[](https://packagist.org/packages/ddeboer/imap)
|
[](https://packagist.org/packages/ddeboer/imap)
|
||||||
[](https://packagist.org/packages/ddeboer/imap)
|
[](https://packagist.org/packages/ddeboer/imap)
|
||||||
[](https://github.com/ddeboer/imap/actions)
|
[](https://github.com/ddeboer/imap/actions)
|
||||||
[](https://codecov.io/gh/ddeboer/imap?branch=master)
|
[](https://codecov.io/gh/ddeboer/imap?branch=master)
|
||||||
|
|
||||||
A PHP IMAP library to read and process e-mails over IMAP protocol, built with robust Object-Oriented architecture.
|
A PHP IMAP library to read and process e-mails over IMAP protocol, built with robust Object-Oriented architecture.
|
||||||
|
|
||||||
This library requires PHP >= 7.4 with [IMAP](https://www.php.net/manual/en/book.imap.php),
|
This library requires PHP >= 8.2 with [IMAP](https://www.php.net/manual/en/book.imap.php),
|
||||||
[iconv](https://www.php.net/manual/en/book.iconv.php) and
|
[iconv](https://www.php.net/manual/en/book.iconv.php) and
|
||||||
[Multibyte String](https://www.php.net/manual/en/book.mbstring.php) extensions installed.
|
[Multibyte String](https://www.php.net/manual/en/book.mbstring.php) extensions installed.
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ By the way most of the common search criteria are available and functioning, bro
|
|||||||
References:
|
References:
|
||||||
|
|
||||||
1. https://stackoverflow.com/questions/36356715/imap-search-unknown-search-criterion-or
|
1. https://stackoverflow.com/questions/36356715/imap-search-unknown-search-criterion-or
|
||||||
1. imap-2007f.tar.gz: `./src/c-client/mail.c` and `./docs/internal.txt`
|
2. imap-2007f.tar.gz: `./src/c-client/mail.c` and `./docs/internal.txt`
|
||||||
|
|
||||||
#### Message Properties and Operations
|
#### Message Properties and Operations
|
||||||
|
|
||||||
@@ -182,19 +182,29 @@ $message->isDraft();
|
|||||||
$message->isSeen();
|
$message->isSeen();
|
||||||
```
|
```
|
||||||
|
|
||||||
Get message headers as a [\Ddeboer\Imap\Message\Headers](/src/Ddeboer/Imap/Message/Headers.php) object:
|
Get message headers as a [\Ddeboer\Imap\Message\Headers](/src/Message/Headers.php) object:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$message->getHeaders();
|
$message->getHeaders();
|
||||||
```
|
```
|
||||||
|
|
||||||
Get message body as HTML or plain text:
|
Get message body as HTML or plain text (only first part):
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$message->getBodyHtml(); // Content of text/html part, if present
|
$message->getBodyHtml(); // Content of text/html part, if present
|
||||||
$message->getBodyText(); // Content of text/plain part, if present
|
$message->getBodyText(); // Content of text/plain part, if present
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Get complete body (all parts):
|
||||||
|
|
||||||
|
```php
|
||||||
|
$body = $message->getCompleteBodyHtml(); // Content of text/html part, if present
|
||||||
|
if ($body === null) { // If body is null, there are no HTML parts, so let's try getting the text body
|
||||||
|
$body = $message->getCompleteBodyText(); // Content of text/plain part, if present
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Reading the message body keeps the message as unseen.
|
Reading the message body keeps the message as unseen.
|
||||||
If you want to mark the message as seen:
|
If you want to mark the message as seen:
|
||||||
|
|
||||||
@@ -284,24 +294,12 @@ Mockability is granted by interfaces present for each API.
|
|||||||
Dig into [MockabilityTest](tests/MockabilityTest.php) for an example of a
|
Dig into [MockabilityTest](tests/MockabilityTest.php) for an example of a
|
||||||
mocked workflow.
|
mocked workflow.
|
||||||
|
|
||||||
## Running the Tests
|
## Contributing: run the build locally
|
||||||
|
|
||||||
This library is functionally tested on [Travis CI](https://travis-ci.org/ddeboer/imap)
|
Docker is needed to run the build on your computer.
|
||||||
against a local Dovecot server.
|
|
||||||
|
|
||||||
If you have your own IMAP (test) account, you can run the tests locally by
|
First command you need to run is `make start-imap-server`, which starts an IMAP server locally.
|
||||||
providing your IMAP credentials:
|
|
||||||
|
|
||||||
```bash
|
Then the local build can be triggered with a bare `make`.
|
||||||
$ composer install
|
|
||||||
$ IMAP_SERVER_NAME="my.imap.server.com" IMAP_SERVER_PORT="60993" IMAP_USERNAME="johndoe" IMAP_PASSWORD="p4ssword" vendor/bin/phpunit
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also copy `phpunit.xml.dist` file to a custom `phpunit.xml` and put
|
When you finish the development, stop the local IMAP server with `make stop-imap-server`.
|
||||||
these environment variables in it.
|
|
||||||
|
|
||||||
**WARNING** Tests create new mailboxes without removing them.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ docker-compose run tests
|
|
||||||
```
|
|
||||||
+9
-13
@@ -22,19 +22,20 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.0.1",
|
"php": "~8.2.0 || ~8.3.0",
|
||||||
|
"ext-dom": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"ext-imap": "*",
|
"ext-imap": "*",
|
||||||
|
"ext-libxml": "*",
|
||||||
"ext-mbstring": "*"
|
"ext-mbstring": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^v3.4.0",
|
"friendsofphp/php-cs-fixer": "^3.38.2",
|
||||||
"laminas/laminas-mail": "^2.15.1",
|
"laminas/laminas-mail": "^2.25.1",
|
||||||
"malukenho/mcbumpface": "^1.1.5",
|
"phpstan/phpstan": "^1.10.43",
|
||||||
"phpstan/phpstan": "^1.3.3",
|
"phpstan/phpstan-phpunit": "^1.3.15",
|
||||||
"phpstan/phpstan-phpunit": "^1.0.0",
|
"phpstan/phpstan-strict-rules": "^1.5.2",
|
||||||
"phpstan/phpstan-strict-rules": "^1.1.0",
|
"phpunit/phpunit": "^10.4.2"
|
||||||
"phpunit/phpunit": "^9.5.11"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@@ -45,10 +46,5 @@
|
|||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Ddeboer\\Imap\\Tests\\": "tests/"
|
"Ddeboer\\Imap\\Tests\\": "tests/"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"allow-plugins": {
|
|
||||||
"malukenho/mcbumpface": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -50,9 +50,11 @@ final class Connection implements ConnectionInterface
|
|||||||
|
|
||||||
public function close(int $flag = 0): bool
|
public function close(int $flag = 0): bool
|
||||||
{
|
{
|
||||||
|
$stream = $this->resource->getStream();
|
||||||
|
|
||||||
$this->resource->clearLastMailboxUsedCache();
|
$this->resource->clearLastMailboxUsedCache();
|
||||||
|
|
||||||
return \imap_close($this->resource->getStream(), $flag);
|
return \imap_close($stream, $flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQuota(string $root = 'INBOX'): array
|
public function getQuota(string $root = 'INBOX'): array
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ namespace Ddeboer\Imap;
|
|||||||
|
|
||||||
use Ddeboer\Imap\Exception\CreateMailboxException;
|
use Ddeboer\Imap\Exception\CreateMailboxException;
|
||||||
use Ddeboer\Imap\Exception\DeleteMailboxException;
|
use Ddeboer\Imap\Exception\DeleteMailboxException;
|
||||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
|
||||||
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
use Ddeboer\Imap\Exception\MailboxDoesNotExistException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,8 +30,6 @@ interface ConnectionInterface extends \Countable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the connection is still active.
|
* Check if the connection is still active.
|
||||||
*
|
|
||||||
* @throws InvalidResourceException If connection was closed
|
|
||||||
*/
|
*/
|
||||||
public function ping(): bool;
|
public function ping(): bool;
|
||||||
|
|
||||||
|
|||||||
Vendored
Regular → Executable
+1
-1
@@ -4,6 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap\Exception;
|
namespace Ddeboer\Imap\Exception;
|
||||||
|
|
||||||
final class InvalidResourceException extends AbstractException
|
final class RenameMailboxException extends AbstractException
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
+5
-20
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap;
|
namespace Ddeboer\Imap;
|
||||||
|
|
||||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
|
||||||
use Ddeboer\Imap\Exception\ReopenMailboxException;
|
use Ddeboer\Imap\Exception\ReopenMailboxException;
|
||||||
use IMAP\Connection;
|
use IMAP\Connection;
|
||||||
|
|
||||||
@@ -13,33 +12,21 @@ use IMAP\Connection;
|
|||||||
*/
|
*/
|
||||||
final class ImapResource implements ImapResourceInterface
|
final class ImapResource implements ImapResourceInterface
|
||||||
{
|
{
|
||||||
/**
|
private Connection $resource;
|
||||||
* @var resource
|
private ?MailboxInterface $mailbox;
|
||||||
*/
|
|
||||||
private $resource;
|
|
||||||
private ?MailboxInterface $mailbox = null;
|
|
||||||
private static ?string $lastMailboxUsedCache = null;
|
private static ?string $lastMailboxUsedCache = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
|
||||||
* @param Connection|resource $resource
|
|
||||||
*/
|
*/
|
||||||
public function __construct($resource, MailboxInterface $mailbox = null)
|
public function __construct(Connection $resource, MailboxInterface $mailbox = null)
|
||||||
{
|
{
|
||||||
$this->resource = $resource;
|
$this->resource = $resource;
|
||||||
$this->mailbox = $mailbox;
|
$this->mailbox = $mailbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStream()
|
public function getStream(): Connection
|
||||||
{
|
{
|
||||||
if (
|
|
||||||
!$this->resource instanceof Connection
|
|
||||||
&& (false === \is_resource($this->resource) || 'imap' !== \get_resource_type($this->resource))
|
|
||||||
) {
|
|
||||||
throw new InvalidResourceException('Supplied resource is not a valid imap resource');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->initMailbox();
|
$this->initMailbox();
|
||||||
|
|
||||||
return $this->resource;
|
return $this->resource;
|
||||||
@@ -76,10 +63,8 @@ final class ImapResource implements ImapResourceInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the current mailbox is open.
|
* Check whether the current mailbox is open.
|
||||||
*
|
|
||||||
* @param resource $resource
|
|
||||||
*/
|
*/
|
||||||
private static function isMailboxOpen(MailboxInterface $mailbox, $resource): bool
|
private static function isMailboxOpen(MailboxInterface $mailbox, Connection $resource): bool
|
||||||
{
|
{
|
||||||
$currentMailboxName = $mailbox->getFullEncodedName();
|
$currentMailboxName = $mailbox->getFullEncodedName();
|
||||||
if ($currentMailboxName === self::$lastMailboxUsedCache) {
|
if ($currentMailboxName === self::$lastMailboxUsedCache) {
|
||||||
|
|||||||
@@ -4,18 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap;
|
namespace Ddeboer\Imap;
|
||||||
|
|
||||||
use Ddeboer\Imap\Exception\InvalidResourceException;
|
use IMAP\Connection;
|
||||||
|
|
||||||
interface ImapResourceInterface
|
interface ImapResourceInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get IMAP resource stream.
|
* Get IMAP resource stream.
|
||||||
*
|
|
||||||
* @throws InvalidResourceException
|
|
||||||
*
|
|
||||||
* @return resource
|
|
||||||
*/
|
*/
|
||||||
public function getStream();
|
public function getStream(): Connection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear last mailbox used cache.
|
* Clear last mailbox used cache.
|
||||||
|
|||||||
+19
-6
@@ -4,12 +4,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap;
|
namespace Ddeboer\Imap;
|
||||||
|
|
||||||
use DateTimeInterface;
|
|
||||||
use Ddeboer\Imap\Exception\ImapNumMsgException;
|
use Ddeboer\Imap\Exception\ImapNumMsgException;
|
||||||
use Ddeboer\Imap\Exception\ImapStatusException;
|
use Ddeboer\Imap\Exception\ImapStatusException;
|
||||||
use Ddeboer\Imap\Exception\InvalidSearchCriteriaException;
|
use Ddeboer\Imap\Exception\InvalidSearchCriteriaException;
|
||||||
use Ddeboer\Imap\Exception\MessageCopyException;
|
use Ddeboer\Imap\Exception\MessageCopyException;
|
||||||
use Ddeboer\Imap\Exception\MessageMoveException;
|
use Ddeboer\Imap\Exception\MessageMoveException;
|
||||||
|
use Ddeboer\Imap\Exception\RenameMailboxException;
|
||||||
use Ddeboer\Imap\Search\ConditionInterface;
|
use Ddeboer\Imap\Search\ConditionInterface;
|
||||||
use Ddeboer\Imap\Search\LogicalOperator\All;
|
use Ddeboer\Imap\Search\LogicalOperator\All;
|
||||||
|
|
||||||
@@ -41,6 +41,23 @@ final class Mailbox implements MailboxInterface
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renameTo(string $name): bool
|
||||||
|
{
|
||||||
|
$encodedName = \mb_convert_encoding($name, 'UTF7-IMAP', 'UTF-8');
|
||||||
|
$oldFullName = $this->getFullEncodedName();
|
||||||
|
$newFullName = \preg_replace('/' . \preg_quote(\mb_convert_encoding($this->name, 'UTF7-IMAP', 'UTF-8')) . '$/', $encodedName, $oldFullName);
|
||||||
|
\assert(null !== $newFullName);
|
||||||
|
|
||||||
|
$return = \imap_renamemailbox($this->resource->getStream(), $oldFullName, $newFullName);
|
||||||
|
if (false === $return) {
|
||||||
|
throw new RenameMailboxException('Could not rename mailbox');
|
||||||
|
}
|
||||||
|
$this->name = $name;
|
||||||
|
$this->info->name = $newFullName;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEncodedName(): string
|
public function getEncodedName(): string
|
||||||
{
|
{
|
||||||
/** @var string $name */
|
/** @var string $name */
|
||||||
@@ -104,10 +121,6 @@ final class Mailbox implements MailboxInterface
|
|||||||
}
|
}
|
||||||
$query = $search->toString();
|
$query = $search->toString();
|
||||||
|
|
||||||
if (\PHP_VERSION_ID < 80000) {
|
|
||||||
$descending = (int) $descending;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to clear the stack to know whether imap_last_error()
|
// We need to clear the stack to know whether imap_last_error()
|
||||||
// is related to this imap_search
|
// is related to this imap_search
|
||||||
\imap_errors();
|
\imap_errors();
|
||||||
@@ -178,7 +191,7 @@ final class Mailbox implements MailboxInterface
|
|||||||
return $this->getMessages();
|
return $this->getMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool
|
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool
|
||||||
{
|
{
|
||||||
$arguments = [
|
$arguments = [
|
||||||
$this->resource->getStream(),
|
$this->resource->getStream(),
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap;
|
namespace Ddeboer\Imap;
|
||||||
|
|
||||||
use DateTimeInterface;
|
|
||||||
use Ddeboer\Imap\Message\PartInterface;
|
use Ddeboer\Imap\Message\PartInterface;
|
||||||
use Ddeboer\Imap\Search\ConditionInterface;
|
use Ddeboer\Imap\Search\ConditionInterface;
|
||||||
|
|
||||||
@@ -20,6 +19,11 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
public function getName(): string;
|
public function getName(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set new mailbox name.
|
||||||
|
*/
|
||||||
|
public function renameTo(string $name): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get mailbox encoded path.
|
* Get mailbox encoded path.
|
||||||
*/
|
*/
|
||||||
@@ -92,7 +96,7 @@ interface MailboxInterface extends \Countable, \IteratorAggregate
|
|||||||
/**
|
/**
|
||||||
* Add a message to the mailbox.
|
* Add a message to the mailbox.
|
||||||
*/
|
*/
|
||||||
public function addMessage(string $message, string $options = null, DateTimeInterface $internalDate = null): bool;
|
public function addMessage(string $message, string $options = null, \DateTimeInterface $internalDate = null): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a tree of threaded message for the current Mailbox.
|
* Returns a tree of threaded message for the current Mailbox.
|
||||||
|
|||||||
+9
-4
@@ -80,7 +80,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
|||||||
}
|
}
|
||||||
$this->messageNumberVerified = true;
|
$this->messageNumberVerified = true;
|
||||||
|
|
||||||
$msgno = null;
|
|
||||||
\set_error_handler(static function (): bool {
|
\set_error_handler(static function (): bool {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -89,7 +88,7 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
|||||||
|
|
||||||
\restore_error_handler();
|
\restore_error_handler();
|
||||||
|
|
||||||
if (\is_numeric($msgno) && $msgno > 0) {
|
if ($msgno > 0) {
|
||||||
$this->imapMsgNo = $msgno;
|
$this->imapMsgNo = $msgno;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -133,6 +132,14 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
|||||||
return $this->rawMessage;
|
return $this->rawMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
|
||||||
|
*/
|
||||||
|
public function saveRawMessage($file): void
|
||||||
|
{
|
||||||
|
$this->doSaveContent($file, '');
|
||||||
|
}
|
||||||
|
|
||||||
public function getHeaders(): Message\Headers
|
public function getHeaders(): Message\Headers
|
||||||
{
|
{
|
||||||
if (null === $this->headers) {
|
if (null === $this->headers) {
|
||||||
@@ -198,8 +205,6 @@ final class Message extends Message\AbstractMessage implements MessageInterface
|
|||||||
|
|
||||||
public function maskAsSeen(): bool
|
public function maskAsSeen(): bool
|
||||||
{
|
{
|
||||||
\trigger_error(\sprintf('%s is deprecated and will be removed in 2.0. Use %s::markAsSeen instead.', __METHOD__, __CLASS__), \E_USER_DEPRECATED);
|
|
||||||
|
|
||||||
return $this->markAsSeen();
|
return $this->markAsSeen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,45 +203,117 @@ abstract class AbstractMessage extends AbstractPart
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get body HTML.
|
* Get first body HTML part.
|
||||||
*/
|
*/
|
||||||
final public function getBodyHtml(): ?string
|
final public function getBodyHtml(): ?string
|
||||||
|
{
|
||||||
|
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
|
||||||
|
|
||||||
|
return $htmlParts[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all contents parts of specific subtype (self::SUBTYPE_HTML or self::SUBTYPE_PLAIN).
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
final public function getAllContentsBySubtype(string $subtype): array
|
||||||
{
|
{
|
||||||
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
|
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
$parts = [];
|
||||||
|
/** @var PartInterface $part */
|
||||||
foreach ($iterator as $part) {
|
foreach ($iterator as $part) {
|
||||||
if (self::SUBTYPE_HTML === $part->getSubtype()) {
|
if ($subtype === $part->getSubtype()) {
|
||||||
return $part->getDecodedContent();
|
$parts[] = $part->getDecodedContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (\count($parts) > 0) {
|
||||||
|
return $parts;
|
||||||
|
}
|
||||||
|
|
||||||
// If message has no parts and is HTML, return content of message itself.
|
// If message has no parts and is of right type, return content of message.
|
||||||
if (self::SUBTYPE_HTML === $this->getSubtype()) {
|
if ($subtype === $this->getSubtype()) {
|
||||||
return $this->getDecodedContent();
|
return [$this->getDecodedContent()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get body HTML parts.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
final public function getBodyHtmlParts(): array
|
||||||
|
{
|
||||||
|
return $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all body HTML parts merged into 1 html.
|
||||||
|
*/
|
||||||
|
final public function getCompleteBodyHtml(): ?string
|
||||||
|
{
|
||||||
|
$htmlParts = $this->getAllContentsBySubtype(self::SUBTYPE_HTML);
|
||||||
|
|
||||||
|
if (1 === \count($htmlParts)) {
|
||||||
|
return $htmlParts[0];
|
||||||
|
}
|
||||||
|
if (0 === \count($htmlParts)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
\libxml_use_internal_errors(true); // Suppress parse errors, get errors with libxml_get_errors();
|
||||||
|
|
||||||
|
$newDom = new \DOMDocument();
|
||||||
|
|
||||||
|
$newBody = '';
|
||||||
|
$newDom->loadHTML(\implode('', $htmlParts));
|
||||||
|
|
||||||
|
$bodyTags = $newDom->getElementsByTagName('body');
|
||||||
|
|
||||||
|
foreach ($bodyTags as $body) {
|
||||||
|
foreach ($body->childNodes as $node) {
|
||||||
|
$newBody .= $newDom->saveHTML($node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$newDom = new \DOMDocument();
|
||||||
|
$newDom->loadHTML($newBody);
|
||||||
|
|
||||||
|
$completeHtml = $newDom->saveHTML();
|
||||||
|
|
||||||
|
return false === $completeHtml ? null : $completeHtml;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get body text.
|
* Get body text.
|
||||||
*/
|
*/
|
||||||
final public function getBodyText(): ?string
|
final public function getBodyText(): ?string
|
||||||
{
|
{
|
||||||
$iterator = new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
|
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
|
||||||
foreach ($iterator as $part) {
|
|
||||||
if (self::SUBTYPE_PLAIN === $part->getSubtype()) {
|
return $plainParts[0] ?? null;
|
||||||
return $part->getDecodedContent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If message has no parts, return content of message itself.
|
/**
|
||||||
if (self::SUBTYPE_PLAIN === $this->getSubtype()) {
|
* Get all body PLAIN parts merged into 1 string.
|
||||||
return $this->getDecodedContent();
|
*
|
||||||
}
|
* @return null|string Null if message has no PLAIN message parts
|
||||||
|
*/
|
||||||
|
final public function getCompleteBodyText(): ?string
|
||||||
|
{
|
||||||
|
$plainParts = $this->getAllContentsBySubtype(self::SUBTYPE_PLAIN);
|
||||||
|
|
||||||
|
if (1 === \count($plainParts)) {
|
||||||
|
return $plainParts[0];
|
||||||
|
}
|
||||||
|
if (0 === \count($plainParts)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return \implode("\n", $plainParts);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get attachments (if any) linked to this e-mail.
|
* Get attachments (if any) linked to this e-mail.
|
||||||
*
|
*
|
||||||
@@ -269,7 +341,7 @@ abstract class AbstractMessage extends AbstractPart
|
|||||||
$attachments[] = $childPart;
|
$attachments[] = $childPart;
|
||||||
}
|
}
|
||||||
if ($childPart->hasChildren()) {
|
if ($childPart->hasChildren()) {
|
||||||
$attachments = \array_merge($attachments, self::gatherAttachments($childPart));
|
$attachments = [...$attachments, ...self::gatherAttachments($childPart)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,7 @@ abstract class AbstractPart implements PartInterface
|
|||||||
private ?string $encoding = null;
|
private ?string $encoding = null;
|
||||||
private ?string $disposition = null;
|
private ?string $disposition = null;
|
||||||
private ?string $description = null;
|
private ?string $description = null;
|
||||||
/** @var null|int|string */
|
private string|int|null $bytes;
|
||||||
private $bytes;
|
|
||||||
private ?string $lines = null;
|
private ?string $lines = null;
|
||||||
private ?string $content = null;
|
private ?string $content = null;
|
||||||
private ?string $decodedContent = null;
|
private ?string $decodedContent = null;
|
||||||
@@ -256,6 +255,26 @@ abstract class AbstractPart implements PartInterface
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save raw message content to file.
|
||||||
|
*
|
||||||
|
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
|
||||||
|
*/
|
||||||
|
final protected function doSaveContent($file, string $partNumber): void
|
||||||
|
{
|
||||||
|
$return = \imap_savebody(
|
||||||
|
$this->resource->getStream(),
|
||||||
|
$file,
|
||||||
|
$this->getNumber(),
|
||||||
|
$partNumber,
|
||||||
|
\FT_UID | \FT_PEEK
|
||||||
|
);
|
||||||
|
|
||||||
|
if (false === $return) {
|
||||||
|
throw new ImapFetchbodyException('imap_savebody failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final public function getParts(): array
|
final public function getParts(): array
|
||||||
{
|
{
|
||||||
$this->lazyParseStructure();
|
$this->lazyParseStructure();
|
||||||
@@ -265,8 +284,6 @@ abstract class AbstractPart implements PartInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current child part.
|
* Get current child part.
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
#[\ReturnTypeWillChange]
|
#[\ReturnTypeWillChange]
|
||||||
final public function current()
|
final public function current()
|
||||||
@@ -360,7 +377,7 @@ abstract class AbstractPart implements PartInterface
|
|||||||
|
|
||||||
// When the message is not multipart and the body is the attachment content
|
// When the message is not multipart and the body is the attachment content
|
||||||
// Prevents infinite recursion
|
// Prevents infinite recursion
|
||||||
if (self::isAttachment($this->structure) && !$this instanceof Attachment) {
|
if (!$this instanceof Attachment && self::isAttachment($this->structure)) {
|
||||||
$this->parts[] = new Attachment($this->resource, $this->getNumber(), '1', $this->structure);
|
$this->parts[] = new Attachment($this->resource, $this->getNumber(), '1', $this->structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,12 +389,11 @@ abstract class AbstractPart implements PartInterface
|
|||||||
}
|
}
|
||||||
foreach ($parts as $key => $partStructure) {
|
foreach ($parts as $key => $partStructure) {
|
||||||
$partNumber = (!$this instanceof Message) ? $this->partNumber . '.' : '';
|
$partNumber = (!$this instanceof Message) ? $this->partNumber . '.' : '';
|
||||||
$partNumber .= (string) ($key + 1);
|
$partNumber .= $key + 1;
|
||||||
|
|
||||||
$newPartClass = self::isAttachment($partStructure)
|
$newPartClass = self::isAttachment($partStructure)
|
||||||
? Attachment::class
|
? Attachment::class
|
||||||
: SimplePart::class
|
: SimplePart::class;
|
||||||
;
|
|
||||||
|
|
||||||
$this->parts[] = new $newPartClass($this->resource, $this->getNumber(), $partNumber, $partStructure);
|
$this->parts[] = new $newPartClass($this->resource, $this->getNumber(), $partNumber, $partStructure);
|
||||||
}
|
}
|
||||||
@@ -427,10 +443,6 @@ abstract class AbstractPart implements PartInterface
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (self::SUBTYPE_RFC822 === \strtoupper($part->subtype)) {
|
return self::SUBTYPE_RFC822 === \strtoupper($part->subtype);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+36
-1
@@ -18,6 +18,13 @@ interface BasicMessageInterface extends PartInterface
|
|||||||
*/
|
*/
|
||||||
public function getRawMessage(): string;
|
public function getRawMessage(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the raw message, including all headers, parts, etc. unencoded and unparsed to file.
|
||||||
|
*
|
||||||
|
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
|
||||||
|
*/
|
||||||
|
public function saveRawMessage($file): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get message headers.
|
* Get message headers.
|
||||||
*/
|
*/
|
||||||
@@ -109,17 +116,45 @@ interface BasicMessageInterface extends PartInterface
|
|||||||
public function getReferences(): array;
|
public function getReferences(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get body HTML.
|
* Get message parts by type.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getAllContentsBySubtype(string $subtype): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get first body HTML part.
|
||||||
*
|
*
|
||||||
* @return null|string Null if message has no HTML message part
|
* @return null|string Null if message has no HTML message part
|
||||||
*/
|
*/
|
||||||
public function getBodyHtml(): ?string;
|
public function getBodyHtml(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all body HTML parts as array.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getBodyHtmlParts(): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all body HTML parts merged into 1 html.
|
||||||
|
*
|
||||||
|
* @return null|string Null if message has no HTML message parts
|
||||||
|
*/
|
||||||
|
public function getCompleteBodyHtml(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get body text.
|
* Get body text.
|
||||||
*/
|
*/
|
||||||
public function getBodyText(): ?string;
|
public function getBodyText(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all body PLAIN parts merged into 1 string.
|
||||||
|
*
|
||||||
|
* @return null|string Null if message has no PLAIN message parts
|
||||||
|
*/
|
||||||
|
public function getCompleteBodyText(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get attachments (if any) linked to this e-mail.
|
* Get attachments (if any) linked to this e-mail.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ final class EmbeddedMessage extends AbstractMessage implements EmbeddedMessageIn
|
|||||||
return $this->rawMessage;
|
return $this->rawMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resource|string $file the path to the saved file as a string, or a valid file descriptor
|
||||||
|
*/
|
||||||
|
public function saveRawMessage($file): void
|
||||||
|
{
|
||||||
|
$this->doSaveContent($file, $this->getPartNumber());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get content part number.
|
* Get content part number.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap\Message;
|
namespace Ddeboer\Imap\Message;
|
||||||
|
|
||||||
|
use Ddeboer\Imap\Exception\UnsupportedCharsetException;
|
||||||
|
|
||||||
final class Headers extends Parameters
|
final class Headers extends Parameters
|
||||||
{
|
{
|
||||||
public function __construct(\stdClass $headers)
|
public function __construct(\stdClass $headers)
|
||||||
@@ -14,7 +16,11 @@ final class Headers extends Parameters
|
|||||||
$headers = \array_change_key_case((array) $headers);
|
$headers = \array_change_key_case((array) $headers);
|
||||||
|
|
||||||
foreach ($headers as $key => $value) {
|
foreach ($headers as $key => $value) {
|
||||||
|
try {
|
||||||
$this[$key] = $this->parseHeader($key, $value);
|
$this[$key] = $this->parseHeader($key, $value);
|
||||||
|
} catch (UnsupportedCharsetException) {
|
||||||
|
// safely skip header with unsupported charset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +56,6 @@ final class Headers extends Parameters
|
|||||||
case 'sender':
|
case 'sender':
|
||||||
case 'return_path':
|
case 'return_path':
|
||||||
\assert(\is_array($value));
|
\assert(\is_array($value));
|
||||||
/** @var \stdClass $address */
|
|
||||||
foreach ($value as $address) {
|
foreach ($value as $address) {
|
||||||
if (isset($address->mailbox)) {
|
if (isset($address->mailbox)) {
|
||||||
$address->host = $address->host ?? null;
|
$address->host = $address->host ?? null;
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ final class MessageIterator extends \ArrayIterator implements MessageIteratorInt
|
|||||||
'The current value "%s" isn\'t an integer and doesn\'t represent a message;'
|
'The current value "%s" isn\'t an integer and doesn\'t represent a message;'
|
||||||
. ' try to cycle this "%s" with a native php function like foreach or with the method getArrayCopy(),'
|
. ' try to cycle this "%s" with a native php function like foreach or with the method getArrayCopy(),'
|
||||||
. ' or check it by calling the methods valid().',
|
. ' or check it by calling the methods valid().',
|
||||||
\is_object($current) ? \get_class($current) : \gettype($current),
|
\get_debug_type($current),
|
||||||
static::class
|
self::class
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Ddeboer\Imap\Search;
|
namespace Ddeboer\Imap\Search;
|
||||||
|
|
||||||
use DateTimeInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a date condition.
|
* Represents a date condition.
|
||||||
*/
|
*/
|
||||||
@@ -19,14 +17,14 @@ abstract class AbstractDate implements ConditionInterface
|
|||||||
/**
|
/**
|
||||||
* The date to be used for the condition.
|
* The date to be used for the condition.
|
||||||
*/
|
*/
|
||||||
private DateTimeInterface $date;
|
private \DateTimeInterface $date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param DateTimeInterface $date optional date for the condition
|
* @param \DateTimeInterface $date optional date for the condition
|
||||||
*/
|
*/
|
||||||
public function __construct(DateTimeInterface $date, string $dateFormat = 'j-M-Y')
|
public function __construct(\DateTimeInterface $date, string $dateFormat = 'j-M-Y')
|
||||||
{
|
{
|
||||||
$this->date = $date;
|
$this->date = $date;
|
||||||
$this->dateFormat = $dateFormat;
|
$this->dateFormat = $dateFormat;
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
"psr/log": "*",
|
"psr/log": "*",
|
||||||
"nesbot/carbon": "*",
|
"nesbot/carbon": "*",
|
||||||
"psr/simple-cache": "^1.0|^2.0|^3.0",
|
"psr/simple-cache": "^1.0|^2.0|^3.0",
|
||||||
"illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0",
|
"illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0",
|
||||||
"illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0"
|
"illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.0",
|
"phpunit/phpunit": "^9.0",
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
namespace LdapRecord\Auth;
|
namespace LdapRecord\Auth;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use LdapRecord\Configuration\ConfigurationException;
|
||||||
use LdapRecord\Configuration\DomainConfiguration;
|
use LdapRecord\Configuration\DomainConfiguration;
|
||||||
|
use LdapRecord\ConnectionException;
|
||||||
use LdapRecord\Events\DispatcherInterface;
|
use LdapRecord\Events\DispatcherInterface;
|
||||||
use LdapRecord\LdapInterface;
|
use LdapRecord\LdapInterface;
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ class Guard
|
|||||||
* Attempt binding a user to the LDAP server. Supports sasl and anonymous binding.
|
* Attempt binding a user to the LDAP server. Supports sasl and anonymous binding.
|
||||||
*
|
*
|
||||||
* @throws BindException
|
* @throws BindException
|
||||||
* @throws \LdapRecord\ConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
public function bind(?string $username = null, ?string $password = null): void
|
public function bind(?string $username = null, ?string $password = null): void
|
||||||
{
|
{
|
||||||
@@ -102,7 +104,7 @@ class Guard
|
|||||||
/**
|
/**
|
||||||
* Authenticate by binding to the LDAP server.
|
* Authenticate by binding to the LDAP server.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\ConnectionException
|
* @throws ConnectionException
|
||||||
*/
|
*/
|
||||||
protected function authenticate(?string $username = null, ?string $password = null): bool
|
protected function authenticate(?string $username = null, ?string $password = null): bool
|
||||||
{
|
{
|
||||||
@@ -119,8 +121,8 @@ class Guard
|
|||||||
* Bind to the LDAP server using the configured username and password.
|
* Bind to the LDAP server using the configured username and password.
|
||||||
*
|
*
|
||||||
* @throws BindException
|
* @throws BindException
|
||||||
* @throws \LdapRecord\ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws \LdapRecord\Configuration\ConfigurationException
|
* @throws ConfigurationException
|
||||||
*/
|
*/
|
||||||
public function bindAsConfiguredUser(): void
|
public function bindAsConfiguredUser(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class Connection
|
|||||||
/**
|
/**
|
||||||
* Set the connection configuration.
|
* Set the connection configuration.
|
||||||
*
|
*
|
||||||
* @throws Configuration\ConfigurationException
|
* @throws ConfigurationException
|
||||||
*/
|
*/
|
||||||
public function setConfiguration(DomainConfiguration|array $config = []): void
|
public function setConfiguration(DomainConfiguration|array $config = []): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
namespace LdapRecord;
|
namespace LdapRecord;
|
||||||
|
|
||||||
use LDAP\Connection as RawLdapConnection;
|
use LDAP\Connection as RawLdapConnection;
|
||||||
|
use Ldap\Result;
|
||||||
|
use Ldap\ResultEntry;
|
||||||
|
|
||||||
class Ldap implements LdapInterface
|
class Ldap implements LdapInterface
|
||||||
{
|
{
|
||||||
@@ -24,7 +26,7 @@ class Ldap implements LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-first-entry.php
|
* @see http://php.net/manual/en/function.ldap-first-entry.php
|
||||||
*
|
*
|
||||||
* @param \Ldap\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function getFirstEntry(mixed $result): mixed
|
public function getFirstEntry(mixed $result): mixed
|
||||||
{
|
{
|
||||||
@@ -38,7 +40,7 @@ class Ldap implements LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-next-entry.php
|
* @see http://php.net/manual/en/function.ldap-next-entry.php
|
||||||
*
|
*
|
||||||
* @param \Ldap\ResultEntry $entry
|
* @param ResultEntry $entry
|
||||||
*/
|
*/
|
||||||
public function getNextEntry(mixed $entry): mixed
|
public function getNextEntry(mixed $entry): mixed
|
||||||
{
|
{
|
||||||
@@ -52,7 +54,7 @@ class Ldap implements LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-get-attributes.php
|
* @see http://php.net/manual/en/function.ldap-get-attributes.php
|
||||||
*
|
*
|
||||||
* @param \Ldap\ResultEntry $entry
|
* @param ResultEntry $entry
|
||||||
*/
|
*/
|
||||||
public function getAttributes(mixed $entry): array|false
|
public function getAttributes(mixed $entry): array|false
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace LdapRecord;
|
namespace LdapRecord;
|
||||||
|
|
||||||
use LDAP\Connection;
|
use LDAP\Connection;
|
||||||
|
use LDAP\Result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://ldap.com/ldap-oid-reference-guide
|
* @see https://ldap.com/ldap-oid-reference-guide
|
||||||
@@ -339,7 +340,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-get-entries.php
|
* @see http://php.net/manual/en/function.ldap-get-entries.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function getEntries(mixed $result): array;
|
public function getEntries(mixed $result): array;
|
||||||
|
|
||||||
@@ -348,7 +349,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-first-entry.php
|
* @see https://www.php.net/manual/en/function.ldap-first-entry.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function getFirstEntry(mixed $result): mixed;
|
public function getFirstEntry(mixed $result): mixed;
|
||||||
|
|
||||||
@@ -357,7 +358,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-next-entry.php
|
* @see https://www.php.net/manual/en/function.ldap-next-entry.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $entry
|
* @param Result $entry
|
||||||
*/
|
*/
|
||||||
public function getNextEntry(mixed $entry): mixed;
|
public function getNextEntry(mixed $entry): mixed;
|
||||||
|
|
||||||
@@ -366,14 +367,14 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-get-attributes.php
|
* @see https://www.php.net/manual/en/function.ldap-get-attributes.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $entry
|
* @param Result $entry
|
||||||
*/
|
*/
|
||||||
public function getAttributes(mixed $entry): array|false;
|
public function getAttributes(mixed $entry): array|false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads all the values of the attribute in the entry in the result.
|
* Reads all the values of the attribute in the entry in the result.
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $entry
|
* @param Result $entry
|
||||||
*/
|
*/
|
||||||
public function getValuesLen(mixed $entry, string $attribute): array|false;
|
public function getValuesLen(mixed $entry, string $attribute): array|false;
|
||||||
|
|
||||||
@@ -398,7 +399,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-count-entries.php
|
* @see https://www.php.net/manual/en/function.ldap-count-entries.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function countEntries(mixed $result): int;
|
public function countEntries(mixed $result): int;
|
||||||
|
|
||||||
@@ -463,7 +464,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-search.php
|
* @see http://php.net/manual/en/function.ldap-search.php
|
||||||
*
|
*
|
||||||
* @return \LDAP\Result
|
* @return Result
|
||||||
*/
|
*/
|
||||||
public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
||||||
|
|
||||||
@@ -472,7 +473,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-list.php
|
* @see http://php.net/manual/en/function.ldap-list.php
|
||||||
*
|
*
|
||||||
* @return \LDAP\Result
|
* @return Result
|
||||||
*/
|
*/
|
||||||
public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
||||||
|
|
||||||
@@ -481,7 +482,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see http://php.net/manual/en/function.ldap-read.php
|
* @see http://php.net/manual/en/function.ldap-read.php
|
||||||
*
|
*
|
||||||
* @return \LDAP\Result
|
* @return Result
|
||||||
*/
|
*/
|
||||||
public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
|
||||||
|
|
||||||
@@ -490,7 +491,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-parse-result.php
|
* @see https://www.php.net/manual/en/function.ldap-parse-result.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false;
|
public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false;
|
||||||
|
|
||||||
@@ -595,7 +596,7 @@ interface LdapInterface
|
|||||||
*
|
*
|
||||||
* @see https://www.php.net/manual/en/function.ldap-free-result.php
|
* @see https://www.php.net/manual/en/function.ldap-free-result.php
|
||||||
*
|
*
|
||||||
* @param \LDAP\Result $result
|
* @param Result $result
|
||||||
*/
|
*/
|
||||||
public function freeResult(mixed $result): bool;
|
public function freeResult(mixed $result): bool;
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -4,6 +4,7 @@ namespace LdapRecord\Models\ActiveDirectory;
|
|||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LdapRecord\Connection;
|
use LdapRecord\Connection;
|
||||||
|
use LdapRecord\LdapRecordException;
|
||||||
use LdapRecord\Models\Attributes\Sid;
|
use LdapRecord\Models\Attributes\Sid;
|
||||||
use LdapRecord\Models\Entry as BaseEntry;
|
use LdapRecord\Models\Entry as BaseEntry;
|
||||||
use LdapRecord\Models\Events\Updated;
|
use LdapRecord\Models\Events\Updated;
|
||||||
@@ -99,7 +100,7 @@ class Entry extends BaseEntry implements ActiveDirectory
|
|||||||
/**
|
/**
|
||||||
* Restore a deleted object.
|
* Restore a deleted object.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function restore(?string $newParentDn = null): bool
|
public function restore(?string $newParentDn = null): bool
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-2
@@ -4,6 +4,7 @@ namespace LdapRecord\Models\ActiveDirectory\Scopes;
|
|||||||
|
|
||||||
use LdapRecord\Models\ActiveDirectory\Entry;
|
use LdapRecord\Models\ActiveDirectory\Entry;
|
||||||
use LdapRecord\Models\Model;
|
use LdapRecord\Models\Model;
|
||||||
|
use LdapRecord\Models\ModelNotFoundException;
|
||||||
use LdapRecord\Models\Scope;
|
use LdapRecord\Models\Scope;
|
||||||
use LdapRecord\Query\Model\Builder;
|
use LdapRecord\Query\Model\Builder;
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ class InConfigurationContext implements Scope
|
|||||||
/**
|
/**
|
||||||
* Refines the base dn to be inside the configuration context.
|
* Refines the base dn to be inside the configuration context.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\Models\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public function apply(Builder $query, Model $model): void
|
public function apply(Builder $query, Model $model): void
|
||||||
{
|
{
|
||||||
@@ -22,7 +23,7 @@ class InConfigurationContext implements Scope
|
|||||||
/**
|
/**
|
||||||
* Get the LDAP server configuration naming context distinguished name.
|
* Get the LDAP server configuration naming context distinguished name.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\Models\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
protected function getConfigurationNamingContext(Model $model)
|
protected function getConfigurationNamingContext(Model $model)
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace LdapRecord\Models\Concerns;
|
namespace LdapRecord\Models\Concerns;
|
||||||
|
|
||||||
/** @mixin \LdapRecord\Models\Model */
|
use LdapRecord\Models\Model;
|
||||||
|
|
||||||
|
/** @mixin Model */
|
||||||
trait CanAuthenticate
|
trait CanAuthenticate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-1
@@ -6,9 +6,10 @@ use Closure;
|
|||||||
use LdapRecord\Events\NullDispatcher;
|
use LdapRecord\Events\NullDispatcher;
|
||||||
use LdapRecord\Models\Events;
|
use LdapRecord\Models\Events;
|
||||||
use LdapRecord\Models\Events\Event;
|
use LdapRecord\Models\Events\Event;
|
||||||
|
use LdapRecord\Models\Model;
|
||||||
use LdapRecord\Support\Arr;
|
use LdapRecord\Support\Arr;
|
||||||
|
|
||||||
/** @mixin \LdapRecord\Models\Model */
|
/** @mixin Model */
|
||||||
trait HasEvents
|
trait HasEvents
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-1
@@ -4,9 +4,10 @@ namespace LdapRecord\Models\Concerns;
|
|||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use LdapRecord\Models\Model;
|
||||||
use LdapRecord\Models\Scope;
|
use LdapRecord\Models\Scope;
|
||||||
|
|
||||||
/** @mixin \LdapRecord\Models\Model */
|
/** @mixin Model */
|
||||||
trait HasGlobalScopes
|
trait HasGlobalScopes
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-1
@@ -5,8 +5,9 @@ namespace LdapRecord\Models\Concerns;
|
|||||||
use LdapRecord\ConnectionException;
|
use LdapRecord\ConnectionException;
|
||||||
use LdapRecord\LdapRecordException;
|
use LdapRecord\LdapRecordException;
|
||||||
use LdapRecord\Models\Attributes\Password;
|
use LdapRecord\Models\Attributes\Password;
|
||||||
|
use LdapRecord\Models\Model;
|
||||||
|
|
||||||
/** @mixin \LdapRecord\Models\Model */
|
/** @mixin Model */
|
||||||
trait HasPassword
|
trait HasPassword
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-1
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
namespace LdapRecord\Models\Concerns;
|
namespace LdapRecord\Models\Concerns;
|
||||||
|
|
||||||
|
use LdapRecord\Models\Model;
|
||||||
use LdapRecord\Query\Model\Builder;
|
use LdapRecord\Query\Model\Builder;
|
||||||
|
|
||||||
/** @mixin \LdapRecord\Models\Model */
|
/** @mixin Model */
|
||||||
trait HasScopes
|
trait HasScopes
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-1
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace LdapRecord\Models\Concerns;
|
namespace LdapRecord\Models\Concerns;
|
||||||
|
|
||||||
|
use LdapRecord\Models\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Taylor Otwell
|
* @author Taylor Otwell
|
||||||
*
|
*
|
||||||
* @see https://laravel.com
|
* @see https://laravel.com
|
||||||
*
|
*
|
||||||
* @mixin \LdapRecord\Models\Model
|
* @mixin Model
|
||||||
*/
|
*/
|
||||||
trait HidesAttributes
|
trait HidesAttributes
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use JsonSerializable;
|
|||||||
use LdapRecord\Connection;
|
use LdapRecord\Connection;
|
||||||
use LdapRecord\Container;
|
use LdapRecord\Container;
|
||||||
use LdapRecord\EscapesValues;
|
use LdapRecord\EscapesValues;
|
||||||
|
use LdapRecord\LdapRecordException;
|
||||||
use LdapRecord\Models\Attributes\DistinguishedName;
|
use LdapRecord\Models\Attributes\DistinguishedName;
|
||||||
use LdapRecord\Models\Attributes\Guid;
|
use LdapRecord\Models\Attributes\Guid;
|
||||||
use LdapRecord\Query\Builder as BaseBuilder;
|
use LdapRecord\Query\Builder as BaseBuilder;
|
||||||
@@ -246,7 +247,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Get the RootDSE (AD schema) record from the directory.
|
* Get the RootDSE (AD schema) record from the directory.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\Models\ModelNotFoundException
|
* @throws ModelNotFoundException
|
||||||
*/
|
*/
|
||||||
public static function getRootDse(?string $connection = null): Model
|
public static function getRootDse(?string $connection = null): Model
|
||||||
{
|
{
|
||||||
@@ -919,7 +920,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Save the model to the directory without raising any events.
|
* Save the model to the directory without raising any events.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function saveQuietly(array $attributes = []): void
|
public function saveQuietly(array $attributes = []): void
|
||||||
{
|
{
|
||||||
@@ -931,7 +932,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Save the model to the directory.
|
* Save the model to the directory.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function save(array $attributes = []): void
|
public function save(array $attributes = []): void
|
||||||
{
|
{
|
||||||
@@ -951,7 +952,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Inserts the model into the directory.
|
* Inserts the model into the directory.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
protected function performInsert(): void
|
protected function performInsert(): void
|
||||||
{
|
{
|
||||||
@@ -998,7 +999,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Updates the model in the directory.
|
* Updates the model in the directory.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
protected function performUpdate(): void
|
protected function performUpdate(): void
|
||||||
{
|
{
|
||||||
@@ -1020,7 +1021,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Create the model in the directory.
|
* Create the model in the directory.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public static function create(array $attributes = []): static
|
public static function create(array $attributes = []): static
|
||||||
{
|
{
|
||||||
@@ -1035,7 +1036,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* Add an attribute on the model with the given value.
|
* Add an attribute on the model with the given value.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function addAttribute(string $attribute, mixed $value): void
|
public function addAttribute(string $attribute, mixed $value): void
|
||||||
{
|
{
|
||||||
@@ -1054,7 +1055,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* Update the model.
|
* Update the model.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function update(array $attributes = []): void
|
public function update(array $attributes = []): void
|
||||||
{
|
{
|
||||||
@@ -1067,7 +1068,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* Update the model attribute with the specified value.
|
* Update the model attribute with the specified value.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function replaceAttribute(string $attribute, mixed $value): void
|
public function replaceAttribute(string $attribute, mixed $value): void
|
||||||
{
|
{
|
||||||
@@ -1085,7 +1086,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Destroy the models for the given distinguished names.
|
* Destroy the models for the given distinguished names.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public static function destroy(mixed $dns, bool $recursive = false): int
|
public static function destroy(mixed $dns, bool $recursive = false): int
|
||||||
{
|
{
|
||||||
@@ -1121,7 +1122,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* not exist or does not contain a distinguished name.
|
* not exist or does not contain a distinguished name.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function delete(bool $recursive = false): void
|
public function delete(bool $recursive = false): void
|
||||||
{
|
{
|
||||||
@@ -1146,7 +1147,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
/**
|
/**
|
||||||
* Deletes leaf nodes that are attached to the model.
|
* Deletes leaf nodes that are attached to the model.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
protected function deleteLeafNodes(): void
|
protected function deleteLeafNodes(): void
|
||||||
{
|
{
|
||||||
@@ -1162,7 +1163,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* Remove an attribute on the model.
|
* Remove an attribute on the model.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function removeAttribute(string $attribute, mixed $value = null): void
|
public function removeAttribute(string $attribute, mixed $value = null): void
|
||||||
{
|
{
|
||||||
@@ -1181,7 +1182,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* ["memberuid" => []]
|
* ["memberuid" => []]
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function removeAttributes(array|string $attributes): void
|
public function removeAttributes(array|string $attributes): void
|
||||||
{
|
{
|
||||||
@@ -1238,7 +1239,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
*
|
*
|
||||||
* @throws UnexpectedValueException
|
* @throws UnexpectedValueException
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function move(Model|string $newParentDn, bool $deleteOldRdn = true): void
|
public function move(Model|string $newParentDn, bool $deleteOldRdn = true): void
|
||||||
{
|
{
|
||||||
@@ -1255,7 +1256,7 @@ abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, String
|
|||||||
* Rename the model to a new RDN and new parent.
|
* Rename the model to a new RDN and new parent.
|
||||||
*
|
*
|
||||||
* @throws ModelDoesNotExistException
|
* @throws ModelDoesNotExistException
|
||||||
* @throws \LdapRecord\LdapRecordException
|
* @throws LdapRecordException
|
||||||
*/
|
*/
|
||||||
public function rename(string $rdn, Model|string|null $newParentDn = null, bool $deleteOldRdn = true): void
|
public function rename(string $rdn, Model|string|null $newParentDn = null, bool $deleteOldRdn = true): void
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-2
@@ -2,21 +2,23 @@
|
|||||||
|
|
||||||
namespace LdapRecord\Testing;
|
namespace LdapRecord\Testing;
|
||||||
|
|
||||||
|
use LdapRecord\Connection;
|
||||||
use LdapRecord\Container;
|
use LdapRecord\Container;
|
||||||
|
use LdapRecord\ContainerException;
|
||||||
|
|
||||||
class DirectoryFake
|
class DirectoryFake
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The LDAP connections that were replaced with fakes.
|
* The LDAP connections that were replaced with fakes.
|
||||||
*
|
*
|
||||||
* @var \LdapRecord\Connection[]
|
* @var Connection[]
|
||||||
*/
|
*/
|
||||||
protected static array $replaced = [];
|
protected static array $replaced = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace a connection a fake.
|
* Replace a connection a fake.
|
||||||
*
|
*
|
||||||
* @throws \LdapRecord\ContainerException
|
* @throws ContainerException
|
||||||
*/
|
*/
|
||||||
public static function setup(?string $name = null): ConnectionFake
|
public static function setup(?string $name = null): ConnectionFake
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,160 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [7.1.1](https://github.com/googleapis/php-jwt/compare/v7.1.0...v7.1.1) (2026-09-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Limit the number of segments a JWT can be exploded into ([#639](https://github.com/googleapis/php-jwt/issues/639)) ([93d248c](https://github.com/googleapis/php-jwt/commit/93d248c650aea615d74a5ffa20c91c7a818e9b8d))
|
||||||
|
|
||||||
|
## [7.1.0](https://github.com/googleapis/php-jwt/compare/v7.0.5...v7.1.0) (2026-06-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add support for PS256 ([#637](https://github.com/googleapis/php-jwt/issues/637)) ([aa0b447](https://github.com/googleapis/php-jwt/commit/aa0b4472c137255545b177a1840891304eac55f1))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Skip parsing valid unsupported curves ([#638](https://github.com/googleapis/php-jwt/issues/638)) ([8a6c2a7](https://github.com/googleapis/php-jwt/commit/8a6c2a75d7f45e781c93d618939f8a045fe69f53))
|
||||||
|
* Update homepage URL in composer.json ([#635](https://github.com/googleapis/php-jwt/issues/635)) ([f7ae571](https://github.com/googleapis/php-jwt/commit/f7ae571efe255aed89c8f8d0f2cb7f71c5835664))
|
||||||
|
* Validate numeric type of iat, nbf and exp claims in encode ([#634](https://github.com/googleapis/php-jwt/issues/634)) ([958e422](https://github.com/googleapis/php-jwt/commit/958e422961e874843a7fcc339e55a0101a66201d))
|
||||||
|
|
||||||
|
## [7.0.5](https://github.com/firebase/php-jwt/compare/v7.0.4...v7.0.5) (2026-03-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* RSA from JWK sometimes returns empty Instance ([#628](https://github.com/firebase/php-jwt/issues/628)) ([b4c78aa](https://github.com/firebase/php-jwt/commit/b4c78aa731664122198ad36c0033aa29e807397a))
|
||||||
|
|
||||||
|
## [7.0.4](https://github.com/firebase/php-jwt/compare/v7.0.3...v7.0.4) (2026-03-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* readme examples, add tests for all examples ([#626](https://github.com/firebase/php-jwt/issues/626)) ([510a00c](https://github.com/firebase/php-jwt/commit/510a00c0e6353bc7d68412fab67e57a13954cb46))
|
||||||
|
* use urlsafeB64Decode everywhere ([#627](https://github.com/firebase/php-jwt/issues/627)) ([b889495](https://github.com/firebase/php-jwt/commit/b889495c83ddc3f3885ca3f0b65b41b1cb37a3b1))
|
||||||
|
|
||||||
|
## [7.0.3](https://github.com/firebase/php-jwt/compare/v7.0.2...v7.0.3) (2026-02-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
|
||||||
|
* add environment for Release Please job ([#619](https://github.com/firebase/php-jwt/issues/619)) ([300fd02](https://github.com/firebase/php-jwt/commit/300fd02c883f096c9067df652dbd23f62cb5e2a7))
|
||||||
|
|
||||||
|
## [7.0.2](https://github.com/firebase/php-jwt/compare/v7.0.1...v7.0.2) (2025-12-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add key length validation for ec keys ([#615](https://github.com/firebase/php-jwt/issues/615)) ([7044f9a](https://github.com/firebase/php-jwt/commit/7044f9ae7e7d175d28cca71714feb236f1c0e252))
|
||||||
|
|
||||||
|
## [7.0.0](https://github.com/firebase/php-jwt/compare/v6.11.1...v7.0.0) (2025-12-15)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠️ ⚠️ ⚠️ Security Fixes ⚠️ ⚠️ ⚠️
|
||||||
|
* add key size validation ([#613](https://github.com/firebase/php-jwt/issues/613)) ([6b80341](https://github.com/firebase/php-jwt/commit/6b80341bf57838ea2d011487917337901cd71576))
|
||||||
|
**NOTE**: This fix will cause keys with a size below the minimally allowed size to break.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add SensitiveParameter attribute to security-critical parameters ([#603](https://github.com/firebase/php-jwt/issues/603)) ([4dbfac0](https://github.com/firebase/php-jwt/commit/4dbfac0260eeb0e9e643063c99998e3219cc539b))
|
||||||
|
* store timestamp in `ExpiredException` ([#604](https://github.com/firebase/php-jwt/issues/604)) ([f174826](https://github.com/firebase/php-jwt/commit/f1748260d218a856b6a0c23715ac7fae1d7ca95b))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* validate iat and nbf on payload ([#568](https://github.com/firebase/php-jwt/issues/568)) ([953b2c8](https://github.com/firebase/php-jwt/commit/953b2c88bb445b7e3bb82a5141928f13d7343afd))
|
||||||
|
|
||||||
|
## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775))
|
||||||
|
|
||||||
|
## [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)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9))
|
||||||
|
|
||||||
|
## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2))
|
||||||
|
|
||||||
|
## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e))
|
||||||
|
* different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4))
|
||||||
|
|
||||||
|
## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718))
|
||||||
|
|
||||||
|
## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a))
|
||||||
|
|
||||||
|
## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797))
|
||||||
|
|
||||||
## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12)
|
## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loaded 100 of 1296 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user