#13035 added JWT repository
This commit is contained in:
parent
fbec8c0a05
commit
670829fa58
|
@ -28,7 +28,8 @@
|
|||
"php-di/php-di": "^7.0",
|
||||
"zircote/swagger-php": "^4.8",
|
||||
"doctrine/annotations": "^2.0",
|
||||
"ramsey/uuid": "^4.7"
|
||||
"ramsey/uuid": "^4.7",
|
||||
"lcobucci/jwt": "^5.2"
|
||||
},
|
||||
"repositories": {
|
||||
"phpchartjs": {
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/**
|
||||
* Class to JWT.
|
||||
*
|
||||
* @category Class
|
||||
* @package Pandora FMS
|
||||
* @subpackage Token
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2023 Pandora FMS
|
||||
* Please see https://pandorafms.com/community/ for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Begin.
|
||||
use Lcobucci\JWT\Configuration;
|
||||
use Lcobucci\JWT\Encoding\JoseEncoder;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
use Lcobucci\JWT\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\Token\Parser;
|
||||
use Lcobucci\JWT\Validation\Constraint\SignedWith;
|
||||
|
||||
/**
|
||||
* JWT Repository.
|
||||
*/
|
||||
final class JWTRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* Signature
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $signature;
|
||||
|
||||
/**
|
||||
* Token
|
||||
*
|
||||
* @var Token
|
||||
*/
|
||||
private $token;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $_signature Signature of JWT.
|
||||
*/
|
||||
public function __construct(string $_signature)
|
||||
{
|
||||
$this->signature = $_signature;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function create(): string
|
||||
{
|
||||
global $config;
|
||||
$sha = new Sha256();
|
||||
$configJWT = Configuration::forSymmetricSigner(
|
||||
$sha,
|
||||
InMemory::plainText($this->signature)
|
||||
);
|
||||
|
||||
$now = new DateTimeImmutable();
|
||||
$token = $configJWT->builder()->issuedAt($now)->canOnlyBeUsedAfter($now)->expiresAt($now->modify('+1 minute'))->withClaim('id_user', $config['id_user'])->getToken($configJWT->signer(), $configJWT->signingKey());
|
||||
|
||||
return $token->toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate a JWT, USE FIRST setToken().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate():bool
|
||||
{
|
||||
$sha = new Sha256();
|
||||
$configJWT = Configuration::forSymmetricSigner(
|
||||
$sha,
|
||||
InMemory::plainText($this->signature)
|
||||
);
|
||||
$signed = new SignedWith($sha, InMemory::plainText($this->signature));
|
||||
$constraints = [$signed];
|
||||
|
||||
return $configJWT->validator()->validate($this->token, ...$constraints);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get payload of token.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function payload():object
|
||||
{
|
||||
return $this->token->claims();
|
||||
}
|
||||
|
||||
|
||||
public function setToken(string $tokenString)
|
||||
{
|
||||
$encoder = new JoseEncoder();
|
||||
$parser = new Parser($encoder);
|
||||
$this->token = $parser->parse($tokenString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate random signature.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generateSignature(): string
|
||||
{
|
||||
return bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,24 +2,6 @@
|
|||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit94a17e624d873685991e8ae888e00eb9::getLoader();
|
||||
|
|
|
@ -42,9 +42,6 @@ namespace Composer\Autoload;
|
|||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
|
@ -109,7 +106,6 @@ class ClassLoader
|
|||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -429,8 +425,7 @@ class ClassLoader
|
|||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -560,26 +555,18 @@ class ClassLoader
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
|
|
|
@ -21,14 +21,12 @@ use Composer\Semver\VersionParser;
|
|||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @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, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
|
@ -39,7 +37,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, 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-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
|
@ -98,7 +96,7 @@ class InstalledVersions
|
|||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@ class InstalledVersions
|
|||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$constraint = $parser->parseConstraints($constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
|
@ -243,7 +241,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
|
@ -257,7 +255,7 @@ class InstalledVersions
|
|||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return 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 array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
|
@ -266,7 +264,7 @@ class InstalledVersions
|
|||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) {
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
|
@ -280,7 +278,7 @@ class InstalledVersions
|
|||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @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, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
|
@ -303,7 +301,7 @@ class InstalledVersions
|
|||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param 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[]}>} $data
|
||||
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
|
@ -313,7 +311,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @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, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
|
@ -328,9 +326,7 @@ class InstalledVersions
|
|||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @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[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
|
@ -341,18 +337,13 @@ class InstalledVersions
|
|||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C' && is_file(__DIR__ . '/installed.php')) {
|
||||
/** @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[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
|
|
@ -2,33 +2,28 @@
|
|||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'e8aa6e4b5a1db2f56ae794f1505391a8' => $vendorDir . '/amphp/amp/lib/functions.php',
|
||||
'76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => $vendorDir . '/amphp/byte-stream/lib/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => $vendorDir . '/amphp/byte-stream/lib/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'3da389f428d8ee50333e4391c3f45046' => $vendorDir . '/amphp/serialization/src/functions.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'8dc56fe697ca93c4b40d876df1c94584' => $vendorDir . '/amphp/process/lib/functions.php',
|
||||
'bcb7d4fc55f4b1a7e10f5806723e9892' => $vendorDir . '/amphp/sync/src/functions.php',
|
||||
'e187e371b30897d6dc51cac6a8c94ff6' => $vendorDir . '/amphp/sync/src/ConcurrentIterator/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'430de19db8b7ee88fdbe5c545d82d33d' => $vendorDir . '/amphp/parallel/lib/Context/functions.php',
|
||||
'888e1afeed2e8d13ef5a662692091e6e' => $vendorDir . '/amphp/parallel/lib/Sync/functions.php',
|
||||
'384cf4f2eb4d2f896db72315a76066ad' => $vendorDir . '/amphp/parallel/lib/Worker/functions.php',
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'861372841bb4b8ba9fdd215894666f40' => $vendorDir . '/amphp/parallel-functions/src/functions.php',
|
||||
'07d7f1a47144818725fd8d91a907ac57' => $vendorDir . '/laminas/laminas-diactoros/src/functions/create_uploaded_file.php',
|
||||
'da94ac5d3ca7d2dbab84ce561ce72bfd' => $vendorDir . '/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.php',
|
||||
'3d97c8dcdfba8cb85d3b34f116bb248b' => $vendorDir . '/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.php',
|
||||
|
@ -36,6 +31,11 @@ return array(
|
|||
'de95e0ac670b27c84ef8c5ac41fc1b34' => $vendorDir . '/laminas/laminas-diactoros/src/functions/normalize_server.php',
|
||||
'b6c2870932b0250c10334a86dcb33c7f' => $vendorDir . '/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.php',
|
||||
'd02cf21124526632320d6f20b1bbf905' => $vendorDir . '/laminas/laminas-diactoros/src/functions/parse_cookie_header.php',
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => $vendorDir . '/nikic/fast-route/src/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'861372841bb4b8ba9fdd215894666f40' => $vendorDir . '/amphp/parallel-functions/src/functions.php',
|
||||
'db356362850385d08a5381de2638b5fd' => $vendorDir . '/mpdf/mpdf/src/functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
@ -31,6 +31,7 @@ return array(
|
|||
'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'),
|
||||
'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
|
||||
'PandoraFMS\\Enterprise\\' => array($baseDir . '/enterprise/include/lib'),
|
||||
'PandoraFMS\\' => array($baseDir . '/include/lib'),
|
||||
|
@ -42,6 +43,7 @@ return array(
|
|||
'Mpdf\\' => array($vendorDir . '/mpdf/mpdf/src'),
|
||||
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
|
||||
'Models\\' => array($baseDir . '/include/rest-api/models'),
|
||||
'Lcobucci\\JWT\\' => array($vendorDir . '/lcobucci/jwt/src'),
|
||||
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
|
||||
'Laminas\\Json\\' => array($vendorDir . '/laminas/laminas-json/src'),
|
||||
'Laminas\\Diactoros\\' => array($vendorDir . '/laminas/laminas-diactoros/src'),
|
||||
|
|
|
@ -25,26 +25,56 @@ class ComposerAutoloaderInit94a17e624d873685991e8ae888e00eb9
|
|||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit94a17e624d873685991e8ae888e00eb9', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit94a17e624d873685991e8ae888e00eb9', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit94a17e624d873685991e8ae888e00eb9::getInitializer($loader));
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit94a17e624d873685991e8ae888e00eb9::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit94a17e624d873685991e8ae888e00eb9::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit94a17e624d873685991e8ae888e00eb9::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire94a17e624d873685991e8ae888e00eb9($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileIdentifier
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
function composerRequire94a17e624d873685991e8ae888e00eb9($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,26 +10,21 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
'e8aa6e4b5a1db2f56ae794f1505391a8' => __DIR__ . '/..' . '/amphp/amp/lib/functions.php',
|
||||
'76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => __DIR__ . '/..' . '/amphp/byte-stream/lib/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => __DIR__ . '/..' . '/amphp/byte-stream/lib/functions.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'3da389f428d8ee50333e4391c3f45046' => __DIR__ . '/..' . '/amphp/serialization/src/functions.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'8dc56fe697ca93c4b40d876df1c94584' => __DIR__ . '/..' . '/amphp/process/lib/functions.php',
|
||||
'bcb7d4fc55f4b1a7e10f5806723e9892' => __DIR__ . '/..' . '/amphp/sync/src/functions.php',
|
||||
'e187e371b30897d6dc51cac6a8c94ff6' => __DIR__ . '/..' . '/amphp/sync/src/ConcurrentIterator/functions.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'430de19db8b7ee88fdbe5c545d82d33d' => __DIR__ . '/..' . '/amphp/parallel/lib/Context/functions.php',
|
||||
'888e1afeed2e8d13ef5a662692091e6e' => __DIR__ . '/..' . '/amphp/parallel/lib/Sync/functions.php',
|
||||
'384cf4f2eb4d2f896db72315a76066ad' => __DIR__ . '/..' . '/amphp/parallel/lib/Worker/functions.php',
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'861372841bb4b8ba9fdd215894666f40' => __DIR__ . '/..' . '/amphp/parallel-functions/src/functions.php',
|
||||
'07d7f1a47144818725fd8d91a907ac57' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/create_uploaded_file.php',
|
||||
'da94ac5d3ca7d2dbab84ce561ce72bfd' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/marshal_headers_from_sapi.php',
|
||||
'3d97c8dcdfba8cb85d3b34f116bb248b' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/marshal_method_from_sapi.php',
|
||||
|
@ -37,6 +32,11 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
'de95e0ac670b27c84ef8c5ac41fc1b34' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/normalize_server.php',
|
||||
'b6c2870932b0250c10334a86dcb33c7f' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/normalize_uploaded_files.php',
|
||||
'd02cf21124526632320d6f20b1bbf905' => __DIR__ . '/..' . '/laminas/laminas-diactoros/src/functions/parse_cookie_header.php',
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'253c157292f75eb38082b5acb06f3f01' => __DIR__ . '/..' . '/nikic/fast-route/src/functions.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'861372841bb4b8ba9fdd215894666f40' => __DIR__ . '/..' . '/amphp/parallel-functions/src/functions.php',
|
||||
'db356362850385d08a5381de2638b5fd' => __DIR__ . '/..' . '/mpdf/mpdf/src/functions.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
|
||||
|
@ -90,6 +90,7 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
'Psr\\Http\\Server\\' => 16,
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
'Psr\\Container\\' => 14,
|
||||
'Psr\\Clock\\' => 10,
|
||||
'Psr\\Cache\\' => 10,
|
||||
'PandoraFMS\\Enterprise\\' => 22,
|
||||
'PandoraFMS\\' => 11,
|
||||
|
@ -113,6 +114,7 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
),
|
||||
'L' =>
|
||||
array (
|
||||
'Lcobucci\\JWT\\' => 13,
|
||||
'Laravel\\SerializableClosure\\' => 28,
|
||||
'Laminas\\Json\\' => 13,
|
||||
'Laminas\\Diactoros\\' => 18,
|
||||
|
@ -271,6 +273,10 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/container/src',
|
||||
),
|
||||
'Psr\\Clock\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/clock/src',
|
||||
),
|
||||
'Psr\\Cache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/cache/src',
|
||||
|
@ -315,6 +321,10 @@ class ComposerStaticInit94a17e624d873685991e8ae888e00eb9
|
|||
array (
|
||||
0 => __DIR__ . '/../..' . '/include/rest-api/models',
|
||||
),
|
||||
'Lcobucci\\JWT\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/lcobucci/jwt/src',
|
||||
),
|
||||
'Laravel\\SerializableClosure\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/laravel/serializable-closure/src',
|
||||
|
|
|
@ -1616,6 +1616,82 @@
|
|||
},
|
||||
"install-path": "../laravel/serializable-closure"
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"version": "5.2.0",
|
||||
"version_normalized": "5.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lcobucci/jwt.git",
|
||||
"reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lcobucci/jwt/zipball/0ba88aed12c04bd2ed9924f500673f32b67a6211",
|
||||
"reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-sodium": "*",
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"psr/clock": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.27.0",
|
||||
"lcobucci/clock": "^3.0",
|
||||
"lcobucci/coding-standard": "^11.0",
|
||||
"phpbench/phpbench": "^1.2.9",
|
||||
"phpstan/extension-installer": "^1.2",
|
||||
"phpstan/phpstan": "^1.10.7",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.3",
|
||||
"phpstan/phpstan-phpunit": "^1.3.10",
|
||||
"phpstan/phpstan-strict-rules": "^1.5.0",
|
||||
"phpunit/phpunit": "^10.2.6"
|
||||
},
|
||||
"suggest": {
|
||||
"lcobucci/clock": ">= 3.0"
|
||||
},
|
||||
"time": "2023-11-20T21:17:42+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Luís Cobucci",
|
||||
"email": "lcobucci@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
|
||||
"keywords": [
|
||||
"JWS",
|
||||
"jwt"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/lcobucci/jwt/issues",
|
||||
"source": "https://github.com/lcobucci/jwt/tree/5.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/lcobucci",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/lcobucci",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../lcobucci/jwt"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.5.0",
|
||||
|
@ -2406,6 +2482,57 @@
|
|||
},
|
||||
"install-path": "../psr/cache"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/clock.git",
|
||||
"reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
|
||||
"reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0"
|
||||
},
|
||||
"time": "2022-11-25T14:36:26+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Clock\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for reading the clock.",
|
||||
"homepage": "https://github.com/php-fig/clock",
|
||||
"keywords": [
|
||||
"clock",
|
||||
"now",
|
||||
"psr",
|
||||
"psr-20",
|
||||
"time"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-fig/clock/issues",
|
||||
"source": "https://github.com/php-fig/clock/tree/1.0.0"
|
||||
},
|
||||
"install-path": "../psr/clock"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "2.0.2",
|
||||
|
|
|
@ -1,328 +1,337 @@
|
|||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'pandorafms/console',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '8bf414b51f3333555f84df8b23614ca4b68c7fd4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'fbec8c0a05f72bfcc2044c0a4857d5e31f534ad5',
|
||||
'name' => 'pandorafms/console',
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'amphp/amp' => array(
|
||||
'pretty_version' => 'v2.6.2',
|
||||
'version' => '2.6.2.0',
|
||||
'reference' => '9d5100cebffa729aaffecd3ad25dc5aeea4f13bb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/amp',
|
||||
'aliases' => array(),
|
||||
'reference' => '9d5100cebffa729aaffecd3ad25dc5aeea4f13bb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/byte-stream' => array(
|
||||
'pretty_version' => 'v1.8.1',
|
||||
'version' => '1.8.1.0',
|
||||
'reference' => 'acbd8002b3536485c997c4e019206b3f10ca15bd',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/byte-stream',
|
||||
'aliases' => array(),
|
||||
'reference' => 'acbd8002b3536485c997c4e019206b3f10ca15bd',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/parallel' => array(
|
||||
'pretty_version' => 'v1.4.3',
|
||||
'version' => '1.4.3.0',
|
||||
'reference' => '3aac213ba7858566fd83d38ccb85b91b2d652cb0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/parallel',
|
||||
'aliases' => array(),
|
||||
'reference' => '3aac213ba7858566fd83d38ccb85b91b2d652cb0',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/parallel-functions' => array(
|
||||
'pretty_version' => 'v1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => '04e92fcacfc921a56dfe12c23b3265e62593a7cb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/parallel-functions',
|
||||
'aliases' => array(),
|
||||
'reference' => '04e92fcacfc921a56dfe12c23b3265e62593a7cb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/parser' => array(
|
||||
'pretty_version' => 'v1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => 'ff1de4144726c5dad5fab97f66692ebe8de3e151',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/parser',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ff1de4144726c5dad5fab97f66692ebe8de3e151',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/process' => array(
|
||||
'pretty_version' => 'v1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'reference' => '76e9495fd6818b43a20167cb11d8a67f7744ee0f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/process',
|
||||
'aliases' => array(),
|
||||
'reference' => '76e9495fd6818b43a20167cb11d8a67f7744ee0f',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/serialization' => array(
|
||||
'pretty_version' => 'v1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => '693e77b2fb0b266c3c7d622317f881de44ae94a1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/serialization',
|
||||
'aliases' => array(),
|
||||
'reference' => '693e77b2fb0b266c3c7d622317f881de44ae94a1',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/sync' => array(
|
||||
'pretty_version' => 'v1.4.2',
|
||||
'version' => '1.4.2.0',
|
||||
'reference' => '85ab06764f4f36d63b1356b466df6111cf4b89cf',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/sync',
|
||||
'aliases' => array(),
|
||||
'reference' => '85ab06764f4f36d63b1356b466df6111cf4b89cf',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'artica/phpchartjs' => array(
|
||||
'pretty_version' => 'v1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => '681980c084ad505f9dc811d3d1f02ffc9442ccee',
|
||||
'type' => 'package',
|
||||
'install_path' => __DIR__ . '/../artica/phpchartjs',
|
||||
'aliases' => array(),
|
||||
'reference' => '681980c084ad505f9dc811d3d1f02ffc9442ccee',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'brick/math' => array(
|
||||
'pretty_version' => '0.11.0',
|
||||
'version' => '0.11.0.0',
|
||||
'reference' => '0ad82ce168c82ba30d1c01ec86116ab52f589478',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../brick/math',
|
||||
'aliases' => array(),
|
||||
'reference' => '0ad82ce168c82ba30d1c01ec86116ab52f589478',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'chrome-php/chrome' => array(
|
||||
'pretty_version' => 'v1.10.0',
|
||||
'version' => '1.10.0.0',
|
||||
'reference' => '2b7cb13e618602d13bdede20b6b7ae478f3f6eaa',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../chrome-php/chrome',
|
||||
'aliases' => array(),
|
||||
'reference' => '2b7cb13e618602d13bdede20b6b7ae478f3f6eaa',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'chrome-php/wrench' => array(
|
||||
'pretty_version' => 'v1.5.0',
|
||||
'version' => '1.5.0.0',
|
||||
'reference' => '725246324339e5fd5d798361b561e81004324f96',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../chrome-php/wrench',
|
||||
'aliases' => array(),
|
||||
'reference' => '725246324339e5fd5d798361b561e81004324f96',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'doctrine/annotations' => array(
|
||||
'pretty_version' => '2.0.1',
|
||||
'version' => '2.0.1.0',
|
||||
'reference' => 'e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../doctrine/annotations',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'doctrine/deprecations' => array(
|
||||
'pretty_version' => '1.1.3',
|
||||
'version' => '1.1.3.0',
|
||||
'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../doctrine/deprecations',
|
||||
'aliases' => array(),
|
||||
'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'doctrine/lexer' => array(
|
||||
'pretty_version' => '2.1.0',
|
||||
'version' => '2.1.0.0',
|
||||
'reference' => '39ab8fcf5a51ce4b85ca97c7a7d033eb12831124',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../doctrine/lexer',
|
||||
'aliases' => array(),
|
||||
'reference' => '39ab8fcf5a51ce4b85ca97c7a7d033eb12831124',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'egulias/email-validator' => array(
|
||||
'pretty_version' => '3.2.6',
|
||||
'version' => '3.2.6.0',
|
||||
'reference' => 'e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../egulias/email-validator',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'evenement/evenement' => array(
|
||||
'pretty_version' => 'v3.0.2',
|
||||
'version' => '3.0.2.0',
|
||||
'reference' => '0a16b0d71ab13284339abb99d9d2bd813640efbc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../evenement/evenement',
|
||||
'aliases' => array(),
|
||||
'reference' => '0a16b0d71ab13284339abb99d9d2bd813640efbc',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'fig/http-message-util' => array(
|
||||
'pretty_version' => '1.1.5',
|
||||
'version' => '1.1.5.0',
|
||||
'reference' => '9d94dc0154230ac39e5bf89398b324a86f63f765',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../fig/http-message-util',
|
||||
'aliases' => array(),
|
||||
'reference' => '9d94dc0154230ac39e5bf89398b324a86f63f765',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.6.2',
|
||||
'version' => '2.6.2.0',
|
||||
'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'halfpastfouram/collection' => array(
|
||||
'pretty_version' => 'v1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => '0862d0b431fef9dc2245518dc06b86ff00dcd102',
|
||||
'type' => 'package',
|
||||
'install_path' => __DIR__ . '/../halfpastfouram/collection',
|
||||
'aliases' => array(),
|
||||
'reference' => '0862d0b431fef9dc2245518dc06b86ff00dcd102',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laminas/laminas-diactoros' => array(
|
||||
'pretty_version' => '3.3.0',
|
||||
'version' => '3.3.0.0',
|
||||
'reference' => '4db52734837c60259c9b2d7caf08eef8f7f9b9ac',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../laminas/laminas-diactoros',
|
||||
'aliases' => array(),
|
||||
'reference' => '4db52734837c60259c9b2d7caf08eef8f7f9b9ac',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laminas/laminas-json' => array(
|
||||
'pretty_version' => '3.6.0',
|
||||
'version' => '3.6.0.0',
|
||||
'reference' => '53ff787b20b77197f38680c737e8dfffa846b85b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../laminas/laminas-json',
|
||||
'aliases' => array(),
|
||||
'reference' => '53ff787b20b77197f38680c737e8dfffa846b85b',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laravel/serializable-closure' => array(
|
||||
'pretty_version' => 'v1.3.3',
|
||||
'version' => '1.3.3.0',
|
||||
'reference' => '3dbf8a8e914634c48d389c1234552666b3d43754',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../laravel/serializable-closure',
|
||||
'aliases' => array(),
|
||||
'reference' => '3dbf8a8e914634c48d389c1234552666b3d43754',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'lcobucci/jwt' => array(
|
||||
'pretty_version' => '5.2.0',
|
||||
'version' => '5.2.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../lcobucci/jwt',
|
||||
'aliases' => array(),
|
||||
'reference' => '0ba88aed12c04bd2ed9924f500673f32b67a6211',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'monolog/monolog' => array(
|
||||
'pretty_version' => '3.5.0',
|
||||
'version' => '3.5.0.0',
|
||||
'reference' => 'c915e2634718dbc8a4a15c61b0e62e7a44e14448',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../monolog/monolog',
|
||||
'aliases' => array(),
|
||||
'reference' => 'c915e2634718dbc8a4a15c61b0e62e7a44e14448',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mpdf/mpdf' => array(
|
||||
'pretty_version' => 'v8.2.2',
|
||||
'version' => '8.2.2.0',
|
||||
'reference' => '596a87b876d7793be7be060a8ac13424de120dd5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mpdf/mpdf',
|
||||
'aliases' => array(),
|
||||
'reference' => '596a87b876d7793be7be060a8ac13424de120dd5',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mpdf/psr-http-message-shim' => array(
|
||||
'pretty_version' => '1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => '3206e6b80b6d2479e148ee497e9f2bebadc919db',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mpdf/psr-http-message-shim',
|
||||
'aliases' => array(),
|
||||
'reference' => '3206e6b80b6d2479e148ee497e9f2bebadc919db',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mpdf/psr-log-aware-trait' => array(
|
||||
'pretty_version' => 'v3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'a633da6065e946cc491e1c962850344bb0bf3e78',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mpdf/psr-log-aware-trait',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a633da6065e946cc491e1c962850344bb0bf3e78',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'myclabs/deep-copy' => array(
|
||||
'pretty_version' => '1.11.1',
|
||||
'version' => '1.11.1.0',
|
||||
'reference' => '7284c22080590fb39f2ffa3e9057f10a4ddd0e0c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../myclabs/deep-copy',
|
||||
'aliases' => array(),
|
||||
'reference' => '7284c22080590fb39f2ffa3e9057f10a4ddd0e0c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nikic/fast-route' => array(
|
||||
'pretty_version' => 'v1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'reference' => '181d480e08d9476e61381e04a71b34dc0432e812',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/fast-route',
|
||||
'aliases' => array(),
|
||||
'reference' => '181d480e08d9476e61381e04a71b34dc0432e812',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nyholm/psr7' => array(
|
||||
'pretty_version' => '1.8.1',
|
||||
'version' => '1.8.1.0',
|
||||
'reference' => 'aa5fc277a4f5508013d571341ade0c3886d4d00e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nyholm/psr7',
|
||||
'aliases' => array(),
|
||||
'reference' => 'aa5fc277a4f5508013d571341ade0c3886d4d00e',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nyholm/psr7-server' => array(
|
||||
'pretty_version' => '1.1.0',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => '4335801d851f554ca43fa6e7d2602141538854dc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nyholm/psr7-server',
|
||||
'aliases' => array(),
|
||||
'reference' => '4335801d851f554ca43fa6e7d2602141538854dc',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'pandorafms/console' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '8bf414b51f3333555f84df8b23614ca4b68c7fd4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'fbec8c0a05f72bfcc2044c0a4857d5e31f534ad5',
|
||||
'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(),
|
||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-di/invoker' => array(
|
||||
'pretty_version' => '2.3.4',
|
||||
'version' => '2.3.4.0',
|
||||
'reference' => '33234b32dafa8eb69202f950a1fc92055ed76a86',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../php-di/invoker',
|
||||
'aliases' => array(),
|
||||
'reference' => '33234b32dafa8eb69202f950a1fc92055ed76a86',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-di/php-di' => array(
|
||||
'pretty_version' => '7.0.6',
|
||||
'version' => '7.0.6.0',
|
||||
'reference' => '8097948a89f6ec782839b3e958432f427cac37fd',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../php-di/php-di',
|
||||
'aliases' => array(),
|
||||
'reference' => '8097948a89f6ec782839b3e958432f427cac37fd',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-http/message-factory-implementation' => array(
|
||||
|
@ -334,19 +343,28 @@
|
|||
'psr/cache' => array(
|
||||
'pretty_version' => '3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'aa5030cfa5405eccfdcb1083ce040c2cb8d253bf',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/cache',
|
||||
'aliases' => array(),
|
||||
'reference' => 'aa5030cfa5405eccfdcb1083ce040c2cb8d253bf',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/clock' => array(
|
||||
'pretty_version' => '1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/clock',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e41a24703d4560fd0acb709162f73b8adfc3aa0d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '2.0.2',
|
||||
'version' => '2.0.2.0',
|
||||
'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/container',
|
||||
'aliases' => array(),
|
||||
'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/container-implementation' => array(
|
||||
|
@ -358,10 +376,10 @@
|
|||
'psr/http-factory' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'e616d01114759c4c489f93b099585439f795fe35',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e616d01114759c4c489f93b099585439f795fe35',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory-implementation' => array(
|
||||
|
@ -374,10 +392,10 @@
|
|||
'psr/http-message' => array(
|
||||
'pretty_version' => '1.1',
|
||||
'version' => '1.1.0.0',
|
||||
'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-message',
|
||||
'aliases' => array(),
|
||||
'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-message-implementation' => array(
|
||||
|
@ -390,28 +408,28 @@
|
|||
'psr/http-server-handler' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-server-handler',
|
||||
'aliases' => array(),
|
||||
'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-server-middleware' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-server-middleware',
|
||||
'aliases' => array(),
|
||||
'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log' => array(
|
||||
'pretty_version' => '3.0.0',
|
||||
'version' => '3.0.0.0',
|
||||
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log-implementation' => array(
|
||||
|
@ -423,28 +441,28 @@
|
|||
'ralouphie/getallheaders' => array(
|
||||
'pretty_version' => '3.0.3',
|
||||
'version' => '3.0.3.0',
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
|
||||
'aliases' => array(),
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ramsey/collection' => array(
|
||||
'pretty_version' => '2.0.0',
|
||||
'version' => '2.0.0.0',
|
||||
'reference' => 'a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ramsey/collection',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ramsey/uuid' => array(
|
||||
'pretty_version' => '4.7.5',
|
||||
'version' => '4.7.5.0',
|
||||
'reference' => '5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ramsey/uuid',
|
||||
'aliases' => array(),
|
||||
'reference' => '5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'rhumsaa/uuid' => array(
|
||||
|
@ -456,172 +474,172 @@
|
|||
'setasign/fpdi' => array(
|
||||
'pretty_version' => 'v2.6.0',
|
||||
'version' => '2.6.0.0',
|
||||
'reference' => 'a6db878129ec6c7e141316ee71872923e7f1b7ad',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../setasign/fpdi',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a6db878129ec6c7e141316ee71872923e7f1b7ad',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'slim/psr7' => array(
|
||||
'pretty_version' => '1.6.1',
|
||||
'version' => '1.6.1.0',
|
||||
'reference' => '72d2b2bac94ab4575d369f605dbfafbe168d3163',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../slim/psr7',
|
||||
'aliases' => array(),
|
||||
'reference' => '72d2b2bac94ab4575d369f605dbfafbe168d3163',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'slim/slim' => array(
|
||||
'pretty_version' => '4.12.0',
|
||||
'version' => '4.12.0.0',
|
||||
'reference' => 'e9e99c2b24398b967841c6c4c3048622cc7e2b18',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../slim/slim',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e9e99c2b24398b967841c6c4c3048622cc7e2b18',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'swiftmailer/swiftmailer' => array(
|
||||
'pretty_version' => 'v6.3.0',
|
||||
'version' => '6.3.0.0',
|
||||
'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../swiftmailer/swiftmailer',
|
||||
'aliases' => array(),
|
||||
'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/deprecation-contracts' => array(
|
||||
'pretty_version' => 'v3.4.0',
|
||||
'version' => '3.4.0.0',
|
||||
'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/filesystem' => array(
|
||||
'pretty_version' => 'v7.0.3',
|
||||
'version' => '7.0.3.0',
|
||||
'reference' => '2890e3a825bc0c0558526c04499c13f83e1b6b12',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/filesystem',
|
||||
'aliases' => array(),
|
||||
'reference' => '2890e3a825bc0c0558526c04499c13f83e1b6b12',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/finder' => array(
|
||||
'pretty_version' => 'v7.0.0',
|
||||
'version' => '7.0.0.0',
|
||||
'reference' => '6e5688d69f7cfc4ed4a511e96007e06c2d34ce56',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/finder',
|
||||
'aliases' => array(),
|
||||
'reference' => '6e5688d69f7cfc4ed4a511e96007e06c2d34ce56',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-iconv' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '6de50471469b8c9afc38164452ab2b6170ee71c1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-iconv',
|
||||
'aliases' => array(),
|
||||
'reference' => '6de50471469b8c9afc38164452ab2b6170ee71c1',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-idn' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
'aliases' => array(),
|
||||
'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '42292d99c55abe617799667f454222c54c60e229',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'reference' => '42292d99c55abe617799667f454222c54c60e229',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php72' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
|
||||
'aliases' => array(),
|
||||
'reference' => '70f4aebd92afca2f865444d30a4d2151c13c3179',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.28.0',
|
||||
'version' => '1.28.0.0',
|
||||
'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/process' => array(
|
||||
'pretty_version' => 'v7.0.3',
|
||||
'version' => '7.0.3.0',
|
||||
'reference' => '937a195147e0c27b2759ade834169ed006d0bc74',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/process',
|
||||
'aliases' => array(),
|
||||
'reference' => '937a195147e0c27b2759ade834169ed006d0bc74',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-dumper' => array(
|
||||
'pretty_version' => 'v3.4.47',
|
||||
'version' => '3.4.47.0',
|
||||
'reference' => '0719f6cf4633a38b2c1585140998579ce23b4b7d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||
'aliases' => array(),
|
||||
'reference' => '0719f6cf4633a38b2c1585140998579ce23b4b7d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/yaml' => array(
|
||||
'pretty_version' => 'v7.0.3',
|
||||
'version' => '7.0.3.0',
|
||||
'reference' => '2d4fca631c00700597e9442a0b2451ce234513d3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/yaml',
|
||||
'aliases' => array(),
|
||||
'reference' => '2d4fca631c00700597e9442a0b2451ce234513d3',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'tinymce/tinymce' => array(
|
||||
'pretty_version' => '6.8.2',
|
||||
'version' => '6.8.2.0',
|
||||
'reference' => 'b0073db409746748af4fc06fbee337bb99f462d9',
|
||||
'type' => 'component',
|
||||
'install_path' => __DIR__ . '/../tinymce/tinymce',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b0073db409746748af4fc06fbee337bb99f462d9',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'zircote/swagger-php' => array(
|
||||
'pretty_version' => '4.8.3',
|
||||
'version' => '4.8.3.0',
|
||||
'reference' => '598958d8a83cfbd44ba36388b2f9ed69e8b86ed4',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../zircote/swagger-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '598958d8a83cfbd44ba36388b2f9ed69e8b86ed4',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -16,35 +16,7 @@ if ($issues) {
|
|||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
require_once __DIR__.'/../../include/functions_ui.php';
|
||||
|
||||
$url = str_replace('/var/www/html/', '', __DIR__);
|
||||
$url = str_replace('/vendor/composer', '', $url);
|
||||
|
||||
echo '<link rel="stylesheet" type="text/css" href="include/styles/pandora.css">';
|
||||
?>
|
||||
|
||||
<style>
|
||||
body {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<?php
|
||||
|
||||
$random_backgrounds = scandir('/var/www/html/'.$url. '/images/backgrounds/random_backgrounds');
|
||||
unset($random_backgrounds[0], $random_backgrounds[1]);
|
||||
$random_background = array_rand($random_backgrounds);
|
||||
|
||||
echo '<div style="width:100%;min-height: 100%;position: absolute; display:flex;align-items:center;justify-content:center;background-size:cover !important; background-position: center: !important; background: linear-gradient(rgba(255, 255, 255, .20), rgba(255, 255, 255, .20)), url('.$url. '/../images/backgrounds/random_backgrounds/'.$random_backgrounds[$random_background].');">';
|
||||
echo '<center><div align="middle" class="license_databox w600px pdd_10px" style="background-color: white;">';
|
||||
echo '<img style="width: 500px; margin-top: 30px;" src="images/custom_logo/logo-default-pandorafms.png"><h2> Composer detected issues in your platform:</h2>';
|
||||
echo '<div class="w80p height_80px" style="text-align:left;font-size: larger">';
|
||||
echo sprintf(
|
||||
'PandoraFMS requires PHP 8.2 to work properly and the version %s has been detected. Please update the PHP version of the system.',
|
||||
PHP_VERSION,
|
||||
);
|
||||
echo '</div></div></center></div>';
|
||||
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(
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3"
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2014, Luís Cobucci
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"JWT",
|
||||
"JWS"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Luís Cobucci",
|
||||
"email": "lcobucci@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"ext-openssl": "*",
|
||||
"ext-sodium": "*",
|
||||
"psr/clock": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.27.0",
|
||||
"lcobucci/clock": "^3.0",
|
||||
"lcobucci/coding-standard": "^11.0",
|
||||
"phpbench/phpbench": "^1.2.9",
|
||||
"phpstan/extension-installer": "^1.2",
|
||||
"phpstan/phpstan": "^1.10.7",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.3",
|
||||
"phpstan/phpstan-phpunit": "^1.3.10",
|
||||
"phpstan/phpstan-strict-rules": "^1.5.0",
|
||||
"phpunit/phpunit": "^10.2.6"
|
||||
},
|
||||
"suggest": {
|
||||
"lcobucci/clock": ">= 3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\JWT\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"infection/extension-installer": true,
|
||||
"ocramius/package-versions": true,
|
||||
"phpstan/extension-installer": true
|
||||
},
|
||||
"platform": {
|
||||
"php": "8.1.99"
|
||||
},
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"local>lcobucci/.github:renovate-config"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\Encoding\CannotEncodeContent;
|
||||
use Lcobucci\JWT\Signer\CannotSignPayload;
|
||||
use Lcobucci\JWT\Signer\Ecdsa\ConversionFailed;
|
||||
use Lcobucci\JWT\Signer\InvalidKeyProvided;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\Token\RegisteredClaimGiven;
|
||||
|
||||
/** @immutable */
|
||||
interface Builder
|
||||
{
|
||||
/**
|
||||
* Appends new items to audience
|
||||
*
|
||||
* @param non-empty-string ...$audiences
|
||||
*/
|
||||
public function permittedFor(string ...$audiences): Builder;
|
||||
|
||||
/**
|
||||
* Configures the expiration time
|
||||
*/
|
||||
public function expiresAt(DateTimeImmutable $expiration): Builder;
|
||||
|
||||
/**
|
||||
* Configures the token id
|
||||
*
|
||||
* @param non-empty-string $id
|
||||
*/
|
||||
public function identifiedBy(string $id): Builder;
|
||||
|
||||
/**
|
||||
* Configures the time that the token was issued
|
||||
*/
|
||||
public function issuedAt(DateTimeImmutable $issuedAt): Builder;
|
||||
|
||||
/**
|
||||
* Configures the issuer
|
||||
*
|
||||
* @param non-empty-string $issuer
|
||||
*/
|
||||
public function issuedBy(string $issuer): Builder;
|
||||
|
||||
/**
|
||||
* Configures the time before which the token cannot be accepted
|
||||
*/
|
||||
public function canOnlyBeUsedAfter(DateTimeImmutable $notBefore): Builder;
|
||||
|
||||
/**
|
||||
* Configures the subject
|
||||
*
|
||||
* @param non-empty-string $subject
|
||||
*/
|
||||
public function relatedTo(string $subject): Builder;
|
||||
|
||||
/**
|
||||
* Configures a header item
|
||||
*
|
||||
* @param non-empty-string $name
|
||||
*/
|
||||
public function withHeader(string $name, mixed $value): Builder;
|
||||
|
||||
/**
|
||||
* Configures a claim item
|
||||
*
|
||||
* @param non-empty-string $name
|
||||
*
|
||||
* @throws RegisteredClaimGiven When trying to set a registered claim.
|
||||
*/
|
||||
public function withClaim(string $name, mixed $value): Builder;
|
||||
|
||||
/**
|
||||
* Returns a signed token to be used
|
||||
*
|
||||
* @throws CannotEncodeContent When data cannot be converted to JSON.
|
||||
* @throws CannotSignPayload When payload signing fails.
|
||||
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
|
||||
* @throws ConversionFailed When signature could not be converted.
|
||||
*/
|
||||
public function getToken(Signer $signer, Key $key): UnencryptedToken;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
interface ClaimsFormatter
|
||||
{
|
||||
/**
|
||||
* @param array<non-empty-string, mixed> $claims
|
||||
*
|
||||
* @return array<non-empty-string, mixed>
|
||||
*/
|
||||
public function formatClaims(array $claims): array;
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Closure;
|
||||
use Lcobucci\JWT\Encoding\ChainedFormatter;
|
||||
use Lcobucci\JWT\Encoding\JoseEncoder;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
/**
|
||||
* Configuration container for the JWT Builder and Parser
|
||||
*
|
||||
* Serves like a small DI container to simplify the creation and usage
|
||||
* of the objects.
|
||||
*/
|
||||
final class Configuration
|
||||
{
|
||||
private Parser $parser;
|
||||
private Validator $validator;
|
||||
|
||||
/** @var Closure(ClaimsFormatter $claimFormatter): Builder */
|
||||
private Closure $builderFactory;
|
||||
|
||||
/** @var Constraint[] */
|
||||
private array $validationConstraints = [];
|
||||
|
||||
private function __construct(
|
||||
private readonly Signer $signer,
|
||||
private readonly Key $signingKey,
|
||||
private readonly Key $verificationKey,
|
||||
Encoder $encoder,
|
||||
Decoder $decoder,
|
||||
) {
|
||||
$this->parser = new Token\Parser($decoder);
|
||||
$this->validator = new Validation\Validator();
|
||||
|
||||
$this->builderFactory = static function (ClaimsFormatter $claimFormatter) use ($encoder): Builder {
|
||||
return new Token\Builder($encoder, $claimFormatter);
|
||||
};
|
||||
}
|
||||
|
||||
public static function forAsymmetricSigner(
|
||||
Signer $signer,
|
||||
Key $signingKey,
|
||||
Key $verificationKey,
|
||||
Encoder $encoder = new JoseEncoder(),
|
||||
Decoder $decoder = new JoseEncoder(),
|
||||
): self {
|
||||
return new self(
|
||||
$signer,
|
||||
$signingKey,
|
||||
$verificationKey,
|
||||
$encoder,
|
||||
$decoder,
|
||||
);
|
||||
}
|
||||
|
||||
public static function forSymmetricSigner(
|
||||
Signer $signer,
|
||||
Key $key,
|
||||
Encoder $encoder = new JoseEncoder(),
|
||||
Decoder $decoder = new JoseEncoder(),
|
||||
): self {
|
||||
return new self(
|
||||
$signer,
|
||||
$key,
|
||||
$key,
|
||||
$encoder,
|
||||
$decoder,
|
||||
);
|
||||
}
|
||||
|
||||
/** @param callable(ClaimsFormatter): Builder $builderFactory */
|
||||
public function setBuilderFactory(callable $builderFactory): void
|
||||
{
|
||||
$this->builderFactory = $builderFactory(...);
|
||||
}
|
||||
|
||||
public function builder(?ClaimsFormatter $claimFormatter = null): Builder
|
||||
{
|
||||
return ($this->builderFactory)($claimFormatter ?? ChainedFormatter::default());
|
||||
}
|
||||
|
||||
public function parser(): Parser
|
||||
{
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
public function setParser(Parser $parser): void
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function signer(): Signer
|
||||
{
|
||||
return $this->signer;
|
||||
}
|
||||
|
||||
public function signingKey(): Key
|
||||
{
|
||||
return $this->signingKey;
|
||||
}
|
||||
|
||||
public function verificationKey(): Key
|
||||
{
|
||||
return $this->verificationKey;
|
||||
}
|
||||
|
||||
public function validator(): Validator
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
public function setValidator(Validator $validator): void
|
||||
{
|
||||
$this->validator = $validator;
|
||||
}
|
||||
|
||||
/** @return Constraint[] */
|
||||
public function validationConstraints(): array
|
||||
{
|
||||
return $this->validationConstraints;
|
||||
}
|
||||
|
||||
public function setValidationConstraints(Constraint ...$validationConstraints): void
|
||||
{
|
||||
$this->validationConstraints = $validationConstraints;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
|
||||
interface Decoder
|
||||
{
|
||||
/**
|
||||
* Decodes from JSON, validating the errors
|
||||
*
|
||||
* @param non-empty-string $json
|
||||
*
|
||||
* @throws CannotDecodeContent When something goes wrong while decoding.
|
||||
*/
|
||||
public function jsonDecode(string $json): mixed;
|
||||
|
||||
/**
|
||||
* Decodes from Base64URL
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*
|
||||
* @return ($data is non-empty-string ? non-empty-string : string)
|
||||
*
|
||||
* @throws CannotDecodeContent When something goes wrong while decoding.
|
||||
*/
|
||||
public function base64UrlDecode(string $data): string;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotEncodeContent;
|
||||
|
||||
interface Encoder
|
||||
{
|
||||
/**
|
||||
* Encodes to JSON, validating the errors
|
||||
*
|
||||
* @return non-empty-string
|
||||
*
|
||||
* @throws CannotEncodeContent When something goes wrong while encoding.
|
||||
*/
|
||||
public function jsonEncode(mixed $data): string;
|
||||
|
||||
/**
|
||||
* Encodes to base64url
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*
|
||||
* @return ($data is non-empty-string ? non-empty-string : string)
|
||||
*/
|
||||
public function base64UrlEncode(string $data): string;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use JsonException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
use RuntimeException;
|
||||
|
||||
final class CannotDecodeContent extends RuntimeException implements Exception
|
||||
{
|
||||
public static function jsonIssues(JsonException $previous): self
|
||||
{
|
||||
return new self(message: 'Error while decoding from JSON', previous: $previous);
|
||||
}
|
||||
|
||||
public static function invalidBase64String(): self
|
||||
{
|
||||
return new self('Error while decoding from Base64Url, invalid base64 characters detected');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use JsonException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
use RuntimeException;
|
||||
|
||||
final class CannotEncodeContent extends RuntimeException implements Exception
|
||||
{
|
||||
public static function jsonIssues(JsonException $previous): self
|
||||
{
|
||||
return new self(message: 'Error while encoding to JSON', previous: $previous);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
|
||||
final class ChainedFormatter implements ClaimsFormatter
|
||||
{
|
||||
/** @var array<ClaimsFormatter> */
|
||||
private array $formatters;
|
||||
|
||||
public function __construct(ClaimsFormatter ...$formatters)
|
||||
{
|
||||
$this->formatters = $formatters;
|
||||
}
|
||||
|
||||
public static function default(): self
|
||||
{
|
||||
return new self(new UnifyAudience(), new MicrosecondBasedDateConversion());
|
||||
}
|
||||
|
||||
public static function withUnixTimestampDates(): self
|
||||
{
|
||||
return new self(new UnifyAudience(), new UnixTimestampDates());
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function formatClaims(array $claims): array
|
||||
{
|
||||
foreach ($this->formatters as $formatter) {
|
||||
$claims = $formatter->formatClaims($claims);
|
||||
}
|
||||
|
||||
return $claims;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use JsonException;
|
||||
use Lcobucci\JWT\Decoder;
|
||||
use Lcobucci\JWT\Encoder;
|
||||
use Lcobucci\JWT\SodiumBase64Polyfill;
|
||||
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
|
||||
/**
|
||||
* A utilitarian class that encodes and decodes data according to JOSE specifications
|
||||
*/
|
||||
final class JoseEncoder implements Encoder, Decoder
|
||||
{
|
||||
public function jsonEncode(mixed $data): string
|
||||
{
|
||||
try {
|
||||
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $exception) {
|
||||
throw CannotEncodeContent::jsonIssues($exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function jsonDecode(string $json): mixed
|
||||
{
|
||||
try {
|
||||
return json_decode(json: $json, associative: true, flags: JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $exception) {
|
||||
throw CannotDecodeContent::jsonIssues($exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function base64UrlEncode(string $data): string
|
||||
{
|
||||
return SodiumBase64Polyfill::bin2base64(
|
||||
$data,
|
||||
SodiumBase64Polyfill::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING,
|
||||
);
|
||||
}
|
||||
|
||||
public function base64UrlDecode(string $data): string
|
||||
{
|
||||
return SodiumBase64Polyfill::base642bin(
|
||||
$data,
|
||||
SodiumBase64Polyfill::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING,
|
||||
);
|
||||
}
|
||||
}
|
36
pandora_console/vendor/lcobucci/jwt/src/Encoding/MicrosecondBasedDateConversion.php
vendored
Normal file
36
pandora_console/vendor/lcobucci/jwt/src/Encoding/MicrosecondBasedDateConversion.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class MicrosecondBasedDateConversion implements ClaimsFormatter
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function formatClaims(array $claims): array
|
||||
{
|
||||
foreach (RegisteredClaims::DATE_CLAIMS as $claim) {
|
||||
if (! array_key_exists($claim, $claims)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$claims[$claim] = $this->convertDate($claims[$claim]);
|
||||
}
|
||||
|
||||
return $claims;
|
||||
}
|
||||
|
||||
private function convertDate(DateTimeImmutable $date): int|float
|
||||
{
|
||||
if ($date->format('u') === '000000') {
|
||||
return (int) $date->format('U');
|
||||
}
|
||||
|
||||
return (float) $date->format('U.u');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function current;
|
||||
|
||||
final class UnifyAudience implements ClaimsFormatter
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function formatClaims(array $claims): array
|
||||
{
|
||||
if (
|
||||
! array_key_exists(RegisteredClaims::AUDIENCE, $claims)
|
||||
|| count($claims[RegisteredClaims::AUDIENCE]) !== 1
|
||||
) {
|
||||
return $claims;
|
||||
}
|
||||
|
||||
$claims[RegisteredClaims::AUDIENCE] = current($claims[RegisteredClaims::AUDIENCE]);
|
||||
|
||||
return $claims;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class UnixTimestampDates implements ClaimsFormatter
|
||||
{
|
||||
/** @inheritdoc */
|
||||
public function formatClaims(array $claims): array
|
||||
{
|
||||
foreach (RegisteredClaims::DATE_CLAIMS as $claim) {
|
||||
if (! array_key_exists($claim, $claims)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$claims[$claim] = $this->convertDate($claims[$claim]);
|
||||
}
|
||||
|
||||
return $claims;
|
||||
}
|
||||
|
||||
private function convertDate(DateTimeImmutable $date): int
|
||||
{
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Closure;
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\Encoding\ChainedFormatter;
|
||||
use Lcobucci\JWT\Encoding\JoseEncoder;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\SignedWith;
|
||||
use Lcobucci\JWT\Validation\ValidAt;
|
||||
use Lcobucci\JWT\Validation\Validator;
|
||||
use Psr\Clock\ClockInterface as Clock;
|
||||
|
||||
use function assert;
|
||||
|
||||
final class JwtFacade
|
||||
{
|
||||
private readonly Clock $clock;
|
||||
|
||||
public function __construct(
|
||||
private readonly Parser $parser = new Token\Parser(new JoseEncoder()),
|
||||
?Clock $clock = null,
|
||||
) {
|
||||
$this->clock = $clock ?? new class implements Clock {
|
||||
public function now(): DateTimeImmutable
|
||||
{
|
||||
return new DateTimeImmutable();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @param Closure(Builder, DateTimeImmutable):Builder $customiseBuilder */
|
||||
public function issue(
|
||||
Signer $signer,
|
||||
Key $signingKey,
|
||||
Closure $customiseBuilder,
|
||||
): UnencryptedToken {
|
||||
$builder = new Token\Builder(new JoseEncoder(), ChainedFormatter::withUnixTimestampDates());
|
||||
|
||||
$now = $this->clock->now();
|
||||
$builder = $builder
|
||||
->issuedAt($now)
|
||||
->canOnlyBeUsedAfter($now)
|
||||
->expiresAt($now->modify('+5 minutes'));
|
||||
|
||||
return $customiseBuilder($builder, $now)->getToken($signer, $signingKey);
|
||||
}
|
||||
|
||||
/** @param non-empty-string $jwt */
|
||||
public function parse(
|
||||
string $jwt,
|
||||
SignedWith $signedWith,
|
||||
ValidAt $validAt,
|
||||
Constraint ...$constraints,
|
||||
): UnencryptedToken {
|
||||
$token = $this->parser->parse($jwt);
|
||||
assert($token instanceof UnencryptedToken);
|
||||
|
||||
(new Validator())->assert(
|
||||
$token,
|
||||
$signedWith,
|
||||
$validAt,
|
||||
...$constraints,
|
||||
);
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
use Lcobucci\JWT\Token\InvalidTokenStructure;
|
||||
use Lcobucci\JWT\Token\UnsupportedHeaderFound;
|
||||
|
||||
interface Parser
|
||||
{
|
||||
/**
|
||||
* Parses the JWT and returns a token
|
||||
*
|
||||
* @param non-empty-string $jwt
|
||||
*
|
||||
* @throws CannotDecodeContent When something goes wrong while decoding.
|
||||
* @throws InvalidTokenStructure When token string structure is invalid.
|
||||
* @throws UnsupportedHeaderFound When parsed token has an unsupported header.
|
||||
*/
|
||||
public function parse(string $jwt): Token;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Signer\CannotSignPayload;
|
||||
use Lcobucci\JWT\Signer\Ecdsa\ConversionFailed;
|
||||
use Lcobucci\JWT\Signer\InvalidKeyProvided;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
|
||||
interface Signer
|
||||
{
|
||||
/**
|
||||
* Returns the algorithm id
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function algorithmId(): string;
|
||||
|
||||
/**
|
||||
* Creates a hash for the given payload
|
||||
*
|
||||
* @param non-empty-string $payload
|
||||
*
|
||||
* @return non-empty-string
|
||||
*
|
||||
* @throws CannotSignPayload When payload signing fails.
|
||||
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
|
||||
* @throws ConversionFailed When signature could not be converted.
|
||||
*/
|
||||
public function sign(string $payload, Key $key): string;
|
||||
|
||||
/**
|
||||
* Returns if the expected hash matches with the data and key
|
||||
*
|
||||
* @param non-empty-string $expected
|
||||
* @param non-empty-string $payload
|
||||
*
|
||||
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
|
||||
* @throws ConversionFailed When signature could not be converted.
|
||||
*/
|
||||
public function verify(string $expected, string $payload, Key $key): bool;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
|
||||
use function hash_equals;
|
||||
use function sodium_crypto_generichash;
|
||||
use function strlen;
|
||||
|
||||
final class Blake2b implements Signer
|
||||
{
|
||||
private const MINIMUM_KEY_LENGTH_IN_BITS = 256;
|
||||
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'BLAKE2B';
|
||||
}
|
||||
|
||||
public function sign(string $payload, Key $key): string
|
||||
{
|
||||
$actualKeyLength = 8 * strlen($key->contents());
|
||||
|
||||
if ($actualKeyLength < self::MINIMUM_KEY_LENGTH_IN_BITS) {
|
||||
throw InvalidKeyProvided::tooShort(self::MINIMUM_KEY_LENGTH_IN_BITS, $actualKeyLength);
|
||||
}
|
||||
|
||||
return sodium_crypto_generichash($payload, $key->contents());
|
||||
}
|
||||
|
||||
public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return hash_equals($expected, $this->sign($payload, $key));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class CannotSignPayload extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function errorHappened(string $error): self
|
||||
{
|
||||
return new self('There was an error while creating the signature:' . $error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa\MultibyteStringConverter;
|
||||
use Lcobucci\JWT\Signer\Ecdsa\SignatureConverter;
|
||||
|
||||
use const OPENSSL_KEYTYPE_EC;
|
||||
|
||||
abstract class Ecdsa extends OpenSSL
|
||||
{
|
||||
public function __construct(
|
||||
private readonly SignatureConverter $converter = new MultibyteStringConverter(),
|
||||
) {
|
||||
}
|
||||
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return $this->converter->fromAsn1(
|
||||
$this->createSignature($key->contents(), $key->passphrase(), $payload),
|
||||
$this->pointLength(),
|
||||
);
|
||||
}
|
||||
|
||||
final public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return $this->verifySignature(
|
||||
$this->converter->toAsn1($expected, $this->pointLength()),
|
||||
$payload,
|
||||
$key->contents(),
|
||||
);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
final protected function guardAgainstIncompatibleKey(int $type, int $lengthInBits): void
|
||||
{
|
||||
if ($type !== OPENSSL_KEYTYPE_EC) {
|
||||
throw InvalidKeyProvided::incompatibleKeyType(
|
||||
self::KEY_TYPE_MAP[OPENSSL_KEYTYPE_EC],
|
||||
self::KEY_TYPE_MAP[$type],
|
||||
);
|
||||
}
|
||||
|
||||
$expectedKeyLength = $this->expectedKeyLength();
|
||||
|
||||
if ($lengthInBits !== $expectedKeyLength) {
|
||||
throw InvalidKeyProvided::incompatibleKeyLength($expectedKeyLength, $lengthInBits);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return positive-int
|
||||
*/
|
||||
abstract public function expectedKeyLength(): int;
|
||||
|
||||
/**
|
||||
* Returns the length of each point in the signature, so that we can calculate and verify R and S points properly
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return positive-int
|
||||
*/
|
||||
abstract public function pointLength(): int;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class ConversionFailed extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function invalidLength(): self
|
||||
{
|
||||
return new self('Invalid signature length.');
|
||||
}
|
||||
|
||||
public static function incorrectStartSequence(): self
|
||||
{
|
||||
return new self('Invalid data. Should start with a sequence.');
|
||||
}
|
||||
|
||||
public static function integerExpected(): self
|
||||
{
|
||||
return new self('Invalid data. Should contain an integer.');
|
||||
}
|
||||
}
|
148
pandora_console/vendor/lcobucci/jwt/src/Signer/Ecdsa/MultibyteStringConverter.php
vendored
Normal file
148
pandora_console/vendor/lcobucci/jwt/src/Signer/Ecdsa/MultibyteStringConverter.php
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014-2018 Spomky-Labs
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*
|
||||
* @link https://github.com/web-token/jwt-framework/blob/v1.2/src/Component/Core/Util/ECSignature.php
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use function assert;
|
||||
use function bin2hex;
|
||||
use function dechex;
|
||||
use function hex2bin;
|
||||
use function hexdec;
|
||||
use function is_string;
|
||||
use function str_pad;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
|
||||
use const STR_PAD_LEFT;
|
||||
|
||||
/**
|
||||
* ECDSA signature converter using ext-mbstring
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class MultibyteStringConverter implements SignatureConverter
|
||||
{
|
||||
private const ASN1_SEQUENCE = '30';
|
||||
private const ASN1_INTEGER = '02';
|
||||
private const ASN1_MAX_SINGLE_BYTE = 128;
|
||||
private const ASN1_LENGTH_2BYTES = '81';
|
||||
private const ASN1_BIG_INTEGER_LIMIT = '7f';
|
||||
private const ASN1_NEGATIVE_INTEGER = '00';
|
||||
private const BYTE_SIZE = 2;
|
||||
|
||||
public function toAsn1(string $points, int $length): string
|
||||
{
|
||||
$points = bin2hex($points);
|
||||
|
||||
if (self::octetLength($points) !== $length) {
|
||||
throw ConversionFailed::invalidLength();
|
||||
}
|
||||
|
||||
$pointR = self::preparePositiveInteger(substr($points, 0, $length));
|
||||
$pointS = self::preparePositiveInteger(substr($points, $length, null));
|
||||
|
||||
$lengthR = self::octetLength($pointR);
|
||||
$lengthS = self::octetLength($pointS);
|
||||
|
||||
$totalLength = $lengthR + $lengthS + self::BYTE_SIZE + self::BYTE_SIZE;
|
||||
$lengthPrefix = $totalLength > self::ASN1_MAX_SINGLE_BYTE ? self::ASN1_LENGTH_2BYTES : '';
|
||||
|
||||
$asn1 = hex2bin(
|
||||
self::ASN1_SEQUENCE
|
||||
. $lengthPrefix . dechex($totalLength)
|
||||
. self::ASN1_INTEGER . dechex($lengthR) . $pointR
|
||||
. self::ASN1_INTEGER . dechex($lengthS) . $pointS,
|
||||
);
|
||||
assert(is_string($asn1));
|
||||
assert($asn1 !== '');
|
||||
|
||||
return $asn1;
|
||||
}
|
||||
|
||||
private static function octetLength(string $data): int
|
||||
{
|
||||
return (int) (strlen($data) / self::BYTE_SIZE);
|
||||
}
|
||||
|
||||
private static function preparePositiveInteger(string $data): string
|
||||
{
|
||||
if (substr($data, 0, self::BYTE_SIZE) > self::ASN1_BIG_INTEGER_LIMIT) {
|
||||
return self::ASN1_NEGATIVE_INTEGER . $data;
|
||||
}
|
||||
|
||||
while (
|
||||
substr($data, 0, self::BYTE_SIZE) === self::ASN1_NEGATIVE_INTEGER
|
||||
&& substr($data, 2, self::BYTE_SIZE) <= self::ASN1_BIG_INTEGER_LIMIT
|
||||
) {
|
||||
$data = substr($data, 2, null);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function fromAsn1(string $signature, int $length): string
|
||||
{
|
||||
$message = bin2hex($signature);
|
||||
$position = 0;
|
||||
|
||||
if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_SEQUENCE) {
|
||||
throw ConversionFailed::incorrectStartSequence();
|
||||
}
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
if (self::readAsn1Content($message, $position, self::BYTE_SIZE) === self::ASN1_LENGTH_2BYTES) {
|
||||
$position += self::BYTE_SIZE;
|
||||
}
|
||||
|
||||
$pointR = self::retrievePositiveInteger(self::readAsn1Integer($message, $position));
|
||||
$pointS = self::retrievePositiveInteger(self::readAsn1Integer($message, $position));
|
||||
|
||||
$points = hex2bin(str_pad($pointR, $length, '0', STR_PAD_LEFT) . str_pad($pointS, $length, '0', STR_PAD_LEFT));
|
||||
assert(is_string($points));
|
||||
assert($points !== '');
|
||||
|
||||
return $points;
|
||||
}
|
||||
|
||||
private static function readAsn1Content(string $message, int &$position, int $length): string
|
||||
{
|
||||
$content = substr($message, $position, $length);
|
||||
$position += $length;
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private static function readAsn1Integer(string $message, int &$position): string
|
||||
{
|
||||
if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_INTEGER) {
|
||||
throw ConversionFailed::integerExpected();
|
||||
}
|
||||
|
||||
$length = (int) hexdec(self::readAsn1Content($message, $position, self::BYTE_SIZE));
|
||||
|
||||
return self::readAsn1Content($message, $position, $length * self::BYTE_SIZE);
|
||||
}
|
||||
|
||||
private static function retrievePositiveInteger(string $data): string
|
||||
{
|
||||
while (
|
||||
substr($data, 0, self::BYTE_SIZE) === self::ASN1_NEGATIVE_INTEGER
|
||||
&& substr($data, 2, self::BYTE_SIZE) > self::ASN1_BIG_INTEGER_LIMIT
|
||||
) {
|
||||
$data = substr($data, 2, null);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
final class Sha256 extends Ecdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES256';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
return 256;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
final class Sha384 extends Ecdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES384';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 96;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
return 384;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
final class Sha512 extends Ecdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES512';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 132;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
// ES512 means ECDSA using P-521 and SHA-512.
|
||||
// The key size is indeed 521 bits.
|
||||
return 521;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
/**
|
||||
* Manipulates the result of a ECDSA signature (points R and S) according to the
|
||||
* JWA specs.
|
||||
*
|
||||
* OpenSSL creates a signature using the ASN.1 format and, according the JWA specs,
|
||||
* the signature for JWTs must be the concatenated values of points R and S (in
|
||||
* big-endian octet order).
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7518#page-9
|
||||
* @see https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
|
||||
*/
|
||||
interface SignatureConverter
|
||||
{
|
||||
/**
|
||||
* Converts the signature generated by OpenSSL into what JWA defines
|
||||
*
|
||||
* @return non-empty-string
|
||||
*
|
||||
* @throws ConversionFailed When there was an issue during the format conversion.
|
||||
*/
|
||||
public function fromAsn1(string $signature, int $length): string;
|
||||
|
||||
/**
|
||||
* Converts the JWA signature into something OpenSSL understands
|
||||
*
|
||||
* @param non-empty-string $points
|
||||
*
|
||||
* @return non-empty-string
|
||||
*
|
||||
* @throws ConversionFailed When there was an issue during the format conversion.
|
||||
*/
|
||||
public function toAsn1(string $points, int $length): string;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
use SodiumException;
|
||||
|
||||
use function sodium_crypto_sign_detached;
|
||||
use function sodium_crypto_sign_verify_detached;
|
||||
|
||||
final class Eddsa implements Signer
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'EdDSA';
|
||||
}
|
||||
|
||||
public function sign(string $payload, Key $key): string
|
||||
{
|
||||
try {
|
||||
return sodium_crypto_sign_detached($payload, $key->contents());
|
||||
} catch (SodiumException $sodiumException) {
|
||||
throw new InvalidKeyProvided($sodiumException->getMessage(), 0, $sodiumException);
|
||||
}
|
||||
}
|
||||
|
||||
public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
try {
|
||||
return sodium_crypto_sign_verify_detached($expected, $payload, $key->contents());
|
||||
} catch (SodiumException $sodiumException) {
|
||||
throw new InvalidKeyProvided($sodiumException->getMessage(), 0, $sodiumException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
|
||||
use function hash_equals;
|
||||
use function hash_hmac;
|
||||
use function strlen;
|
||||
|
||||
abstract class Hmac implements Signer
|
||||
{
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
$actualKeyLength = 8 * strlen($key->contents());
|
||||
$expectedKeyLength = $this->minimumBitsLengthForKey();
|
||||
|
||||
if ($actualKeyLength < $expectedKeyLength) {
|
||||
throw InvalidKeyProvided::tooShort($expectedKeyLength, $actualKeyLength);
|
||||
}
|
||||
|
||||
return hash_hmac($this->algorithm(), $payload, $key->contents(), true);
|
||||
}
|
||||
|
||||
final public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return hash_equals($expected, $this->sign($payload, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
abstract public function algorithm(): string;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return positive-int
|
||||
*/
|
||||
abstract public function minimumBitsLengthForKey(): int;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
final class Sha256 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS256';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha256';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 256;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
final class Sha384 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS384';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha384';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 384;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
final class Sha512 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS512';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha512';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 512;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class InvalidKeyProvided extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function cannotBeParsed(string $details): self
|
||||
{
|
||||
return new self('It was not possible to parse your key, reason:' . $details);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $expectedType
|
||||
* @param non-empty-string $actualType
|
||||
*/
|
||||
public static function incompatibleKeyType(string $expectedType, string $actualType): self
|
||||
{
|
||||
return new self(
|
||||
'The type of the provided key is not "' . $expectedType
|
||||
. '", "' . $actualType . '" provided',
|
||||
);
|
||||
}
|
||||
|
||||
/** @param positive-int $expectedLength */
|
||||
public static function incompatibleKeyLength(int $expectedLength, int $actualLength): self
|
||||
{
|
||||
return new self(
|
||||
'The length of the provided key is different than ' . $expectedLength . ' bits, '
|
||||
. $actualLength . ' bits provided',
|
||||
);
|
||||
}
|
||||
|
||||
public static function cannotBeEmpty(): self
|
||||
{
|
||||
return new self('Key cannot be empty');
|
||||
}
|
||||
|
||||
public static function tooShort(int $expectedLength, int $actualLength): self
|
||||
{
|
||||
return new self('Key provided is shorter than ' . $expectedLength . ' bits,'
|
||||
. ' only ' . $actualLength . ' bits provided');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
interface Key
|
||||
{
|
||||
/** @return non-empty-string */
|
||||
public function contents(): string;
|
||||
|
||||
public function passphrase(): string;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Key;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
use Throwable;
|
||||
|
||||
final class FileCouldNotBeRead extends InvalidArgumentException implements Exception
|
||||
{
|
||||
/** @param non-empty-string $path */
|
||||
public static function onPath(string $path, ?Throwable $cause = null): self
|
||||
{
|
||||
return new self(
|
||||
message: 'The path "' . $path . '" does not contain a valid key file',
|
||||
previous: $cause,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Key;
|
||||
|
||||
use Lcobucci\JWT\Signer\InvalidKeyProvided;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\SodiumBase64Polyfill;
|
||||
use SplFileObject;
|
||||
use Throwable;
|
||||
|
||||
use function assert;
|
||||
use function is_string;
|
||||
|
||||
final class InMemory implements Key
|
||||
{
|
||||
/** @param non-empty-string $contents */
|
||||
private function __construct(public readonly string $contents, public readonly string $passphrase)
|
||||
{
|
||||
}
|
||||
|
||||
/** @param non-empty-string $contents */
|
||||
public static function plainText(string $contents, string $passphrase = ''): self
|
||||
{
|
||||
self::guardAgainstEmptyKey($contents);
|
||||
|
||||
return new self($contents, $passphrase);
|
||||
}
|
||||
|
||||
/** @param non-empty-string $contents */
|
||||
public static function base64Encoded(string $contents, string $passphrase = ''): self
|
||||
{
|
||||
$decoded = SodiumBase64Polyfill::base642bin(
|
||||
$contents,
|
||||
SodiumBase64Polyfill::SODIUM_BASE64_VARIANT_ORIGINAL,
|
||||
);
|
||||
|
||||
self::guardAgainstEmptyKey($decoded);
|
||||
|
||||
return new self($decoded, $passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $path
|
||||
*
|
||||
* @throws FileCouldNotBeRead
|
||||
*/
|
||||
public static function file(string $path, string $passphrase = ''): self
|
||||
{
|
||||
try {
|
||||
$file = new SplFileObject($path);
|
||||
} catch (Throwable $exception) {
|
||||
throw FileCouldNotBeRead::onPath($path, $exception);
|
||||
}
|
||||
|
||||
$fileSize = $file->getSize();
|
||||
$contents = $fileSize > 0 ? $file->fread($file->getSize()) : '';
|
||||
assert(is_string($contents));
|
||||
|
||||
self::guardAgainstEmptyKey($contents);
|
||||
|
||||
return new self($contents, $passphrase);
|
||||
}
|
||||
|
||||
/** @phpstan-assert non-empty-string $contents */
|
||||
private static function guardAgainstEmptyKey(string $contents): void
|
||||
{
|
||||
if ($contents === '') {
|
||||
throw InvalidKeyProvided::cannotBeEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public function contents(): string
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
public function passphrase(): string
|
||||
{
|
||||
return $this->passphrase;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
use OpenSSLAsymmetricKey;
|
||||
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function is_int;
|
||||
use function openssl_error_string;
|
||||
use function openssl_pkey_get_details;
|
||||
use function openssl_pkey_get_private;
|
||||
use function openssl_pkey_get_public;
|
||||
use function openssl_sign;
|
||||
use function openssl_verify;
|
||||
|
||||
use const OPENSSL_KEYTYPE_DH;
|
||||
use const OPENSSL_KEYTYPE_DSA;
|
||||
use const OPENSSL_KEYTYPE_EC;
|
||||
use const OPENSSL_KEYTYPE_RSA;
|
||||
use const PHP_EOL;
|
||||
|
||||
abstract class OpenSSL implements Signer
|
||||
{
|
||||
protected const KEY_TYPE_MAP = [
|
||||
OPENSSL_KEYTYPE_RSA => 'RSA',
|
||||
OPENSSL_KEYTYPE_DSA => 'DSA',
|
||||
OPENSSL_KEYTYPE_DH => 'DH',
|
||||
OPENSSL_KEYTYPE_EC => 'EC',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*
|
||||
* @throws CannotSignPayload
|
||||
* @throws InvalidKeyProvided
|
||||
*/
|
||||
final protected function createSignature(
|
||||
string $pem,
|
||||
string $passphrase,
|
||||
string $payload,
|
||||
): string {
|
||||
$key = $this->getPrivateKey($pem, $passphrase);
|
||||
|
||||
$signature = '';
|
||||
|
||||
if (! openssl_sign($payload, $signature, $key, $this->algorithm())) {
|
||||
throw CannotSignPayload::errorHappened($this->fullOpenSSLErrorString());
|
||||
}
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/** @throws CannotSignPayload */
|
||||
private function getPrivateKey(string $pem, string $passphrase): OpenSSLAsymmetricKey
|
||||
{
|
||||
return $this->validateKey(openssl_pkey_get_private($pem, $passphrase));
|
||||
}
|
||||
|
||||
/** @throws InvalidKeyProvided */
|
||||
final protected function verifySignature(
|
||||
string $expected,
|
||||
string $payload,
|
||||
string $pem,
|
||||
): bool {
|
||||
$key = $this->getPublicKey($pem);
|
||||
$result = openssl_verify($payload, $expected, $key, $this->algorithm());
|
||||
|
||||
return $result === 1;
|
||||
}
|
||||
|
||||
/** @throws InvalidKeyProvided */
|
||||
private function getPublicKey(string $pem): OpenSSLAsymmetricKey
|
||||
{
|
||||
return $this->validateKey(openssl_pkey_get_public($pem));
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises an exception when the key type is not the expected type
|
||||
*
|
||||
* @throws InvalidKeyProvided
|
||||
*/
|
||||
private function validateKey(OpenSSLAsymmetricKey|bool $key): OpenSSLAsymmetricKey
|
||||
{
|
||||
if (is_bool($key)) {
|
||||
throw InvalidKeyProvided::cannotBeParsed($this->fullOpenSSLErrorString());
|
||||
}
|
||||
|
||||
$details = openssl_pkey_get_details($key);
|
||||
assert(is_array($details));
|
||||
|
||||
assert(array_key_exists('bits', $details));
|
||||
assert(is_int($details['bits']));
|
||||
assert(array_key_exists('type', $details));
|
||||
assert(is_int($details['type']));
|
||||
|
||||
$this->guardAgainstIncompatibleKey($details['type'], $details['bits']);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
private function fullOpenSSLErrorString(): string
|
||||
{
|
||||
$error = '';
|
||||
|
||||
while ($msg = openssl_error_string()) {
|
||||
$error .= PHP_EOL . '* ' . $msg;
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
/** @throws InvalidKeyProvided */
|
||||
abstract protected function guardAgainstIncompatibleKey(int $type, int $lengthInBits): void;
|
||||
|
||||
/**
|
||||
* Returns which algorithm to be used to create/verify the signature (using OpenSSL constants)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function algorithm(): int;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use const OPENSSL_KEYTYPE_RSA;
|
||||
|
||||
abstract class Rsa extends OpenSSL
|
||||
{
|
||||
private const MINIMUM_KEY_LENGTH = 2048;
|
||||
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return $this->createSignature($key->contents(), $key->passphrase(), $payload);
|
||||
}
|
||||
|
||||
final public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return $this->verifySignature($expected, $payload, $key->contents());
|
||||
}
|
||||
|
||||
final protected function guardAgainstIncompatibleKey(int $type, int $lengthInBits): void
|
||||
{
|
||||
if ($type !== OPENSSL_KEYTYPE_RSA) {
|
||||
throw InvalidKeyProvided::incompatibleKeyType(
|
||||
self::KEY_TYPE_MAP[OPENSSL_KEYTYPE_RSA],
|
||||
self::KEY_TYPE_MAP[$type],
|
||||
);
|
||||
}
|
||||
|
||||
if ($lengthInBits < self::MINIMUM_KEY_LENGTH) {
|
||||
throw InvalidKeyProvided::tooShort(self::MINIMUM_KEY_LENGTH, $lengthInBits);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
final class Sha256 extends Rsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
final class Sha384 extends Rsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS384';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
final class Sha512 extends Rsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS512';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
use SodiumException;
|
||||
|
||||
use function base64_decode;
|
||||
use function base64_encode;
|
||||
use function function_exists;
|
||||
use function is_string;
|
||||
use function rtrim;
|
||||
use function sodium_base642bin;
|
||||
use function sodium_bin2base64;
|
||||
use function strtr;
|
||||
|
||||
/** @internal */
|
||||
final class SodiumBase64Polyfill
|
||||
{
|
||||
public const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
|
||||
public const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
|
||||
public const SODIUM_BASE64_VARIANT_URLSAFE = 5;
|
||||
public const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
|
||||
|
||||
/** @return ($decoded is non-empty-string ? non-empty-string : string) */
|
||||
public static function bin2base64(string $decoded, int $variant): string
|
||||
{
|
||||
if (! function_exists('sodium_bin2base64')) {
|
||||
return self::bin2base64Fallback($decoded, $variant); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return sodium_bin2base64($decoded, $variant);
|
||||
}
|
||||
|
||||
/** @return ($decoded is non-empty-string ? non-empty-string : string) */
|
||||
public static function bin2base64Fallback(string $decoded, int $variant): string
|
||||
{
|
||||
$encoded = base64_encode($decoded);
|
||||
|
||||
if (
|
||||
$variant === self::SODIUM_BASE64_VARIANT_URLSAFE
|
||||
|| $variant === self::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
|
||||
) {
|
||||
$encoded = strtr($encoded, '+/', '-_');
|
||||
}
|
||||
|
||||
if (
|
||||
$variant === self::SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING
|
||||
|| $variant === self::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
|
||||
) {
|
||||
$encoded = rtrim($encoded, '=');
|
||||
}
|
||||
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ($encoded is non-empty-string ? non-empty-string : string)
|
||||
*
|
||||
* @throws CannotDecodeContent
|
||||
*/
|
||||
public static function base642bin(string $encoded, int $variant): string
|
||||
{
|
||||
if (! function_exists('sodium_base642bin')) {
|
||||
return self::base642binFallback($encoded, $variant); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
try {
|
||||
return sodium_base642bin($encoded, $variant, '');
|
||||
} catch (SodiumException) {
|
||||
throw CannotDecodeContent::invalidBase64String();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ($encoded is non-empty-string ? non-empty-string : string)
|
||||
*
|
||||
* @throws CannotDecodeContent
|
||||
*/
|
||||
public static function base642binFallback(string $encoded, int $variant): string
|
||||
{
|
||||
if (
|
||||
$variant === self::SODIUM_BASE64_VARIANT_URLSAFE
|
||||
|| $variant === self::SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
|
||||
) {
|
||||
$encoded = strtr($encoded, '-_', '+/');
|
||||
}
|
||||
|
||||
$decoded = base64_decode($encoded, true);
|
||||
|
||||
if (! is_string($decoded)) {
|
||||
throw CannotDecodeContent::invalidBase64String();
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\Token\DataSet;
|
||||
|
||||
interface Token
|
||||
{
|
||||
/**
|
||||
* Returns the token headers
|
||||
*/
|
||||
public function headers(): DataSet;
|
||||
|
||||
/**
|
||||
* Returns if the token is allowed to be used by the audience
|
||||
*
|
||||
* @param non-empty-string $audience
|
||||
*/
|
||||
public function isPermittedFor(string $audience): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token has the given id
|
||||
*
|
||||
* @param non-empty-string $id
|
||||
*/
|
||||
public function isIdentifiedBy(string $id): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token has the given subject
|
||||
*
|
||||
* @param non-empty-string $subject
|
||||
*/
|
||||
public function isRelatedTo(string $subject): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token was issued by any of given issuers
|
||||
*
|
||||
* @param non-empty-string ...$issuers
|
||||
*/
|
||||
public function hasBeenIssuedBy(string ...$issuers): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token was issued before of given time
|
||||
*/
|
||||
public function hasBeenIssuedBefore(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token minimum time is before than given time
|
||||
*/
|
||||
public function isMinimumTimeBefore(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Returns if the token is expired
|
||||
*/
|
||||
public function isExpired(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Returns an encoded representation of the token
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function toString(): string;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\Builder as BuilderInterface;
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
use Lcobucci\JWT\Encoder;
|
||||
use Lcobucci\JWT\Encoding\CannotEncodeContent;
|
||||
use Lcobucci\JWT\Signer;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
|
||||
use function array_diff;
|
||||
use function array_merge;
|
||||
use function in_array;
|
||||
|
||||
/** @immutable */
|
||||
final class Builder implements BuilderInterface
|
||||
{
|
||||
/** @var array<non-empty-string, mixed> */
|
||||
private array $headers = ['typ' => 'JWT', 'alg' => null];
|
||||
|
||||
/** @var array<non-empty-string, mixed> */
|
||||
private array $claims = [];
|
||||
|
||||
public function __construct(private readonly Encoder $encoder, private readonly ClaimsFormatter $claimFormatter)
|
||||
{
|
||||
}
|
||||
|
||||
public function permittedFor(string ...$audiences): BuilderInterface
|
||||
{
|
||||
$configured = $this->claims[RegisteredClaims::AUDIENCE] ?? [];
|
||||
$toAppend = array_diff($audiences, $configured);
|
||||
|
||||
return $this->setClaim(RegisteredClaims::AUDIENCE, array_merge($configured, $toAppend));
|
||||
}
|
||||
|
||||
public function expiresAt(DateTimeImmutable $expiration): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::EXPIRATION_TIME, $expiration);
|
||||
}
|
||||
|
||||
public function identifiedBy(string $id): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::ID, $id);
|
||||
}
|
||||
|
||||
public function issuedAt(DateTimeImmutable $issuedAt): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::ISSUED_AT, $issuedAt);
|
||||
}
|
||||
|
||||
public function issuedBy(string $issuer): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::ISSUER, $issuer);
|
||||
}
|
||||
|
||||
public function canOnlyBeUsedAfter(DateTimeImmutable $notBefore): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::NOT_BEFORE, $notBefore);
|
||||
}
|
||||
|
||||
public function relatedTo(string $subject): BuilderInterface
|
||||
{
|
||||
return $this->setClaim(RegisteredClaims::SUBJECT, $subject);
|
||||
}
|
||||
|
||||
public function withHeader(string $name, mixed $value): BuilderInterface
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->headers[$name] = $value;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withClaim(string $name, mixed $value): BuilderInterface
|
||||
{
|
||||
if (in_array($name, RegisteredClaims::ALL, true)) {
|
||||
throw RegisteredClaimGiven::forClaim($name);
|
||||
}
|
||||
|
||||
return $this->setClaim($name, $value);
|
||||
}
|
||||
|
||||
/** @param non-empty-string $name */
|
||||
private function setClaim(string $name, mixed $value): BuilderInterface
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->claims[$name] = $value;
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<non-empty-string, mixed> $items
|
||||
*
|
||||
* @throws CannotEncodeContent When data cannot be converted to JSON.
|
||||
*/
|
||||
private function encode(array $items): string
|
||||
{
|
||||
return $this->encoder->base64UrlEncode(
|
||||
$this->encoder->jsonEncode($items),
|
||||
);
|
||||
}
|
||||
|
||||
public function getToken(Signer $signer, Key $key): UnencryptedToken
|
||||
{
|
||||
$headers = $this->headers;
|
||||
$headers['alg'] = $signer->algorithmId();
|
||||
|
||||
$encodedHeaders = $this->encode($headers);
|
||||
$encodedClaims = $this->encode($this->claimFormatter->formatClaims($this->claims));
|
||||
|
||||
$signature = $signer->sign($encodedHeaders . '.' . $encodedClaims, $key);
|
||||
$encodedSignature = $this->encoder->base64UrlEncode($signature);
|
||||
|
||||
return new Plain(
|
||||
new DataSet($headers, $encodedHeaders),
|
||||
new DataSet($this->claims, $encodedClaims),
|
||||
new Signature($signature, $encodedSignature),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class DataSet
|
||||
{
|
||||
/** @param array<non-empty-string, mixed> $data */
|
||||
public function __construct(private readonly array $data, private readonly string $encoded)
|
||||
{
|
||||
}
|
||||
|
||||
/** @param non-empty-string $name */
|
||||
public function get(string $name, mixed $default = null): mixed
|
||||
{
|
||||
return $this->data[$name] ?? $default;
|
||||
}
|
||||
|
||||
/** @param non-empty-string $name */
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->data);
|
||||
}
|
||||
|
||||
/** @return array<non-empty-string, mixed> */
|
||||
public function all(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->encoded;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class InvalidTokenStructure extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function missingOrNotEnoughSeparators(): self
|
||||
{
|
||||
return new self('The JWT string must have two dots');
|
||||
}
|
||||
|
||||
public static function missingHeaderPart(): self
|
||||
{
|
||||
return new self('The JWT string is missing the Header part');
|
||||
}
|
||||
|
||||
public static function missingClaimsPart(): self
|
||||
{
|
||||
return new self('The JWT string is missing the Claim part');
|
||||
}
|
||||
|
||||
public static function missingSignaturePart(): self
|
||||
{
|
||||
return new self('The JWT string is missing the Signature part');
|
||||
}
|
||||
|
||||
/** @param non-empty-string $part */
|
||||
public static function arrayExpected(string $part): self
|
||||
{
|
||||
return new self($part . ' must be an array with non-empty-string keys');
|
||||
}
|
||||
|
||||
public static function dateIsNotParseable(string $value): self
|
||||
{
|
||||
return new self('Value is not in the allowed date format: ' . $value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\JWT\Decoder;
|
||||
use Lcobucci\JWT\Parser as ParserInterface;
|
||||
use Lcobucci\JWT\Token as TokenInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function is_array;
|
||||
use function is_numeric;
|
||||
use function number_format;
|
||||
|
||||
final class Parser implements ParserInterface
|
||||
{
|
||||
private const MICROSECOND_PRECISION = 6;
|
||||
|
||||
public function __construct(private readonly Decoder $decoder)
|
||||
{
|
||||
}
|
||||
|
||||
public function parse(string $jwt): TokenInterface
|
||||
{
|
||||
[$encodedHeaders, $encodedClaims, $encodedSignature] = $this->splitJwt($jwt);
|
||||
|
||||
if ($encodedHeaders === '') {
|
||||
throw InvalidTokenStructure::missingHeaderPart();
|
||||
}
|
||||
|
||||
if ($encodedClaims === '') {
|
||||
throw InvalidTokenStructure::missingClaimsPart();
|
||||
}
|
||||
|
||||
if ($encodedSignature === '') {
|
||||
throw InvalidTokenStructure::missingSignaturePart();
|
||||
}
|
||||
|
||||
$header = $this->parseHeader($encodedHeaders);
|
||||
|
||||
return new Plain(
|
||||
new DataSet($header, $encodedHeaders),
|
||||
new DataSet($this->parseClaims($encodedClaims), $encodedClaims),
|
||||
$this->parseSignature($encodedSignature),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the JWT string into an array
|
||||
*
|
||||
* @param non-empty-string $jwt
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @throws InvalidTokenStructure When JWT doesn't have all parts.
|
||||
*/
|
||||
private function splitJwt(string $jwt): array
|
||||
{
|
||||
$data = explode('.', $jwt);
|
||||
|
||||
if (count($data) !== 3) {
|
||||
throw InvalidTokenStructure::missingOrNotEnoughSeparators();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the header from a string
|
||||
*
|
||||
* @param non-empty-string $data
|
||||
*
|
||||
* @return array<non-empty-string, mixed>
|
||||
*
|
||||
* @throws UnsupportedHeaderFound When an invalid header is informed.
|
||||
* @throws InvalidTokenStructure When parsed content isn't an array.
|
||||
*/
|
||||
private function parseHeader(string $data): array
|
||||
{
|
||||
$header = $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
|
||||
|
||||
if (! is_array($header)) {
|
||||
throw InvalidTokenStructure::arrayExpected('headers');
|
||||
}
|
||||
|
||||
$this->guardAgainstEmptyStringKeys($header, 'headers');
|
||||
|
||||
if (array_key_exists('enc', $header)) {
|
||||
throw UnsupportedHeaderFound::encryption();
|
||||
}
|
||||
|
||||
if (! array_key_exists('typ', $header)) {
|
||||
$header['typ'] = 'JWT';
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the claim set from a string
|
||||
*
|
||||
* @param non-empty-string $data
|
||||
*
|
||||
* @return array<non-empty-string, mixed>
|
||||
*
|
||||
* @throws InvalidTokenStructure When parsed content isn't an array or contains non-parseable dates.
|
||||
*/
|
||||
private function parseClaims(string $data): array
|
||||
{
|
||||
$claims = $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
|
||||
|
||||
if (! is_array($claims)) {
|
||||
throw InvalidTokenStructure::arrayExpected('claims');
|
||||
}
|
||||
|
||||
$this->guardAgainstEmptyStringKeys($claims, 'claims');
|
||||
|
||||
if (array_key_exists(RegisteredClaims::AUDIENCE, $claims)) {
|
||||
$claims[RegisteredClaims::AUDIENCE] = (array) $claims[RegisteredClaims::AUDIENCE];
|
||||
}
|
||||
|
||||
foreach (RegisteredClaims::DATE_CLAIMS as $claim) {
|
||||
if (! array_key_exists($claim, $claims)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$claims[$claim] = $this->convertDate($claims[$claim]);
|
||||
}
|
||||
|
||||
return $claims;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $array
|
||||
* @param non-empty-string $part
|
||||
*
|
||||
* @phpstan-assert array<non-empty-string, mixed> $array
|
||||
*/
|
||||
private function guardAgainstEmptyStringKeys(array $array, string $part): void
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
if ($key === '') {
|
||||
throw InvalidTokenStructure::arrayExpected($part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws InvalidTokenStructure */
|
||||
private function convertDate(int|float|string $timestamp): DateTimeImmutable
|
||||
{
|
||||
if (! is_numeric($timestamp)) {
|
||||
throw InvalidTokenStructure::dateIsNotParseable($timestamp);
|
||||
}
|
||||
|
||||
$normalizedTimestamp = number_format((float) $timestamp, self::MICROSECOND_PRECISION, '.', '');
|
||||
|
||||
$date = DateTimeImmutable::createFromFormat('U.u', $normalizedTimestamp);
|
||||
|
||||
if ($date === false) {
|
||||
throw InvalidTokenStructure::dateIsNotParseable($normalizedTimestamp);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature from given data
|
||||
*
|
||||
* @param non-empty-string $data
|
||||
*/
|
||||
private function parseSignature(string $data): Signature
|
||||
{
|
||||
$hash = $this->decoder->base64UrlDecode($data);
|
||||
|
||||
return new Signature($hash, $data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
|
||||
use function in_array;
|
||||
|
||||
final class Plain implements UnencryptedToken
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DataSet $headers,
|
||||
private readonly DataSet $claims,
|
||||
private readonly Signature $signature,
|
||||
) {
|
||||
}
|
||||
|
||||
public function headers(): DataSet
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function claims(): DataSet
|
||||
{
|
||||
return $this->claims;
|
||||
}
|
||||
|
||||
public function signature(): Signature
|
||||
{
|
||||
return $this->signature;
|
||||
}
|
||||
|
||||
public function payload(): string
|
||||
{
|
||||
return $this->headers->toString() . '.' . $this->claims->toString();
|
||||
}
|
||||
|
||||
public function isPermittedFor(string $audience): bool
|
||||
{
|
||||
return in_array($audience, $this->claims->get(RegisteredClaims::AUDIENCE, []), true);
|
||||
}
|
||||
|
||||
public function isIdentifiedBy(string $id): bool
|
||||
{
|
||||
return $this->claims->get(RegisteredClaims::ID) === $id;
|
||||
}
|
||||
|
||||
public function isRelatedTo(string $subject): bool
|
||||
{
|
||||
return $this->claims->get(RegisteredClaims::SUBJECT) === $subject;
|
||||
}
|
||||
|
||||
public function hasBeenIssuedBy(string ...$issuers): bool
|
||||
{
|
||||
return in_array($this->claims->get(RegisteredClaims::ISSUER), $issuers, true);
|
||||
}
|
||||
|
||||
public function hasBeenIssuedBefore(DateTimeInterface $now): bool
|
||||
{
|
||||
return $now >= $this->claims->get(RegisteredClaims::ISSUED_AT);
|
||||
}
|
||||
|
||||
public function isMinimumTimeBefore(DateTimeInterface $now): bool
|
||||
{
|
||||
return $now >= $this->claims->get(RegisteredClaims::NOT_BEFORE);
|
||||
}
|
||||
|
||||
public function isExpired(DateTimeInterface $now): bool
|
||||
{
|
||||
if (! $this->claims->has(RegisteredClaims::EXPIRATION_TIME)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $now >= $this->claims->get(RegisteredClaims::EXPIRATION_TIME);
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->headers->toString() . '.'
|
||||
. $this->claims->toString() . '.'
|
||||
. $this->signature->toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class RegisteredClaimGiven extends InvalidArgumentException implements Exception
|
||||
{
|
||||
private const DEFAULT_MESSAGE = 'Builder#withClaim() is meant to be used for non-registered claims, '
|
||||
. 'check the documentation on how to set claim "%s"';
|
||||
|
||||
/** @param non-empty-string $name */
|
||||
public static function forClaim(string $name): self
|
||||
{
|
||||
return new self(sprintf(self::DEFAULT_MESSAGE, $name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
/**
|
||||
* Defines the list of claims that are registered in the IANA "JSON Web Token Claims" registry
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1
|
||||
*/
|
||||
interface RegisteredClaims
|
||||
{
|
||||
public const ALL = [
|
||||
self::AUDIENCE,
|
||||
self::EXPIRATION_TIME,
|
||||
self::ID,
|
||||
self::ISSUED_AT,
|
||||
self::ISSUER,
|
||||
self::NOT_BEFORE,
|
||||
self::SUBJECT,
|
||||
];
|
||||
|
||||
public const DATE_CLAIMS = [
|
||||
self::ISSUED_AT,
|
||||
self::NOT_BEFORE,
|
||||
self::EXPIRATION_TIME,
|
||||
];
|
||||
|
||||
/**
|
||||
* Identifies the recipients that the JWT is intended for
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1.3
|
||||
*/
|
||||
public const AUDIENCE = 'aud';
|
||||
|
||||
/**
|
||||
* Identifies the expiration time on or after which the JWT MUST NOT be accepted for processing
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1.4
|
||||
*/
|
||||
public const EXPIRATION_TIME = 'exp';
|
||||
|
||||
/**
|
||||
* Provides a unique identifier for the JWT
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1.7
|
||||
*/
|
||||
public const ID = 'jti';
|
||||
|
||||
/**
|
||||
* Identifies the time at which the JWT was issued
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1.6
|
||||
*/
|
||||
public const ISSUED_AT = 'iat';
|
||||
|
||||
/**
|
||||
* Identifies the principal that issued the JWT
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc7519#section-4.1.1
|
||||
*/
|
||||
public const ISSUER = 'iss';
|
||||
|
||||
/**
|
||||
* Identifies the time before which the JWT MUST NOT be accepted for processing
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc7519#section-4.1.5
|
||||
*/
|
||||
public const NOT_BEFORE = 'nbf';
|
||||
|
||||
/**
|
||||
* Identifies the principal that is the subject of the JWT.
|
||||
*
|
||||
* https://tools.ietf.org/html/rfc7519#section-4.1.2
|
||||
*/
|
||||
public const SUBJECT = 'sub';
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
final class Signature
|
||||
{
|
||||
/**
|
||||
* @param non-empty-string $hash
|
||||
* @param non-empty-string $encoded
|
||||
*/
|
||||
public function __construct(private readonly string $hash, private readonly string $encoded)
|
||||
{
|
||||
}
|
||||
|
||||
/** @return non-empty-string */
|
||||
public function hash(): string
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded version of the signature
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->encoded;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class UnsupportedHeaderFound extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function encryption(): self
|
||||
{
|
||||
return new self('Encryption is not supported yet');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Token\DataSet;
|
||||
use Lcobucci\JWT\Token\Signature;
|
||||
|
||||
interface UnencryptedToken extends Token
|
||||
{
|
||||
/**
|
||||
* Returns the token claims
|
||||
*/
|
||||
public function claims(): DataSet;
|
||||
|
||||
/**
|
||||
* Returns the token signature
|
||||
*/
|
||||
public function signature(): Signature;
|
||||
|
||||
/**
|
||||
* Returns the token payload
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function payload(): string;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
|
||||
interface Constraint
|
||||
{
|
||||
/** @throws ConstraintViolation */
|
||||
public function assert(Token $token): void;
|
||||
}
|
18
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/CannotValidateARegisteredClaim.php
vendored
Normal file
18
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/CannotValidateARegisteredClaim.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class CannotValidateARegisteredClaim extends InvalidArgumentException implements Exception
|
||||
{
|
||||
/** @param non-empty-string $claim */
|
||||
public static function create(string $claim): self
|
||||
{
|
||||
return new self(
|
||||
'The claim "' . $claim . '" is a registered claim, another constraint must be used to validate its value',
|
||||
);
|
||||
}
|
||||
}
|
42
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/HasClaimWithValue.php
vendored
Normal file
42
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/HasClaimWithValue.php
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
|
||||
use function in_array;
|
||||
|
||||
final class HasClaimWithValue implements Constraint
|
||||
{
|
||||
/** @param non-empty-string $claim */
|
||||
public function __construct(private readonly string $claim, private readonly mixed $expectedValue)
|
||||
{
|
||||
if (in_array($claim, Token\RegisteredClaims::ALL, true)) {
|
||||
throw CannotValidateARegisteredClaim::create($claim);
|
||||
}
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token instanceof UnencryptedToken) {
|
||||
throw ConstraintViolation::error('You should pass a plain token', $this);
|
||||
}
|
||||
|
||||
$claims = $token->claims();
|
||||
|
||||
if (! $claims->has($this->claim)) {
|
||||
throw ConstraintViolation::error('The token does not have the claim "' . $this->claim . '"', $this);
|
||||
}
|
||||
|
||||
if ($claims->get($this->claim) !== $this->expectedValue) {
|
||||
throw ConstraintViolation::error(
|
||||
'The claim "' . $this->claim . '" does not have the expected value',
|
||||
$this,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
26
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/IdentifiedBy.php
vendored
Normal file
26
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/IdentifiedBy.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
|
||||
final class IdentifiedBy implements Constraint
|
||||
{
|
||||
/** @param non-empty-string $id */
|
||||
public function __construct(private readonly string $id)
|
||||
{
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token->isIdentifiedBy($this->id)) {
|
||||
throw ConstraintViolation::error(
|
||||
'The token is not identified with the expected ID',
|
||||
$this,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
|
||||
final class IssuedBy implements Constraint
|
||||
{
|
||||
/** @var non-empty-string[] */
|
||||
private readonly array $issuers;
|
||||
|
||||
/** @param non-empty-string ...$issuers */
|
||||
public function __construct(string ...$issuers)
|
||||
{
|
||||
$this->issuers = $issuers;
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token->hasBeenIssuedBy(...$this->issuers)) {
|
||||
throw ConstraintViolation::error(
|
||||
'The token was not issued by the given issuers',
|
||||
$this,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
15
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/LeewayCannotBeNegative.php
vendored
Normal file
15
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/LeewayCannotBeNegative.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class LeewayCannotBeNegative extends InvalidArgumentException implements Exception
|
||||
{
|
||||
public static function create(): self
|
||||
{
|
||||
return new self('Leeway cannot be negative');
|
||||
}
|
||||
}
|
67
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/LooseValidAt.php
vendored
Normal file
67
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/LooseValidAt.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\ValidAt as ValidAtInterface;
|
||||
use Psr\Clock\ClockInterface as Clock;
|
||||
|
||||
final class LooseValidAt implements ValidAtInterface
|
||||
{
|
||||
private readonly DateInterval $leeway;
|
||||
|
||||
public function __construct(private readonly Clock $clock, ?DateInterval $leeway = null)
|
||||
{
|
||||
$this->leeway = $this->guardLeeway($leeway);
|
||||
}
|
||||
|
||||
private function guardLeeway(?DateInterval $leeway): DateInterval
|
||||
{
|
||||
if ($leeway === null) {
|
||||
return new DateInterval('PT0S');
|
||||
}
|
||||
|
||||
if ($leeway->invert === 1) {
|
||||
throw LeewayCannotBeNegative::create();
|
||||
}
|
||||
|
||||
return $leeway;
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
$now = $this->clock->now();
|
||||
|
||||
$this->assertIssueTime($token, $now->add($this->leeway));
|
||||
$this->assertMinimumTime($token, $now->add($this->leeway));
|
||||
$this->assertExpiration($token, $now->sub($this->leeway));
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertExpiration(Token $token, DateTimeInterface $now): void
|
||||
{
|
||||
if ($token->isExpired($now)) {
|
||||
throw ConstraintViolation::error('The token is expired', $this);
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertMinimumTime(Token $token, DateTimeInterface $now): void
|
||||
{
|
||||
if (! $token->isMinimumTimeBefore($now)) {
|
||||
throw ConstraintViolation::error('The token cannot be used yet', $this);
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertIssueTime(Token $token, DateTimeInterface $now): void
|
||||
{
|
||||
if (! $token->hasBeenIssuedBefore($now)) {
|
||||
throw ConstraintViolation::error('The token was issued in the future', $this);
|
||||
}
|
||||
}
|
||||
}
|
26
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/PermittedFor.php
vendored
Normal file
26
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/PermittedFor.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
|
||||
final class PermittedFor implements Constraint
|
||||
{
|
||||
/** @param non-empty-string $audience */
|
||||
public function __construct(private readonly string $audience)
|
||||
{
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token->isPermittedFor($this->audience)) {
|
||||
throw ConstraintViolation::error(
|
||||
'The token is not allowed to be used by this audience',
|
||||
$this,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
|
||||
final class RelatedTo implements Constraint
|
||||
{
|
||||
/** @param non-empty-string $subject */
|
||||
public function __construct(private readonly string $subject)
|
||||
{
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token->isRelatedTo($this->subject)) {
|
||||
throw ConstraintViolation::error(
|
||||
'The token is not related to the expected subject',
|
||||
$this,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
32
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWith.php
vendored
Normal file
32
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWith.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\SignedWith as SignedWithInterface;
|
||||
|
||||
final class SignedWith implements SignedWithInterface
|
||||
{
|
||||
public function __construct(private readonly Signer $signer, private readonly Signer\Key $key)
|
||||
{
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token instanceof UnencryptedToken) {
|
||||
throw ConstraintViolation::error('You should pass a plain token', $this);
|
||||
}
|
||||
|
||||
if ($token->headers()->get('alg') !== $this->signer->algorithmId()) {
|
||||
throw ConstraintViolation::error('Token signer mismatch', $this);
|
||||
}
|
||||
|
||||
if (! $this->signer->verify($token->signature()->hash(), $token->payload(), $this->key)) {
|
||||
throw ConstraintViolation::error('Token signature mismatch', $this);
|
||||
}
|
||||
}
|
||||
}
|
38
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWithOneInSet.php
vendored
Normal file
38
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWithOneInSet.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\SignedWith as SignedWithInterface;
|
||||
|
||||
use const PHP_EOL;
|
||||
|
||||
final class SignedWithOneInSet implements SignedWithInterface
|
||||
{
|
||||
/** @var array<SignedWithUntilDate> */
|
||||
private readonly array $constraints;
|
||||
|
||||
public function __construct(SignedWithUntilDate ...$constraints)
|
||||
{
|
||||
$this->constraints = $constraints;
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
$errorMessage = 'It was not possible to verify the signature of the token, reasons:';
|
||||
|
||||
foreach ($this->constraints as $constraint) {
|
||||
try {
|
||||
$constraint->assert($token);
|
||||
|
||||
return;
|
||||
} catch (ConstraintViolation $violation) {
|
||||
$errorMessage .= PHP_EOL . '- ' . $violation->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
throw ConstraintViolation::error($errorMessage, $this);
|
||||
}
|
||||
}
|
47
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWithUntilDate.php
vendored
Normal file
47
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/SignedWithUntilDate.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\Signer;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\SignedWith as SignedWithInterface;
|
||||
use Psr\Clock\ClockInterface;
|
||||
|
||||
final class SignedWithUntilDate implements SignedWithInterface
|
||||
{
|
||||
private readonly SignedWith $verifySignature;
|
||||
private readonly ClockInterface $clock;
|
||||
|
||||
public function __construct(
|
||||
Signer $signer,
|
||||
Signer\Key $key,
|
||||
private readonly DateTimeImmutable $validUntil,
|
||||
?ClockInterface $clock = null,
|
||||
) {
|
||||
$this->verifySignature = new SignedWith($signer, $key);
|
||||
|
||||
$this->clock = $clock ?? new class () implements ClockInterface {
|
||||
public function now(): DateTimeImmutable
|
||||
{
|
||||
return new DateTimeImmutable();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if ($this->validUntil < $this->clock->now()) {
|
||||
throw ConstraintViolation::error(
|
||||
'This constraint was only usable until '
|
||||
. $this->validUntil->format(DateTimeInterface::RFC3339),
|
||||
$this,
|
||||
);
|
||||
}
|
||||
|
||||
$this->verifySignature->assert($token);
|
||||
}
|
||||
}
|
84
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/StrictValidAt.php
vendored
Normal file
84
pandora_console/vendor/lcobucci/jwt/src/Validation/Constraint/StrictValidAt.php
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\ValidAt as ValidAtInterface;
|
||||
use Psr\Clock\ClockInterface as Clock;
|
||||
|
||||
final class StrictValidAt implements ValidAtInterface
|
||||
{
|
||||
private readonly DateInterval $leeway;
|
||||
|
||||
public function __construct(private readonly Clock $clock, ?DateInterval $leeway = null)
|
||||
{
|
||||
$this->leeway = $this->guardLeeway($leeway);
|
||||
}
|
||||
|
||||
private function guardLeeway(?DateInterval $leeway): DateInterval
|
||||
{
|
||||
if ($leeway === null) {
|
||||
return new DateInterval('PT0S');
|
||||
}
|
||||
|
||||
if ($leeway->invert === 1) {
|
||||
throw LeewayCannotBeNegative::create();
|
||||
}
|
||||
|
||||
return $leeway;
|
||||
}
|
||||
|
||||
public function assert(Token $token): void
|
||||
{
|
||||
if (! $token instanceof UnencryptedToken) {
|
||||
throw ConstraintViolation::error('You should pass a plain token', $this);
|
||||
}
|
||||
|
||||
$now = $this->clock->now();
|
||||
|
||||
$this->assertIssueTime($token, $now->add($this->leeway));
|
||||
$this->assertMinimumTime($token, $now->add($this->leeway));
|
||||
$this->assertExpiration($token, $now->sub($this->leeway));
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertExpiration(UnencryptedToken $token, DateTimeInterface $now): void
|
||||
{
|
||||
if (! $token->claims()->has(Token\RegisteredClaims::EXPIRATION_TIME)) {
|
||||
throw ConstraintViolation::error('"Expiration Time" claim missing', $this);
|
||||
}
|
||||
|
||||
if ($token->isExpired($now)) {
|
||||
throw ConstraintViolation::error('The token is expired', $this);
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertMinimumTime(UnencryptedToken $token, DateTimeInterface $now): void
|
||||
{
|
||||
if (! $token->claims()->has(Token\RegisteredClaims::NOT_BEFORE)) {
|
||||
throw ConstraintViolation::error('"Not Before" claim missing', $this);
|
||||
}
|
||||
|
||||
if (! $token->isMinimumTimeBefore($now)) {
|
||||
throw ConstraintViolation::error('The token cannot be used yet', $this);
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws ConstraintViolation */
|
||||
private function assertIssueTime(UnencryptedToken $token, DateTimeInterface $now): void
|
||||
{
|
||||
if (! $token->claims()->has(Token\RegisteredClaims::ISSUED_AT)) {
|
||||
throw ConstraintViolation::error('"Issued At" claim missing', $this);
|
||||
}
|
||||
|
||||
if (! $token->hasBeenIssuedBefore($now)) {
|
||||
throw ConstraintViolation::error('The token was issued in the future', $this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
use Lcobucci\JWT\Exception;
|
||||
use RuntimeException;
|
||||
|
||||
final class ConstraintViolation extends RuntimeException implements Exception
|
||||
{
|
||||
/** @param class-string<Constraint>|null $constraint */
|
||||
public function __construct(
|
||||
string $message = '',
|
||||
public readonly ?string $constraint = null,
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
/** @param non-empty-string $message */
|
||||
public static function error(string $message, Constraint $constraint): self
|
||||
{
|
||||
return new self(message: $message, constraint: $constraint::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
use Lcobucci\JWT\Exception;
|
||||
use RuntimeException;
|
||||
|
||||
final class NoConstraintsGiven extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
48
pandora_console/vendor/lcobucci/jwt/src/Validation/RequiredConstraintsViolated.php
vendored
Normal file
48
pandora_console/vendor/lcobucci/jwt/src/Validation/RequiredConstraintsViolated.php
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
use Lcobucci\JWT\Exception;
|
||||
use RuntimeException;
|
||||
|
||||
use function array_map;
|
||||
use function implode;
|
||||
|
||||
final class RequiredConstraintsViolated extends RuntimeException implements Exception
|
||||
{
|
||||
/** @param ConstraintViolation[] $violations */
|
||||
public function __construct(
|
||||
string $message = '',
|
||||
public readonly array $violations = [],
|
||||
) {
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
public static function fromViolations(ConstraintViolation ...$violations): self
|
||||
{
|
||||
return new self(message: self::buildMessage($violations), violations: $violations);
|
||||
}
|
||||
|
||||
/** @param ConstraintViolation[] $violations */
|
||||
private static function buildMessage(array $violations): string
|
||||
{
|
||||
$violations = array_map(
|
||||
static function (ConstraintViolation $violation): string {
|
||||
return '- ' . $violation->getMessage();
|
||||
},
|
||||
$violations,
|
||||
);
|
||||
|
||||
$message = "The token violates some mandatory constraints, details:\n";
|
||||
$message .= implode("\n", $violations);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/** @return ConstraintViolation[] */
|
||||
public function violations(): array
|
||||
{
|
||||
return $this->violations;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
interface SignedWith extends Constraint
|
||||
{
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
interface ValidAt extends Constraint
|
||||
{
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation;
|
||||
|
||||
use Lcobucci\JWT\Token;
|
||||
|
||||
final class Validator implements \Lcobucci\JWT\Validator
|
||||
{
|
||||
public function assert(Token $token, Constraint ...$constraints): void
|
||||
{
|
||||
if ($constraints === []) {
|
||||
throw new NoConstraintsGiven('No constraint given.');
|
||||
}
|
||||
|
||||
$violations = [];
|
||||
|
||||
foreach ($constraints as $constraint) {
|
||||
$this->checkConstraint($constraint, $token, $violations);
|
||||
}
|
||||
|
||||
if ($violations) {
|
||||
throw RequiredConstraintsViolated::fromViolations(...$violations);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param ConstraintViolation[] $violations */
|
||||
private function checkConstraint(
|
||||
Constraint $constraint,
|
||||
Token $token,
|
||||
array &$violations,
|
||||
): void {
|
||||
try {
|
||||
$constraint->assert($token);
|
||||
} catch (ConstraintViolation $e) {
|
||||
$violations[] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function validate(Token $token, Constraint ...$constraints): bool
|
||||
{
|
||||
if ($constraints === []) {
|
||||
throw new NoConstraintsGiven('No constraint given.');
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($constraints as $constraint) {
|
||||
$constraint->assert($token);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (ConstraintViolation) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Validation\Constraint;
|
||||
use Lcobucci\JWT\Validation\NoConstraintsGiven;
|
||||
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
|
||||
|
||||
interface Validator
|
||||
{
|
||||
/**
|
||||
* @throws RequiredConstraintsViolated
|
||||
* @throws NoConstraintsGiven
|
||||
*/
|
||||
public function assert(Token $token, Constraint ...$constraints): void;
|
||||
|
||||
/** @throws NoConstraintsGiven */
|
||||
public function validate(Token $token, Constraint ...$constraints): bool;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file, in reverse chronological order by release.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
First stable release after PSR-20 acceptance
|
||||
|
||||
## 0.1.0
|
||||
|
||||
First release
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2017 PHP Framework Interoperability Group
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,61 @@
|
|||
# PSR Clock
|
||||
|
||||
This repository holds the interface for [PSR-20][psr-url].
|
||||
|
||||
Note that this is not a clock of its own. It is merely an interface that
|
||||
describes a clock. See the specification for more details.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
composer require psr/clock
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
If you need a clock, you can use the interface like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Psr\Clock\ClockInterface;
|
||||
|
||||
class Foo
|
||||
{
|
||||
private ClockInterface $clock;
|
||||
|
||||
public function __construct(ClockInterface $clock)
|
||||
{
|
||||
$this->clock = $clock;
|
||||
}
|
||||
|
||||
public function doSomething()
|
||||
{
|
||||
/** @var DateTimeImmutable $currentDateAndTime */
|
||||
$currentDateAndTime = $this->clock->now();
|
||||
// do something useful with that information
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can then pick one of the [implementations][implementation-url] of the interface to get a clock.
|
||||
|
||||
If you want to implement the interface, you can require this package and
|
||||
implement `Psr\Clock\ClockInterface` in your code.
|
||||
|
||||
Don't forget to add `psr/clock-implementation` to your `composer.json`s `provides`-section like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"provides": {
|
||||
"psr/clock-implementation": "1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And please read the [specification text][specification-url] for details on the interface.
|
||||
|
||||
[psr-url]: https://www.php-fig.org/psr/psr-20
|
||||
[package-url]: https://packagist.org/packages/psr/clock
|
||||
[implementation-url]: https://packagist.org/providers/psr/clock-implementation
|
||||
[specification-url]: https://github.com/php-fig/fig-standards/blob/master/proposed/clock.md
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "psr/clock",
|
||||
"description": "Common interface for reading the clock.",
|
||||
"keywords": ["psr", "psr-20", "time", "clock", "now"],
|
||||
"homepage": "https://github.com/php-fig/clock",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Clock\\": "src/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Psr\Clock;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
interface ClockInterface
|
||||
{
|
||||
/**
|
||||
* Returns the current time as a DateTimeImmutable Object
|
||||
*/
|
||||
public function now(): DateTimeImmutable;
|
||||
}
|
Loading…
Reference in New Issue