package and depencies
This commit is contained in:
21
vendor/lcobucci/clock/LICENSE
vendored
Normal file
21
vendor/lcobucci/clock/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Luís Cobucci
|
||||
|
||||
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.
|
48
vendor/lcobucci/clock/composer.json
vendored
Normal file
48
vendor/lcobucci/clock/composer.json
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "lcobucci/clock",
|
||||
"description": "Yet another clock abstraction",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Luís Cobucci",
|
||||
"email": "lcobucci@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "~8.1.0 || ~8.2.0",
|
||||
"psr/clock": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.26",
|
||||
"lcobucci/coding-standard": "^9.0",
|
||||
"phpstan/extension-installer": "^1.2",
|
||||
"phpstan/phpstan": "^1.9.4",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.3.2",
|
||||
"phpstan/phpstan-strict-rules": "^1.4.4",
|
||||
"phpunit/phpunit": "^9.5.27"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\Clock\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\Clock\\": "test"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"infection/extension-installer": true,
|
||||
"phpstan/extension-installer": true
|
||||
}
|
||||
},
|
||||
"provide": {
|
||||
"psr/clock-implementation": "1.0"
|
||||
}
|
||||
}
|
6
vendor/lcobucci/clock/renovate.json
vendored
Normal file
6
vendor/lcobucci/clock/renovate.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"local>lcobucci/.github:renovate-config"
|
||||
]
|
||||
}
|
12
vendor/lcobucci/clock/src/Clock.php
vendored
Normal file
12
vendor/lcobucci/clock/src/Clock.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\Clock;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Psr\Clock\ClockInterface;
|
||||
|
||||
interface Clock extends ClockInterface
|
||||
{
|
||||
public function now(): DateTimeImmutable;
|
||||
}
|
29
vendor/lcobucci/clock/src/FrozenClock.php
vendored
Normal file
29
vendor/lcobucci/clock/src/FrozenClock.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\Clock;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
|
||||
final class FrozenClock implements Clock
|
||||
{
|
||||
public function __construct(private DateTimeImmutable $now)
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromUTC(): self
|
||||
{
|
||||
return new self(new DateTimeImmutable('now', new DateTimeZone('UTC')));
|
||||
}
|
||||
|
||||
public function setTo(DateTimeImmutable $now): void
|
||||
{
|
||||
$this->now = $now;
|
||||
}
|
||||
|
||||
public function now(): DateTimeImmutable
|
||||
{
|
||||
return $this->now;
|
||||
}
|
||||
}
|
31
vendor/lcobucci/clock/src/SystemClock.php
vendored
Normal file
31
vendor/lcobucci/clock/src/SystemClock.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\Clock;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
|
||||
use function date_default_timezone_get;
|
||||
|
||||
final class SystemClock implements Clock
|
||||
{
|
||||
public function __construct(private readonly DateTimeZone $timezone)
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromUTC(): self
|
||||
{
|
||||
return new self(new DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
public static function fromSystemTimezone(): self
|
||||
{
|
||||
return new self(new DateTimeZone(date_default_timezone_get()));
|
||||
}
|
||||
|
||||
public function now(): DateTimeImmutable
|
||||
{
|
||||
return new DateTimeImmutable('now', $this->timezone);
|
||||
}
|
||||
}
|
3
vendor/lcobucci/jwt/.gitignore
vendored
3
vendor/lcobucci/jwt/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
/vendor
|
||||
/phpunit.xml
|
||||
/composer.lock
|
56
vendor/lcobucci/jwt/.scrutinizer.yml
vendored
56
vendor/lcobucci/jwt/.scrutinizer.yml
vendored
@@ -1,56 +0,0 @@
|
||||
build:
|
||||
environment:
|
||||
mysql: false
|
||||
postgresql: false
|
||||
redis: false
|
||||
rabbitmq: false
|
||||
php:
|
||||
version: 5.6
|
||||
tools:
|
||||
php_sim: true
|
||||
php_pdepend: true
|
||||
php_analyzer: true
|
||||
php_changetracking: true
|
||||
php_code_sniffer:
|
||||
config:
|
||||
standard: "PSR2"
|
||||
php_mess_detector: true
|
||||
checks:
|
||||
php:
|
||||
code_rating: true
|
||||
duplication: true
|
||||
argument_type_checks: true
|
||||
assignment_of_null_return: true
|
||||
avoid_conflicting_incrementers: true
|
||||
avoid_useless_overridden_methods: true
|
||||
catch_class_exists: true
|
||||
closure_use_modifiable: true
|
||||
closure_use_not_conflicting: true
|
||||
deprecated_code_usage: true
|
||||
method_calls_on_non_object: true
|
||||
missing_arguments: true
|
||||
no_duplicate_arguments: true
|
||||
no_non_implemented_abstract_methods: true
|
||||
no_property_on_interface: true
|
||||
parameter_non_unique: true
|
||||
precedence_in_conditions: true
|
||||
precedence_mistakes: true
|
||||
require_php_tag_first: true
|
||||
security_vulnerabilities: true
|
||||
sql_injection_vulnerabilities: true
|
||||
too_many_arguments: true
|
||||
unreachable_code: true
|
||||
unused_methods: true
|
||||
unused_parameters: true
|
||||
unused_properties: true
|
||||
unused_variables: true
|
||||
use_statement_alias_conflict: true
|
||||
useless_calls: true
|
||||
variable_existence: true
|
||||
verify_access_scope_valid: true
|
||||
verify_argument_usable_as_reference: true
|
||||
verify_property_names: true
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- test/*
|
15
vendor/lcobucci/jwt/.travis.yml
vendored
15
vendor/lcobucci/jwt/.travis.yml
vendored
@@ -1,15 +0,0 @@
|
||||
language: php
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- nightly
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
before_script:
|
||||
- composer install --prefer-dist -o
|
2
vendor/lcobucci/jwt/LICENSE
vendored
2
vendor/lcobucci/jwt/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014-2015, Luís Otávio Cobucci Oblonczyk
|
||||
Copyright (c) 2014, Luís Cobucci
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
194
vendor/lcobucci/jwt/README.md
vendored
194
vendor/lcobucci/jwt/README.md
vendored
@@ -1,194 +0,0 @@
|
||||
# JWT
|
||||
[](https://gitter.im/lcobucci/jwt?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://packagist.org/packages/lcobucci/jwt) [](https://packagist.org/packages/lcobucci/jwt)
|
||||
|
||||

|
||||
[](http://travis-ci.org/#!/lcobucci/jwt)
|
||||
[](https://scrutinizer-ci.com/g/lcobucci/jwt/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/lcobucci/jwt/?branch=master)
|
||||
|
||||
A simple library to work with JSON Web Token and JSON Web Signature (requires PHP 5.6+).
|
||||
The implementation is based on the [RFC 7519](https://tools.ietf.org/html/rfc7519).
|
||||
|
||||
## Installation
|
||||
|
||||
Package is available on [Packagist](http://packagist.org/packages/lcobucci/jwt),
|
||||
you can install it using [Composer](http://getcomposer.org).
|
||||
|
||||
```shell
|
||||
composer require lcobucci/jwt
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
- PHP 5.6+
|
||||
- OpenSSL Extension
|
||||
|
||||
## Basic usage
|
||||
|
||||
### Creating
|
||||
|
||||
Just use the builder to create a new JWT/JWS tokens:
|
||||
|
||||
```php
|
||||
use Lcobucci\JWT\Builder;
|
||||
|
||||
$time = time();
|
||||
$token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim)
|
||||
->permittedFor('http://example.org') // Configures the audience (aud claim)
|
||||
->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
|
||||
->issuedAt($time) // Configures the time that the token was issue (iat claim)
|
||||
->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim)
|
||||
->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
|
||||
->withClaim('uid', 1) // Configures a new claim, called "uid"
|
||||
->getToken(); // Retrieves the generated token
|
||||
|
||||
|
||||
$token->getHeaders(); // Retrieves the token headers
|
||||
$token->getClaims(); // Retrieves the token claims
|
||||
|
||||
echo $token->getHeader('jti'); // will print "4f1g23a12aa"
|
||||
echo $token->getClaim('iss'); // will print "http://example.com"
|
||||
echo $token->getClaim('uid'); // will print "1"
|
||||
echo $token; // The string representation of the object is a JWT string (pretty easy, right?)
|
||||
```
|
||||
|
||||
### Parsing from strings
|
||||
|
||||
Use the parser to create a new token from a JWT string (using the previous token as example):
|
||||
|
||||
```php
|
||||
use Lcobucci\JWT\Parser;
|
||||
|
||||
$token = (new Parser())->parse((string) $token); // Parses from a string
|
||||
$token->getHeaders(); // Retrieves the token header
|
||||
$token->getClaims(); // Retrieves the token claims
|
||||
|
||||
echo $token->getHeader('jti'); // will print "4f1g23a12aa"
|
||||
echo $token->getClaim('iss'); // will print "http://example.com"
|
||||
echo $token->getClaim('uid'); // will print "1"
|
||||
```
|
||||
|
||||
### Validating
|
||||
|
||||
We can easily validate if the token is valid (using the previous token and time as example):
|
||||
|
||||
```php
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
|
||||
$data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
|
||||
$data->setIssuer('http://example.com');
|
||||
$data->setAudience('http://example.org');
|
||||
$data->setId('4f1g23a12aa');
|
||||
|
||||
var_dump($token->validate($data)); // false, because token cannot be used before now() + 60
|
||||
|
||||
$data->setCurrentTime($time + 61); // changing the validation time to future
|
||||
|
||||
var_dump($token->validate($data)); // true, because current time is between "nbf" and "exp" claims
|
||||
|
||||
$data->setCurrentTime($time + 4000); // changing the validation time to future
|
||||
|
||||
var_dump($token->validate($data)); // false, because token is expired since current time is greater than exp
|
||||
|
||||
// We can also use the $leeway parameter to deal with clock skew (see notes below)
|
||||
// If token's claimed time is invalid but the difference between that and the validation time is less than $leeway,
|
||||
// then token is still considered valid
|
||||
$dataWithLeeway = new ValidationData($time, 20);
|
||||
$dataWithLeeway->setIssuer('http://example.com');
|
||||
$dataWithLeeway->setAudience('http://example.org');
|
||||
$dataWithLeeway->setId('4f1g23a12aa');
|
||||
|
||||
var_dump($token->validate($dataWithLeeway)); // false, because token can't be used before now() + 60, not within leeway
|
||||
|
||||
$dataWithLeeway->setCurrentTime($time + 51); // changing the validation time to future
|
||||
|
||||
var_dump($token->validate($dataWithLeeway)); // true, because current time plus leeway is between "nbf" and "exp" claims
|
||||
|
||||
$dataWithLeeway->setCurrentTime($time + 3610); // changing the validation time to future but within leeway
|
||||
|
||||
var_dump($token->validate($dataWithLeeway)); // true, because current time - 20 seconds leeway is less than exp
|
||||
|
||||
$dataWithLeeway->setCurrentTime($time + 4000); // changing the validation time to future outside of leeway
|
||||
|
||||
var_dump($token->validate($dataWithLeeway)); // false, because token is expired since current time is greater than exp
|
||||
```
|
||||
|
||||
#### Important
|
||||
|
||||
- You have to configure ```ValidationData``` informing all claims you want to validate the token.
|
||||
- If ```ValidationData``` contains claims that are not being used in token or token has claims that are not
|
||||
configured in ```ValidationData``` they will be ignored by ```Token::validate()```.
|
||||
- ```exp```, ```nbf``` and ```iat``` claims are configured by default in ```ValidationData::__construct()```
|
||||
with the current UNIX time (```time()```).
|
||||
- The optional ```$leeway``` parameter of ```ValidationData``` will cause us to use that number of seconds of leeway
|
||||
when validating the time-based claims, pretending we are further in the future for the "Issued At" (```iat```) and "Not
|
||||
Before" (```nbf```) claims and pretending we are further in the past for the "Expiration Time" (```exp```) claim. This
|
||||
allows for situations where the clock of the issuing server has a different time than the clock of the verifying server,
|
||||
as mentioned in [section 4.1 of RFC 7519](https://tools.ietf.org/html/rfc7519#section-4.1).
|
||||
|
||||
## Token signature
|
||||
|
||||
We can use signatures to be able to verify if the token was not modified after its generation. This library implements Hmac, RSA and ECDSA signatures (using 256, 384 and 512).
|
||||
|
||||
### Important
|
||||
|
||||
Do not allow the string sent to the Parser to dictate which signature algorithm
|
||||
to use, or else your application will be vulnerable to a [critical JWT security vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries).
|
||||
|
||||
The examples below are safe because the choice in `Signer` is hard-coded and
|
||||
cannot be influenced by malicious users.
|
||||
|
||||
### Hmac
|
||||
|
||||
Hmac signatures are really simple to be used:
|
||||
|
||||
```php
|
||||
use Lcobucci\JWT\Builder;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\Signer\Hmac\Sha256;
|
||||
|
||||
$signer = new Sha256();
|
||||
$time = time();
|
||||
|
||||
$token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim)
|
||||
->permittedFor('http://example.org') // Configures the audience (aud claim)
|
||||
->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
|
||||
->issuedAt($time) // Configures the time that the token was issue (iat claim)
|
||||
->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim)
|
||||
->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
|
||||
->withClaim('uid', 1) // Configures a new claim, called "uid"
|
||||
->getToken($signer, new Key('testing')); // Retrieves the generated token
|
||||
|
||||
|
||||
var_dump($token->verify($signer, 'testing 1')); // false, because the key is different
|
||||
var_dump($token->verify($signer, 'testing')); // true, because the key is the same
|
||||
```
|
||||
|
||||
### RSA and ECDSA
|
||||
|
||||
RSA and ECDSA signatures are based on public and private keys so you have to generate using the private key and verify using the public key:
|
||||
|
||||
```php
|
||||
use Lcobucci\JWT\Builder;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys
|
||||
|
||||
$signer = new Sha256();
|
||||
$privateKey = new Key('file://{path to your private key}');
|
||||
$time = time();
|
||||
|
||||
$token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim)
|
||||
->permittedFor('http://example.org') // Configures the audience (aud claim)
|
||||
->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
|
||||
->issuedAt($time) // Configures the time that the token was issue (iat claim)
|
||||
->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim)
|
||||
->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim)
|
||||
->withClaim('uid', 1) // Configures a new claim, called "uid"
|
||||
->getToken($signer, $privateKey); // Retrieves the generated token
|
||||
|
||||
$publicKey = new Key('file://{path to your public key}');
|
||||
|
||||
var_dump($token->verify($signer, $publicKey)); // true when the public key was generated by the private one =)
|
||||
```
|
||||
|
||||
**It's important to say that if you're using RSA keys you shouldn't invoke ECDSA signers (and vice-versa), otherwise ```sign()``` and ```verify()``` will raise an exception!**
|
61
vendor/lcobucci/jwt/composer.json
vendored
61
vendor/lcobucci/jwt/composer.json
vendored
@@ -1,32 +1,42 @@
|
||||
{
|
||||
"name": "lcobucci/jwt",
|
||||
"description": "A simple library to work with JSON Web Token and JSON Web Signature",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Luís Otávio Cobucci Oblonczyk",
|
||||
"email": "lcobucci@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"JWT",
|
||||
"JWS"
|
||||
],
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
"authors": [
|
||||
{
|
||||
"name": "Luís Cobucci",
|
||||
"email": "lcobucci@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*"
|
||||
"ext-openssl": "*",
|
||||
"ext-sodium": "*",
|
||||
"lcobucci/clock": "^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7 || ^7.3",
|
||||
"squizlabs/php_codesniffer": "~2.3",
|
||||
"phpmd/phpmd": "~2.2",
|
||||
"phpunit/php-invoker": "~1.1",
|
||||
"mikey179/vfsstream": "~1.5"
|
||||
"infection/infection": "^0.21",
|
||||
"lcobucci/coding-standard": "^6.0",
|
||||
"mikey179/vfsstream": "^1.6.7",
|
||||
"phpbench/phpbench": "^1.2",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/php-invoker": "^3.1",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -36,14 +46,21 @@
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Lcobucci\\JWT\\": [
|
||||
"test/_keys",
|
||||
"test/unit",
|
||||
"test/functional"
|
||||
]
|
||||
"test/performance"
|
||||
],
|
||||
"Lcobucci\\JWT\\FunctionalTests\\": "test/functional"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1-dev"
|
||||
}
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"phpstan/extension-installer": true,
|
||||
"infection/extension-installer": true,
|
||||
"ocramius/package-versions": true
|
||||
},
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
27
vendor/lcobucci/jwt/phpunit.xml.dist
vendored
27
vendor/lcobucci/jwt/phpunit.xml.dist
vendored
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
beStrictAboutTodoAnnotatedTests="true"
|
||||
beStrictAboutChangesToGlobalState="true"
|
||||
beStrictAboutCoversAnnotation="true"
|
||||
beStrictAboutResourceUsageDuringSmallTests="true"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
forceCoversAnnotation="true">
|
||||
<testsuites>
|
||||
<testsuite name="Unit Test Suite">
|
||||
<directory>test/unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Integration Test Suite">
|
||||
<directory>test/functional</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
447
vendor/lcobucci/jwt/src/Builder.php
vendored
447
vendor/lcobucci/jwt/src/Builder.php
vendored
@@ -1,472 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Claim\Factory as ClaimFactory;
|
||||
use Lcobucci\JWT\Parsing\Encoder;
|
||||
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 function implode;
|
||||
use Lcobucci\JWT\Token\Plain;
|
||||
use Lcobucci\JWT\Token\RegisteredClaimGiven;
|
||||
|
||||
/**
|
||||
* This class makes easier the token creation process
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Builder
|
||||
interface Builder
|
||||
{
|
||||
/**
|
||||
* The token header
|
||||
*
|
||||
* @var array
|
||||
* Appends new items to audience
|
||||
*/
|
||||
private $headers = ['typ'=> 'JWT', 'alg' => 'none'];
|
||||
|
||||
/**
|
||||
* The token claim set
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $claims = [];
|
||||
|
||||
/**
|
||||
* The data encoder
|
||||
*
|
||||
* @var Encoder
|
||||
*/
|
||||
private $encoder;
|
||||
|
||||
/**
|
||||
* The factory of claims
|
||||
*
|
||||
* @var ClaimFactory
|
||||
*/
|
||||
private $claimFactory;
|
||||
|
||||
/**
|
||||
* @var Signer|null
|
||||
*/
|
||||
private $signer;
|
||||
|
||||
/**
|
||||
* @var Key|null
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* Initializes a new builder
|
||||
*
|
||||
* @param Encoder $encoder
|
||||
* @param ClaimFactory $claimFactory
|
||||
*/
|
||||
public function __construct(
|
||||
Encoder $encoder = null,
|
||||
ClaimFactory $claimFactory = null
|
||||
) {
|
||||
$this->encoder = $encoder ?: new Encoder();
|
||||
$this->claimFactory = $claimFactory ?: new ClaimFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the audience
|
||||
*
|
||||
* @deprecated This method has been wrongly added and doesn't exist on v4
|
||||
* @see Builder::permittedFor()
|
||||
*
|
||||
* @param string $audience
|
||||
* @param bool $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function canOnlyBeUsedBy($audience, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('aud', (string) $audience, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the audience
|
||||
*
|
||||
* @param string $audience
|
||||
* @param bool $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function permittedFor($audience, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('aud', (string) $audience, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the audience
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::permittedFor()
|
||||
*
|
||||
* @param string $audience
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setAudience($audience, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('aud', (string) $audience, $replicateAsHeader);
|
||||
}
|
||||
public function permittedFor(string ...$audiences): Builder;
|
||||
|
||||
/**
|
||||
* Configures the expiration time
|
||||
*
|
||||
* @param int $expiration
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function expiresAt($expiration, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('exp', (int) $expiration, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the expiration time
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::expiresAt()
|
||||
*
|
||||
* @param int $expiration
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setExpiration($expiration, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('exp', (int) $expiration, $replicateAsHeader);
|
||||
}
|
||||
public function expiresAt(DateTimeImmutable $expiration): Builder;
|
||||
|
||||
/**
|
||||
* Configures the token id
|
||||
*
|
||||
* @param string $id
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function identifiedBy($id, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('jti', (string) $id, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the token id
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::identifiedBy()
|
||||
*
|
||||
* @param string $id
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setId($id, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->identifiedBy($id, $replicateAsHeader);
|
||||
}
|
||||
public function identifiedBy(string $id): Builder;
|
||||
|
||||
/**
|
||||
* Configures the time that the token was issued
|
||||
*
|
||||
* @param int $issuedAt
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function issuedAt($issuedAt, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('iat', (int) $issuedAt, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the time that the token was issued
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::issuedAt()
|
||||
*
|
||||
* @param int $issuedAt
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setIssuedAt($issuedAt, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->issuedAt($issuedAt, $replicateAsHeader);
|
||||
}
|
||||
public function issuedAt(DateTimeImmutable $issuedAt): Builder;
|
||||
|
||||
/**
|
||||
* Configures the issuer
|
||||
*
|
||||
* @param string $issuer
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function issuedBy($issuer, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('iss', (string) $issuer, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the issuer
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::issuedBy()
|
||||
*
|
||||
* @param string $issuer
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setIssuer($issuer, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->issuedBy($issuer, $replicateAsHeader);
|
||||
}
|
||||
public function issuedBy(string $issuer): Builder;
|
||||
|
||||
/**
|
||||
* Configures the time before which the token cannot be accepted
|
||||
*
|
||||
* @param int $notBefore
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function canOnlyBeUsedAfter($notBefore, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('nbf', (int) $notBefore, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the time before which the token cannot be accepted
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::canOnlyBeUsedAfter()
|
||||
*
|
||||
* @param int $notBefore
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setNotBefore($notBefore, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->canOnlyBeUsedAfter($notBefore, $replicateAsHeader);
|
||||
}
|
||||
public function canOnlyBeUsedAfter(DateTimeImmutable $notBefore): Builder;
|
||||
|
||||
/**
|
||||
* Configures the subject
|
||||
*
|
||||
* @param string $subject
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function relatedTo($subject, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->setRegisteredClaim('sub', (string) $subject, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the subject
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::relatedTo()
|
||||
*
|
||||
* @param string $subject
|
||||
* @param boolean $replicateAsHeader
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setSubject($subject, $replicateAsHeader = false)
|
||||
{
|
||||
return $this->relatedTo($subject, $replicateAsHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a registered claim
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @param boolean $replicate
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function setRegisteredClaim($name, $value, $replicate)
|
||||
{
|
||||
$this->withClaim($name, $value);
|
||||
|
||||
if ($replicate) {
|
||||
$this->headers[$name] = $this->claims[$name];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
public function relatedTo(string $subject): Builder;
|
||||
|
||||
/**
|
||||
* Configures a header item
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function withHeader($name, $value)
|
||||
{
|
||||
$this->headers[(string) $name] = $this->claimFactory->create($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a header item
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::withHeader()
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function setHeader($name, $value)
|
||||
{
|
||||
return $this->withHeader($name, $value);
|
||||
}
|
||||
public function withHeader(string $name, $value): Builder;
|
||||
|
||||
/**
|
||||
* Configures a claim item
|
||||
*
|
||||
* @deprecated This method has been wrongly added and doesn't exist on v4
|
||||
* @see Builder::withClaim()
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Builder
|
||||
* @throws RegisteredClaimGiven When trying to set a registered claim.
|
||||
*/
|
||||
public function with($name, $value)
|
||||
{
|
||||
return $this->withClaim($name, $value);
|
||||
}
|
||||
public function withClaim(string $name, $value): Builder;
|
||||
|
||||
/**
|
||||
* Configures a claim item
|
||||
* Returns a signed token to be used
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Builder
|
||||
* @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 withClaim($name, $value)
|
||||
{
|
||||
$this->claims[(string) $name] = $this->claimFactory->create($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a claim item
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::withClaim()
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
return $this->withClaim($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs the data
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::getToken()
|
||||
*
|
||||
* @param Signer $signer
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function sign(Signer $signer, $key)
|
||||
{
|
||||
if (! $key instanceof Key) {
|
||||
$key = new Key($key);
|
||||
}
|
||||
|
||||
$this->signer = $signer;
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the signature from the builder
|
||||
*
|
||||
* @deprecated This method will be removed on v4
|
||||
* @see Builder::getToken()
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function unsign()
|
||||
{
|
||||
$this->signer = null;
|
||||
$this->key = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resultant token
|
||||
*
|
||||
* @return Token
|
||||
*/
|
||||
public function getToken(Signer $signer = null, Key $key = null)
|
||||
{
|
||||
$signer = $signer ?: $this->signer;
|
||||
$key = $key ?: $this->key;
|
||||
|
||||
if ($signer instanceof Signer) {
|
||||
$signer->modifyHeader($this->headers);
|
||||
}
|
||||
|
||||
$payload = [
|
||||
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)),
|
||||
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims))
|
||||
];
|
||||
|
||||
$signature = $this->createSignature($payload, $signer, $key);
|
||||
|
||||
if ($signature !== null) {
|
||||
$payload[] = $this->encoder->base64UrlEncode($signature);
|
||||
}
|
||||
|
||||
return new Token($this->headers, $this->claims, $signature, $payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $payload
|
||||
*
|
||||
* @return Signature|null
|
||||
*/
|
||||
private function createSignature(array $payload, Signer $signer = null, Key $key = null)
|
||||
{
|
||||
if ($signer === null || $key === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $signer->sign(implode('.', $payload), $key);
|
||||
}
|
||||
public function getToken(Signer $signer, Key $key): Plain;
|
||||
}
|
||||
|
40
vendor/lcobucci/jwt/src/Claim.php
vendored
40
vendor/lcobucci/jwt/src/Claim.php
vendored
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* Basic interface for token claims
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
interface Claim extends JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Returns the claim name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Returns the claim value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue();
|
||||
|
||||
/**
|
||||
* Returns the string representation of the claim
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
}
|
75
vendor/lcobucci/jwt/src/Claim/Basic.php
vendored
75
vendor/lcobucci/jwt/src/Claim/Basic.php
vendored
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\Claim;
|
||||
|
||||
/**
|
||||
* The default claim
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Basic implements Claim
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Initializes the claim
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct($name, $value)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->value;
|
||||
}
|
||||
}
|
34
vendor/lcobucci/jwt/src/Claim/EqualsTo.php
vendored
34
vendor/lcobucci/jwt/src/Claim/EqualsTo.php
vendored
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\Claim;
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
|
||||
/**
|
||||
* Validatable claim that checks if value is strictly equals to the given data
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class EqualsTo extends Basic implements Claim, Validatable
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(ValidationData $data)
|
||||
{
|
||||
if ($data->has($this->getName())) {
|
||||
return $this->getValue() === $data->get($this->getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
118
vendor/lcobucci/jwt/src/Claim/Factory.php
vendored
118
vendor/lcobucci/jwt/src/Claim/Factory.php
vendored
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\Claim;
|
||||
|
||||
/**
|
||||
* Class that create claims
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Factory
|
||||
{
|
||||
/**
|
||||
* The list of claim callbacks
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $callbacks;
|
||||
|
||||
/**
|
||||
* Initializes the factory, registering the default callbacks
|
||||
*
|
||||
* @param array $callbacks
|
||||
*/
|
||||
public function __construct(array $callbacks = [])
|
||||
{
|
||||
$this->callbacks = array_merge(
|
||||
[
|
||||
'iat' => [$this, 'createLesserOrEqualsTo'],
|
||||
'nbf' => [$this, 'createLesserOrEqualsTo'],
|
||||
'exp' => [$this, 'createGreaterOrEqualsTo'],
|
||||
'iss' => [$this, 'createEqualsTo'],
|
||||
'aud' => [$this, 'createEqualsTo'],
|
||||
'sub' => [$this, 'createEqualsTo'],
|
||||
'jti' => [$this, 'createEqualsTo']
|
||||
],
|
||||
$callbacks
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new claim
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Claim
|
||||
*/
|
||||
public function create($name, $value)
|
||||
{
|
||||
if (!empty($this->callbacks[$name])) {
|
||||
return call_user_func($this->callbacks[$name], $name, $value);
|
||||
}
|
||||
|
||||
return $this->createBasic($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a claim that can be compared (greator or equals)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return GreaterOrEqualsTo
|
||||
*/
|
||||
private function createGreaterOrEqualsTo($name, $value)
|
||||
{
|
||||
return new GreaterOrEqualsTo($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a claim that can be compared (greator or equals)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return LesserOrEqualsTo
|
||||
*/
|
||||
private function createLesserOrEqualsTo($name, $value)
|
||||
{
|
||||
return new LesserOrEqualsTo($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a claim that can be compared (equals)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return EqualsTo
|
||||
*/
|
||||
private function createEqualsTo($name, $value)
|
||||
{
|
||||
return new EqualsTo($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a basic claim
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Basic
|
||||
*/
|
||||
private function createBasic($name, $value)
|
||||
{
|
||||
return new Basic($name, $value);
|
||||
}
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\Claim;
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
|
||||
/**
|
||||
* Validatable claim that checks if value is greater or equals the given data
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class GreaterOrEqualsTo extends Basic implements Claim, Validatable
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(ValidationData $data)
|
||||
{
|
||||
if ($data->has($this->getName())) {
|
||||
return $this->getValue() >= $data->get($this->getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\Claim;
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
|
||||
/**
|
||||
* Validatable claim that checks if value is lesser or equals to the given data
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class LesserOrEqualsTo extends Basic implements Claim, Validatable
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(ValidationData $data)
|
||||
{
|
||||
if ($data->has($this->getName())) {
|
||||
return $this->getValue() <= $data->get($this->getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
30
vendor/lcobucci/jwt/src/Claim/Validatable.php
vendored
30
vendor/lcobucci/jwt/src/Claim/Validatable.php
vendored
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Claim;
|
||||
|
||||
use Lcobucci\JWT\ValidationData;
|
||||
|
||||
/**
|
||||
* Basic interface for validatable token claims
|
||||
*
|
||||
* @deprecated This interface will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
interface Validatable
|
||||
{
|
||||
/**
|
||||
* Returns if claim is valid according with given data
|
||||
*
|
||||
* @param ValidationData $data
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate(ValidationData $data);
|
||||
}
|
14
vendor/lcobucci/jwt/src/ClaimsFormatter.php
vendored
Normal file
14
vendor/lcobucci/jwt/src/ClaimsFormatter.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
interface ClaimsFormatter
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $claims
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function formatClaims(array $claims): array;
|
||||
}
|
155
vendor/lcobucci/jwt/src/Configuration.php
vendored
Normal file
155
vendor/lcobucci/jwt/src/Configuration.php
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
<?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\Signer\Key\InMemory;
|
||||
use Lcobucci\JWT\Signer\None;
|
||||
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 Signer $signer;
|
||||
private Key $signingKey;
|
||||
private Key $verificationKey;
|
||||
private Validator $validator;
|
||||
|
||||
/** @var Closure(ClaimsFormatter $claimFormatter): Builder */
|
||||
private Closure $builderFactory;
|
||||
|
||||
/** @var Constraint[] */
|
||||
private array $validationConstraints = [];
|
||||
|
||||
private function __construct(
|
||||
Signer $signer,
|
||||
Key $signingKey,
|
||||
Key $verificationKey,
|
||||
?Encoder $encoder = null,
|
||||
?Decoder $decoder = null
|
||||
) {
|
||||
$this->signer = $signer;
|
||||
$this->signingKey = $signingKey;
|
||||
$this->verificationKey = $verificationKey;
|
||||
$this->parser = new Token\Parser($decoder ?? new JoseEncoder());
|
||||
$this->validator = new Validation\Validator();
|
||||
|
||||
$this->builderFactory = static function (ClaimsFormatter $claimFormatter) use ($encoder): Builder {
|
||||
return new Token\Builder($encoder ?? new JoseEncoder(), $claimFormatter);
|
||||
};
|
||||
}
|
||||
|
||||
public static function forAsymmetricSigner(
|
||||
Signer $signer,
|
||||
Key $signingKey,
|
||||
Key $verificationKey,
|
||||
?Encoder $encoder = null,
|
||||
?Decoder $decoder = null
|
||||
): self {
|
||||
return new self(
|
||||
$signer,
|
||||
$signingKey,
|
||||
$verificationKey,
|
||||
$encoder,
|
||||
$decoder
|
||||
);
|
||||
}
|
||||
|
||||
public static function forSymmetricSigner(
|
||||
Signer $signer,
|
||||
Key $key,
|
||||
?Encoder $encoder = null,
|
||||
?Decoder $decoder = null
|
||||
): self {
|
||||
return new self(
|
||||
$signer,
|
||||
$key,
|
||||
$key,
|
||||
$encoder,
|
||||
$decoder
|
||||
);
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated since v4.3 */
|
||||
public static function forUnsecuredSigner(
|
||||
?Encoder $encoder = null,
|
||||
?Decoder $decoder = null
|
||||
): self {
|
||||
$key = InMemory::empty();
|
||||
|
||||
return new self(
|
||||
new None(),
|
||||
$key,
|
||||
$key,
|
||||
$encoder,
|
||||
$decoder
|
||||
);
|
||||
}
|
||||
|
||||
/** @param callable(ClaimsFormatter): Builder $builderFactory */
|
||||
public function setBuilderFactory(callable $builderFactory): void
|
||||
{
|
||||
$this->builderFactory = Closure::fromCallable($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;
|
||||
}
|
||||
}
|
27
vendor/lcobucci/jwt/src/Decoder.php
vendored
Normal file
27
vendor/lcobucci/jwt/src/Decoder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
|
||||
interface Decoder
|
||||
{
|
||||
/**
|
||||
* Decodes from JSON, validating the errors
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws CannotDecodeContent When something goes wrong while decoding.
|
||||
*/
|
||||
public function jsonDecode(string $json);
|
||||
|
||||
/**
|
||||
* Decodes from Base64URL
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*
|
||||
* @throws CannotDecodeContent When something goes wrong while decoding.
|
||||
*/
|
||||
public function base64UrlDecode(string $data): string;
|
||||
}
|
25
vendor/lcobucci/jwt/src/Encoder.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Encoder.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Encoding\CannotEncodeContent;
|
||||
|
||||
interface Encoder
|
||||
{
|
||||
/**
|
||||
* Encodes to JSON, validating the errors
|
||||
*
|
||||
* @param mixed $data
|
||||
*
|
||||
* @throws CannotEncodeContent When something goes wrong while encoding.
|
||||
*/
|
||||
public function jsonEncode($data): string;
|
||||
|
||||
/**
|
||||
* Encodes to base64url
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*/
|
||||
public function base64UrlEncode(string $data): string;
|
||||
}
|
21
vendor/lcobucci/jwt/src/Encoding/CannotDecodeContent.php
vendored
Normal file
21
vendor/lcobucci/jwt/src/Encoding/CannotDecodeContent.php
vendored
Normal file
@@ -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('Error while decoding from JSON', 0, $previous);
|
||||
}
|
||||
|
||||
public static function invalidBase64String(): self
|
||||
{
|
||||
return new self('Error while decoding from Base64Url, invalid base64 characters detected');
|
||||
}
|
||||
}
|
16
vendor/lcobucci/jwt/src/Encoding/CannotEncodeContent.php
vendored
Normal file
16
vendor/lcobucci/jwt/src/Encoding/CannotEncodeContent.php
vendored
Normal file
@@ -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('Error while encoding to JSON', 0, $previous);
|
||||
}
|
||||
}
|
37
vendor/lcobucci/jwt/src/Encoding/ChainedFormatter.php
vendored
Normal file
37
vendor/lcobucci/jwt/src/Encoding/ChainedFormatter.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Encoding;
|
||||
|
||||
use Lcobucci\JWT\ClaimsFormatter;
|
||||
|
||||
final class ChainedFormatter implements ClaimsFormatter
|
||||
{
|
||||
/** @var list<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;
|
||||
}
|
||||
}
|
60
vendor/lcobucci/jwt/src/Encoding/JoseEncoder.php
vendored
Normal file
60
vendor/lcobucci/jwt/src/Encoding/JoseEncoder.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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 with JOSE specifications
|
||||
*/
|
||||
final class JoseEncoder implements Encoder, Decoder
|
||||
{
|
||||
private const JSON_DEFAULT_DEPTH = 512;
|
||||
|
||||
/** @inheritdoc */
|
||||
public function jsonEncode($data): string
|
||||
{
|
||||
try {
|
||||
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $exception) {
|
||||
throw CannotEncodeContent::jsonIssues($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function jsonDecode(string $json)
|
||||
{
|
||||
try {
|
||||
return json_decode($json, true, self::JSON_DEFAULT_DEPTH, 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
|
||||
);
|
||||
}
|
||||
}
|
37
vendor/lcobucci/jwt/src/Encoding/MicrosecondBasedDateConversion.php
vendored
Normal file
37
vendor/lcobucci/jwt/src/Encoding/MicrosecondBasedDateConversion.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
/** @return int|float */
|
||||
private function convertDate(DateTimeImmutable $date)
|
||||
{
|
||||
if ($date->format('u') === '000000') {
|
||||
return (int) $date->format('U');
|
||||
}
|
||||
|
||||
return (float) $date->format('U.u');
|
||||
}
|
||||
}
|
29
vendor/lcobucci/jwt/src/Encoding/UnifyAudience.php
vendored
Normal file
29
vendor/lcobucci/jwt/src/Encoding/UnifyAudience.php
vendored
Normal file
@@ -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;
|
||||
}
|
||||
}
|
32
vendor/lcobucci/jwt/src/Encoding/UnixTimestampDates.php
vendored
Normal file
32
vendor/lcobucci/jwt/src/Encoding/UnixTimestampDates.php
vendored
Normal file
@@ -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();
|
||||
}
|
||||
}
|
10
vendor/lcobucci/jwt/src/Exception.php
vendored
Normal file
10
vendor/lcobucci/jwt/src/Exception.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Throwable;
|
||||
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
}
|
66
vendor/lcobucci/jwt/src/JwtFacade.php
vendored
Normal file
66
vendor/lcobucci/jwt/src/JwtFacade.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Closure;
|
||||
use DateTimeImmutable;
|
||||
use Lcobucci\Clock\Clock;
|
||||
use Lcobucci\Clock\SystemClock;
|
||||
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 function assert;
|
||||
|
||||
final class JwtFacade
|
||||
{
|
||||
private Parser $parser;
|
||||
private Clock $clock;
|
||||
|
||||
public function __construct(?Parser $parser = null, ?Clock $clock = null)
|
||||
{
|
||||
$this->parser = $parser ?? new Token\Parser(new JoseEncoder());
|
||||
$this->clock = $clock ?? SystemClock::fromSystemTimezone();
|
||||
}
|
||||
|
||||
/** @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
|
||||
->issuedAt($now)
|
||||
->canOnlyBeUsedAfter($now)
|
||||
->expiresAt($now->modify('+5 minutes'));
|
||||
|
||||
return $customiseBuilder($builder, $now)->getToken($signer, $signingKey);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
155
vendor/lcobucci/jwt/src/Parser.php
vendored
155
vendor/lcobucci/jwt/src/Parser.php
vendored
@@ -1,157 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Claim\Factory as ClaimFactory;
|
||||
use Lcobucci\JWT\Parsing\Decoder;
|
||||
use Lcobucci\JWT\Encoding\CannotDecodeContent;
|
||||
use Lcobucci\JWT\Token\InvalidTokenStructure;
|
||||
use Lcobucci\JWT\Token\UnsupportedHeaderFound;
|
||||
|
||||
/**
|
||||
* This class parses the JWT strings and convert them into tokens
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Parser
|
||||
interface Parser
|
||||
{
|
||||
/**
|
||||
* The data decoder
|
||||
*
|
||||
* @var Decoder
|
||||
*/
|
||||
private $decoder;
|
||||
|
||||
/**
|
||||
* The claims factory
|
||||
*
|
||||
* @var ClaimFactory
|
||||
*/
|
||||
private $claimFactory;
|
||||
|
||||
/**
|
||||
* Initializes the object
|
||||
*
|
||||
* @param Decoder $decoder
|
||||
* @param ClaimFactory $claimFactory
|
||||
*/
|
||||
public function __construct(
|
||||
Decoder $decoder = null,
|
||||
ClaimFactory $claimFactory = null
|
||||
) {
|
||||
$this->decoder = $decoder ?: new Decoder();
|
||||
$this->claimFactory = $claimFactory ?: new ClaimFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the JWT and returns a token
|
||||
*
|
||||
* @param string $jwt
|
||||
*
|
||||
* @return Token
|
||||
* @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($jwt)
|
||||
{
|
||||
$data = $this->splitJwt($jwt);
|
||||
$header = $this->parseHeader($data[0]);
|
||||
$claims = $this->parseClaims($data[1]);
|
||||
$signature = $this->parseSignature($header, $data[2]);
|
||||
|
||||
foreach ($claims as $name => $value) {
|
||||
if (isset($header[$name])) {
|
||||
$header[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($signature === null) {
|
||||
unset($data[2]);
|
||||
}
|
||||
|
||||
return new Token($header, $claims, $signature, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the JWT string into an array
|
||||
*
|
||||
* @param string $jwt
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidArgumentException When JWT is not a string or is invalid
|
||||
*/
|
||||
protected function splitJwt($jwt)
|
||||
{
|
||||
if (!is_string($jwt)) {
|
||||
throw new InvalidArgumentException('The JWT string must have two dots');
|
||||
}
|
||||
|
||||
$data = explode('.', $jwt);
|
||||
|
||||
if (count($data) != 3) {
|
||||
throw new InvalidArgumentException('The JWT string must have two dots');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the header from a string
|
||||
*
|
||||
* @param string $data
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidArgumentException When an invalid header is informed
|
||||
*/
|
||||
protected function parseHeader($data)
|
||||
{
|
||||
$header = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
|
||||
|
||||
if (isset($header['enc'])) {
|
||||
throw new InvalidArgumentException('Encryption is not supported yet');
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the claim set from a string
|
||||
*
|
||||
* @param string $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseClaims($data)
|
||||
{
|
||||
$claims = (array) $this->decoder->jsonDecode($this->decoder->base64UrlDecode($data));
|
||||
|
||||
foreach ($claims as $name => &$value) {
|
||||
$value = $this->claimFactory->create($name, $value);
|
||||
}
|
||||
|
||||
return $claims;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature from given data
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $data
|
||||
*
|
||||
* @return Signature
|
||||
*/
|
||||
protected function parseSignature(array $header, $data)
|
||||
{
|
||||
if ($data == '' || !isset($header['alg']) || $header['alg'] == 'none') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$hash = $this->decoder->base64UrlDecode($data);
|
||||
|
||||
return new Signature($hash);
|
||||
}
|
||||
public function parse(string $jwt): Token;
|
||||
}
|
||||
|
56
vendor/lcobucci/jwt/src/Parsing/Decoder.php
vendored
56
vendor/lcobucci/jwt/src/Parsing/Decoder.php
vendored
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Parsing;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class that decodes data according with the specs of RFC-4648
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*/
|
||||
class Decoder
|
||||
{
|
||||
/**
|
||||
* Decodes from JSON, validating the errors (will return an associative array
|
||||
* instead of objects)
|
||||
*
|
||||
* @param string $json
|
||||
* @return mixed
|
||||
*
|
||||
* @throws RuntimeException When something goes wrong while decoding
|
||||
*/
|
||||
public function jsonDecode($json)
|
||||
{
|
||||
$data = json_decode($json);
|
||||
|
||||
if (json_last_error() != JSON_ERROR_NONE) {
|
||||
throw new RuntimeException('Error while decoding to JSON: ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes from base64url
|
||||
*
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
public function base64UrlDecode($data)
|
||||
{
|
||||
if ($remainder = strlen($data) % 4) {
|
||||
$data .= str_repeat('=', 4 - $remainder);
|
||||
}
|
||||
|
||||
return base64_decode(strtr($data, '-_', '+/'));
|
||||
}
|
||||
}
|
51
vendor/lcobucci/jwt/src/Parsing/Encoder.php
vendored
51
vendor/lcobucci/jwt/src/Parsing/Encoder.php
vendored
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Parsing;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class that encodes data according with the specs of RFC-4648
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc4648#section-5
|
||||
*/
|
||||
class Encoder
|
||||
{
|
||||
/**
|
||||
* Encodes to JSON, validating the errors
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException When something goes wrong while encoding
|
||||
*/
|
||||
public function jsonEncode($data)
|
||||
{
|
||||
$json = json_encode($data);
|
||||
|
||||
if (json_last_error() != JSON_ERROR_NONE) {
|
||||
throw new RuntimeException('Error while encoding to JSON: ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes to base64url
|
||||
*
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
public function base64UrlEncode($data)
|
||||
{
|
||||
return str_replace('=', '', strtr(base64_encode($data), '+/', '-_'));
|
||||
}
|
||||
}
|
61
vendor/lcobucci/jwt/src/Signature.php
vendored
61
vendor/lcobucci/jwt/src/Signature.php
vendored
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
|
||||
/**
|
||||
* This class represents a token signature
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Signature
|
||||
{
|
||||
/**
|
||||
* The resultant hash
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $hash;
|
||||
|
||||
/**
|
||||
* Initializes the object
|
||||
*
|
||||
* @param string $hash
|
||||
*/
|
||||
public function __construct($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the current hash matches with with the result of the creation of
|
||||
* a new signature with given data
|
||||
*
|
||||
* @param Signer $signer
|
||||
* @param string $payload
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function verify(Signer $signer, $payload, $key)
|
||||
{
|
||||
return $signer->verify($this->hash, $payload, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current hash as a string representation of the signature
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
}
|
51
vendor/lcobucci/jwt/src/Signer.php
vendored
51
vendor/lcobucci/jwt/src/Signer.php
vendored
@@ -1,59 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Signer\CannotSignPayload;
|
||||
use Lcobucci\JWT\Signer\Ecdsa\ConversionFailed;
|
||||
use Lcobucci\JWT\Signer\InvalidKeyProvided;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
|
||||
/**
|
||||
* Basic interface for token signers
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
interface Signer
|
||||
{
|
||||
/**
|
||||
* Returns the algorithm id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAlgorithmId();
|
||||
public function algorithmId(): string;
|
||||
|
||||
/**
|
||||
* Apply changes on headers according with algorithm
|
||||
* Creates a hash for the given payload
|
||||
*
|
||||
* @param array $headers
|
||||
* @throws CannotSignPayload When payload signing fails.
|
||||
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
|
||||
* @throws ConversionFailed When signature could not be converted.
|
||||
*/
|
||||
public function modifyHeader(array &$headers);
|
||||
|
||||
/**
|
||||
* Returns a signature for given data
|
||||
*
|
||||
* @param string $payload
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return Signature
|
||||
*
|
||||
* @throws InvalidArgumentException When given key is invalid
|
||||
*/
|
||||
public function sign($payload, $key);
|
||||
public function sign(string $payload, Key $key): string;
|
||||
|
||||
/**
|
||||
* Returns if the expected hash matches with the data and key
|
||||
*
|
||||
* @param string $expected
|
||||
* @param string $payload
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws InvalidArgumentException When given key is invalid
|
||||
* @throws InvalidKeyProvided When issue key is invalid/incompatible.
|
||||
* @throws ConversionFailed When signature could not be converted.
|
||||
*/
|
||||
public function verify($expected, $payload, $key);
|
||||
public function verify(string $expected, string $payload, Key $key): bool;
|
||||
}
|
||||
|
85
vendor/lcobucci/jwt/src/Signer/BaseSigner.php
vendored
85
vendor/lcobucci/jwt/src/Signer/BaseSigner.php
vendored
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signature;
|
||||
use Lcobucci\JWT\Signer;
|
||||
|
||||
/**
|
||||
* Base class for signers
|
||||
*
|
||||
* @deprecated This class will be removed on v4
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
abstract class BaseSigner implements Signer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modifyHeader(array &$headers)
|
||||
{
|
||||
$headers['alg'] = $this->getAlgorithmId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sign($payload, $key)
|
||||
{
|
||||
return new Signature($this->createHash($payload, $this->getKey($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function verify($expected, $payload, $key)
|
||||
{
|
||||
return $this->doVerify($expected, $payload, $this->getKey($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return Key
|
||||
*/
|
||||
private function getKey($key)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
$key = new Key($key);
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hash with the given data
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $payload
|
||||
* @param Key $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function createHash($payload, Key $key);
|
||||
|
||||
/**
|
||||
* Performs the signature verification
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $expected
|
||||
* @param string $payload
|
||||
* @param Key $key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function doVerify($expected, $payload, Key $key);
|
||||
}
|
36
vendor/lcobucci/jwt/src/Signer/Blake2b.php
vendored
Normal file
36
vendor/lcobucci/jwt/src/Signer/Blake2b.php
vendored
Normal file
@@ -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));
|
||||
}
|
||||
}
|
15
vendor/lcobucci/jwt/src/Signer/CannotSignPayload.php
vendored
Normal file
15
vendor/lcobucci/jwt/src/Signer/CannotSignPayload.php
vendored
Normal file
@@ -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);
|
||||
}
|
||||
}
|
78
vendor/lcobucci/jwt/src/Signer/Ecdsa.php
vendored
78
vendor/lcobucci/jwt/src/Signer/Ecdsa.php
vendored
@@ -1,69 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Base class for ECDSA signers
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
abstract class Ecdsa extends OpenSSL
|
||||
{
|
||||
/**
|
||||
* @var SignatureConverter
|
||||
*/
|
||||
private $converter;
|
||||
private SignatureConverter $converter;
|
||||
|
||||
public function __construct(SignatureConverter $converter = null)
|
||||
public function __construct(?SignatureConverter $converter = null)
|
||||
{
|
||||
$this->converter = $converter ?: new MultibyteStringConverter();
|
||||
$this->converter = $converter ?? new MultibyteStringConverter();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createHash($payload, Key $key)
|
||||
/** @deprecated */
|
||||
public static function create(): Ecdsa
|
||||
{
|
||||
return new static(); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return $this->converter->fromAsn1(
|
||||
parent::createHash($payload, $key),
|
||||
$this->getKeyLength()
|
||||
$this->createSignature($key->contents(), $key->passphrase(), $payload),
|
||||
$this->pointLength()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function doVerify($expected, $payload, Key $key)
|
||||
final public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return parent::doVerify(
|
||||
$this->converter->toAsn1($expected, $this->getKeyLength()),
|
||||
return $this->verifySignature(
|
||||
$this->converter->toAsn1($expected, $this->pointLength()),
|
||||
$payload,
|
||||
$key
|
||||
$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 */
|
||||
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
|
||||
*/
|
||||
abstract public function getKeyLength();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
final public function getKeyType()
|
||||
{
|
||||
return OPENSSL_KEYTYPE_EC;
|
||||
}
|
||||
abstract public function pointLength(): int;
|
||||
}
|
||||
|
25
vendor/lcobucci/jwt/src/Signer/Ecdsa/ConversionFailed.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Signer/Ecdsa/ConversionFailed.php
vendored
Normal file
@@ -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.');
|
||||
}
|
||||
}
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -9,16 +11,19 @@
|
||||
*
|
||||
* @link https://github.com/web-token/jwt-framework/blob/v1.2/src/Component/Core/Util/ECSignature.php
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function assert;
|
||||
use function bin2hex;
|
||||
use function dechex;
|
||||
use function hex2bin;
|
||||
use function hexdec;
|
||||
use function is_string;
|
||||
use function mb_strlen;
|
||||
use function mb_substr;
|
||||
use function str_pad;
|
||||
|
||||
use const STR_PAD_LEFT;
|
||||
|
||||
/**
|
||||
@@ -28,24 +33,24 @@ use const STR_PAD_LEFT;
|
||||
*/
|
||||
final class MultibyteStringConverter implements SignatureConverter
|
||||
{
|
||||
const ASN1_SEQUENCE = '30';
|
||||
const ASN1_INTEGER = '02';
|
||||
const ASN1_MAX_SINGLE_BYTE = 128;
|
||||
const ASN1_LENGTH_2BYTES = '81';
|
||||
const ASN1_BIG_INTEGER_LIMIT = '7f';
|
||||
const ASN1_NEGATIVE_INTEGER = '00';
|
||||
const BYTE_SIZE = 2;
|
||||
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($signature, $length)
|
||||
public function toAsn1(string $points, int $length): string
|
||||
{
|
||||
$signature = bin2hex($signature);
|
||||
$points = bin2hex($points);
|
||||
|
||||
if (self::octetLength($signature) !== $length) {
|
||||
throw new InvalidArgumentException('Invalid signature length.');
|
||||
if (self::octetLength($points) !== $length) {
|
||||
throw ConversionFailed::invalidLength();
|
||||
}
|
||||
|
||||
$pointR = self::preparePositiveInteger(mb_substr($signature, 0, $length, '8bit'));
|
||||
$pointS = self::preparePositiveInteger(mb_substr($signature, $length, null, '8bit'));
|
||||
$pointR = self::preparePositiveInteger(mb_substr($points, 0, $length, '8bit'));
|
||||
$pointS = self::preparePositiveInteger(mb_substr($points, $length, null, '8bit'));
|
||||
|
||||
$lengthR = self::octetLength($pointR);
|
||||
$lengthS = self::octetLength($pointS);
|
||||
@@ -59,38 +64,42 @@ final class MultibyteStringConverter implements SignatureConverter
|
||||
. self::ASN1_INTEGER . dechex($lengthR) . $pointR
|
||||
. self::ASN1_INTEGER . dechex($lengthS) . $pointS
|
||||
);
|
||||
assert(is_string($asn1));
|
||||
|
||||
return $asn1;
|
||||
}
|
||||
|
||||
private static function octetLength($data)
|
||||
private static function octetLength(string $data): int
|
||||
{
|
||||
return (int) (mb_strlen($data, '8bit') / self::BYTE_SIZE);
|
||||
}
|
||||
|
||||
private static function preparePositiveInteger($data)
|
||||
private static function preparePositiveInteger(string $data): string
|
||||
{
|
||||
if (mb_substr($data, 0, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) {
|
||||
return self::ASN1_NEGATIVE_INTEGER . $data;
|
||||
}
|
||||
|
||||
while (mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
|
||||
&& mb_substr($data, 2, self::BYTE_SIZE, '8bit') <= self::ASN1_BIG_INTEGER_LIMIT) {
|
||||
while (
|
||||
mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
|
||||
&& mb_substr($data, 2, self::BYTE_SIZE, '8bit') <= self::ASN1_BIG_INTEGER_LIMIT
|
||||
) {
|
||||
$data = mb_substr($data, 2, null, '8bit');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function fromAsn1($signature, $length)
|
||||
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 new InvalidArgumentException('Invalid data. Should start with a sequence.');
|
||||
throw ConversionFailed::incorrectStartSequence();
|
||||
}
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
if (self::readAsn1Content($message, $position, self::BYTE_SIZE) === self::ASN1_LENGTH_2BYTES) {
|
||||
$position += self::BYTE_SIZE;
|
||||
}
|
||||
@@ -99,11 +108,12 @@ final class MultibyteStringConverter implements SignatureConverter
|
||||
$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));
|
||||
|
||||
return $points;
|
||||
}
|
||||
|
||||
private static function readAsn1Content($message, &$position, $length)
|
||||
private static function readAsn1Content(string $message, int &$position, int $length): string
|
||||
{
|
||||
$content = mb_substr($message, $position, $length, '8bit');
|
||||
$position += $length;
|
||||
@@ -111,10 +121,10 @@ final class MultibyteStringConverter implements SignatureConverter
|
||||
return $content;
|
||||
}
|
||||
|
||||
private static function readAsn1Integer($message, &$position)
|
||||
private static function readAsn1Integer(string $message, int &$position): string
|
||||
{
|
||||
if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_INTEGER) {
|
||||
throw new InvalidArgumentException('Invalid data. Should contain an integer.');
|
||||
throw ConversionFailed::integerExpected();
|
||||
}
|
||||
|
||||
$length = (int) hexdec(self::readAsn1Content($message, $position, self::BYTE_SIZE));
|
||||
@@ -122,10 +132,12 @@ final class MultibyteStringConverter implements SignatureConverter
|
||||
return self::readAsn1Content($message, $position, $length * self::BYTE_SIZE);
|
||||
}
|
||||
|
||||
private static function retrievePositiveInteger($data)
|
||||
private static function retrievePositiveInteger(string $data): string
|
||||
{
|
||||
while (mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
|
||||
&& mb_substr($data, 2, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) {
|
||||
while (
|
||||
mb_substr($data, 0, self::BYTE_SIZE, '8bit') === self::ASN1_NEGATIVE_INTEGER
|
||||
&& mb_substr($data, 2, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT
|
||||
) {
|
||||
$data = mb_substr($data, 2, null, '8bit');
|
||||
}
|
||||
|
||||
|
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha256.php
vendored
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha256.php
vendored
@@ -1,43 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
/**
|
||||
* Signer for ECDSA SHA-256
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha256 extends Ecdsa
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
final class Sha256 extends Ecdsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES256';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return 'sha256';
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKeyLength()
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
return 256;
|
||||
}
|
||||
}
|
||||
|
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha384.php
vendored
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha384.php
vendored
@@ -1,43 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
/**
|
||||
* Signer for ECDSA SHA-384
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha384 extends Ecdsa
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
final class Sha384 extends Ecdsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES384';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return 'sha384';
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKeyLength()
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 96;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
return 384;
|
||||
}
|
||||
}
|
||||
|
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha512.php
vendored
38
vendor/lcobucci/jwt/src/Signer/Ecdsa/Sha512.php
vendored
@@ -1,43 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
/**
|
||||
* Signer for ECDSA SHA-512
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha512 extends Ecdsa
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
final class Sha512 extends Ecdsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES512';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return 'sha512';
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getKeyLength()
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 132;
|
||||
}
|
||||
|
||||
public function expectedKeyLength(): int
|
||||
{
|
||||
return 521;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
/**
|
||||
@@ -19,20 +21,14 @@ interface SignatureConverter
|
||||
/**
|
||||
* Converts the signature generated by OpenSSL into what JWA defines
|
||||
*
|
||||
* @param string $signature
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
* @throws ConversionFailed When there was an issue during the format conversion.
|
||||
*/
|
||||
public function fromAsn1($signature, $length);
|
||||
public function fromAsn1(string $signature, int $length): string;
|
||||
|
||||
/**
|
||||
* Converts the JWA signature into something OpenSSL understands
|
||||
*
|
||||
* @param string $points
|
||||
* @param int $length
|
||||
*
|
||||
* @return string
|
||||
* @throws ConversionFailed When there was an issue during the format conversion.
|
||||
*/
|
||||
public function toAsn1($points, $length);
|
||||
public function toAsn1(string $points, int $length): string;
|
||||
}
|
||||
|
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha256.php
vendored
Normal file
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha256.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeEcdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha256 extends UnsafeEcdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES256';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha384.php
vendored
Normal file
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha384.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeEcdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha384 extends UnsafeEcdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES384';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 96;
|
||||
}
|
||||
}
|
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha512.php
vendored
Normal file
27
vendor/lcobucci/jwt/src/Signer/Ecdsa/UnsafeSha512.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Ecdsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeEcdsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha512 extends UnsafeEcdsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'ES512';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
|
||||
public function pointLength(): int
|
||||
{
|
||||
return 132;
|
||||
}
|
||||
}
|
36
vendor/lcobucci/jwt/src/Signer/Eddsa.php
vendored
Normal file
36
vendor/lcobucci/jwt/src/Signer/Eddsa.php
vendored
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
81
vendor/lcobucci/jwt/src/Signer/Hmac.php
vendored
81
vendor/lcobucci/jwt/src/Signer/Hmac.php
vendored
@@ -1,75 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
/**
|
||||
* Base class for hmac signers
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
abstract class Hmac extends BaseSigner
|
||||
use Lcobucci\JWT\Signer;
|
||||
|
||||
use function hash_equals;
|
||||
use function hash_hmac;
|
||||
use function strlen;
|
||||
|
||||
abstract class Hmac implements Signer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createHash($payload, Key $key)
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return hash_hmac($this->getAlgorithm(), $payload, $key->getContent(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function doVerify($expected, $payload, Key $key)
|
||||
{
|
||||
if (!is_string($expected)) {
|
||||
return false;
|
||||
$actualKeyLength = 8 * strlen($key->contents());
|
||||
$expectedKeyLength = $this->minimumBitsLengthForKey();
|
||||
if ($actualKeyLength < $expectedKeyLength) {
|
||||
throw InvalidKeyProvided::tooShort($expectedKeyLength, $actualKeyLength);
|
||||
}
|
||||
|
||||
$callback = function_exists('hash_equals') ? 'hash_equals' : [$this, 'hashEquals'];
|
||||
|
||||
return call_user_func($callback, $expected, $this->createHash($payload, $key));
|
||||
return hash_hmac($this->algorithm(), $payload, $key->contents(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP < 5.6 timing attack safe hash comparison
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $expected
|
||||
* @param string $generated
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hashEquals($expected, $generated)
|
||||
final public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
$expectedLength = strlen($expected);
|
||||
|
||||
if ($expectedLength !== strlen($generated)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = 0;
|
||||
|
||||
for ($i = 0; $i < $expectedLength; ++$i) {
|
||||
$res |= ord($expected[$i]) ^ ord($generated[$i]);
|
||||
}
|
||||
|
||||
return $res === 0;
|
||||
return hash_equals($expected, $this->sign($payload, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm name
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getAlgorithm();
|
||||
abstract public function algorithm(): string;
|
||||
|
||||
/** @return positive-int */
|
||||
abstract public function minimumBitsLengthForKey(): int;
|
||||
}
|
||||
|
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha256.php
vendored
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha256.php
vendored
@@ -1,35 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/**
|
||||
* Signer for HMAC SHA-256
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Sha256 extends Hmac
|
||||
final class Sha256 extends Hmac
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS256';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha256';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 256;
|
||||
}
|
||||
}
|
||||
|
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha384.php
vendored
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha384.php
vendored
@@ -1,35 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/**
|
||||
* Signer for HMAC SHA-384
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Sha384 extends Hmac
|
||||
final class Sha384 extends Hmac
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS384';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha384';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 384;
|
||||
}
|
||||
}
|
||||
|
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha512.php
vendored
29
vendor/lcobucci/jwt/src/Signer/Hmac/Sha512.php
vendored
@@ -1,35 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/**
|
||||
* Signer for HMAC SHA-512
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Sha512 extends Hmac
|
||||
final class Sha512 extends Hmac
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS512';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha512';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 512;
|
||||
}
|
||||
}
|
||||
|
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha256.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha256.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha256 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS256';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha256';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha384.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha384.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha384 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS384';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha384';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha512.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Signer/Hmac/UnsafeSha512.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
use Lcobucci\JWT\Signer\Hmac;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha512 extends Hmac
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'HS512';
|
||||
}
|
||||
|
||||
public function algorithm(): string
|
||||
{
|
||||
return 'sha512';
|
||||
}
|
||||
|
||||
public function minimumBitsLengthForKey(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
42
vendor/lcobucci/jwt/src/Signer/InvalidKeyProvided.php
vendored
Normal file
42
vendor/lcobucci/jwt/src/Signer/InvalidKeyProvided.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
public static function incompatibleKeyType(string $expectedType, string $actualType): self
|
||||
{
|
||||
return new self(
|
||||
'The type of the provided key is not "' . $expectedType
|
||||
. '", "' . $actualType . '" provided'
|
||||
);
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
89
vendor/lcobucci/jwt/src/Signer/Key.php
vendored
89
vendor/lcobucci/jwt/src/Signer/Key.php
vendored
@@ -1,92 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use SplFileObject;
|
||||
|
||||
/**
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 3.0.4
|
||||
*/
|
||||
final class Key
|
||||
interface Key
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $content;
|
||||
public function contents(): string;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $passphrase;
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
* @param string $passphrase
|
||||
*/
|
||||
public function __construct($content, $passphrase = null)
|
||||
{
|
||||
$this->setContent($content);
|
||||
$this->passphrase = $passphrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function setContent($content)
|
||||
{
|
||||
if (strpos($content, 'file://') === 0) {
|
||||
$content = $this->readFile($content);
|
||||
}
|
||||
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function readFile($content)
|
||||
{
|
||||
try {
|
||||
$file = new SplFileObject(substr($content, 7));
|
||||
$content = '';
|
||||
|
||||
while (! $file->eof()) {
|
||||
$content .= $file->fgets();
|
||||
}
|
||||
|
||||
return $content;
|
||||
} catch (Exception $exception) {
|
||||
throw new InvalidArgumentException('You must provide a valid key file', 0, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPassphrase()
|
||||
{
|
||||
return $this->passphrase;
|
||||
}
|
||||
public function passphrase(): string;
|
||||
}
|
||||
|
20
vendor/lcobucci/jwt/src/Signer/Key/FileCouldNotBeRead.php
vendored
Normal file
20
vendor/lcobucci/jwt/src/Signer/Key/FileCouldNotBeRead.php
vendored
Normal file
@@ -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
|
||||
{
|
||||
public static function onPath(string $path, ?Throwable $cause = null): self
|
||||
{
|
||||
return new self(
|
||||
'The path "' . $path . '" does not contain a valid key file',
|
||||
0,
|
||||
$cause
|
||||
);
|
||||
}
|
||||
}
|
85
vendor/lcobucci/jwt/src/Signer/Key/InMemory.php
vendored
Normal file
85
vendor/lcobucci/jwt/src/Signer/Key/InMemory.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?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
|
||||
{
|
||||
private string $contents;
|
||||
private string $passphrase;
|
||||
|
||||
/** @param non-empty-string $contents */
|
||||
private function __construct(string $contents, string $passphrase)
|
||||
{
|
||||
// @phpstan-ignore-next-line
|
||||
if ($contents === '') {
|
||||
throw InvalidKeyProvided::cannotBeEmpty();
|
||||
}
|
||||
|
||||
$this->contents = $contents;
|
||||
$this->passphrase = $passphrase;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated since v4.3 */
|
||||
public static function empty(): self
|
||||
{
|
||||
$emptyKey = new self('empty', 'empty');
|
||||
$emptyKey->contents = '';
|
||||
$emptyKey->passphrase = '';
|
||||
|
||||
return $emptyKey;
|
||||
}
|
||||
|
||||
/** @param non-empty-string $contents */
|
||||
public static function plainText(string $contents, string $passphrase = ''): self
|
||||
{
|
||||
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
|
||||
);
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
return new self($decoded, $passphrase);
|
||||
}
|
||||
|
||||
/** @throws FileCouldNotBeRead */
|
||||
public static function file(string $path, string $passphrase = ''): self
|
||||
{
|
||||
try {
|
||||
$file = new SplFileObject($path);
|
||||
} catch (Throwable $exception) {
|
||||
throw FileCouldNotBeRead::onPath($path, $exception);
|
||||
}
|
||||
|
||||
$contents = $file->fread($file->getSize());
|
||||
assert(is_string($contents));
|
||||
assert($contents !== '');
|
||||
|
||||
return new self($contents, $passphrase);
|
||||
}
|
||||
|
||||
public function contents(): string
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
public function passphrase(): string
|
||||
{
|
||||
return $this->passphrase;
|
||||
}
|
||||
}
|
54
vendor/lcobucci/jwt/src/Signer/Key/LocalFileReference.php
vendored
Normal file
54
vendor/lcobucci/jwt/src/Signer/Key/LocalFileReference.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Key;
|
||||
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
|
||||
use function file_exists;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
/** @deprecated please use {@see InMemory} instead */
|
||||
final class LocalFileReference implements Key
|
||||
{
|
||||
private const PATH_PREFIX = 'file://';
|
||||
|
||||
private string $path;
|
||||
private string $passphrase;
|
||||
private string $contents;
|
||||
|
||||
private function __construct(string $path, string $passphrase)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->passphrase = $passphrase;
|
||||
}
|
||||
|
||||
/** @throws FileCouldNotBeRead */
|
||||
public static function file(string $path, string $passphrase = ''): self
|
||||
{
|
||||
if (strpos($path, self::PATH_PREFIX) === 0) {
|
||||
$path = substr($path, 7);
|
||||
}
|
||||
|
||||
if (! file_exists($path)) {
|
||||
throw FileCouldNotBeRead::onPath($path);
|
||||
}
|
||||
|
||||
return new self($path, $passphrase);
|
||||
}
|
||||
|
||||
public function contents(): string
|
||||
{
|
||||
if (! isset($this->contents)) {
|
||||
$this->contents = InMemory::file($this->path)->contents();
|
||||
}
|
||||
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
public function passphrase(): string
|
||||
{
|
||||
return $this->passphrase;
|
||||
}
|
||||
}
|
44
vendor/lcobucci/jwt/src/Signer/Keychain.php
vendored
44
vendor/lcobucci/jwt/src/Signer/Keychain.php
vendored
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
/**
|
||||
* A utilitarian class that encapsulates the retrieval of public and private keys
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @deprecated Since we've removed OpenSSL from ECDSA there's no reason to use this class
|
||||
*/
|
||||
class Keychain
|
||||
{
|
||||
/**
|
||||
* Returns a private key from file path or content
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $passphrase
|
||||
*
|
||||
* @return Key
|
||||
*/
|
||||
public function getPrivateKey($key, $passphrase = null)
|
||||
{
|
||||
return new Key($key, $passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a public key from file path or content
|
||||
*
|
||||
* @param string $certificate
|
||||
*
|
||||
* @return Key
|
||||
*/
|
||||
public function getPublicKey($certificate)
|
||||
{
|
||||
return new Key($certificate);
|
||||
}
|
||||
}
|
27
vendor/lcobucci/jwt/src/Signer/None.php
vendored
Normal file
27
vendor/lcobucci/jwt/src/Signer/None.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use Lcobucci\JWT\Signer;
|
||||
|
||||
/** @deprecated Deprecated since v4.3 */
|
||||
final class None implements Signer
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'none';
|
||||
}
|
||||
|
||||
// @phpcs:ignore SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
|
||||
public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
// @phpcs:ignore SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
|
||||
public function verify(string $expected, string $payload, Key $key): bool
|
||||
{
|
||||
return $expected === '';
|
||||
}
|
||||
}
|
131
vendor/lcobucci/jwt/src/Signer/OpenSSL.php
vendored
131
vendor/lcobucci/jwt/src/Signer/OpenSSL.php
vendored
@@ -1,11 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Signer;
|
||||
use OpenSSLAsymmetricKey;
|
||||
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function is_array;
|
||||
use function is_resource;
|
||||
use function is_bool;
|
||||
use function is_int;
|
||||
use function openssl_error_string;
|
||||
use function openssl_free_key;
|
||||
use function openssl_pkey_get_details;
|
||||
@@ -14,34 +19,51 @@ use function openssl_pkey_get_public;
|
||||
use function openssl_sign;
|
||||
use function openssl_verify;
|
||||
|
||||
abstract class OpenSSL extends BaseSigner
|
||||
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
|
||||
{
|
||||
public function createHash($payload, Key $key)
|
||||
{
|
||||
$privateKey = $this->getPrivateKey($key->getContent(), $key->getPassphrase());
|
||||
protected const KEY_TYPE_MAP = [
|
||||
OPENSSL_KEYTYPE_RSA => 'RSA',
|
||||
OPENSSL_KEYTYPE_DSA => 'DSA',
|
||||
OPENSSL_KEYTYPE_DH => 'DH',
|
||||
OPENSSL_KEYTYPE_EC => 'EC',
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws CannotSignPayload
|
||||
* @throws InvalidKeyProvided
|
||||
*/
|
||||
final protected function createSignature(
|
||||
string $pem,
|
||||
string $passphrase,
|
||||
string $payload
|
||||
): string {
|
||||
$key = $this->getPrivateKey($pem, $passphrase);
|
||||
|
||||
try {
|
||||
$signature = '';
|
||||
|
||||
if (! openssl_sign($payload, $signature, $privateKey, $this->getAlgorithm())) {
|
||||
throw new InvalidArgumentException(
|
||||
'There was an error while creating the signature: ' . openssl_error_string()
|
||||
);
|
||||
if (! openssl_sign($payload, $signature, $key, $this->algorithm())) {
|
||||
throw CannotSignPayload::errorHappened($this->fullOpenSSLErrorString());
|
||||
}
|
||||
|
||||
return $signature;
|
||||
} finally {
|
||||
openssl_free_key($privateKey);
|
||||
$this->freeKey($key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pem
|
||||
* @param string $passphrase
|
||||
* @return resource|OpenSSLAsymmetricKey
|
||||
*
|
||||
* @return resource
|
||||
* @throws CannotSignPayload
|
||||
*/
|
||||
private function getPrivateKey($pem, $passphrase)
|
||||
private function getPrivateKey(string $pem, string $passphrase)
|
||||
{
|
||||
$privateKey = openssl_pkey_get_private($pem, $passphrase);
|
||||
$this->validateKey($privateKey);
|
||||
@@ -49,27 +71,25 @@ abstract class OpenSSL extends BaseSigner
|
||||
return $privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expected
|
||||
* @param $payload
|
||||
* @param $pem
|
||||
* @return bool
|
||||
*/
|
||||
public function doVerify($expected, $payload, Key $key)
|
||||
{
|
||||
$publicKey = $this->getPublicKey($key->getContent());
|
||||
$result = openssl_verify($payload, $expected, $publicKey, $this->getAlgorithm());
|
||||
openssl_free_key($publicKey);
|
||||
/** @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());
|
||||
$this->freeKey($key);
|
||||
|
||||
return $result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pem
|
||||
* @return resource|OpenSSLAsymmetricKey
|
||||
*
|
||||
* @return resource
|
||||
* @throws InvalidKeyProvided
|
||||
*/
|
||||
private function getPublicKey($pem)
|
||||
private function getPublicKey(string $pem)
|
||||
{
|
||||
$publicKey = openssl_pkey_get_public($pem);
|
||||
$this->validateKey($publicKey);
|
||||
@@ -80,36 +100,55 @@ abstract class OpenSSL extends BaseSigner
|
||||
/**
|
||||
* Raises an exception when the key type is not the expected type
|
||||
*
|
||||
* @param resource|bool $key
|
||||
* @param resource|OpenSSLAsymmetricKey|bool $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws InvalidKeyProvided
|
||||
*/
|
||||
private function validateKey($key)
|
||||
private function validateKey($key): void
|
||||
{
|
||||
if (! is_resource($key)) {
|
||||
throw new InvalidArgumentException(
|
||||
'It was not possible to parse your key, reason: ' . openssl_error_string()
|
||||
);
|
||||
if (is_bool($key)) {
|
||||
throw InvalidKeyProvided::cannotBeParsed($this->fullOpenSSLErrorString());
|
||||
}
|
||||
|
||||
$details = openssl_pkey_get_details($key);
|
||||
assert(is_array($details));
|
||||
|
||||
if (! isset($details['key']) || $details['type'] !== $this->getKeyType()) {
|
||||
throw new InvalidArgumentException('This key is not compatible with this signer');
|
||||
}
|
||||
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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of key to be used to create/verify the signature (using OpenSSL constants)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function getKeyType();
|
||||
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;
|
||||
|
||||
/** @param resource|OpenSSLAsymmetricKey $key */
|
||||
private function freeKey($key): void
|
||||
{
|
||||
if ($key instanceof OpenSSLAsymmetricKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
openssl_free_key($key); // Deprecated and no longer necessary as of PHP >= 8.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns which algorithm to be used to create/verify the signature (using OpenSSL constants)
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function getAlgorithm();
|
||||
abstract public function algorithm(): int;
|
||||
}
|
||||
|
37
vendor/lcobucci/jwt/src/Signer/Rsa.php
vendored
37
vendor/lcobucci/jwt/src/Signer/Rsa.php
vendored
@@ -1,24 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use const OPENSSL_KEYTYPE_RSA;
|
||||
|
||||
/**
|
||||
* Base class for RSASSA-PKCS1 signers
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
abstract class Rsa extends OpenSSL
|
||||
{
|
||||
final public function getKeyType()
|
||||
private const MINIMUM_KEY_LENGTH = 2048;
|
||||
|
||||
final public function sign(string $payload, Key $key): string
|
||||
{
|
||||
return OPENSSL_KEYTYPE_RSA;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha256.php
vendored
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha256.php
vendored
@@ -1,34 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
/**
|
||||
* Signer for RSA SHA-256
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha256 extends Rsa
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
final class Sha256 extends Rsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
|
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha384.php
vendored
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha384.php
vendored
@@ -1,34 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
/**
|
||||
* Signer for RSA SHA-384
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha384 extends Rsa
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
final class Sha384 extends Rsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS384';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
|
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha512.php
vendored
26
vendor/lcobucci/jwt/src/Signer/Rsa/Sha512.php
vendored
@@ -1,34 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
/**
|
||||
* Signer for RSA SHA-512
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Sha512 extends Rsa
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
final class Sha512 extends Rsa
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithmId()
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS512';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAlgorithm()
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
|
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha256.php
vendored
Normal file
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha256.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeRsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA256;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha256 extends UnsafeRsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS256';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA256;
|
||||
}
|
||||
}
|
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha384.php
vendored
Normal file
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha384.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeRsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA384;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha384 extends UnsafeRsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS384';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA384;
|
||||
}
|
||||
}
|
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha512.php
vendored
Normal file
22
vendor/lcobucci/jwt/src/Signer/Rsa/UnsafeSha512.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer\Rsa;
|
||||
|
||||
use Lcobucci\JWT\Signer\UnsafeRsa;
|
||||
|
||||
use const OPENSSL_ALGO_SHA512;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
final class UnsafeSha512 extends UnsafeRsa
|
||||
{
|
||||
public function algorithmId(): string
|
||||
{
|
||||
return 'RS512';
|
||||
}
|
||||
|
||||
public function algorithm(): int
|
||||
{
|
||||
return OPENSSL_ALGO_SHA512;
|
||||
}
|
||||
}
|
60
vendor/lcobucci/jwt/src/Signer/UnsafeEcdsa.php
vendored
Normal file
60
vendor/lcobucci/jwt/src/Signer/UnsafeEcdsa.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
abstract class UnsafeEcdsa extends OpenSSL
|
||||
{
|
||||
private SignatureConverter $converter;
|
||||
|
||||
public function __construct(SignatureConverter $converter)
|
||||
{
|
||||
$this->converter = $converter;
|
||||
}
|
||||
|
||||
public static function create(): UnsafeEcdsa
|
||||
{
|
||||
return new static(new MultibyteStringConverter()); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
|
||||
// phpcs:ignore SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
|
||||
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],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of each point in the signature, so that we can calculate and verify R and S points properly
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function pointLength(): int;
|
||||
}
|
31
vendor/lcobucci/jwt/src/Signer/UnsafeRsa.php
vendored
Normal file
31
vendor/lcobucci/jwt/src/Signer/UnsafeRsa.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Signer;
|
||||
|
||||
use const OPENSSL_KEYTYPE_RSA;
|
||||
|
||||
/** @deprecated Deprecated since v4.2 */
|
||||
abstract class UnsafeRsa extends OpenSSL
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
// phpcs:ignore SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
|
||||
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],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
88
vendor/lcobucci/jwt/src/SodiumBase64Polyfill.php
vendored
Normal file
88
vendor/lcobucci/jwt/src/SodiumBase64Polyfill.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/** @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 $sodiumException) {
|
||||
throw CannotDecodeContent::invalidBase64String();
|
||||
}
|
||||
}
|
||||
|
||||
/** @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;
|
||||
}
|
||||
}
|
268
vendor/lcobucci/jwt/src/Token.php
vendored
268
vendor/lcobucci/jwt/src/Token.php
vendored
@@ -1,285 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
|
||||
*
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT;
|
||||
|
||||
use BadMethodCallException;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use Generator;
|
||||
use Lcobucci\JWT\Claim\Validatable;
|
||||
use Lcobucci\JWT\Signer\Key;
|
||||
use OutOfBoundsException;
|
||||
use Lcobucci\JWT\Token\DataSet;
|
||||
|
||||
/**
|
||||
* Basic structure of the JWT
|
||||
*
|
||||
* @author Luís Otávio Cobucci Oblonczyk <lcobucci@gmail.com>
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Token
|
||||
interface Token
|
||||
{
|
||||
/**
|
||||
* The token headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $headers;
|
||||
|
||||
/**
|
||||
* The token claim set
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $claims;
|
||||
|
||||
/**
|
||||
* The token signature
|
||||
*
|
||||
* @var Signature
|
||||
*/
|
||||
private $signature;
|
||||
|
||||
/**
|
||||
* The encoded data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $payload;
|
||||
|
||||
/**
|
||||
* Initializes the object
|
||||
*
|
||||
* @param array $headers
|
||||
* @param array $claims
|
||||
* @param array $payload
|
||||
* @param Signature $signature
|
||||
*/
|
||||
public function __construct(
|
||||
array $headers = ['alg' => 'none'],
|
||||
array $claims = [],
|
||||
Signature $signature = null,
|
||||
array $payload = ['', '']
|
||||
) {
|
||||
$this->headers = $headers;
|
||||
$this->claims = $claims;
|
||||
$this->signature = $signature;
|
||||
$this->payload = $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
public function headers(): DataSet;
|
||||
|
||||
/**
|
||||
* Returns if the header is configured
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean
|
||||
* Returns if the token is allowed to be used by the audience
|
||||
*/
|
||||
public function hasHeader($name)
|
||||
{
|
||||
return array_key_exists($name, $this->headers);
|
||||
}
|
||||
public function isPermittedFor(string $audience): bool;
|
||||
|
||||
/**
|
||||
* Returns the value of a token header
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws OutOfBoundsException
|
||||
* Returns if the token has the given id
|
||||
*/
|
||||
public function getHeader($name, $default = null)
|
||||
{
|
||||
if ($this->hasHeader($name)) {
|
||||
return $this->getHeaderValue($name);
|
||||
}
|
||||
|
||||
if ($default === null) {
|
||||
throw new OutOfBoundsException('Requested header is not configured');
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
public function isIdentifiedBy(string $id): bool;
|
||||
|
||||
/**
|
||||
* Returns the value stored in header
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
* Returns if the token has the given subject
|
||||
*/
|
||||
private function getHeaderValue($name)
|
||||
{
|
||||
$header = $this->headers[$name];
|
||||
|
||||
if ($header instanceof Claim) {
|
||||
return $header->getValue();
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
public function isRelatedTo(string $subject): bool;
|
||||
|
||||
/**
|
||||
* Returns the token claim set
|
||||
*
|
||||
* @return array
|
||||
* Returns if the token was issued by any of given issuers
|
||||
*/
|
||||
public function getClaims()
|
||||
{
|
||||
return $this->claims;
|
||||
}
|
||||
public function hasBeenIssuedBy(string ...$issuers): bool;
|
||||
|
||||
/**
|
||||
* Returns if the claim is configured
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean
|
||||
* Returns if the token was issued before of given time
|
||||
*/
|
||||
public function hasClaim($name)
|
||||
{
|
||||
return array_key_exists($name, $this->claims);
|
||||
}
|
||||
public function hasBeenIssuedBefore(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Returns the value of a token claim
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws OutOfBoundsException
|
||||
* Returns if the token minimum time is before than given time
|
||||
*/
|
||||
public function getClaim($name, $default = null)
|
||||
{
|
||||
if ($this->hasClaim($name)) {
|
||||
return $this->claims[$name]->getValue();
|
||||
}
|
||||
|
||||
if ($default === null) {
|
||||
throw new OutOfBoundsException('Requested claim is not configured');
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
public function isMinimumTimeBefore(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Verify if the key matches with the one that created the signature
|
||||
*
|
||||
* @param Signer $signer
|
||||
* @param Key|string $key
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws BadMethodCallException When token is not signed
|
||||
* Returns if the token is expired
|
||||
*/
|
||||
public function verify(Signer $signer, $key)
|
||||
{
|
||||
if ($this->signature === null) {
|
||||
throw new BadMethodCallException('This token is not signed');
|
||||
}
|
||||
|
||||
if ($this->headers['alg'] !== $signer->getAlgorithmId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->signature->verify($signer, $this->getPayload(), $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if the token is valid
|
||||
*
|
||||
* @param ValidationData $data
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate(ValidationData $data)
|
||||
{
|
||||
foreach ($this->getValidatableClaims() as $claim) {
|
||||
if (!$claim->validate($data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the token is expired.
|
||||
*
|
||||
* @param DateTimeInterface $now Defaults to the current time.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isExpired(DateTimeInterface $now = null)
|
||||
{
|
||||
$exp = $this->getClaim('exp', false);
|
||||
|
||||
if ($exp === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$now = $now ?: new DateTime();
|
||||
|
||||
$expiresAt = new DateTime();
|
||||
$expiresAt->setTimestamp($exp);
|
||||
|
||||
return $now > $expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Yields the validatable claims
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
private function getValidatableClaims()
|
||||
{
|
||||
foreach ($this->claims as $claim) {
|
||||
if ($claim instanceof Validatable) {
|
||||
yield $claim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token payload
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPayload()
|
||||
{
|
||||
return $this->payload[0] . '.' . $this->payload[1];
|
||||
}
|
||||
public function isExpired(DateTimeInterface $now): bool;
|
||||
|
||||
/**
|
||||
* Returns an encoded representation of the token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$data = implode('.', $this->payload);
|
||||
|
||||
if ($this->signature === null) {
|
||||
$data .= '.';
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
public function toString(): string;
|
||||
}
|
||||
|
128
vendor/lcobucci/jwt/src/Token/Builder.php
vendored
Normal file
128
vendor/lcobucci/jwt/src/Token/Builder.php
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
<?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 function array_diff;
|
||||
use function array_merge;
|
||||
use function in_array;
|
||||
|
||||
final class Builder implements BuilderInterface
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private array $headers = ['typ' => 'JWT', 'alg' => null];
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private array $claims = [];
|
||||
|
||||
private Encoder $encoder;
|
||||
private ClaimsFormatter $claimFormatter;
|
||||
|
||||
public function __construct(Encoder $encoder, ClaimsFormatter $claimFormatter)
|
||||
{
|
||||
$this->encoder = $encoder;
|
||||
$this->claimFormatter = $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);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function withHeader(string $name, $value): BuilderInterface
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function withClaim(string $name, $value): BuilderInterface
|
||||
{
|
||||
if (in_array($name, RegisteredClaims::ALL, true)) {
|
||||
throw RegisteredClaimGiven::forClaim($name);
|
||||
}
|
||||
|
||||
return $this->setClaim($name, $value);
|
||||
}
|
||||
|
||||
/** @param mixed $value */
|
||||
private function setClaim(string $name, $value): BuilderInterface
|
||||
{
|
||||
$this->claims[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<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): Plain
|
||||
{
|
||||
$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)
|
||||
);
|
||||
}
|
||||
}
|
46
vendor/lcobucci/jwt/src/Token/DataSet.php
vendored
Normal file
46
vendor/lcobucci/jwt/src/Token/DataSet.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use function array_key_exists;
|
||||
|
||||
final class DataSet
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private array $data;
|
||||
private string $encoded;
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
public function __construct(array $data, string $encoded)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->encoded = $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get(string $name, $default = null)
|
||||
{
|
||||
return $this->data[$name] ?? $default;
|
||||
}
|
||||
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->data);
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function all(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->encoded;
|
||||
}
|
||||
}
|
25
vendor/lcobucci/jwt/src/Token/InvalidTokenStructure.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/Token/InvalidTokenStructure.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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 arrayExpected(string $part): self
|
||||
{
|
||||
return new self($part . ' must be an array');
|
||||
}
|
||||
|
||||
public static function dateIsNotParseable(string $value): self
|
||||
{
|
||||
return new self('Value is not in the allowed date format: ' . $value);
|
||||
}
|
||||
}
|
154
vendor/lcobucci/jwt/src/Token/Parser.php
vendored
Normal file
154
vendor/lcobucci/jwt/src/Token/Parser.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?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;
|
||||
|
||||
private Decoder $decoder;
|
||||
|
||||
public function __construct(Decoder $decoder)
|
||||
{
|
||||
$this->decoder = $decoder;
|
||||
}
|
||||
|
||||
public function parse(string $jwt): TokenInterface
|
||||
{
|
||||
[$encodedHeaders, $encodedClaims, $encodedSignature] = $this->splitJwt($jwt);
|
||||
|
||||
$header = $this->parseHeader($encodedHeaders);
|
||||
|
||||
return new Plain(
|
||||
new DataSet($header, $encodedHeaders),
|
||||
new DataSet($this->parseClaims($encodedClaims), $encodedClaims),
|
||||
$this->parseSignature($header, $encodedSignature)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the JWT string into an array
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @return 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');
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* @return 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');
|
||||
}
|
||||
|
||||
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 int|float|string $timestamp
|
||||
*
|
||||
* @throws InvalidTokenStructure
|
||||
*/
|
||||
private function convertDate($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 mixed[] $header
|
||||
*/
|
||||
private function parseSignature(array $header, string $data): Signature
|
||||
{
|
||||
if ($data === '' || ! array_key_exists('alg', $header) || $header['alg'] === 'none') {
|
||||
return Signature::fromEmptyData();
|
||||
}
|
||||
|
||||
$hash = $this->decoder->base64UrlDecode($data);
|
||||
|
||||
return new Signature($hash, $data);
|
||||
}
|
||||
}
|
92
vendor/lcobucci/jwt/src/Token/Plain.php
vendored
Normal file
92
vendor/lcobucci/jwt/src/Token/Plain.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
|
||||
use function in_array;
|
||||
|
||||
final class Plain implements UnencryptedToken
|
||||
{
|
||||
private DataSet $headers;
|
||||
private DataSet $claims;
|
||||
private Signature $signature;
|
||||
|
||||
public function __construct(
|
||||
DataSet $headers,
|
||||
DataSet $claims,
|
||||
Signature $signature
|
||||
) {
|
||||
$this->headers = $headers;
|
||||
$this->claims = $claims;
|
||||
$this->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();
|
||||
}
|
||||
}
|
20
vendor/lcobucci/jwt/src/Token/RegisteredClaimGiven.php
vendored
Normal file
20
vendor/lcobucci/jwt/src/Token/RegisteredClaimGiven.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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"';
|
||||
|
||||
public static function forClaim(string $name): self
|
||||
{
|
||||
return new self(sprintf(self::DEFAULT_MESSAGE, $name));
|
||||
}
|
||||
}
|
77
vendor/lcobucci/jwt/src/Token/RegisteredClaims.php
vendored
Normal file
77
vendor/lcobucci/jwt/src/Token/RegisteredClaims.php
vendored
Normal file
@@ -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';
|
||||
}
|
35
vendor/lcobucci/jwt/src/Token/Signature.php
vendored
Normal file
35
vendor/lcobucci/jwt/src/Token/Signature.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Token;
|
||||
|
||||
final class Signature
|
||||
{
|
||||
private string $hash;
|
||||
private string $encoded;
|
||||
|
||||
public function __construct(string $hash, string $encoded)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
$this->encoded = $encoded;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated since v4.3 */
|
||||
public static function fromEmptyData(): self
|
||||
{
|
||||
return new self('', '');
|
||||
}
|
||||
|
||||
public function hash(): string
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded version of the signature
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->encoded;
|
||||
}
|
||||
}
|
15
vendor/lcobucci/jwt/src/Token/UnsupportedHeaderFound.php
vendored
Normal file
15
vendor/lcobucci/jwt/src/Token/UnsupportedHeaderFound.php
vendored
Normal file
@@ -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');
|
||||
}
|
||||
}
|
25
vendor/lcobucci/jwt/src/UnencryptedToken.php
vendored
Normal file
25
vendor/lcobucci/jwt/src/UnencryptedToken.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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
|
||||
*/
|
||||
public function payload(): string;
|
||||
}
|
12
vendor/lcobucci/jwt/src/Validation/Constraint.php
vendored
Normal file
12
vendor/lcobucci/jwt/src/Validation/Constraint.php
vendored
Normal file
@@ -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;
|
||||
}
|
17
vendor/lcobucci/jwt/src/Validation/Constraint/CannotValidateARegisteredClaim.php
vendored
Normal file
17
vendor/lcobucci/jwt/src/Validation/Constraint/CannotValidateARegisteredClaim.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Lcobucci\JWT\Exception;
|
||||
|
||||
final class CannotValidateARegisteredClaim extends InvalidArgumentException implements Exception
|
||||
{
|
||||
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'
|
||||
);
|
||||
}
|
||||
}
|
50
vendor/lcobucci/jwt/src/Validation/Constraint/HasClaimWithValue.php
vendored
Normal file
50
vendor/lcobucci/jwt/src/Validation/Constraint/HasClaimWithValue.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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
|
||||
{
|
||||
private string $claim;
|
||||
|
||||
/** @var mixed */
|
||||
private $expectedValue;
|
||||
|
||||
/** @param mixed $expectedValue */
|
||||
public function __construct(string $claim, $expectedValue)
|
||||
{
|
||||
if (in_array($claim, Token\RegisteredClaims::ALL, true)) {
|
||||
throw CannotValidateARegisteredClaim::create($claim);
|
||||
}
|
||||
|
||||
$this->claim = $claim;
|
||||
$this->expectedValue = $expectedValue;
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
28
vendor/lcobucci/jwt/src/Validation/Constraint/IdentifiedBy.php
vendored
Normal file
28
vendor/lcobucci/jwt/src/Validation/Constraint/IdentifiedBy.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
{
|
||||
private string $id;
|
||||
|
||||
public function __construct(string $id)
|
||||
{
|
||||
$this->id = $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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
29
vendor/lcobucci/jwt/src/Validation/Constraint/IssuedBy.php
vendored
Normal file
29
vendor/lcobucci/jwt/src/Validation/Constraint/IssuedBy.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?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 string[] */
|
||||
private array $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
vendor/lcobucci/jwt/src/Validation/Constraint/LeewayCannotBeNegative.php
vendored
Normal file
15
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');
|
||||
}
|
||||
}
|
69
vendor/lcobucci/jwt/src/Validation/Constraint/LooseValidAt.php
vendored
Normal file
69
vendor/lcobucci/jwt/src/Validation/Constraint/LooseValidAt.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\Clock\Clock;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\ValidAt as ValidAtInterface;
|
||||
|
||||
final class LooseValidAt implements ValidAtInterface
|
||||
{
|
||||
private Clock $clock;
|
||||
private DateInterval $leeway;
|
||||
|
||||
public function __construct(Clock $clock, ?DateInterval $leeway = null)
|
||||
{
|
||||
$this->clock = $clock;
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
28
vendor/lcobucci/jwt/src/Validation/Constraint/PermittedFor.php
vendored
Normal file
28
vendor/lcobucci/jwt/src/Validation/Constraint/PermittedFor.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
{
|
||||
private string $audience;
|
||||
|
||||
public function __construct(string $audience)
|
||||
{
|
||||
$this->audience = $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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
28
vendor/lcobucci/jwt/src/Validation/Constraint/RelatedTo.php
vendored
Normal file
28
vendor/lcobucci/jwt/src/Validation/Constraint/RelatedTo.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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
|
||||
{
|
||||
private string $subject;
|
||||
|
||||
public function __construct(string $subject)
|
||||
{
|
||||
$this->subject = $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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
37
vendor/lcobucci/jwt/src/Validation/Constraint/SignedWith.php
vendored
Normal file
37
vendor/lcobucci/jwt/src/Validation/Constraint/SignedWith.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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
|
||||
{
|
||||
private Signer $signer;
|
||||
private Signer\Key $key;
|
||||
|
||||
public function __construct(Signer $signer, Signer\Key $key)
|
||||
{
|
||||
$this->signer = $signer;
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
}
|
86
vendor/lcobucci/jwt/src/Validation/Constraint/StrictValidAt.php
vendored
Normal file
86
vendor/lcobucci/jwt/src/Validation/Constraint/StrictValidAt.php
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Lcobucci\JWT\Validation\Constraint;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Lcobucci\Clock\Clock;
|
||||
use Lcobucci\JWT\Token;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\ConstraintViolation;
|
||||
use Lcobucci\JWT\Validation\ValidAt as ValidAtInterface;
|
||||
|
||||
final class StrictValidAt implements ValidAtInterface
|
||||
{
|
||||
private Clock $clock;
|
||||
private DateInterval $leeway;
|
||||
|
||||
public function __construct(Clock $clock, ?DateInterval $leeway = null)
|
||||
{
|
||||
$this->clock = $clock;
|
||||
$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);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user