🍲dfcv🏰dd⋉(● ∸ ●)⋊@% PNG %k25u25%fgd5n! PNG %k25u25%fgd5n!clock/src/SystemClock.php000064400000001175152427537560011423 0ustar00timezone); } } clock/src/Clock.php000064400000000322152427537560010207 0ustar00now = $now; } public function now(): DateTimeImmutable { return $this->now; } } clock/composer.json000064400000002406152427537560010403 0ustar00{ "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", "stella-maris/clock": "^0.1.7" }, "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" } } clock/LICENSE000064400000002056152427537560006667 0ustar00MIT 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. clock/renovate.json000064400000000206152427537560010373 0ustar00{ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>lcobucci/.github:renovate-config" ] } jwt/src/Encoding/CannotEncodeContent.php000064400000000562152427537560014314 0ustar00convertDate($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'); } } jwt/src/Encoding/JoseEncoder.php000064400000003343152427537560012621 0ustar00 */ private array $formatters; public function __construct(ClaimsFormatter ...$formatters) { $this->formatters = $formatters; } public static function default(): self { return new self(new UnifyAudience(), new MicrosecondBasedDateConversion()); } /** @inheritdoc */ public function formatClaims(array $claims): array { foreach ($this->formatters as $formatter) { $claims = $formatter->formatClaims($claims); } return $claims; } } jwt/src/Encoding/UnifyAudience.php000064400000001244152427537560013147 0ustar00 */ private array $headers = ['typ' => 'JWT', 'alg' => null]; /** @var array */ 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 $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) ); } } jwt/src/Token/InvalidTokenStructure.php000064400000001177152427537560014266 0ustar00hash = $hash; $this->encoded = $encoded; } 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; } } jwt/src/Token/UnsupportedHeaderFound.php000064400000000515152427537560014406 0ustar00headers = $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(); } } jwt/src/Token/DataSet.php000064400000001554152427537560011302 0ustar00 */ private array $data; private string $encoded; /** @param 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 mixed[] */ public function all(): array { return $this->data; } public function toString(): string { return $this->encoded; } } jwt/src/Token/Parser.php000064400000010053152427537560011203 0ustar00decoder = $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); } } jwt/src/Signer/Ecdsa/MultibyteStringConverter.php000064400000011130152427537560016167 0ustar00 self::ASN1_MAX_SINGLE_BYTE ? self::ASN1_LENGTH_2BYTES : ''; $asn1 = hex2bin( self::ASN1_SEQUENCE . $lengthPrefix . dechex($totalLength) . self::ASN1_INTEGER . dechex($lengthR) . $pointR . self::ASN1_INTEGER . dechex($lengthS) . $pointS ); assert(is_string($asn1)); return $asn1; } private static function octetLength(string $data): int { return (int) (mb_strlen($data, '8bit') / self::BYTE_SIZE); } 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 ) { $data = mb_substr($data, 2, null, '8bit'); } return $data; } public function fromAsn1(string $signature, int $length): string { $message = bin2hex($signature); $position = 0; if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_SEQUENCE) { throw ConversionFailed::incorrectStartSequence(); } // @phpstan-ignore-next-line if (self::readAsn1Content($message, $position, self::BYTE_SIZE) === self::ASN1_LENGTH_2BYTES) { $position += self::BYTE_SIZE; } $pointR = self::retrievePositiveInteger(self::readAsn1Integer($message, $position)); $pointS = self::retrievePositiveInteger(self::readAsn1Integer($message, $position)); $points = hex2bin(str_pad($pointR, $length, '0', STR_PAD_LEFT) . str_pad($pointS, $length, '0', STR_PAD_LEFT)); assert(is_string($points)); return $points; } private static function readAsn1Content(string $message, int &$position, int $length): string { $content = mb_substr($message, $position, $length, '8bit'); $position += $length; return $content; } private static function readAsn1Integer(string $message, int &$position): string { if (self::readAsn1Content($message, $position, self::BYTE_SIZE) !== self::ASN1_INTEGER) { throw ConversionFailed::integerExpected(); } $length = (int) hexdec(self::readAsn1Content($message, $position, self::BYTE_SIZE)); return self::readAsn1Content($message, $position, $length * self::BYTE_SIZE); } private static function retrievePositiveInteger(string $data): string { while ( 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; } } jwt/src/Signer/Ecdsa/Sha512.php000064400000000625152427537560012104 0ustar00contents = $contents; $this->passphrase = $passphrase; } public static function empty(): self { return new self('', ''); } public static function plainText(string $contents, string $passphrase = ''): self { return new self($contents, $passphrase); } public static function base64Encoded(string $contents, string $passphrase = ''): self { $decoded = base64_decode($contents, true); if ($decoded === false) { throw CannotDecodeContent::invalidBase64String(); } 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)); return new self($contents, $passphrase); } public function contents(): string { return $this->contents; } public function passphrase(): string { return $this->passphrase; } } jwt/src/Signer/Key/LocalFileReference.php000064400000002315152427537560014321 0ustar00path = $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; } } jwt/src/Signer/Key/FileCouldNotBeRead.php000064400000000723152427537560014243 0ustar00getPrivateKey($pem, $passphrase); try { $signature = ''; if (! openssl_sign($payload, $signature, $key, $this->algorithm())) { $error = openssl_error_string(); assert(is_string($error)); throw CannotSignPayload::errorHappened($error); } return $signature; } finally { $this->freeKey($key); } } /** * @return resource|OpenSSLAsymmetricKey * * @throws CannotSignPayload */ private function getPrivateKey(string $pem, string $passphrase) { $privateKey = openssl_pkey_get_private($pem, $passphrase); $this->validateKey($privateKey); return $privateKey; } /** @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; } /** * @return resource|OpenSSLAsymmetricKey * * @throws InvalidKeyProvided */ private function getPublicKey(string $pem) { $publicKey = openssl_pkey_get_public($pem); $this->validateKey($publicKey); return $publicKey; } /** * Raises an exception when the key type is not the expected type * * @param resource|OpenSSLAsymmetricKey|bool $key * * @throws InvalidKeyProvided */ private function validateKey($key): void { if (is_bool($key)) { $error = openssl_error_string(); assert(is_string($error)); throw InvalidKeyProvided::cannotBeParsed($error); } $details = openssl_pkey_get_details($key); assert(is_array($details)); if (! array_key_exists('key', $details) || $details['type'] !== $this->keyType()) { throw InvalidKeyProvided::incompatibleKey(); } } /** @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 the type of key to be used to create/verify the signature (using OpenSSL constants) * * @internal */ abstract public function keyType(): int; /** * Returns which algorithm to be used to create/verify the signature (using OpenSSL constants) * * @internal */ abstract public function algorithm(): int; } jwt/src/Signer/CannotSignPayload.php000064400000000564152427537560013501 0ustar00algorithm(), $payload, $key->contents(), true); } final public function verify(string $expected, string $payload, Key $key): bool { return hash_equals($expected, $this->sign($payload, $key)); } abstract public function algorithm(): string; } jwt/src/Signer/Rsa.php000064400000001065152427537560010646 0ustar00createSignature($key->contents(), $key->passphrase(), $payload); } final public function verify(string $expected, string $payload, Key $key): bool { return $this->verifySignature($expected, $payload, $key->contents()); } final public function keyType(): int { return OPENSSL_KEYTYPE_RSA; } } jwt/src/Signer/InvalidKeyProvided.php000064400000001000152427537560013642 0ustar00converter = $converter; } public static function create(): Ecdsa { 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->keyLength() ); } final public function verify(string $expected, string $payload, Key $key): bool { return $this->verifySignature( $this->converter->toAsn1($expected, $this->keyLength()), $payload, $key->contents() ); } final public function keyType(): int { return OPENSSL_KEYTYPE_EC; } /** * 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 keyLength(): int; } jwt/src/Validation/Constraint/LeewayCannotBeNegative.php000064400000000523152427537560017431 0ustar00id = $id; } public function assert(Token $token): void { if (! $token->isIdentifiedBy($this->id)) { throw new ConstraintViolation( 'The token is not identified with the expected ID' ); } } } jwt/src/Validation/Constraint/ValidAt.php000064400000003611152427537560014433 0ustar00clock = $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 new ConstraintViolation('The token is expired'); } } /** @throws ConstraintViolation */ private function assertMinimumTime(Token $token, DateTimeInterface $now): void { if (! $token->isMinimumTimeBefore($now)) { throw new ConstraintViolation('The token cannot be used yet'); } } /** @throws ConstraintViolation */ private function assertIssueTime(Token $token, DateTimeInterface $now): void { if (! $token->hasBeenIssuedBefore($now)) { throw new ConstraintViolation('The token was issued in the future'); } } } jwt/src/Validation/Constraint/RelatedTo.php000064400000001147152427537560014774 0ustar00subject = $subject; } public function assert(Token $token): void { if (! $token->isRelatedTo($this->subject)) { throw new ConstraintViolation( 'The token is not related to the expected subject' ); } } } jwt/src/Validation/Constraint/SignedWith.php000064400000001744152427537560015161 0ustar00signer = $signer; $this->key = $key; } public function assert(Token $token): void { if (! $token instanceof Token\Plain) { throw new ConstraintViolation('You should pass a plain token'); } if ($token->headers()->get('alg') !== $this->signer->algorithmId()) { throw new ConstraintViolation('Token signer mismatch'); } if (! $this->signer->verify($token->signature()->hash(), $token->payload(), $this->key)) { throw new ConstraintViolation('Token signature mismatch'); } } } jwt/src/Validation/Constraint/IssuedBy.php000064400000001205152427537560014633 0ustar00issuers = $issuers; } public function assert(Token $token): void { if (! $token->hasBeenIssuedBy(...$this->issuers)) { throw new ConstraintViolation( 'The token was not issued by the given issuers' ); } } } jwt/src/Validation/Constraint/PermittedFor.php000064400000001166152427537560015516 0ustar00audience = $audience; } public function assert(Token $token): void { if (! $token->isPermittedFor($this->audience)) { throw new ConstraintViolation( 'The token is not allowed to be used by this audience' ); } } } jwt/src/Validation/NoConstraintsGiven.php000064400000000310152427537560014551 0ustar00violations = $violations; return $exception; } /** @param ConstraintViolation[] $violations */ private static function buildMessage(array $violations): string { $violations = array_map( static function (ConstraintViolation $violation): string { return '- ' . $violation->getMessage(); }, $violations ); $message = "The token violates some mandatory constraints, details:\n"; $message .= implode("\n", $violations); return $message; } /** @return ConstraintViolation[] */ public function violations(): array { return $this->violations; } } jwt/src/Validation/Constraint.php000064400000000315152427537560013105 0ustar00checkConstraint($constraint, $token, $violations); } if ($violations) { throw RequiredConstraintsViolated::fromViolations(...$violations); } } /** @param ConstraintViolation[] $violations */ private function checkConstraint( Constraint $constraint, Token $token, array &$violations ): void { try { $constraint->assert($token); } catch (ConstraintViolation $e) { $violations[] = $e; } } public function validate(Token $token, Constraint ...$constraints): bool { if ($constraints === []) { throw new NoConstraintsGiven('No constraint given.'); } try { foreach ($constraints as $constraint) { $constraint->assert($token); } return true; } catch (ConstraintViolation $e) { return false; } } } jwt/src/Encoder.php000064400000001012152427537560010241 0ustar00signer = $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 ); } 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; } } jwt/src/ClaimsFormatter.php000064400000000365152427537560011770 0ustar00 $claims * * @return array */ public function formatClaims(array $claims): array; } jwt/src/Token.php000064400000002376152427537560007760 0ustar00