Full Code of tymondesigns/jwt-auth for AI

2.x 6c70930a9271 cached
122 files
300.0 KB
78.7k tokens
651 symbols
1 requests
Download .txt
Showing preview only (328K chars total). Download the full file or copy to clipboard to get everything.
Repository: tymondesigns/jwt-auth
Branch: 2.x
Commit: 6c70930a9271
Files: 122
Total size: 300.0 KB

Directory structure:
gitextract_f_blvbi4/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       └── phpunit.yml
├── .gitignore
├── .styleci.yml
├── LICENSE
├── README.md
├── composer.json
├── config/
│   └── config.php
├── docs/
│   ├── auth-guard.md
│   ├── configuration.md
│   ├── exception-handling.md
│   ├── index.md
│   ├── laravel-installation.md
│   ├── lumen-installation.md
│   ├── quick-start.md
│   └── resources.md
├── mkdocs.yml
├── phpunit.xml.dist
├── src/
│   ├── Blacklist.php
│   ├── Claims/
│   │   ├── Audience.php
│   │   ├── Claim.php
│   │   ├── Collection.php
│   │   ├── Custom.php
│   │   ├── DatetimeTrait.php
│   │   ├── Expiration.php
│   │   ├── Factory.php
│   │   ├── IssuedAt.php
│   │   ├── Issuer.php
│   │   ├── JwtId.php
│   │   ├── NotBefore.php
│   │   └── Subject.php
│   ├── Console/
│   │   └── JWTGenerateSecretCommand.php
│   ├── Contracts/
│   │   ├── Claim.php
│   │   ├── Http/
│   │   │   └── Parser.php
│   │   ├── JWTSubject.php
│   │   ├── Providers/
│   │   │   ├── Auth.php
│   │   │   ├── JWT.php
│   │   │   └── Storage.php
│   │   └── Validator.php
│   ├── Exceptions/
│   │   ├── InvalidClaimException.php
│   │   ├── JWTException.php
│   │   ├── PayloadException.php
│   │   ├── TokenBlacklistedException.php
│   │   ├── TokenExpiredException.php
│   │   ├── TokenInvalidException.php
│   │   └── UserNotDefinedException.php
│   ├── Facades/
│   │   ├── JWTAuth.php
│   │   ├── JWTFactory.php
│   │   └── JWTProvider.php
│   ├── Factory.php
│   ├── Http/
│   │   ├── Middleware/
│   │   │   ├── Authenticate.php
│   │   │   ├── AuthenticateAndRenew.php
│   │   │   ├── BaseMiddleware.php
│   │   │   ├── Check.php
│   │   │   └── RefreshToken.php
│   │   └── Parser/
│   │       ├── AuthHeaders.php
│   │       ├── Cookies.php
│   │       ├── InputSource.php
│   │       ├── KeyTrait.php
│   │       ├── LumenRouteParams.php
│   │       ├── Parser.php
│   │       ├── QueryString.php
│   │       └── RouteParams.php
│   ├── JWT.php
│   ├── JWTAuth.php
│   ├── JWTGuard.php
│   ├── Manager.php
│   ├── Payload.php
│   ├── Providers/
│   │   ├── AbstractServiceProvider.php
│   │   ├── Auth/
│   │   │   └── Illuminate.php
│   │   ├── JWT/
│   │   │   ├── Lcobucci.php
│   │   │   └── Provider.php
│   │   ├── LaravelServiceProvider.php
│   │   ├── LumenServiceProvider.php
│   │   └── Storage/
│   │       └── Illuminate.php
│   ├── Support/
│   │   ├── CustomClaims.php
│   │   ├── RefreshFlow.php
│   │   └── Utils.php
│   ├── Token.php
│   └── Validators/
│       ├── PayloadValidator.php
│       ├── TokenValidator.php
│       └── Validator.php
└── tests/
    ├── AbstractTestCase.php
    ├── BlacklistTest.php
    ├── Claims/
    │   ├── ClaimTest.php
    │   ├── CollectionTest.php
    │   ├── DatetimeClaimTest.php
    │   ├── FactoryTest.php
    │   ├── IssuedAtTest.php
    │   └── NotBeforeTest.php
    ├── FactoryTest.php
    ├── Fixtures/
    │   └── Foo.php
    ├── Http/
    │   └── ParserTest.php
    ├── JWTAuthTest.php
    ├── JWTGuardTest.php
    ├── ManagerTest.php
    ├── Middleware/
    │   ├── AbstractMiddlewareTest.php
    │   ├── AuthenticateAndRenewTest.php
    │   ├── AuthenticateTest.php
    │   ├── CheckTest.php
    │   └── RefreshTokenTest.php
    ├── PayloadTest.php
    ├── Providers/
    │   ├── Auth/
    │   │   └── IlluminateTest.php
    │   ├── JWT/
    │   │   ├── LcobucciTest.php
    │   │   └── ProviderTest.php
    │   ├── Keys/
    │   │   ├── id_ecdsa
    │   │   ├── id_ecdsa.pub
    │   │   ├── id_rsa
    │   │   └── id_rsa.pub
    │   └── Storage/
    │       └── IlluminateTest.php
    ├── Stubs/
    │   ├── JWTProviderStub.php
    │   ├── LaravelUserStub.php
    │   ├── TaggedStorage.php
    │   └── UserStub.php
    ├── TokenTest.php
    └── Validators/
        ├── PayloadValidatorTest.php
        └── TokenValidatorTest.php

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.yml]
indent_style = space
indent_size = 2


================================================
FILE: .gitattributes
================================================
* text=auto

/tests export-ignore
/docs export-ignore
/.codecov.yml export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.styleci.yml export-ignore
/.travis.yml export-ignore
/.github export-ignore
/phpunit.xml.dist export-ignore
/README.md export-ignore
/mkdocs.yml export-ignore


================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at tymon148@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributors Guide

Please read and understand the contribution guide before creating an issue or pull request.

## Etiquette

This project is open source, and as such, the maintainers give their free time to build and maintain the source code held within. They make the code freely available in the hope that it will be of use to other developers. It would be extremely unfair for them to suffer abuse or anger for their hard work.

Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the world that developers are civilized and selfless people.

It's the duty of the maintainer to ensure that all submissions to the project are of sufficient quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used.

## Viability

When requesting or submitting new features, first consider whether it might be useful to others. Open source projects are used by many developers, who may have entirely different needs to your own. Think about whether or not your feature is likely to be used by other users of the project.

## Procedure

Before filing an issue:

- Attempt to replicate the problem, to ensure that it wasn't a coincidental incident.
- Check to make sure your feature suggestion isn't already present within the project.
- Check the pull requests tab to ensure that the bug doesn't have a fix in progress.
- Check the pull requests tab to ensure that the feature isn't already in progress.

Before submitting a pull request:

- Ensure that your submission is [viable](#viability) for the project.
- Check the codebase to ensure that your feature doesn't already exist.
- Check the pull requests to ensure that another person hasn't already submitted the feature or fix.

## Requirements

If the project maintainer has any additional requirements, you will find them listed here.

- No additional requirements.


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
### Subject of the issue
Describe your issue here.

### Your environment
| Q                 | A
| ----------------- | ---
| Bug?              | no / yes
| New Feature?      | no / yes
| Framework         | Laravel / Lumen
| Framework version | 5.x.y
| Package version   | 1.x.y
| PHP version       | 5.x.y / 7.x.y

### Steps to reproduce
Tell us how to reproduce this issue.

### Expected behaviour
Tell us what should happen

### Actual behaviour
Tell us what happens instead


================================================
FILE: .github/stale.yml
================================================
daysUntilStale: 60
daysUntilClose: 7
exemptLabels:
  - pinned
  - security
staleLabel: stale


================================================
FILE: .github/workflows/phpunit.yml
================================================
name: PHPUnit tests

on:
  push:
  release:
    types:
      - published

jobs:
  php-tests:
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        php: [8.0, 8.1, 8.2, 8.3, 8.4, 8.5]
        laravel: [9.*, 10.*, 11.*, 12.*, 13.*]
        os: [ubuntu-latest]
        coverage: [none]
        stability: [prefer-lowest, prefer-stable]
        include:
          - php: 8.5
            laravel: 12.*
            os: ubuntu-latest
            coverage: xdebug
            stability: prefer-stable
        exclude:
          - php: 8.0
            laravel: 10.*
          - php: 8.0
            laravel: 11.*
          - php: 8.1
            laravel: 11.*
          - php: 8.0
            laravel: 12.*
          - php: 8.1
            laravel: 12.*
          - php: 8.0
            laravel: 13.*
          - php: 8.1
            laravel: 13.*
          - php: 8.2
            laravel: 13.*

    name: PHP${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v1

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mbstring json openssl
          coverage: ${{ matrix.coverage }}
          ini-values: memory_limit=-1

      - name: Get composer cache directory
        id: composer-cache
        run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: "php-${{ matrix.php }}-laravel-${{ matrix.laravel }}-${{ matrix.stability }}-${{ hashFiles('**/composer.json') }}"
          restore-keys: "php-${{ matrix.php }}-laravel-${{ matrix.laravel }}-${{ matrix.stability }}-${{ hashFiles('**/composer.json') }}"

      - name: Install dependencies
        run: |
          composer require "illuminate/contracts:${{ matrix.laravel }}" --no-interaction --no-progress --no-update
          composer update --${{ matrix.stability }} --no-progress --prefer-dist --no-interaction

      - name: Execute tests
        run: composer test:ci

      - name: Upload coverage
        uses: codecov/codecov-action@v5
        if: matrix.coverage == 'xdebug'
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./coverage.xml


================================================
FILE: .gitignore
================================================
/vendor
composer.lock
build
coverage.xml
.phpunit.result.cache


================================================
FILE: .styleci.yml
================================================
preset: laravel

enabled:
  - no_useless_else
  - unalign_double_arrow


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) Sean Tymon

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.


================================================
FILE: README.md
================================================
![jwt-auth-banner](https://cloud.githubusercontent.com/assets/1801923/9915273/119b9350-5cae-11e5-850b-c941cac60b32.png)

[![PHPUnit](https://github.com/tymondesigns/jwt-auth/workflows/PHPUnit%20tests/badge.svg)](https://github.com/tymondesigns/jwt-auth/actions)
[![Codecov branch](https://img.shields.io/codecov/c/github/tymondesigns/jwt-auth/develop.svg?style=flat-square&logo=codecov)](https://codecov.io/github/tymondesigns/jwt-auth)
[![StyleCI](https://styleci.io/repos/23680678/shield?style=flat-square)](https://styleci.io/repos/23680678)
[![Latest Version](http://img.shields.io/packagist/v/tymon/jwt-auth.svg?style=flat-square&logo=composer)](https://packagist.org/packages/tymon/jwt-auth)
[![Latest Dev Version](https://img.shields.io/packagist/vpre/tymon/jwt-auth.svg?style=flat-square&logo=composer)](https://packagist.org/packages/tymon/jwt-auth#dev-develop)
[![Monthly Downloads](https://img.shields.io/packagist/dm/tymon/jwt-auth.svg?style=flat-square&logo=composer)](https://packagist.org/packages/tymon/jwt-auth)

## Documentation

[jwt-auth.com](https://jwt-auth.com)

-----------------------------------

## Security

If you discover any security related issues, please email tymon148@gmail.com instead of using the issue tracker.

## License

The MIT License (MIT)


================================================
FILE: composer.json
================================================
{
    "name": "tymon/jwt-auth",
    "description": "JSON Web Token Authentication for Laravel and Lumen",
    "keywords": [
        "auth",
        "authentication",
        "json web token",
        "jwt",
        "laravel"
    ],
    "homepage": "https://github.com/tymondesigns/jwt-auth",
    "support": {
        "issues": "https://github.com/tymondesigns/jwt-auth/issues",
        "source": "https://github.com/tymondesigns/jwt-auth"
    },
    "license": "MIT",
    "authors": [
        {
            "name": "Sean Tymon",
            "email": "tymon148@gmail.com",
            "homepage": "https://tymon.xyz",
            "role": "Developer"
        }
    ],
    "require": {
        "php": "^8.0",
        "illuminate/auth": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "illuminate/http": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "illuminate/support": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "lcobucci/jwt": "^4.0|^5.0",
        "nesbot/carbon": "^2.69|^3.0"
    },
    "require-dev": {
        "illuminate/console": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "illuminate/database": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "illuminate/routing": "^9.0|^10.0|^11.0|^12.0|^13.0",
        "mockery/mockery": "^1.6",
        "phpunit/phpunit": "^9.4"
    },
    "autoload": {
        "psr-4": {
            "Tymon\\JWTAuth\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tymon\\JWTAuth\\Test\\": "tests/"
        }
    },
    "extra": {
        "branch-alias": {
            "dev-develop": "1.0-dev",
            "dev-2.x": "2.0-dev"
        },
        "laravel": {
            "aliases": {
                "JWTAuth": "Tymon\\JWTAuth\\Facades\\JWTAuth",
                "JWTFactory": "Tymon\\JWTAuth\\Facades\\JWTFactory"
            },
            "providers": [
                "Tymon\\JWTAuth\\Providers\\LaravelServiceProvider"
            ]
        }
    },
    "config": {
        "sort-packages": true
    },
    "prefer-stable": true,
    "minimum-stability": "dev",
    "scripts": {
        "test": "phpunit --colors=always",
        "test:ci": "composer test -- --verbose --coverage-text --coverage-clover=coverage.xml"
    }
}


================================================
FILE: config/config.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

return [

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Secret
    |--------------------------------------------------------------------------
    |
    | Don't forget to set this in your .env file, as it will be used to sign
    | your tokens. A helper command is provided for this:
    | `php artisan jwt:secret`
    |
    | Note: This will be used for Symmetric algorithms only (HMAC),
    | since RSA and ECDSA use a private/public key combo (See below).
    |
    */

    'secret' => env('JWT_SECRET'),

    /*
    |--------------------------------------------------------------------------
    | JWT Authentication Keys
    |--------------------------------------------------------------------------
    |
    | The algorithm you are using, will determine whether your tokens are
    | signed with a random string (defined in `JWT_SECRET`) or using the
    | following public & private keys.
    |
    | Symmetric Algorithms:
    | HS256, HS384 & HS512 will use `JWT_SECRET`.
    |
    | Asymmetric Algorithms:
    | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
    |
    */

    'keys' => [

        /*
        |--------------------------------------------------------------------------
        | Public Key
        |--------------------------------------------------------------------------
        |
        | A path or resource to your public key.
        |
        | E.g. 'file://path/to/public/key'
        |
        */

        'public' => env('JWT_PUBLIC_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Private Key
        |--------------------------------------------------------------------------
        |
        | A path or resource to your private key.
        |
        | E.g. 'file://path/to/private/key'
        |
        */

        'private' => env('JWT_PRIVATE_KEY'),

        /*
        |--------------------------------------------------------------------------
        | Passphrase
        |--------------------------------------------------------------------------
        |
        | The passphrase for your private key. Can be null if none set.
        |
        */

        'passphrase' => env('JWT_PASSPHRASE'),

    ],

    /*
    |--------------------------------------------------------------------------
    | JWT time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token will be valid for.
    | Defaults to 1 hour.
    |
    | You can also set this to null, to yield a never expiring token.
    | Some people may want this behaviour for e.g. a mobile app.
    | This is not particularly recommended, so make sure you have appropriate
    | systems in place to revoke the token if necessary.
    | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
    |
    */

    'ttl' => env('JWT_TTL', 60),

    /*
    |--------------------------------------------------------------------------
    | Refresh time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token can be refreshed
    | within. I.E. The user can refresh their token within a 2 week window of
    | the original token being created until they must re-authenticate.
    | Defaults to 2 weeks.
    |
    | You can also set this to null, to yield an infinite refresh time.
    | Some may want this instead of never expiring tokens for e.g. a mobile app.
    | This is not particularly recommended, so make sure you have appropriate
    | systems in place to revoke the token if necessary.
    |
    */

    'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),

    /*
    |--------------------------------------------------------------------------
    | JWT hashing algorithm
    |--------------------------------------------------------------------------
    |
    | Specify the hashing algorithm that will be used to sign the token.
    |
    */

    'algo' => env('JWT_ALGO', Tymon\JWTAuth\Providers\JWT\Provider::ALGO_HS256),

    /*
    |--------------------------------------------------------------------------
    | Required Claims
    |--------------------------------------------------------------------------
    |
    | Specify the required claims that must exist in any token.
    | A TokenInvalidException will be thrown if any of these claims are not
    | present in the payload.
    |
    */

    'required_claims' => [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti',
    ],

    /*
    |--------------------------------------------------------------------------
    | Persistent Claims
    |--------------------------------------------------------------------------
    |
    | Specify the claim keys to be persisted when refreshing a token.
    | `sub` and `iat` will automatically be persisted, in
    | addition to the these claims.
    |
    | Note: If a claim does not exist then it will be ignored.
    |
    */

    'persistent_claims' => [
        // 'foo',
        // 'bar',
    ],

    /*
    |--------------------------------------------------------------------------
    | Lock Subject
    |--------------------------------------------------------------------------
    |
    | This will determine whether a `prv` claim is automatically added to
    | the token. The purpose of this is to ensure that if you have multiple
    | authentication models e.g. `App\User` & `App\OtherPerson`, then we
    | should prevent one authentication request from impersonating another,
    | if 2 tokens happen to have the same id across the 2 different models.
    |
    | Under specific circumstances, you may want to disable this behaviour
    | e.g. if you only have one authentication model, then you would save
    | a little on token size.
    |
    */

    'lock_subject' => true,

    /*
    |--------------------------------------------------------------------------
    | Leeway
    |--------------------------------------------------------------------------
    |
    | This property gives the jwt timestamp claims some "leeway".
    | Meaning that if you have any unavoidable slight clock skew on
    | any of your servers then this will afford you some level of cushioning.
    |
    | This applies to the claims `iat`, `nbf` and `exp`.
    |
    | Specify in seconds - only if you know you need it.
    |
    */

    'leeway' => env('JWT_LEEWAY', 0),

    /*
    |--------------------------------------------------------------------------
    | Blacklist Enabled
    |--------------------------------------------------------------------------
    |
    | In order to invalidate tokens, you must have the blacklist enabled.
    | If you do not want or need this functionality, then set this to false.
    |
    */

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    /*
    | -------------------------------------------------------------------------
    | Blacklist Grace Period
    | -------------------------------------------------------------------------
    |
    | When multiple concurrent requests are made with the same JWT,
    | it is possible that some of them fail, due to token regeneration
    | on every request.
    |
    | Set grace period in seconds to prevent parallel request failure.
    |
    */

    'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),

    /*
    |--------------------------------------------------------------------------
    | Cookies encryption
    |--------------------------------------------------------------------------
    |
    | By default Laravel encrypt cookies for security reason.
    | If you decide to not decrypt cookies, you will have to configure Laravel
    | to not encrypt your cookie token by adding its name into the $except
    | array available in the middleware "EncryptCookies" provided by Laravel.
    | see https://laravel.com/docs/master/responses#cookies-and-encryption
    | for details.
    |
    | Set it to true if you want to decrypt cookies.
    |
    */

    'decrypt_cookies' => false,

    /*
    |--------------------------------------------------------------------------
    | Providers
    |--------------------------------------------------------------------------
    |
    | Specify the various providers used throughout the package.
    |
    */

    'providers' => [

        /*
        |--------------------------------------------------------------------------
        | JWT Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to create and decode the tokens.
        |
        */

        'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,

        /*
        |--------------------------------------------------------------------------
        | Authentication Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to authenticate users.
        |
        */

        'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

        /*
        |--------------------------------------------------------------------------
        | Storage Provider
        |--------------------------------------------------------------------------
        |
        | Specify the provider that is used to store tokens in the blacklist.
        |
        */

        'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,

    ],

];


================================================
FILE: docs/auth-guard.md
================================================
## Methods

The following methods are available on the Auth guard instance.

### Multiple Guards

If the newly created 'api' guard is not set as a default guard or you have defined multiple guards to handle authentication,
you should specify the guard when calling auth().

```php
  $token = auth('api')->attempt($credentials);
```

### attempt()

Attempt to authenticate a user via some credentials.

```php
// Generate a token for the user if the credentials are valid
$token = auth()->attempt($credentials);
```

This will return either a jwt or `null`

### login()

Log a user in and return a jwt for them.

```php
// Get some user from somewhere
$user = User::first();

// Get the token
$token = auth()->login($user);
```

### user()

Get the currently authenticated user.

```php
// Get the currently authenticated user
$user = auth()->user();
```

If the user is not then authenticated, then `null` will be returned.

### userOrFail()

Get the currently authenticated user or throw an exception.

```php
try {
    $user = auth()->userOrFail();
} catch (\Tymon\JWTAuth\Exceptions\UserNotDefinedException $e) {
    // do something
}

```

If the user is not set, then a `Tymon\JWTAuth\Exceptions\UserNotDefinedException` will be thrown

### logout()

Log the user out - which will invalidate the current token and unset the authenticated user.

```php
auth()->logout();

// Pass true to force the token to be blacklisted "forever"
auth()->logout(true);
```

### refresh()

Refresh a token, which invalidates the current one

```php
$newToken = auth()->refresh();

// Pass true as the first param to force the token to be blacklisted "forever".
// The second parameter will reset the claims for the new token
$newToken = auth()->refresh(true, true);
```

### invalidate()

Invalidate the token (add it to the blacklist)

```php
auth()->invalidate();

// Pass true as the first param to force the token to be blacklisted "forever".
auth()->invalidate(true);
```

### tokenById()

Get a token based on a given user's id.

```php
$token = auth()->tokenById(123);
```

### payload()

Get the raw JWT payload

```php
$payload = auth()->payload();

// then you can access the claims directly e.g.
$payload->get('sub'); // = 123
$payload['jti']; // = 'asfe4fq434asdf'
$payload('exp') // = 123456
$payload->toArray(); // = ['sub' => 123, 'exp' => 123456, 'jti' => 'asfe4fq434asdf'] etc
```

### validate()

Validate a user's credentials

```php
if (auth()->validate($credentials)) {
    // credentials are valid
}
```

## More advanced usage

### Adding custom claims

```php
$token = auth()->claims(['foo' => 'bar'])->attempt($credentials);
```

### Set the token explicitly

```php
$user = auth()->setToken('eyJhb...')->user();
```

### Set the request instance explicitly

```php
$user = auth()->setRequest($request)->user();
```

### Override the token ttl

```php
$token = auth()->setTTL(7200)->attempt($credentials);
```


================================================
FILE: docs/configuration.md
================================================
Let's review some of the options in the `config/jwt.php` file that we published earlier.
I won't go through all of the options here since [the file itself](https://github.com/tymondesigns/jwt-auth/blob/1.0.0-beta.2/config/config.php) is pretty well documented.

First up is:

```
'secret' => env('JWT_SECRET'),
```

Coming soon...


================================================
FILE: docs/exception-handling.md
================================================
Coming soon...


================================================
FILE: docs/index.md
================================================
JSON Web Token Authentication for Laravel & Lumen

![jwt-auth-banner](https://cloud.githubusercontent.com/assets/1801923/9915273/119b9350-5cae-11e5-850b-c941cac60b32.png)


================================================
FILE: docs/laravel-installation.md
================================================
### Install via composer

Run the following command to pull in the latest version:

```bash
composer require tymon/jwt-auth
```

-------------------------------------------------------------------------------

### Add service provider ( Laravel 5.4 or below )

Add the service provider to the `providers` array in the `config/app.php` config file as follows:

```php
'providers' => [

    ...

    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
```

-------------------------------------------------------------------------------

### Publish the config

Run the following command to publish the package config file:

```bash
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
```

You should now have a `config/jwt.php` file that allows you to configure the basics of this package.

-------------------------------------------------------------------------------

### Generate secret key

I have included a helper command to generate a key for you:

```bash
php artisan jwt:secret
```

This will update your `.env` file with something like `JWT_SECRET=foobar`

It is the key that will be used to sign your tokens. How that happens exactly will depend
on the algorithm that you choose to use.


================================================
FILE: docs/lumen-installation.md
================================================
### Install via composer

Run the following command to pull in the latest version:

```bash
composer require tymon/jwt-auth
```

-------------------------------------------------------------------------------

### Copy the config

Copy the `config` file from `vendor/tymon/jwt-auth/config/config.php` to `config` folder of your Lumen application and rename it to `jwt.php`

Register your config by adding the following in the `bootstrap/app.php` before middleware declaration.

```php
$app->configure('jwt');
```

-------------------------------------------------------------------------------

### Bootstrap file changes

Add the following snippet to the `bootstrap/app.php` file under the providers section as follows:

```php
// Uncomment this line
$app->register(App\Providers\AuthServiceProvider::class);

// Add this line
$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
```

Then uncomment the `auth` middleware in the same file:

```php
$app->routeMiddleware([
    'auth' => App\Http\Middleware\Authenticate::class,
]);
```

-------------------------------------------------------------------------------

### Generate secret key

I have included a helper command to generate a key for you:

```bash
php artisan jwt:secret
```

This will update your `.env` file with something like `JWT_SECRET=foobar`

It is the key that will be used to sign your tokens. How that happens exactly will depend
on the algorithm that you choose to use.


================================================
FILE: docs/quick-start.md
================================================
Before continuing, make sure you have installed the package as per the installation instructions for
[Laravel](laravel-installation) or [Lumen](lumen-installation).

### Update your User model

Firstly you need to implement the `Tymon\JWTAuth\Contracts\JWTSubject` contract on your User model,
which requires that you implement the 2 methods `getJWTIdentifier()` and `getJWTCustomClaims()`.

The example below should give you an idea of how this could look. Obviously you should make any
changes, as necessary, to suit your own needs.

```php
<?php

namespace App;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    // Rest omitted for brevity

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}
```

### Configure Auth guard

*Note: This will only work if you are using Laravel 5.2 and above.*

Inside the `config/auth.php` file you will need to make a few changes to configure Laravel
to use the `jwt` guard to power your application authentication.

Make the following changes to the file:

```php
'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

...

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],
```

Here we are telling the `api` guard to use the `jwt` driver, and we are setting the `api` guard
as the default.

We can now use Laravel's built in Auth system, with jwt-auth doing the work behind the scenes!

### Add some basic authentication routes

First let's add some routes in `routes/api.php` as follows:

```php
Route::group([

    'middleware' => 'api',
    'prefix' => 'auth'

], function ($router) {

    Route::post('login', 'AuthController@login');
    Route::post('logout', 'AuthController@logout');
    Route::post('refresh', 'AuthController@refresh');
    Route::post('me', 'AuthController@me');

});
```

### Create the AuthController

Then create the `AuthController`, either manually or by running the artisan command:

```bash
php artisan make:controller AuthController
```

Then add the following:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json(auth()->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }
}
```

You should now be able to POST to the login endpoint (e.g. `http://example.dev/auth/login`) with some valid
credentials and see a response like:

```json
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
    "token_type": "bearer",
    "expires_in": 3600
}
```

This token can then be used to make authenticated requests to your application.

### Authenticated requests

There are a number of ways to send the token via http:

**Authorization header**

`Authorization: Bearer eyJhbGciOiJIUzI1NiI...`

**Query string parameter**

`http://example.dev/me?token=eyJhbGciOiJIUzI1NiI...`

**Post parameter**

**Cookies**

**Laravel route parameter**


================================================
FILE: docs/resources.md
================================================
- [The Anatomy of a JSON Web Token](https://scotch.io/tutorials/the-anatomy-of-a-json-web-token)
- [jwt.io](https://jwt.io/)

Over the last couple of years, the community has provided some great tutorials and packages that
have helped people get up and running with jwt-auth. So it's only right that I post some of them here.

Coming soon...


================================================
FILE: mkdocs.yml
================================================
site_name: jwt-auth
pages:
    - Home: index.md
    - Laravel Installation: laravel-installation.md
    - Lumen Installation (incomplete): lumen-installation.md
    - Quick start: quick-start.md
    - Auth guard: auth-guard.md
    - Configuration: configuration.md
    - Exception Handling: exception-handling.md
    - Resources: resources.md
theme: readthedocs


================================================
FILE: phpunit.xml.dist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    backupGlobals="false"
    backupStaticAttributes="false"
    beStrictAboutTestsThatDoNotTestAnything="false"
    beStrictAboutOutputDuringTests="true"
    bootstrap="vendor/autoload.php"
    colors="true"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    failOnRisky="true"
    failOnWarning="true"
    processIsolation="false"
    stopOnError="false"
    stopOnFailure="false"
    verbose="true"
    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
>
  <coverage>
    <include>
      <directory suffix=".php">src/</directory>
    </include>
    <exclude>
      <file>src/Providers/AbstractServiceProvider.php</file>
      <file>src/Providers/LaravelServiceProvider.php</file>
      <file>src/Providers/LumenServiceProvider.php</file>
      <directory suffix=".php">src/Facades/</directory>
      <directory suffix=".php">src/Console/</directory>
    </exclude>
    <report>
      <clover outputFile="build/logs/clover.xml"/>
      <html outputDirectory="build/coverage"/>
      <text outputFile="build/coverage.txt"/>
    </report>
  </coverage>
  <testsuites>
    <testsuite name="jwt-auth Test Suite">
      <directory>tests</directory>
    </testsuite>
  </testsuites>
  <logging>
    <junit outputFile="build/report.junit.xml"/>
  </logging>
</phpunit>


================================================
FILE: src/Blacklist.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use Tymon\JWTAuth\Contracts\Providers\Storage;
use Tymon\JWTAuth\Support\Utils;

class Blacklist
{
    /**
     * The storage.
     *
     * @var \Tymon\JWTAuth\Contracts\Providers\Storage
     */
    protected $storage;

    /**
     * The grace period when a token is blacklisted. In seconds.
     *
     * @var int
     */
    protected $gracePeriod = 0;

    /**
     * Number of minutes from issue date in which a JWT can be refreshed.
     *
     * @var int
     */
    protected $refreshTTL = 20160;

    /**
     * The unique key held within the blacklist.
     *
     * @var string
     */
    protected $key = 'jti';

    /**
     * Constructor.
     *
     * @param  \Tymon\JWTAuth\Contracts\Providers\Storage  $storage
     * @return void
     */
    public function __construct(Storage $storage)
    {
        $this->storage = $storage;
    }

    /**
     * Add the token (jti claim) to the blacklist.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return bool
     */
    public function add(Payload $payload)
    {
        // if there is no exp claim then add the jwt to
        // the blacklist indefinitely
        if (! $payload->hasKey('exp')) {
            return $this->addForever($payload);
        }

        // if we have already added this token to the blacklist
        if (! empty($this->storage->get($this->getKey($payload)))) {
            return true;
        }

        $this->storage->add(
            $this->getKey($payload),
            ['valid_until' => $this->getGraceTimestamp()],
            $this->getMinutesUntilExpired($payload)
        );

        return true;
    }

    /**
     * Get the number of minutes until the token expiry.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return int
     */
    protected function getMinutesUntilExpired(Payload $payload)
    {
        $exp = Utils::timestamp($payload['exp']);
        $iat = Utils::timestamp($payload['iat']);

        // get the latter of the two expiration dates and find
        // the number of minutes until the expiration date,
        // plus 1 minute to avoid overlap
        $expiration = $exp->max($iat->addMinutes($this->refreshTTL))->addMinute();

        $minutes = method_exists($expiration, 'diffInRealMinutes')
            ? $expiration->diffInRealMinutes()
            : $expiration->diffInUTCMinutes();

        return (int) ceil(abs($minutes));
    }

    /**
     * Add the token (jti claim) to the blacklist indefinitely.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return bool
     */
    public function addForever(Payload $payload)
    {
        $this->storage->forever($this->getKey($payload), 'forever');

        return true;
    }

    /**
     * Determine whether the token has been blacklisted.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return bool
     */
    public function has(Payload $payload)
    {
        $val = $this->storage->get($this->getKey($payload));

        // exit early if the token was blacklisted forever,
        if ($val === 'forever') {
            return true;
        }

        // check whether the expiry + grace has past
        return ! empty($val) && ! Utils::isFuture($val['valid_until']);
    }

    /**
     * Remove the token (jti claim) from the blacklist.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return bool
     */
    public function remove(Payload $payload)
    {
        return $this->storage->destroy($this->getKey($payload));
    }

    /**
     * Remove all tokens from the blacklist.
     *
     * @return bool
     */
    public function clear()
    {
        $this->storage->flush();

        return true;
    }

    /**
     * Get the timestamp when the blacklist comes into effect
     * This defaults to immediate (0 seconds).
     *
     * @return int
     */
    protected function getGraceTimestamp()
    {
        return Utils::now()->addSeconds($this->gracePeriod)->getTimestamp();
    }

    /**
     * Set the grace period.
     *
     * @param  int  $gracePeriod
     * @return $this
     */
    public function setGracePeriod($gracePeriod)
    {
        $this->gracePeriod = (int) $gracePeriod;

        return $this;
    }

    /**
     * Get the grace period.
     *
     * @return int
     */
    public function getGracePeriod()
    {
        return $this->gracePeriod;
    }

    /**
     * Get the unique key held within the blacklist.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return mixed
     */
    public function getKey(Payload $payload)
    {
        return $payload($this->key);
    }

    /**
     * Set the unique key held within the blacklist.
     *
     * @param  string  $key
     * @return $this
     */
    public function setKey($key)
    {
        $this->key = value($key);

        return $this;
    }

    /**
     * Set the refresh time limit.
     *
     * @param  int  $ttl
     * @return $this
     */
    public function setRefreshTTL($ttl)
    {
        $this->refreshTTL = (int) $ttl;

        return $this;
    }

    /**
     * Get the refresh time limit.
     *
     * @return int
     */
    public function getRefreshTTL()
    {
        return $this->refreshTTL;
    }
}


================================================
FILE: src/Claims/Audience.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

class Audience extends Claim
{
    /**
     * {@inheritdoc}
     */
    protected $name = 'aud';
}


================================================
FILE: src/Claims/Claim.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use JsonSerializable;
use Tymon\JWTAuth\Contracts\Claim as ClaimContract;

abstract class Claim implements Arrayable, ClaimContract, Jsonable, JsonSerializable
{
    /**
     * The claim name.
     *
     * @var string
     */
    protected $name;

    /**
     * The claim value.
     *
     * @var mixed
     */
    private $value;

    /**
     * @param  mixed  $value
     * @return void
     */
    public function __construct($value)
    {
        $this->setValue($value);
    }

    /**
     * Set the claim value, and call a validate method.
     *
     * @param  mixed  $value
     * @return $this
     *
     * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException
     */
    public function setValue($value)
    {
        $this->value = $this->validateCreate($value);

        return $this;
    }

    /**
     * Get the claim value.
     *
     * @return mixed
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * Set the claim name.
     *
     * @param  string  $name
     * @return $this
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get the claim name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Validate the claim in a standalone Claim context.
     *
     * @param  mixed  $value
     * @return bool
     */
    public function validateCreate($value)
    {
        return $value;
    }

    /**
     * Validate the Claim within a Payload context.
     *
     * @return bool
     */
    public function validatePayload()
    {
        return $this->getValue();
    }

    /**
     * Validate the Claim within a refresh context.
     *
     * @param  int  $refreshTTL
     * @return bool
     */
    public function validateRefresh($refreshTTL)
    {
        return $this->getValue();
    }

    /**
     * Checks if the value matches the claim.
     *
     * @param  mixed  $value
     * @param  bool  $strict
     * @return bool
     */
    public function matches($value, $strict = true)
    {
        return $strict ? $this->value === $value : $this->value == $value;
    }

    /**
     * Convert the object into something JSON serializable.
     *
     * @return array
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize(): mixed
    {
        return $this->toArray();
    }

    /**
     * Build a key value array comprising of the claim name and value.
     *
     * @return array
     */
    public function toArray()
    {
        return [$this->getName() => $this->getValue()];
    }

    /**
     * Get the claim as JSON.
     *
     * @param  int  $options
     * @return string
     */
    public function toJson($options = JSON_UNESCAPED_SLASHES)
    {
        return json_encode($this->toArray(), $options);
    }

    /**
     * Get the payload as a string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }
}


================================================
FILE: src/Claims/Collection.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Illuminate\Support\Collection as IlluminateCollection;
use Illuminate\Support\Str;

class Collection extends IlluminateCollection
{
    /**
     * Create a new collection.
     *
     * @param  mixed  $items
     * @return void
     */
    public function __construct($items = [])
    {
        parent::__construct($this->getArrayableItems($items));
    }

    /**
     * Get a Claim instance by it's unique name.
     *
     * @param  string  $name
     * @param  callable|null  $callback
     * @param  mixed  $default
     * @return \Tymon\JWTAuth\Claims\Claim
     */
    public function getByClaimName($name, ?callable $callback = null, $default = null)
    {
        return $this->filter(function (Claim $claim) use ($name) {
            return $claim->getName() === $name;
        })->first($callback, $default);
    }

    /**
     * Validate each claim under a given context.
     *
     * @param  string  $context
     * @return $this
     */
    public function validate($context = 'payload')
    {
        $args = func_get_args();
        array_shift($args);

        $this->each(function ($claim) use ($context, $args) {
            call_user_func_array(
                [$claim, 'validate'.Str::ucfirst($context)],
                $args
            );
        });

        return $this;
    }

    /**
     * Determine if the Collection contains all of the given keys.
     *
     * @param  mixed  $claims
     * @return bool
     */
    public function hasAllClaims($claims)
    {
        return count($claims) && (new static($claims))->diff($this->keys())->isEmpty();
    }

    /**
     * Get the claims as key/val array.
     *
     * @return array
     */
    public function toPlainArray()
    {
        return $this->map(function (Claim $claim) {
            return $claim->getValue();
        })->toArray();
    }

    /**
     * {@inheritdoc}
     */
    protected function getArrayableItems($items)
    {
        return $this->sanitizeClaims($items);
    }

    /**
     * Ensure that the given claims array is keyed by the claim name.
     *
     * @param  mixed  $items
     * @return array
     */
    private function sanitizeClaims($items)
    {
        $claims = [];
        foreach ($items as $key => $value) {
            if (! is_string($key) && $value instanceof Claim) {
                $key = $value->getName();
            }

            $claims[$key] = $value;
        }

        return $claims;
    }
}


================================================
FILE: src/Claims/Custom.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

class Custom extends Claim
{
    /**
     * @param  string  $name
     * @param  mixed  $value
     * @return void
     */
    public function __construct($name, $value)
    {
        parent::__construct($value);
        $this->setName($name);
    }
}


================================================
FILE: src/Claims/DatetimeTrait.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use DateInterval;
use DateTimeInterface;
use Tymon\JWTAuth\Exceptions\InvalidClaimException;
use Tymon\JWTAuth\Support\Utils;

trait DatetimeTrait
{
    /**
     * Time leeway in seconds.
     *
     * @var int
     */
    protected $leeway = 0;

    /**
     * Set the claim value, and call a validate method.
     *
     * @param  mixed  $value
     * @return $this
     *
     * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException
     */
    public function setValue($value)
    {
        if ($value instanceof DateInterval) {
            $value = Utils::now()->add($value);
        }

        if ($value instanceof DateTimeInterface) {
            $value = $value->getTimestamp();
        }

        return parent::setValue($value);
    }

    /**
     * {@inheritdoc}
     */
    public function validateCreate($value)
    {
        if (! is_numeric($value)) {
            throw new InvalidClaimException($this);
        }

        return $value;
    }

    /**
     * Determine whether the value is in the future.
     *
     * @param  mixed  $value
     * @return bool
     */
    protected function isFuture($value)
    {
        return Utils::isFuture($value, $this->leeway);
    }

    /**
     * Determine whether the value is in the past.
     *
     * @param  mixed  $value
     * @return bool
     */
    protected function isPast($value)
    {
        return Utils::isPast($value, $this->leeway);
    }

    /**
     * Set the leeway in seconds.
     *
     * @param  int  $leeway
     * @return $this
     */
    public function setLeeway($leeway)
    {
        $this->leeway = $leeway;

        return $this;
    }
}


================================================
FILE: src/Claims/Expiration.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Tymon\JWTAuth\Exceptions\TokenExpiredException;

class Expiration extends Claim
{
    use DatetimeTrait;

    /**
     * {@inheritdoc}
     */
    protected $name = 'exp';

    /**
     * {@inheritdoc}
     */
    public function validatePayload()
    {
        if ($this->isPast($this->getValue())) {
            throw new TokenExpiredException('Token has expired');
        }
    }
}


================================================
FILE: src/Claims/Factory.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Tymon\JWTAuth\Support\Utils;

class Factory
{
    /**
     * The request.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * The TTL.
     *
     * @var int
     */
    protected $ttl = 60;

    /**
     * Time leeway in seconds.
     *
     * @var int
     */
    protected $leeway = 0;

    /**
     * The classes map.
     *
     * @var array
     */
    private $classMap = [
        'aud' => Audience::class,
        'exp' => Expiration::class,
        'iat' => IssuedAt::class,
        'iss' => Issuer::class,
        'jti' => JwtId::class,
        'nbf' => NotBefore::class,
        'sub' => Subject::class,
    ];

    /**
     * Constructor.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Get the instance of the claim when passing the name and value.
     *
     * @param  string  $name
     * @param  mixed  $value
     * @return \Tymon\JWTAuth\Claims\Claim
     */
    public function get($name, $value)
    {
        if ($this->has($name)) {
            $claim = new $this->classMap[$name]($value);

            return method_exists($claim, 'setLeeway') ?
                $claim->setLeeway($this->leeway) :
                $claim;
        }

        return new Custom($name, $value);
    }

    /**
     * Check whether the claim exists.
     *
     * @param  string  $name
     * @return bool
     */
    public function has($name)
    {
        return array_key_exists($name, $this->classMap);
    }

    /**
     * Generate the initial value and return the Claim instance.
     *
     * @param  string  $name
     * @return \Tymon\JWTAuth\Claims\Claim
     */
    public function make($name)
    {
        return $this->get($name, $this->$name());
    }

    /**
     * Get the Issuer (iss) claim.
     *
     * @return string
     */
    public function iss()
    {
        return $this->request->url();
    }

    /**
     * Get the Issued At (iat) claim.
     *
     * @return int
     */
    public function iat()
    {
        return Utils::now()->getTimestamp();
    }

    /**
     * Get the Expiration (exp) claim.
     *
     * @return int
     */
    public function exp()
    {
        return Utils::now()->addMinutes($this->ttl)->getTimestamp();
    }

    /**
     * Get the Not Before (nbf) claim.
     *
     * @return int
     */
    public function nbf()
    {
        return Utils::now()->getTimestamp();
    }

    /**
     * Get the JWT Id (jti) claim.
     *
     * @return string
     */
    public function jti()
    {
        return Str::random();
    }

    /**
     * Add a new claim mapping.
     *
     * @param  string  $name
     * @param  string  $classPath
     * @return $this
     */
    public function extend($name, $classPath)
    {
        $this->classMap[$name] = $classPath;

        return $this;
    }

    /**
     * Set the request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }

    /**
     * Set the token ttl (in minutes).
     *
     * @param  int  $ttl
     * @return $this
     */
    public function setTTL($ttl)
    {
        $this->ttl = (int) $ttl;

        return $this;
    }

    /**
     * Get the token ttl.
     *
     * @return int
     */
    public function getTTL()
    {
        return $this->ttl;
    }

    /**
     * Set the leeway in seconds.
     *
     * @param  int  $leeway
     * @return $this
     */
    public function setLeeway($leeway)
    {
        $this->leeway = (int) $leeway;

        return $this;
    }

    /**
     * Get the leeway in seconds.
     *
     * @return int
     */
    public function getLeeway()
    {
        return $this->leeway;
    }
}


================================================
FILE: src/Claims/IssuedAt.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Tymon\JWTAuth\Exceptions\InvalidClaimException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class IssuedAt extends Claim
{
    use DatetimeTrait {
        validateCreate as commonValidateCreate;
    }

    /**
     * {@inheritdoc}
     */
    protected $name = 'iat';

    /**
     * {@inheritdoc}
     */
    public function validateCreate($value)
    {
        $this->commonValidateCreate($value);

        if ($this->isFuture($value)) {
            throw new InvalidClaimException($this);
        }

        return $value;
    }

    /**
     * {@inheritdoc}
     */
    public function validatePayload()
    {
        if ($this->isFuture($this->getValue())) {
            throw new TokenInvalidException('Issued At (iat) timestamp cannot be in the future');
        }
    }

    /**
     * {@inheritdoc}
     */
    public function validateRefresh($refreshTTL)
    {
        if ($this->isPast($this->getValue() + $refreshTTL * 60)) {
            throw new TokenExpiredException('Token has expired and can no longer be refreshed');
        }
    }
}


================================================
FILE: src/Claims/Issuer.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

class Issuer extends Claim
{
    /**
     * {@inheritdoc}
     */
    protected $name = 'iss';
}


================================================
FILE: src/Claims/JwtId.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

class JwtId extends Claim
{
    /**
     * {@inheritdoc}
     */
    protected $name = 'jti';
}


================================================
FILE: src/Claims/NotBefore.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class NotBefore extends Claim
{
    use DatetimeTrait;

    /**
     * {@inheritdoc}
     */
    protected $name = 'nbf';

    /**
     * {@inheritdoc}
     */
    public function validatePayload()
    {
        if ($this->isFuture($this->getValue())) {
            throw new TokenInvalidException('Not Before (nbf) timestamp cannot be in the future');
        }
    }
}


================================================
FILE: src/Claims/Subject.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Claims;

class Subject extends Claim
{
    /**
     * {@inheritdoc}
     */
    protected $name = 'sub';
}


================================================
FILE: src/Console/JWTGenerateSecretCommand.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Console;

use Illuminate\Console\Command;
use Illuminate\Support\Str;

class JWTGenerateSecretCommand extends Command
{
    /**
     * The console command signature.
     *
     * @var string
     */
    protected $signature = 'jwt:secret
        {--s|show : Display the key instead of modifying files.}
        {--always-no : Skip generating key if it already exists.}
        {--f|force : Skip confirmation when overwriting an existing key.}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Set the JWTAuth secret key used to sign the tokens';

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $key = Str::random(64);

        if ($this->option('show')) {
            $this->comment($key);

            return;
        }

        if (file_exists($path = $this->envPath()) === false) {
            return $this->displayKey($key);
        }

        if (Str::contains(file_get_contents($path), 'JWT_SECRET') === false) {
            // create new entry
            file_put_contents($path, PHP_EOL."JWT_SECRET=$key".PHP_EOL, FILE_APPEND);
        } else {
            if ($this->option('always-no')) {
                $this->comment('Secret key already exists. Skipping...');

                return;
            }

            if ($this->isConfirmed() === false) {
                $this->comment('Phew... No changes were made to your secret key.');

                return;
            }

            // update existing entry
            file_put_contents($path, str_replace(
                'JWT_SECRET='.$this->laravel['config']['jwt.secret'],
                'JWT_SECRET='.$key, file_get_contents($path)
            ));
        }

        $this->displayKey($key);
    }

    /**
     * Display the key.
     *
     * @param  string  $key
     * @return void
     */
    protected function displayKey($key)
    {
        $this->laravel['config']['jwt.secret'] = $key;

        $this->info("jwt-auth secret [$key] set successfully.");
    }

    /**
     * Check if the modification is confirmed.
     *
     * @return bool
     */
    protected function isConfirmed()
    {
        return $this->option('force') ? true : $this->confirm(
            'This will invalidate all existing tokens. Are you sure you want to override the secret key?'
        );
    }

    /**
     * Get the .env file path.
     *
     * @return string
     */
    protected function envPath()
    {
        if (method_exists($this->laravel, 'environmentFilePath')) {
            return $this->laravel->environmentFilePath();
        }

        // check if laravel version Less than 5.4.17
        if (version_compare($this->laravel->version(), '5.4.17', '<')) {
            return $this->laravel->basePath().DIRECTORY_SEPARATOR.'.env';
        }

        return $this->laravel->basePath('.env');
    }
}


================================================
FILE: src/Contracts/Claim.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts;

interface Claim
{
    /**
     * Set the claim value, and call a validate method.
     *
     * @param  mixed  $value
     * @return $this
     *
     * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException
     */
    public function setValue($value);

    /**
     * Get the claim value.
     *
     * @return mixed
     */
    public function getValue();

    /**
     * Set the claim name.
     *
     * @param  string  $name
     * @return $this
     */
    public function setName($name);

    /**
     * Get the claim name.
     *
     * @return string
     */
    public function getName();

    /**
     * Validate the Claim value.
     *
     * @param  mixed  $value
     * @return bool
     */
    public function validateCreate($value);
}


================================================
FILE: src/Contracts/Http/Parser.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts\Http;

use Illuminate\Http\Request;

interface Parser
{
    /**
     * Parse the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request);
}


================================================
FILE: src/Contracts/JWTSubject.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts;

interface JWTSubject
{
    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier();

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims();
}


================================================
FILE: src/Contracts/Providers/Auth.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts\Providers;

interface Auth
{
    /**
     * Check a user's credentials.
     *
     * @param  array  $credentials
     * @return mixed
     */
    public function byCredentials(array $credentials);

    /**
     * Authenticate a user via the id.
     *
     * @param  mixed  $id
     * @return mixed
     */
    public function byId($id);

    /**
     * Get the currently authenticated user.
     *
     * @return mixed
     */
    public function user();
}


================================================
FILE: src/Contracts/Providers/JWT.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts\Providers;

interface JWT
{
    /**
     * @param  array  $payload
     * @return string
     */
    public function encode(array $payload);

    /**
     * @param  string  $token
     * @return array
     */
    public function decode($token);
}


================================================
FILE: src/Contracts/Providers/Storage.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts\Providers;

interface Storage
{
    /**
     * @param  string  $key
     * @param  mixed  $value
     * @param  int  $minutes
     * @return void
     */
    public function add($key, $value, $minutes);

    /**
     * @param  string  $key
     * @param  mixed  $value
     * @return void
     */
    public function forever($key, $value);

    /**
     * @param  string  $key
     * @return mixed
     */
    public function get($key);

    /**
     * @param  string  $key
     * @return bool
     */
    public function destroy($key);

    /**
     * @return void
     */
    public function flush();
}


================================================
FILE: src/Contracts/Validator.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Contracts;

interface Validator
{
    /**
     * Perform some checks on the value.
     *
     * @param  mixed  $value
     * @return void
     */
    public function check($value);

    /**
     * Helper function to return a boolean.
     *
     * @param  array  $value
     * @return bool
     */
    public function isValid($value);
}


================================================
FILE: src/Exceptions/InvalidClaimException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

use Exception;
use Tymon\JWTAuth\Claims\Claim;

class InvalidClaimException extends JWTException
{
    /**
     * Constructor.
     *
     * @param  \Tymon\JWTAuth\Claims\Claim  $claim
     * @param  int  $code
     * @param  \Exception|null  $previous
     * @return void
     */
    public function __construct(Claim $claim, $code = 0, ?Exception $previous = null)
    {
        parent::__construct('Invalid value provided for claim ['.$claim->getName().']', $code, $previous);
    }
}


================================================
FILE: src/Exceptions/JWTException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

use Exception;

class JWTException extends Exception
{
    /**
     * {@inheritdoc}
     */
    protected $message = 'An error occurred';
}


================================================
FILE: src/Exceptions/PayloadException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

class PayloadException extends JWTException
{
    //
}


================================================
FILE: src/Exceptions/TokenBlacklistedException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

class TokenBlacklistedException extends TokenInvalidException
{
    //
}


================================================
FILE: src/Exceptions/TokenExpiredException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

class TokenExpiredException extends JWTException
{
    //
}


================================================
FILE: src/Exceptions/TokenInvalidException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

class TokenInvalidException extends JWTException
{
    //
}


================================================
FILE: src/Exceptions/UserNotDefinedException.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Exceptions;

class UserNotDefinedException extends JWTException
{
    //
}


================================================
FILE: src/Facades/JWTAuth.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Facades;

use Illuminate\Support\Facades\Facade;

class JWTAuth extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'tymon.jwt.auth';
    }
}


================================================
FILE: src/Facades/JWTFactory.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Facades;

use Illuminate\Support\Facades\Facade;

class JWTFactory extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'tymon.jwt.payload.factory';
    }
}


================================================
FILE: src/Facades/JWTProvider.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Facades;

use Illuminate\Support\Facades\Facade;

class JWTProvider extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'tymon.jwt.provider.jwt';
    }
}


================================================
FILE: src/Factory.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use Tymon\JWTAuth\Claims\Claim;
use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Claims\Factory as ClaimFactory;
use Tymon\JWTAuth\Support\CustomClaims;
use Tymon\JWTAuth\Support\RefreshFlow;
use Tymon\JWTAuth\Validators\PayloadValidator;

class Factory
{
    use CustomClaims, RefreshFlow;

    /**
     * The claim factory.
     *
     * @var \Tymon\JWTAuth\Claims\Factory
     */
    protected $claimFactory;

    /**
     * The validator.
     *
     * @var \Tymon\JWTAuth\Validators\PayloadValidator
     */
    protected $validator;

    /**
     * The default claims.
     *
     * @var array
     */
    protected $defaultClaims = [
        'iss',
        'iat',
        'exp',
        'nbf',
        'jti',
    ];

    /**
     * The claims collection.
     *
     * @var \Tymon\JWTAuth\Claims\Collection
     */
    protected $claims;

    /**
     * Constructor.
     *
     * @param  \Tymon\JWTAuth\Claims\Factory  $claimFactory
     * @param  \Tymon\JWTAuth\Validators\PayloadValidator  $validator
     * @return void
     */
    public function __construct(ClaimFactory $claimFactory, PayloadValidator $validator)
    {
        $this->claimFactory = $claimFactory;
        $this->validator = $validator;
        $this->claims = new Collection;
    }

    /**
     * Create the Payload instance.
     *
     * @param  bool  $resetClaims
     * @return \Tymon\JWTAuth\Payload
     */
    public function make($resetClaims = false)
    {
        if ($resetClaims) {
            $this->emptyClaims();
        }

        return $this->withClaims($this->buildClaimsCollection());
    }

    /**
     * Empty the claims collection.
     *
     * @return $this
     */
    public function emptyClaims()
    {
        $this->claims = new Collection;

        return $this;
    }

    /**
     * Add an array of claims to the Payload.
     *
     * @param  array  $claims
     * @return $this
     */
    protected function addClaims(array $claims)
    {
        foreach ($claims as $name => $value) {
            $this->addClaim($name, $value);
        }

        return $this;
    }

    /**
     * Add a claim to the Payload.
     *
     * @param  string  $name
     * @param  mixed  $value
     * @return $this
     */
    protected function addClaim($name, $value)
    {
        $this->claims->put($name, $value);

        return $this;
    }

    /**
     * Build the default claims.
     *
     * @return $this
     */
    protected function buildClaims()
    {
        // remove the exp claim if it exists and the ttl is null
        if ($this->claimFactory->getTTL() === null && $key = array_search('exp', $this->defaultClaims)) {
            unset($this->defaultClaims[$key]);
        }

        // add the default claims
        foreach ($this->defaultClaims as $claim) {
            $this->addClaim($claim, $this->claimFactory->make($claim));
        }

        // add custom claims on top, allowing them to overwrite defaults
        return $this->addClaims($this->getCustomClaims());
    }

    /**
     * Build out the Claim DTO's.
     *
     * @return \Tymon\JWTAuth\Claims\Collection
     */
    protected function resolveClaims()
    {
        return $this->claims->map(function ($value, $name) {
            return $value instanceof Claim ? $value : $this->claimFactory->get($name, $value);
        });
    }

    /**
     * Build and get the Claims Collection.
     *
     * @return \Tymon\JWTAuth\Claims\Collection
     */
    public function buildClaimsCollection()
    {
        return $this->buildClaims()->resolveClaims();
    }

    /**
     * Get a Payload instance with a claims collection.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $claims
     * @return \Tymon\JWTAuth\Payload
     */
    public function withClaims(Collection $claims)
    {
        return new Payload($claims, $this->validator, $this->refreshFlow);
    }

    /**
     * Set the default claims to be added to the Payload.
     *
     * @param  array  $claims
     * @return $this
     */
    public function setDefaultClaims(array $claims)
    {
        $this->defaultClaims = $claims;

        return $this;
    }

    /**
     * Helper to set the ttl.
     *
     * @param  int  $ttl
     * @return $this
     */
    public function setTTL($ttl)
    {
        $this->claimFactory->setTTL($ttl);

        return $this;
    }

    /**
     * Helper to get the ttl.
     *
     * @return int
     */
    public function getTTL()
    {
        return $this->claimFactory->getTTL();
    }

    /**
     * Get the default claims.
     *
     * @return array
     */
    public function getDefaultClaims()
    {
        return $this->defaultClaims;
    }

    /**
     * Get the PayloadValidator instance.
     *
     * @return \Tymon\JWTAuth\Validators\PayloadValidator
     */
    public function validator()
    {
        return $this->validator;
    }

    /**
     * Magically add a claim.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return $this
     */
    public function __call($method, $parameters)
    {
        $this->addClaim($method, $parameters[0]);

        return $this;
    }
}


================================================
FILE: src/Http/Middleware/Authenticate.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Middleware;

use Closure;

/** @deprecated */
class Authenticate extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function handle($request, Closure $next)
    {
        $this->authenticate($request);

        return $next($request);
    }
}


================================================
FILE: src/Http/Middleware/AuthenticateAndRenew.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Middleware;

use Closure;

/** @deprecated */
class AuthenticateAndRenew extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function handle($request, Closure $next)
    {
        $this->authenticate($request);

        $response = $next($request);

        // Send the refreshed token back to the client.
        return $this->setAuthenticationHeader($response);
    }
}


================================================
FILE: src/Http/Middleware/BaseMiddleware.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Middleware;

use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\JWTAuth;

/** @deprecated */
abstract class BaseMiddleware
{
    /**
     * The JWT Authenticator.
     *
     * @var \Tymon\JWTAuth\JWTAuth
     */
    protected $auth;

    /**
     * Create a new BaseMiddleware instance.
     *
     * @param  \Tymon\JWTAuth\JWTAuth  $auth
     * @return void
     */
    public function __construct(JWTAuth $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Check the request for the presence of a token.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     *
     * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
     */
    public function checkForToken(Request $request)
    {
        if (! $this->auth->parser()->setRequest($request)->hasToken()) {
            throw new UnauthorizedHttpException('jwt-auth', 'Token not provided');
        }
    }

    /**
     * Attempt to authenticate a user via the token in the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function authenticate(Request $request)
    {
        $this->checkForToken($request);

        try {
            if (! $this->auth->parseToken()->authenticate()) {
                throw new UnauthorizedHttpException('jwt-auth', 'User not found');
            }
        } catch (JWTException $e) {
            throw new UnauthorizedHttpException('jwt-auth', $e->getMessage(), $e, $e->getCode());
        }
    }

    /**
     * Set the authentication header.
     *
     * @param  \Illuminate\Http\Response|\Illuminate\Http\JsonResponse  $response
     * @param  string|null  $token
     * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
     */
    protected function setAuthenticationHeader($response, $token = null)
    {
        $token = $token ?: $this->auth->refresh();
        $response->headers->set('Authorization', 'Bearer '.$token);

        return $response;
    }
}


================================================
FILE: src/Http/Middleware/Check.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Middleware;

use Closure;
use Exception;

/** @deprecated */
class Check extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->parser()->setRequest($request)->hasToken()) {
            try {
                $this->auth->parseToken()->authenticate();
            } catch (Exception $e) {
                //
            }
        }

        return $next($request);
    }
}


================================================
FILE: src/Http/Middleware/RefreshToken.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Middleware;

use Closure;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;

/** @deprecated */
class RefreshToken extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     */
    public function handle($request, Closure $next)
    {
        $this->checkForToken($request);

        try {
            $token = $this->auth->parseToken()->refresh();
        } catch (JWTException $e) {
            throw new UnauthorizedHttpException('jwt-auth', $e->getMessage(), $e, $e->getCode());
        }

        $response = $next($request);

        // Send the refreshed token back to the client.
        return $this->setAuthenticationHeader($response, $token);
    }
}


================================================
FILE: src/Http/Parser/AuthHeaders.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;

class AuthHeaders implements ParserContract
{
    /**
     * The header name.
     *
     * @var string
     */
    protected $header = 'authorization';

    /**
     * The header prefix.
     *
     * @var string
     */
    protected $prefix = 'bearer';

    /**
     * Attempt to parse the token from some other possible headers.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    protected function fromAltHeaders(Request $request)
    {
        return $request->server->get('HTTP_AUTHORIZATION') ?: $request->server->get('REDIRECT_HTTP_AUTHORIZATION');
    }

    /**
     * Try to parse the token from the request header.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        $header = $request->headers->get($this->header) ?: $this->fromAltHeaders($request);

        if ($header !== null) {
            $position = strripos($header, $this->prefix);

            if ($position !== false) {
                $header = substr($header, $position + strlen($this->prefix));

                return trim(
                    strpos($header, ',') !== false ? strstr($header, ',', true) : $header
                );
            }
        }

        return null;
    }

    /**
     * Set the header name.
     *
     * @param  string  $headerName
     * @return $this
     */
    public function setHeaderName($headerName)
    {
        $this->header = $headerName;

        return $this;
    }

    /**
     * Set the header prefix.
     *
     * @param  string  $headerPrefix
     * @return $this
     */
    public function setHeaderPrefix($headerPrefix)
    {
        $this->prefix = $headerPrefix;

        return $this;
    }
}


================================================
FILE: src/Http/Parser/Cookies.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;

class Cookies implements ParserContract
{
    use KeyTrait;

    /**
     * Decrypt or not the cookie while parsing.
     *
     * @var bool
     */
    private $decrypt;

    public function __construct($decrypt = true)
    {
        $this->decrypt = $decrypt;
    }

    /**
     * Try to parse the token from the request cookies.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        if ($this->decrypt && $request->hasCookie($this->key)) {
            return Crypt::decrypt($request->cookie($this->key));
        }

        return $request->cookie($this->key);
    }
}


================================================
FILE: src/Http/Parser/InputSource.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;

class InputSource implements ParserContract
{
    use KeyTrait;

    /**
     * Try to parse the token from the request input source.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        return $request->input($this->key);
    }
}


================================================
FILE: src/Http/Parser/KeyTrait.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

trait KeyTrait
{
    /**
     * The key.
     *
     * @var string
     */
    protected $key = 'token';

    /**
     * Set the key.
     *
     * @param  string  $key
     * @return $this
     */
    public function setKey($key)
    {
        $this->key = $key;

        return $this;
    }

    /**
     * Get the key.
     *
     * @return string
     */
    public function getKey()
    {
        return $this->key;
    }
}


================================================
FILE: src/Http/Parser/LumenRouteParams.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class LumenRouteParams extends RouteParams
{
    /**
     * Try to get the token from the route parameters.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        // WARNING: Only use this parser if you know what you're doing!
        // It will only work with poorly-specified aspects of certain Lumen releases.
        // Route is the expected kind of array, and has a parameter with the key we want.
        return Arr::get($request->route(), '2.'.$this->key);
    }
}


================================================
FILE: src/Http/Parser/Parser.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;

class Parser
{
    /**
     * The chain.
     *
     * @var array
     */
    private $chain;

    /**
     * The request.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Constructor.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $chain
     * @return void
     */
    public function __construct(Request $request, array $chain = [])
    {
        $this->request = $request;
        $this->chain = $chain;
    }

    /**
     * Get the parser chain.
     *
     * @return array
     */
    public function getChain()
    {
        return $this->chain;
    }

    /**
     * Add a new parser to the chain.
     *
     * @param  array|\Tymon\JWTAuth\Contracts\Http\Parser  $parsers
     * @return $this
     */
    public function addParser($parsers)
    {
        $this->chain = array_merge($this->chain, is_array($parsers) ? $parsers : [$parsers]);

        return $this;
    }

    /**
     * Set the order of the parser chain.
     *
     * @param  array  $chain
     * @return $this
     */
    public function setChain(array $chain)
    {
        $this->chain = $chain;

        return $this;
    }

    /**
     * Alias for setting the order of the chain.
     *
     * @param  array  $chain
     * @return $this
     */
    public function setChainOrder(array $chain)
    {
        return $this->setChain($chain);
    }

    /**
     * Iterate through the parsers and attempt to retrieve
     * a value, otherwise return null.
     *
     * @return string|null
     */
    public function parseToken()
    {
        foreach ($this->chain as $parser) {
            if ($response = $parser->parse($this->request)) {
                return $response;
            }
        }
    }

    /**
     * Check whether a token exists in the chain.
     *
     * @return bool
     */
    public function hasToken()
    {
        return $this->parseToken() !== null;
    }

    /**
     * Set the request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }
}


================================================
FILE: src/Http/Parser/QueryString.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;

class QueryString implements ParserContract
{
    use KeyTrait;

    /**
     * Try to parse the token from the request query string.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        return $request->query($this->key);
    }
}


================================================
FILE: src/Http/Parser/RouteParams.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Http\Parser;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\Http\Parser as ParserContract;

class RouteParams implements ParserContract
{
    use KeyTrait;

    /**
     * Try to get the token from the route parameters.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return null|string
     */
    public function parse(Request $request)
    {
        $route = $request->route();

        // Route may not be an instance of Illuminate\Routing\Route
        // (it's an array in Lumen <5.2) or not exist at all
        // (if the request was never dispatched)
        if (is_callable([$route, 'parameter'])) {
            return $route->parameter($this->key);
        }
    }
}


================================================
FILE: src/JWT.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use BadMethodCallException;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Parser\Parser;
use Tymon\JWTAuth\Support\CustomClaims;

class JWT
{
    use CustomClaims;

    /**
     * The authentication manager.
     *
     * @var \Tymon\JWTAuth\Manager
     */
    protected $manager;

    /**
     * The HTTP parser.
     *
     * @var \Tymon\JWTAuth\Http\Parser\Parser
     */
    protected $parser;

    /**
     * The token.
     *
     * @var \Tymon\JWTAuth\Token|null
     */
    protected $token;

    /**
     * Lock the subject.
     *
     * @var bool
     */
    protected $lockSubject = true;

    /**
     * JWT constructor.
     *
     * @param  \Tymon\JWTAuth\Manager  $manager
     * @param  \Tymon\JWTAuth\Http\Parser\Parser  $parser
     * @return void
     */
    public function __construct(Manager $manager, Parser $parser)
    {
        $this->manager = $manager;
        $this->parser = $parser;
    }

    /**
     * Generate a token for a given subject.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $subject
     * @return string
     */
    public function fromSubject(JWTSubject $subject)
    {
        $payload = $this->makePayload($subject);

        return $this->manager->encode($payload)->get();
    }

    /**
     * Alias to generate a token for a given user.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $user
     * @return string
     */
    public function fromUser(JWTSubject $user)
    {
        return $this->fromSubject($user);
    }

    /**
     * Refresh an expired token.
     *
     * @param  bool  $forceForever
     * @param  bool  $resetClaims
     * @return string
     */
    public function refresh($forceForever = false, $resetClaims = false)
    {
        $this->requireToken();

        return $this->manager->customClaims($this->getCustomClaims())
                             ->refresh($this->token, $forceForever, $resetClaims)
                             ->get();
    }

    /**
     * Invalidate a token (add it to the blacklist).
     *
     * @param  bool  $forceForever
     * @return $this
     */
    public function invalidate($forceForever = false)
    {
        $this->requireToken();

        $this->manager->invalidate($this->token, $forceForever);

        return $this;
    }

    /**
     * Alias to get the payload, and as a result checks that
     * the token is valid i.e. not expired or blacklisted.
     *
     * @return \Tymon\JWTAuth\Payload
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    public function checkOrFail()
    {
        return $this->getPayload();
    }

    /**
     * Check that the token is valid.
     *
     * @param  bool  $getPayload
     * @return \Tymon\JWTAuth\Payload|bool
     */
    public function check($getPayload = false)
    {
        try {
            $payload = $this->checkOrFail();
        } catch (JWTException $e) {
            return false;
        }

        return $getPayload ? $payload : true;
    }

    /**
     * Get the token.
     *
     * @return \Tymon\JWTAuth\Token|null
     */
    public function getToken()
    {
        if ($this->token === null) {
            try {
                $this->parseToken();
            } catch (JWTException $e) {
                $this->token = null;
            }
        }

        return $this->token;
    }

    /**
     * Parse the token from the request.
     *
     * @return $this
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    public function parseToken()
    {
        if (! $token = $this->parser->parseToken()) {
            throw new JWTException('The token could not be parsed from the request');
        }

        return $this->setToken($token);
    }

    /**
     * Get the raw Payload instance.
     *
     * @return \Tymon\JWTAuth\Payload
     */
    public function getPayload()
    {
        $this->requireToken();

        return $this->manager->decode($this->token);
    }

    /**
     * Alias for getPayload().
     *
     * @return \Tymon\JWTAuth\Payload
     */
    public function payload()
    {
        return $this->getPayload();
    }

    /**
     * Convenience method to get a claim value.
     *
     * @param  string  $claim
     * @return mixed
     */
    public function getClaim($claim)
    {
        return $this->payload()->get($claim);
    }

    /**
     * Create a Payload instance.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $subject
     * @return \Tymon\JWTAuth\Payload
     */
    public function makePayload(JWTSubject $subject)
    {
        return $this->factory()->customClaims($this->getClaimsArray($subject))->make();
    }

    /**
     * Build the claims array and return it.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $subject
     * @return array
     */
    protected function getClaimsArray(JWTSubject $subject)
    {
        return array_merge(
            $this->getClaimsForSubject($subject),
            $subject->getJWTCustomClaims(), // custom claims from JWTSubject method
            $this->customClaims // custom claims from inline setter
        );
    }

    /**
     * Get the claims associated with a given subject.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $subject
     * @return array
     */
    protected function getClaimsForSubject(JWTSubject $subject)
    {
        return array_merge([
            'sub' => $subject->getJWTIdentifier(),
        ], $this->lockSubject ? ['prv' => $this->hashSubjectModel($subject)] : []);
    }

    /**
     * Hash the subject model and return it.
     *
     * @param  string|object  $model
     * @return string
     */
    protected function hashSubjectModel($model)
    {
        return sha1(is_object($model) ? get_class($model) : $model);
    }

    /**
     * Check if the subject model matches the one saved in the token.
     *
     * @param  string|object  $model
     * @return bool
     */
    public function checkSubjectModel($model)
    {
        if (($prv = $this->payload()->get('prv')) === null) {
            return true;
        }

        return $this->hashSubjectModel($model) === $prv;
    }

    /**
     * Set the token.
     *
     * @param  \Tymon\JWTAuth\Token|string  $token
     * @return $this
     */
    public function setToken($token)
    {
        $this->token = $token instanceof Token ? $token : new Token($token);

        return $this;
    }

    /**
     * Unset the current token.
     *
     * @return $this
     */
    public function unsetToken()
    {
        $this->token = null;

        return $this;
    }

    /**
     * Ensure that a token is available.
     *
     * @return void
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    protected function requireToken()
    {
        if (! $this->token) {
            throw new JWTException('A token is required');
        }
    }

    /**
     * Set the request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->parser->setRequest($request);

        return $this;
    }

    /**
     * Set whether the subject should be "locked".
     *
     * @param  bool  $lock
     * @return $this
     */
    public function lockSubject($lock)
    {
        $this->lockSubject = $lock;

        return $this;
    }

    /**
     * Get the Manager instance.
     *
     * @return \Tymon\JWTAuth\Manager
     */
    public function manager()
    {
        return $this->manager;
    }

    /**
     * Get the Parser instance.
     *
     * @return \Tymon\JWTAuth\Http\Parser\Parser
     */
    public function parser()
    {
        return $this->parser;
    }

    /**
     * Get the Payload Factory.
     *
     * @return \Tymon\JWTAuth\Factory
     */
    public function factory()
    {
        return $this->manager->getPayloadFactory();
    }

    /**
     * Get the Blacklist.
     *
     * @return \Tymon\JWTAuth\Blacklist
     */
    public function blacklist()
    {
        return $this->manager->getBlacklist();
    }

    /**
     * Magically call the JWT Manager.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (method_exists($this->manager, $method)) {
            return call_user_func_array([$this->manager, $method], $parameters);
        }

        throw new BadMethodCallException("Method [$method] does not exist.");
    }
}


================================================
FILE: src/JWTAuth.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use Tymon\JWTAuth\Contracts\Providers\Auth;
use Tymon\JWTAuth\Http\Parser\Parser;

/** @deprecated */
class JWTAuth extends JWT
{
    /**
     * The authentication provider.
     *
     * @var \Tymon\JWTAuth\Contracts\Providers\Auth
     */
    protected $auth;

    /**
     * Constructor.
     *
     * @param  \Tymon\JWTAuth\Manager  $manager
     * @param  \Tymon\JWTAuth\Contracts\Providers\Auth  $auth
     * @param  \Tymon\JWTAuth\Http\Parser\Parser  $parser
     * @return void
     */
    public function __construct(Manager $manager, Auth $auth, Parser $parser)
    {
        parent::__construct($manager, $parser);
        $this->auth = $auth;
    }

    /**
     * Attempt to authenticate the user and return the token.
     *
     * @param  array  $credentials
     * @return false|string
     */
    public function attempt(array $credentials)
    {
        if (! $this->auth->byCredentials($credentials)) {
            return false;
        }

        return $this->fromUser($this->user());
    }

    /**
     * Authenticate a user via a token.
     *
     * @return \Tymon\JWTAuth\Contracts\JWTSubject|false
     */
    public function authenticate()
    {
        $id = $this->getPayload()->get('sub');

        if (! $this->auth->byId($id)) {
            return false;
        }

        return $this->user();
    }

    /**
     * Alias for authenticate().
     *
     * @return \Tymon\JWTAuth\Contracts\JWTSubject|false
     */
    public function toUser()
    {
        return $this->authenticate();
    }

    /**
     * Get the authenticated user.
     *
     * @return \Tymon\JWTAuth\Contracts\JWTSubject
     */
    public function user()
    {
        return $this->auth->user();
    }
}


================================================
FILE: src/JWTGuard.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use BadMethodCallException;
use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Traits\Macroable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\UserNotDefinedException;

class JWTGuard implements Guard
{
    use GuardHelpers, Macroable {
        __call as macroCall;
    }

    /**
     * The user we last attempted to retrieve.
     *
     * @var \Illuminate\Contracts\Auth\Authenticatable
     */
    protected $lastAttempted;

    /**
     * The JWT instance.
     *
     * @var \Tymon\JWTAuth\JWT
     */
    protected $jwt;

    /**
     * The request instance.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Instantiate the class.
     *
     * @param  \Tymon\JWTAuth\JWT  $jwt
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(JWT $jwt, UserProvider $provider, Request $request)
    {
        $this->jwt = $jwt;
        $this->provider = $provider;
        $this->request = $request;
    }

    /**
     * {@inheritDoc}
     */
    public function user()
    {
        if ($this->user !== null) {
            return $this->user;
        }

        if ($this->jwt->setRequest($this->request)->getToken() &&
            ($payload = $this->jwt->check(true)) &&
            $this->validateSubject()
        ) {
            return $this->user = $this->provider->retrieveById($payload['sub']);
        }
    }

    /**
     * Get the currently authenticated user or throws an exception.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable
     *
     * @throws \Tymon\JWTAuth\Exceptions\UserNotDefinedException
     */
    public function userOrFail()
    {
        if (! $user = $this->user()) {
            throw new UserNotDefinedException;
        }

        return $user;
    }

    /**
     * Validate a user's credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function validate(array $credentials = [])
    {
        return (bool) $this->attempt($credentials, false);
    }

    /**
     * Attempt to authenticate the user using the given credentials and return the token.
     *
     * @param  array  $credentials
     * @param  bool  $login
     * @return bool|string
     */
    public function attempt(array $credentials = [], $login = true)
    {
        $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

        if ($this->hasValidCredentials($user, $credentials)) {
            return $login ? $this->login($user) : true;
        }

        return false;
    }

    /**
     * Create a token for a user.
     *
     * @param  \Tymon\JWTAuth\Contracts\JWTSubject  $user
     * @return string
     */
    public function login(JWTSubject $user)
    {
        $token = $this->jwt->fromUser($user);
        $this->setToken($token)->setUser($user);

        return $token;
    }

    /**
     * Logout the user, thus invalidating the token.
     *
     * @param  bool  $forceForever
     * @return void
     */
    public function logout($forceForever = false)
    {
        $this->requireToken()->invalidate($forceForever);

        $this->user = null;
        $this->jwt->unsetToken();
    }

    /**
     * Refresh the token.
     *
     * @param  bool  $forceForever
     * @param  bool  $resetClaims
     * @return string
     */
    public function refresh($forceForever = false, $resetClaims = false)
    {
        return $this->requireToken()->refresh($forceForever, $resetClaims);
    }

    /**
     * Invalidate the token.
     *
     * @param  bool  $forceForever
     * @return \Tymon\JWTAuth\JWT
     */
    public function invalidate($forceForever = false)
    {
        return $this->requireToken()->invalidate($forceForever);
    }

    /**
     * Create a new token by User id.
     *
     * @param  mixed  $id
     * @return string|null
     */
    public function tokenById($id)
    {
        if ($user = $this->provider->retrieveById($id)) {
            return $this->jwt->fromUser($user);
        }
    }

    /**
     * Log a user into the application using their credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function once(array $credentials = [])
    {
        if ($this->validate($credentials)) {
            $this->setUser($this->lastAttempted);

            return true;
        }

        return false;
    }

    /**
     * Log the given User into the application.
     *
     * @param  mixed  $id
     * @return bool
     */
    public function onceUsingId($id)
    {
        if ($user = $this->provider->retrieveById($id)) {
            $this->setUser($user);

            return true;
        }

        return false;
    }

    /**
     * Alias for onceUsingId.
     *
     * @param  mixed  $id
     * @return bool
     */
    public function byId($id)
    {
        return $this->onceUsingId($id);
    }

    /**
     * Add any custom claims.
     *
     * @param  array  $claims
     * @return $this
     */
    public function claims(array $claims)
    {
        $this->jwt->claims($claims);

        return $this;
    }

    /**
     * Get the raw Payload instance.
     *
     * @return \Tymon\JWTAuth\Payload
     */
    public function getPayload()
    {
        return $this->requireToken()->getPayload();
    }

    /**
     * Alias for getPayload().
     *
     * @return \Tymon\JWTAuth\Payload
     */
    public function payload()
    {
        return $this->getPayload();
    }

    /**
     * Set the token.
     *
     * @param  \Tymon\JWTAuth\Token|string  $token
     * @return $this
     */
    public function setToken($token)
    {
        $this->jwt->setToken($token);

        return $this;
    }

    /**
     * Set the token ttl.
     *
     * @param  int  $ttl
     * @return $this
     */
    public function setTTL($ttl)
    {
        $this->jwt->factory()->setTTL($ttl);

        return $this;
    }

    /**
     * Get the user provider used by the guard.
     *
     * @return \Illuminate\Contracts\Auth\UserProvider
     */
    public function getProvider()
    {
        return $this->provider;
    }

    /**
     * Set the user provider used by the guard.
     *
     * @param  \Illuminate\Contracts\Auth\UserProvider  $provider
     * @return $this
     */
    public function setProvider(UserProvider $provider)
    {
        $this->provider = $provider;

        return $this;
    }

    /**
     * Return the currently cached user.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Get the current request instance.
     *
     * @return \Illuminate\Http\Request
     */
    public function getRequest()
    {
        return $this->request ?: Request::createFromGlobals();
    }

    /**
     * Set the current request instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return $this
     */
    public function setRequest(Request $request)
    {
        $this->request = $request;

        return $this;
    }

    /**
     * Get the token's auth factory.
     *
     * @return \Tymon\JWTAuth\Factory
     */
    public function factory()
    {
        return $this->jwt->factory();
    }

    /**
     * Get the last user we attempted to authenticate.
     *
     * @return \Illuminate\Contracts\Auth\Authenticatable
     */
    public function getLastAttempted()
    {
        return $this->lastAttempted;
    }

    /**
     * Determine if the user matches the credentials.
     *
     * @param  mixed  $user
     * @param  array  $credentials
     * @return bool
     */
    protected function hasValidCredentials($user, $credentials)
    {
        return $user !== null && $this->provider->validateCredentials($user, $credentials);
    }

    /**
     * Ensure the JWTSubject matches what is in the token.
     *
     * @return bool
     */
    protected function validateSubject()
    {
        // If the provider doesn't have the necessary method
        // to get the underlying model name then allow.
        if (! method_exists($this->provider, 'getModel')) {
            return true;
        }

        return $this->jwt->checkSubjectModel($this->provider->getModel());
    }

    /**
     * Ensure that a token is available in the request.
     *
     * @return \Tymon\JWTAuth\JWT
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    protected function requireToken()
    {
        if (! $this->jwt->setRequest($this->getRequest())->getToken()) {
            throw new JWTException('Token could not be parsed from the request.');
        }

        return $this->jwt;
    }

    /**
     * Magically call the JWT instance.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (method_exists($this->jwt, $method)) {
            return call_user_func_array([$this->jwt, $method], $parameters);
        }

        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        throw new BadMethodCallException("Method [$method] does not exist.");
    }
}


================================================
FILE: src/Manager.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use Tymon\JWTAuth\Contracts\Providers\JWT as JWTContract;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
use Tymon\JWTAuth\Support\CustomClaims;
use Tymon\JWTAuth\Support\RefreshFlow;

class Manager
{
    use CustomClaims, RefreshFlow;

    /**
     * The provider.
     *
     * @var \Tymon\JWTAuth\Contracts\Providers\JWT
     */
    protected $provider;

    /**
     * The blacklist.
     *
     * @var \Tymon\JWTAuth\Blacklist
     */
    protected $blacklist;

    /**
     * the payload factory.
     *
     * @var \Tymon\JWTAuth\Factory
     */
    protected $payloadFactory;

    /**
     * The blacklist flag.
     *
     * @var bool
     */
    protected $blacklistEnabled = true;

    /**
     * the persistent claims.
     *
     * @var array
     */
    protected $persistentClaims = [];

    /**
     * Constructor.
     *
     * @param  \Tymon\JWTAuth\Contracts\Providers\JWT  $provider
     * @param  \Tymon\JWTAuth\Blacklist  $blacklist
     * @param  \Tymon\JWTAuth\Factory  $payloadFactory
     * @return void
     */
    public function __construct(JWTContract $provider, Blacklist $blacklist, Factory $payloadFactory)
    {
        $this->provider = $provider;
        $this->blacklist = $blacklist;
        $this->payloadFactory = $payloadFactory;
    }

    /**
     * Encode a Payload and return the Token.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return \Tymon\JWTAuth\Token
     */
    public function encode(Payload $payload)
    {
        $token = $this->provider->encode($payload->get());

        return new Token($token);
    }

    /**
     * Decode a Token and return the Payload.
     *
     * @param  \Tymon\JWTAuth\Token  $token
     * @param  bool  $checkBlacklist
     * @return \Tymon\JWTAuth\Payload
     *
     * @throws \Tymon\JWTAuth\Exceptions\TokenBlacklistedException
     */
    public function decode(Token $token, $checkBlacklist = true)
    {
        $payloadArray = $this->provider->decode($token->get());

        $payload = $this->payloadFactory
                        ->setRefreshFlow($this->refreshFlow)
                        ->customClaims($payloadArray)
                        ->make();

        if ($checkBlacklist && $this->blacklistEnabled && $this->blacklist->has($payload)) {
            throw new TokenBlacklistedException('The token has been blacklisted');
        }

        return $payload;
    }

    /**
     * Refresh a Token and return a new Token.
     *
     * @param  \Tymon\JWTAuth\Token  $token
     * @param  bool  $forceForever
     * @param  bool  $resetClaims
     * @return \Tymon\JWTAuth\Token
     */
    public function refresh(Token $token, $forceForever = false, $resetClaims = false)
    {
        $this->setRefreshFlow();

        $claims = $this->buildRefreshClaims($this->decode($token));

        if ($this->blacklistEnabled) {
            // Invalidate old token
            $this->invalidate($token, $forceForever);
        }

        // Return the new token
        return $this->encode(
            $this->payloadFactory->customClaims($claims)->make($resetClaims)
        );
    }

    /**
     * Invalidate a Token by adding it to the blacklist.
     *
     * @param  \Tymon\JWTAuth\Token  $token
     * @param  bool  $forceForever
     * @return bool
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    public function invalidate(Token $token, $forceForever = false)
    {
        if (! $this->blacklistEnabled) {
            throw new JWTException('You must have the blacklist enabled to invalidate a token.');
        }

        return call_user_func(
            [$this->blacklist, $forceForever ? 'addForever' : 'add'],
            $this->decode($token, false)
        );
    }

    /**
     * Build the claims to go into the refreshed token.
     *
     * @param  \Tymon\JWTAuth\Payload  $payload
     * @return array
     */
    protected function buildRefreshClaims(Payload $payload)
    {
        // Get the claims to be persisted from the payload
        $persistentClaims = collect($payload->toArray())
            ->only($this->persistentClaims)
            ->toArray();

        // persist the relevant claims
        return array_merge(
            $this->customClaims,
            $persistentClaims,
            [
                'sub' => $payload['sub'],
                'iat' => $payload['iat'],
            ]
        );
    }

    /**
     * Get the Payload Factory instance.
     *
     * @return \Tymon\JWTAuth\Factory
     */
    public function getPayloadFactory()
    {
        return $this->payloadFactory;
    }

    /**
     * Get the JWTProvider instance.
     *
     * @return \Tymon\JWTAuth\Contracts\Providers\JWT
     */
    public function getJWTProvider()
    {
        return $this->provider;
    }

    /**
     * Get the Blacklist instance.
     *
     * @return \Tymon\JWTAuth\Blacklist
     */
    public function getBlacklist()
    {
        return $this->blacklist;
    }

    /**
     * Set whether the blacklist is enabled.
     *
     * @param  bool  $enabled
     * @return $this
     */
    public function setBlacklistEnabled($enabled)
    {
        $this->blacklistEnabled = $enabled;

        return $this;
    }

    /**
     * Set the claims to be persisted when refreshing a token.
     *
     * @param  array  $claims
     * @return $this
     */
    public function setPersistentClaims(array $claims)
    {
        $this->persistentClaims = $claims;

        return $this;
    }
}


================================================
FILE: src/Payload.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use ArrayAccess;
use BadMethodCallException;
use Countable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use JsonSerializable;
use Tymon\JWTAuth\Claims\Claim;
use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Exceptions\PayloadException;
use Tymon\JWTAuth\Validators\PayloadValidator;

class Payload implements ArrayAccess, Arrayable, Countable, Jsonable, JsonSerializable
{
    /**
     * The collection of claims.
     *
     * @var \Tymon\JWTAuth\Claims\Collection
     */
    private $claims;

    /**
     * Build the Payload.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $claims
     * @param  \Tymon\JWTAuth\Validators\PayloadValidator  $validator
     * @param  bool  $refreshFlow
     * @return void
     */
    public function __construct(Collection $claims, PayloadValidator $validator, $refreshFlow = false)
    {
        $this->claims = $validator->setRefreshFlow($refreshFlow)->check($claims);
    }

    /**
     * Get the array of claim instances.
     *
     * @return \Tymon\JWTAuth\Claims\Collection
     */
    public function getClaims()
    {
        return $this->claims;
    }

    /**
     * Checks if a payload matches some expected values.
     *
     * @param  array  $values
     * @param  bool  $strict
     * @return bool
     */
    public function matches(array $values, $strict = false)
    {
        if (empty($values)) {
            return false;
        }

        $claims = $this->getClaims();

        foreach ($values as $key => $value) {
            if (! $claims->has($key) || ! $claims->get($key)->matches($value, $strict)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Checks if a payload strictly matches some expected values.
     *
     * @param  array  $values
     * @return bool
     */
    public function matchesStrict(array $values)
    {
        return $this->matches($values, true);
    }

    /**
     * Get the payload.
     *
     * @param  mixed  $claim
     * @return mixed
     */
    public function get($claim = null)
    {
        $claim = value($claim);

        if ($claim !== null) {
            if (is_array($claim)) {
                return array_map([$this, 'get'], $claim);
            }

            return Arr::get($this->toArray(), $claim);
        }

        return $this->toArray();
    }

    /**
     * Get the underlying Claim instance.
     *
     * @param  string  $claim
     * @return \Tymon\JWTAuth\Claims\Claim
     */
    public function getInternal($claim)
    {
        return $this->claims->getByClaimName($claim);
    }

    /**
     * Determine whether the payload has the claim (by instance).
     *
     * @param  \Tymon\JWTAuth\Claims\Claim  $claim
     * @return bool
     */
    public function has(Claim $claim)
    {
        return $this->claims->has($claim->getName());
    }

    /**
     * Determine whether the payload has the claim (by key).
     *
     * @param  string  $claim
     * @return bool
     */
    public function hasKey($claim)
    {
        return $this->offsetExists($claim);
    }

    /**
     * Get the array of claims.
     *
     * @return array
     */
    public function toArray()
    {
        return $this->claims->toPlainArray();
    }

    /**
     * Convert the object into something JSON serializable.
     *
     * @return array
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return $this->toArray();
    }

    /**
     * Get the payload as JSON.
     *
     * @param  int  $options
     * @return string
     */
    public function toJson($options = JSON_UNESCAPED_SLASHES)
    {
        return json_encode($this->toArray(), $options);
    }

    /**
     * Get the payload as a string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }

    /**
     * Determine if an item exists at an offset.
     *
     * @param  mixed  $key
     * @return bool
     */
    #[\ReturnTypeWillChange]
    public function offsetExists($key)
    {
        return Arr::has($this->toArray(), $key);
    }

    /**
     * Get an item at a given offset.
     *
     * @param  mixed  $key
     * @return mixed
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($key)
    {
        return Arr::get($this->toArray(), $key);
    }

    /**
     * Don't allow changing the payload as it should be immutable.
     *
     * @param  mixed  $key
     * @param  mixed  $value
     *
     * @throws \Tymon\JWTAuth\Exceptions\PayloadException
     */
    #[\ReturnTypeWillChange]
    public function offsetSet($key, $value)
    {
        throw new PayloadException('The payload is immutable');
    }

    /**
     * Don't allow changing the payload as it should be immutable.
     *
     * @param  string  $key
     * @return void
     *
     * @throws \Tymon\JWTAuth\Exceptions\PayloadException
     */
    #[\ReturnTypeWillChange]
    public function offsetUnset($key)
    {
        throw new PayloadException('The payload is immutable');
    }

    /**
     * Count the number of claims.
     *
     * @return int
     */
    #[\ReturnTypeWillChange]
    public function count()
    {
        return count($this->toArray());
    }

    /**
     * Invoke the Payload as a callable function.
     *
     * @param  mixed  $claim
     * @return mixed
     */
    public function __invoke($claim = null)
    {
        return $this->get($claim);
    }

    /**
     * Magically get a claim value.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (preg_match('/get(.+)\b/i', $method, $matches)) {
            foreach ($this->claims as $claim) {
                if (get_class($claim) === 'Tymon\\JWTAuth\\Claims\\'.$matches[1]) {
                    return $claim->getValue();
                }
            }
        }

        throw new BadMethodCallException(sprintf('The claim [%s] does not exist on the payload.', Str::after($method, 'get')));
    }
}


================================================
FILE: src/Providers/AbstractServiceProvider.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers;

use Illuminate\Support\ServiceProvider;
use Namshi\JOSE\JWS;
use Tymon\JWTAuth\Blacklist;
use Tymon\JWTAuth\Claims\Factory as ClaimFactory;
use Tymon\JWTAuth\Console\JWTGenerateSecretCommand;
use Tymon\JWTAuth\Contracts\Providers\Auth;
use Tymon\JWTAuth\Contracts\Providers\JWT as JWTContract;
use Tymon\JWTAuth\Contracts\Providers\Storage;
use Tymon\JWTAuth\Factory;
use Tymon\JWTAuth\Http\Middleware\Authenticate;
use Tymon\JWTAuth\Http\Middleware\AuthenticateAndRenew;
use Tymon\JWTAuth\Http\Middleware\Check;
use Tymon\JWTAuth\Http\Middleware\RefreshToken;
use Tymon\JWTAuth\Http\Parser\AuthHeaders;
use Tymon\JWTAuth\Http\Parser\InputSource;
use Tymon\JWTAuth\Http\Parser\Parser;
use Tymon\JWTAuth\Http\Parser\QueryString;
use Tymon\JWTAuth\JWT;
use Tymon\JWTAuth\JWTAuth;
use Tymon\JWTAuth\JWTGuard;
use Tymon\JWTAuth\Manager;
use Tymon\JWTAuth\Providers\JWT\Lcobucci;
use Tymon\JWTAuth\Providers\JWT\Namshi;
use Tymon\JWTAuth\Validators\PayloadValidator;

abstract class AbstractServiceProvider extends ServiceProvider
{
    /**
     * The middleware aliases.
     *
     * @var array
     */
    protected $middlewareAliases = [
        'jwt.auth' => Authenticate::class,
        'jwt.check' => Check::class,
        'jwt.refresh' => RefreshToken::class,
        'jwt.renew' => AuthenticateAndRenew::class,
    ];

    /**
     * Boot the service provider.
     *
     * @return void
     */
    abstract public function boot();

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerAliases();

        $this->registerJWTProvider();
        $this->registerAuthProvider();
        $this->registerStorageProvider();
        $this->registerJWTBlacklist();

        $this->registerManager();
        $this->registerTokenParser();

        $this->registerJWT();
        $this->registerJWTAuth();
        $this->registerPayloadValidator();
        $this->registerClaimFactory();
        $this->registerPayloadFactory();
        $this->registerJWTCommand();

        $this->commands('tymon.jwt.secret');
    }

    /**
     * Extend Laravel's Auth.
     *
     * @return void
     */
    protected function extendAuthGuard()
    {
        $this->app['auth']->extend('jwt', function ($app, $name, array $config) {
            $guard = new JWTGuard(
                $app['tymon.jwt'],
                $app['auth']->createUserProvider($config['provider']),
                $app['request']
            );

            $app->refresh('request', $guard, 'setRequest');

            return $guard;
        });
    }

    /**
     * Bind some aliases.
     *
     * @return void
     */
    protected function registerAliases()
    {
        $this->app->alias('tymon.jwt', JWT::class);
        $this->app->alias('tymon.jwt.auth', JWTAuth::class);
        $this->app->alias('tymon.jwt.provider.jwt', JWTContract::class);
        $this->app->alias('tymon.jwt.provider.jwt.namshi', Namshi::class);
        $this->app->alias('tymon.jwt.provider.jwt.lcobucci', Lcobucci::class);
        $this->app->alias('tymon.jwt.provider.auth', Auth::class);
        $this->app->alias('tymon.jwt.provider.storage', Storage::class);
        $this->app->alias('tymon.jwt.manager', Manager::class);
        $this->app->alias('tymon.jwt.blacklist', Blacklist::class);
        $this->app->alias('tymon.jwt.payload.factory', Factory::class);
        $this->app->alias('tymon.jwt.validators.payload', PayloadValidator::class);
    }

    /**
     * Register the bindings for the JSON Web Token provider.
     *
     * @return void
     */
    protected function registerJWTProvider()
    {
        $this->registerNamshiProvider();
        $this->registerLcobucciProvider();

        $this->app->singleton('tymon.jwt.provider.jwt', function ($app) {
            return $this->getConfigInstance('providers.jwt');
        });
    }

    /**
     * Register the bindings for the Lcobucci JWT provider.
     *
     * @return void
     */
    protected function registerNamshiProvider()
    {
        $this->app->singleton('tymon.jwt.provider.jwt.namshi', function ($app) {
            return new Namshi(
                new JWS(['typ' => 'JWT', 'alg' => $this->config('algo')]),
                $this->config('secret'),
                $this->config('algo'),
                $this->config('keys')
            );
        });
    }

    /**
     * Register the bindings for the Lcobucci JWT provider.
     *
     * @return void
     */
    protected function registerLcobucciProvider()
    {
        $this->app->singleton('tymon.jwt.provider.jwt.lcobucci', function ($app) {
            return new Lcobucci(
                $this->config('secret'),
                $this->config('algo'),
                $this->config('keys')
            );
        });
    }

    /**
     * Register the bindings for the Auth provider.
     *
     * @return void
     */
    protected function registerAuthProvider()
    {
        $this->app->singleton('tymon.jwt.provider.auth', function () {
            return $this->getConfigInstance('providers.auth');
        });
    }

    /**
     * Register the bindings for the Storage provider.
     *
     * @return void
     */
    protected function registerStorageProvider()
    {
        $this->app->singleton('tymon.jwt.provider.storage', function () {
            return $this->getConfigInstance('providers.storage');
        });
    }

    /**
     * Register the bindings for the JWT Manager.
     *
     * @return void
     */
    protected function registerManager()
    {
        $this->app->singleton('tymon.jwt.manager', function ($app) {
            $instance = new Manager(
                $app['tymon.jwt.provider.jwt'],
                $app['tymon.jwt.blacklist'],
                $app['tymon.jwt.payload.factory']
            );

            return $instance->setBlacklistEnabled((bool) $this->config('blacklist_enabled'))
                            ->setPersistentClaims($this->config('persistent_claims'));
        });
    }

    /**
     * Register the bindings for the Token Parser.
     *
     * @return void
     */
    protected function registerTokenParser()
    {
        $this->app->singleton('tymon.jwt.parser', function ($app) {
            $parser = new Parser(
                $app['request'],
                [
                    new AuthHeaders,
                    new QueryString,
                    new InputSource,
                ]
            );

            $app->refresh('request', $parser, 'setRequest');

            return $parser;
        });
    }

    /**
     * Register the bindings for the main JWT class.
     *
     * @return void
     */
    protected function registerJWT()
    {
        $this->app->singleton('tymon.jwt', function ($app) {
            return (new JWT(
                $app['tymon.jwt.manager'],
                $app['tymon.jwt.parser']
            ))->lockSubject($this->config('lock_subject'));
        });
    }

    /**
     * Register the bindings for the main JWTAuth class.
     *
     * @return void
     */
    protected function registerJWTAuth()
    {
        $this->app->singleton('tymon.jwt.auth', function ($app) {
            return (new JWTAuth(
                $app['tymon.jwt.manager'],
                $app['tymon.jwt.provider.auth'],
                $app['tymon.jwt.parser']
            ))->lockSubject($this->config('lock_subject'));
        });
    }

    /**
     * Register the bindings for the Blacklist.
     *
     * @return void
     */
    protected function registerJWTBlacklist()
    {
        $this->app->singleton('tymon.jwt.blacklist', function ($app) {
            $instance = new Blacklist($app['tymon.jwt.provider.storage']);

            return $instance->setGracePeriod($this->config('blacklist_grace_period'))
                            ->setRefreshTTL($this->config('refresh_ttl'));
        });
    }

    /**
     * Register the bindings for the payload validator.
     *
     * @return void
     */
    protected function registerPayloadValidator()
    {
        $this->app->singleton('tymon.jwt.validators.payload', function () {
            return (new PayloadValidator)
                ->setRefreshTTL($this->config('refresh_ttl'))
                ->setRequiredClaims($this->config('required_claims'));
        });
    }

    /**
     * Register the bindings for the Claim Factory.
     *
     * @return void
     */
    protected function registerClaimFactory()
    {
        $this->app->singleton('tymon.jwt.claim.factory', function ($app) {
            $factory = new ClaimFactory($app['request']);
            $app->refresh('request', $factory, 'setRequest');

            return $factory->setTTL($this->config('ttl'))
                           ->setLeeway($this->config('leeway'));
        });
    }

    /**
     * Register the bindings for the Payload Factory.
     *
     * @return void
     */
    protected function registerPayloadFactory()
    {
        $this->app->singleton('tymon.jwt.payload.factory', function ($app) {
            return new Factory(
                $app['tymon.jwt.claim.factory'],
                $app['tymon.jwt.validators.payload']
            );
        });
    }

    /**
     * Register the Artisan command.
     *
     * @return void
     */
    protected function registerJWTCommand()
    {
        $this->app->singleton('tymon.jwt.secret', function () {
            return new JWTGenerateSecretCommand;
        });
    }

    /**
     * Helper to get the config values.
     *
     * @param  string  $key
     * @param  string  $default
     * @return mixed
     */
    protected function config($key, $default = null)
    {
        return config("jwt.$key", $default);
    }

    /**
     * Get an instantiable configuration instance.
     *
     * @param  string  $key
     * @return mixed
     */
    protected function getConfigInstance($key)
    {
        $instance = $this->config($key);

        if (is_string($instance)) {
            return $this->app->make($instance);
        }

        return $instance;
    }
}


================================================
FILE: src/Providers/Auth/Illuminate.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers\Auth;

use Illuminate\Contracts\Auth\Guard as GuardContract;
use Tymon\JWTAuth\Contracts\Providers\Auth;

class Illuminate implements Auth
{
    /**
     * The authentication guard.
     *
     * @var \Illuminate\Contracts\Auth\Guard
     */
    protected $auth;

    /**
     * Constructor.
     *
     * @param  \Illuminate\Contracts\Auth\Guard  $auth
     * @return void
     */
    public function __construct(GuardContract $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Check a user's credentials.
     *
     * @param  array  $credentials
     * @return bool
     */
    public function byCredentials(array $credentials)
    {
        return $this->auth->once($credentials);
    }

    /**
     * Authenticate a user via the id.
     *
     * @param  mixed  $id
     * @return bool
     */
    public function byId($id)
    {
        return $this->auth->onceUsingId($id);
    }

    /**
     * Get the currently authenticated user.
     *
     * @return mixed
     */
    public function user()
    {
        return $this->auth->user();
    }
}


================================================
FILE: src/Providers/JWT/Lcobucci.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers\JWT;

use Composer\InstalledVersions;
use DateTimeImmutable;
use DateTimeInterface;
use Exception;
use Illuminate\Support\Collection;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer;
use Lcobucci\JWT\Signer\Ecdsa;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Rsa;
use Lcobucci\JWT\Token\Builder;
use Lcobucci\JWT\Token\RegisteredClaims;
use Lcobucci\JWT\Validation\Constraint\SignedWith;
use Tymon\JWTAuth\Contracts\Providers\JWT;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class Lcobucci extends Provider implements JWT
{
    /**
     * \Lcobucci\JWT\Signer.
     */
    protected $signer;

    /**
     * \Lcobucci\JWT\Configuration.
     */
    protected $config;

    /**
     * Create the Lcobucci provider.
     *
     * @param  string  $secret
     * @param  string  $algo
     * @param  array  $keys
     * @param  \Lcobucci\JWT\Configuration|null  $config
     * @return void
     */
    public function __construct($secret, $algo, array $keys, $config = null)
    {
        parent::__construct($secret, $algo, $keys);

        $this->signer = $this->getSigner();
        $this->config = $config ?: $this->buildConfig();
    }

    /**
     * Signers that this provider supports.
     *
     * @var array
     */
    protected $signers = [
        self::ALGO_HS256 => Signer\Hmac\Sha256::class,
        self::ALGO_HS384 => Signer\Hmac\Sha384::class,
        self::ALGO_HS512 => Signer\Hmac\Sha512::class,
        self::ALGO_RS256 => Signer\Rsa\Sha256::class,
        self::ALGO_RS384 => Signer\Rsa\Sha384::class,
        self::ALGO_RS512 => Signer\Rsa\Sha512::class,
        self::ALGO_ES256 => Signer\Ecdsa\Sha256::class,
        self::ALGO_ES384 => Signer\Ecdsa\Sha384::class,
        self::ALGO_ES512 => Signer\Ecdsa\Sha512::class,
    ];

    /**
     * Create a JSON Web Token.
     *
     * @param  array  $payload
     * @return string
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    public function encode(array $payload)
    {
        $builder = $this->getBuilderFromClaims($payload);

        try {
            return $builder
                ->getToken($this->config->signer(), $this->config->signingKey())
                ->toString();
        } catch (Exception $e) {
            throw new JWTException('Could not create token: '.$e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * Decode a JSON Web Token.
     *
     * @param  string  $token
     * @return array
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    public function decode($token)
    {
        try {
            /** @var \Lcobucci\JWT\Token\Plain */
            $token = $this->config->parser()->parse($token);
        } catch (Exception $e) {
            throw new TokenInvalidException('Could not decode token: '.$e->getMessage(), $e->getCode(), $e);
        }

        if (! $this->config->validator()->validate($token, ...$this->config->validationConstraints())) {
            throw new TokenInvalidException('Token Signature could not be verified.');
        }

        return Collection::wrap($token->claims()->all())
            ->map(function ($claim) {
                if ($claim instanceof DateTimeInterface) {
                    return $claim->getTimestamp();
                }

                return is_object($claim) && method_exists($claim, 'getValue')
                    ? $claim->getValue()
                    : $claim;
            })
            ->toArray();
    }

    /**
     * Create an instance of the builder with all of the claims applied.
     *
     * @param  array  $payload
     * @return \Lcobucci\JWT\Token\Builder
     */
    protected function getBuilderFromClaims(array $payload): Builder
    {
        return array_reduce(
            array_keys($payload),
            function (Builder $builder, string $key) use ($payload): Builder {
                $value = $payload[$key];

                return match ($key) {
                    RegisteredClaims::ID => $builder->identifiedBy($value),
                    RegisteredClaims::EXPIRATION_TIME => $builder->expiresAt(DateTimeImmutable::createFromFormat('U', $value)),
                    RegisteredClaims::NOT_BEFORE => $builder->canOnlyBeUsedAfter(DateTimeImmutable::createFromFormat('U', $value)),
                    RegisteredClaims::ISSUED_AT => $builder->issuedAt(DateTimeImmutable::createFromFormat('U', $value)),
                    RegisteredClaims::ISSUER => $builder->issuedBy($value),
                    RegisteredClaims::AUDIENCE => $builder->permittedFor($value),
                    RegisteredClaims::SUBJECT => $builder->relatedTo($value),
                    default => $builder->withClaim($key, $value),
                };
            },
            $this->config->builder()
        );
    }

    /**
     * Build the configuration.
     *
     * @return \Lcobucci\JWT\Configuration
     */
    protected function buildConfig(): Configuration
    {
        $config = $this->isAsymmetric()
            ? Configuration::forAsymmetricSigner(
                $this->signer,
                $this->getSigningKey(),
                $this->getVerificationKey()
            )
            : Configuration::forSymmetricSigner($this->signer, $this->getSigningKey());

        if (method_exists($config, 'withValidationConstraints')) {
            return $config->withValidationConstraints(
                new SignedWith($this->signer, $this->getVerificationKey())
            );
        }

        $config->setValidationConstraints(
            new SignedWith($this->signer, $this->getVerificationKey())
        );

        return $config;
    }

    /**
     * Get the signer instance.
     *
     * @return \Lcobucci\JWT\Signer
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    protected function getSigner()
    {
        if (! array_key_exists($this->algo, $this->signers)) {
            throw new JWTException('The given algorithm could not be found');
        }

        $signer = $this->signers[$this->algo];

        if (is_subclass_of($signer, Ecdsa::class) && $this->usingV4()) {
            return $signer::create();
        }

        return new $signer();
    }

    /**
     * {@inheritdoc}
     */
    protected function isAsymmetric()
    {
        return is_subclass_of($this->signer, Rsa::class)
            || is_subclass_of($this->signer, Ecdsa::class);
    }

    /**
     * {@inheritdoc}
     *
     * @return \Lcobucci\JWT\Signer\Key
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    protected function getSigningKey()
    {
        if ($this->isAsymmetric()) {
            if (! $privateKey = $this->getPrivateKey()) {
                throw new JWTException('Private key is not set.');
            }

            return $this->getKey($privateKey, $this->getPassphrase() ?? '');
        }

        if (! $secret = $this->getSecret()) {
            throw new JWTException('Secret is not set.');
        }

        return $this->getKey($secret);
    }

    /**
     * {@inheritdoc}
     *
     * @return \Lcobucci\JWT\Signer\Key
     *
     * @throws \Tymon\JWTAuth\Exceptions\JWTException
     */
    protected function getVerificationKey()
    {
        if ($this->isAsymmetric()) {
            if (! $public = $this->getPublicKey()) {
                throw new JWTException('Public key is not set.');
            }

            return $this->getKey($public);
        }

        if (! $secret = $this->getSecret()) {
            throw new JWTException('Secret is not set.');
        }

        return $this->getKey($secret);
    }

    /**
     * Get the signing key instance.
     */
    protected function getKey(string $contents, string $passphrase = ''): Key
    {
        return InMemory::plainText($contents, $passphrase);
    }

    /**
     * Determine if the lcobucci/jwt package version is less than 5.0.0.
     */
    protected function usingV4(): bool
    {
        return version_compare(InstalledVersions::getPrettyVersion('lcobucci/jwt'), '5.0.0', '<');
    }
}


================================================
FILE: src/Providers/JWT/Provider.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers\JWT;

use Illuminate\Support\Arr;

abstract class Provider
{
    const ALGO_HS256 = 'HS256';
    const ALGO_HS384 = 'HS384';
    const ALGO_HS512 = 'HS512';
    const ALGO_RS256 = 'RS256';
    const ALGO_RS384 = 'RS384';
    const ALGO_RS512 = 'RS512';
    const ALGO_ES256 = 'ES256';
    const ALGO_ES384 = 'ES384';
    const ALGO_ES512 = 'ES512';

    /**
     * The secret.
     *
     * @var string
     */
    protected $secret;

    /**
     * The array of keys.
     *
     * @var array
     */
    protected $keys;

    /**
     * The used algorithm.
     *
     * @var string
     */
    protected $algo;

    /**
     * Constructor.
     *
     * @param  string  $secret
     * @param  string  $algo
     * @param  array  $keys
     * @return void
     */
    public function __construct($secret, $algo, array $keys)
    {
        $this->secret = $secret;
        $this->algo = $algo;
        $this->keys = $keys;
    }

    /**
     * Set the algorithm used to sign the token.
     *
     * @param  string  $algo
     * @return $this
     */
    public function setAlgo($algo)
    {
        $this->algo = $algo;

        return $this;
    }

    /**
     * Get the algorithm used to sign the token.
     *
     * @return string
     */
    public function getAlgo()
    {
        return $this->algo;
    }

    /**
     * Set the secret used to sign the token.
     *
     * @param  string  $secret
     * @return $this
     */
    public function setSecret($secret)
    {
        $this->secret = $secret;

        return $this;
    }

    /**
     * Get the secret used to sign the token.
     *
     * @return string
     */
    public function getSecret()
    {
        return $this->secret;
    }

    /**
     * Set the keys used to sign the token.
     *
     * @param  array  $keys
     * @return $this
     */
    public function setKeys(array $keys)
    {
        $this->keys = $keys;

        return $this;
    }

    /**
     * Get the array of keys used to sign tokens with an asymmetric algorithm.
     *
     * @return array
     */
    public function getKeys()
    {
        return $this->keys;
    }

    /**
     * Get the public key used to sign tokens with an asymmetric algorithm.
     *
     * @return string|null
     */
    public function getPublicKey()
    {
        return Arr::get($this->keys, 'public');
    }

    /**
     * Get the private key used to sign tokens with an asymmetric algorithm.
     *
     * @return string|null
     */
    public function getPrivateKey()
    {
        return Arr::get($this->keys, 'private');
    }

    /**
     * Get the passphrase used to sign tokens
     * with an asymmetric algorithm.
     *
     * @return string|null
     */
    public function getPassphrase()
    {
        return Arr::get($this->keys, 'passphrase');
    }

    /**
     * Get the key used to sign the tokens.
     *
     * @return string|null
     */
    protected function getSigningKey()
    {
        return $this->isAsymmetric() ? $this->getPrivateKey() : $this->getSecret();
    }

    /**
     * Get the key used to verify the tokens.
     *
     * @return string|null
     */
    protected function getVerificationKey()
    {
        return $this->isAsymmetric() ? $this->getPublicKey() : $this->getSecret();
    }

    /**
     * Determine if the algorithm is asymmetric, and thus requires a public/private key combo.
     *
     * @return bool
     */
    abstract protected function isAsymmetric();
}


================================================
FILE: src/Providers/LaravelServiceProvider.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers;

use Tymon\JWTAuth\Http\Parser\Cookies;
use Tymon\JWTAuth\Http\Parser\RouteParams;

class LaravelServiceProvider extends AbstractServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public function boot()
    {
        $path = realpath(__DIR__.'/../../config/config.php');

        $this->publishes([$path => config_path('jwt.php')], 'config');
        $this->mergeConfigFrom($path, 'jwt');

        $this->aliasMiddleware();

        $this->extendAuthGuard();

        $this->app['tymon.jwt.parser']->addParser([
            new RouteParams,
            new Cookies($this->config('decrypt_cookies')),
        ]);
    }

    /**
     * {@inheritdoc}
     */
    protected function registerStorageProvider()
    {
        $this->app->singleton('tymon.jwt.provider.storage', function () {
            $instance = $this->getConfigInstance('providers.storage');

            if (method_exists($instance, 'setLaravelVersion')) {
                $instance->setLaravelVersion($this->app->version());
            }

            return $instance;
        });
    }

    /**
     * Alias the middleware.
     *
     * @return void
     */
    protected function aliasMiddleware()
    {
        $router = $this->app['router'];

        $method = method_exists($router, 'aliasMiddleware') ? 'aliasMiddleware' : 'middleware';

        foreach ($this->middlewareAliases as $alias => $middleware) {
            $router->$method($alias, $middleware);
        }
    }
}


================================================
FILE: src/Providers/LumenServiceProvider.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers;

use Tymon\JWTAuth\Http\Parser\LumenRouteParams;

class LumenServiceProvider extends AbstractServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public function boot()
    {
        $this->app->configure('jwt');

        $path = realpath(__DIR__.'/../../config/config.php');
        $this->mergeConfigFrom($path, 'jwt');

        $this->app->routeMiddleware($this->middlewareAliases);

        $this->extendAuthGuard();

        $this->app['tymon.jwt.parser']->addParser(new LumenRouteParams);
    }
}


================================================
FILE: src/Providers/Storage/Illuminate.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Providers\Storage;

use BadMethodCallException;
use Illuminate\Contracts\Cache\Repository as CacheContract;
use Psr\SimpleCache\CacheInterface as PsrCacheInterface;
use Tymon\JWTAuth\Contracts\Providers\Storage;

class Illuminate implements Storage
{
    /**
     * The cache repository contract.
     *
     * @var \Illuminate\Contracts\Cache\Repository
     */
    protected $cache;

    /**
     * The used cache tag.
     *
     * @var string
     */
    protected $tag = 'tymon.jwt';

    /**
     * @var bool
     */
    protected $supportsTags;

    /**
     * @var string|null
     */
    protected $laravelVersion;

    /**
     * Constructor.
     *
     * @param  \Illuminate\Contracts\Cache\Repository  $cache
     * @return void
     */
    public function __construct(CacheContract $cache)
    {
        $this->cache = $cache;
    }

    /**
     * Add a new item into storage.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @param  int  $minutes
     * @return void
     */
    public function add($key, $value, $minutes)
    {
        // If the laravel version is 5.8 or higher then convert minutes to seconds.
        if ($this->laravelVersion !== null
            && is_int($minutes)
            && version_compare($this->laravelVersion, '5.8', '>=')
        ) {
            $minutes = $minutes * 60;
        }

        $this->cache()->put($key, $value, $minutes);
    }

    /**
     * Add a new item into storage forever.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return void
     */
    public function forever($key, $value)
    {
        $this->cache()->forever($key, $value);
    }

    /**
     * Get an item from storage.
     *
     * @param  string  $key
     * @return mixed
     */
    public function get($key)
    {
        return $this->cache()->get($key);
    }

    /**
     * Remove an item from storage.
     *
     * @param  string  $key
     * @return bool
     */
    public function destroy($key)
    {
        return $this->cache()->forget($key);
    }

    /**
     * Remove all items associated with the tag.
     *
     * @return void
     */
    public function flush()
    {
        $this->cache()->flush();
    }

    /**
     * Return the cache instance with tags attached.
     *
     * @return \Illuminate\Contracts\Cache\Repository
     */
    protected function cache()
    {
        if ($this->supportsTags === null) {
            $this->determineTagSupport();
        }

        if ($this->supportsTags) {
            return $this->cache->tags($this->tag);
        }

        return $this->cache;
    }

    /**
     * Set the laravel version.
     */
    public function setLaravelVersion($version)
    {
        $this->laravelVersion = $version;

        return $this;
    }

    /**
     * Detect as best we can whether tags are supported with this repository & store,
     * and save our result on the $supportsTags flag.
     *
     * @return void
     */
    protected function determineTagSupport()
    {
        // Laravel >= 5.1.28
        if (method_exists($this->cache, 'tags') || $this->cache instanceof PsrCacheInterface) {
            try {
                // Attempt the repository tags command, which throws exceptions when unsupported
                $this->cache->tags($this->tag);
                $this->supportsTags = true;
            } catch (BadMethodCallException $ex) {
                $this->supportsTags = false;
            }
        } else {
            // Laravel <= 5.1.27
            if (method_exists($this->cache, 'getStore')) {
                // Check for the tags function directly on the store
                $this->supportsTags = method_exists($this->cache->getStore(), 'tags');
            } else {
                // Must be using custom cache repository without getStore(), and all bets are off,
                // or we are mocking the cache contract (in testing), which will not create a getStore method
                $this->supportsTags = false;
            }
        }
    }
}


================================================
FILE: src/Support/CustomClaims.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Support;

trait CustomClaims
{
    /**
     * Custom claims.
     *
     * @var array
     */
    protected $customClaims = [];

    /**
     * Set the custom claims.
     *
     * @param  array  $customClaims
     * @return $this
     */
    public function customClaims(array $customClaims)
    {
        $this->customClaims = $customClaims;

        return $this;
    }

    /**
     * Alias to set the custom claims.
     *
     * @param  array  $customClaims
     * @return $this
     */
    public function claims(array $customClaims)
    {
        return $this->customClaims($customClaims);
    }

    /**
     * Get the custom claims.
     *
     * @return array
     */
    public function getCustomClaims()
    {
        return $this->customClaims;
    }
}


================================================
FILE: src/Support/RefreshFlow.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Support;

trait RefreshFlow
{
    /**
     * The refresh flow flag.
     *
     * @var bool
     */
    protected $refreshFlow = false;

    /**
     * Set the refresh flow flag.
     *
     * @param  bool  $refreshFlow
     * @return $this
     */
    public function setRefreshFlow($refreshFlow = true)
    {
        $this->refreshFlow = $refreshFlow;

        return $this;
    }
}


================================================
FILE: src/Support/Utils.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Support;

use Carbon\Carbon;

class Utils
{
    /**
     * Get the Carbon instance for the current time.
     *
     * @return \Carbon\Carbon
     */
    public static function now()
    {
        return Carbon::now('UTC');
    }

    /**
     * Get the Carbon instance for the timestamp.
     *
     * @param  int  $timestamp
     * @return \Carbon\Carbon
     */
    public static function timestamp($timestamp)
    {
        return Carbon::createFromTimestampUTC($timestamp)->timezone('UTC');
    }

    /**
     * Checks if a timestamp is in the past.
     *
     * @param  int  $timestamp
     * @param  int  $leeway
     * @return bool
     */
    public static function isPast($timestamp, $leeway = 0)
    {
        $timestamp = static::timestamp($timestamp);

        return $leeway > 0
            ? $timestamp->addSeconds($leeway)->isPast()
            : $timestamp->isPast();
    }

    /**
     * Checks if a timestamp is in the future.
     *
     * @param  int  $timestamp
     * @param  int  $leeway
     * @return bool
     */
    public static function isFuture($timestamp, $leeway = 0)
    {
        $timestamp = static::timestamp($timestamp);

        return $leeway > 0
            ? $timestamp->subSeconds($leeway)->isFuture()
            : $timestamp->isFuture();
    }
}


================================================
FILE: src/Token.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth;

use Tymon\JWTAuth\Validators\TokenValidator;

class Token
{
    /**
     * @var string
     */
    private $value;

    /**
     * Create a new JSON Web Token.
     *
     * @param  string  $value
     * @return void
     */
    public function __construct($value)
    {
        $this->value = (string) (new TokenValidator)->check($value);
    }

    /**
     * Get the token.
     *
     * @return string
     */
    public function get()
    {
        return $this->value;
    }

    /**
     * Get the token when casting to string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->get();
    }
}


================================================
FILE: src/Validators/PayloadValidator.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Validators;

use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class PayloadValidator extends Validator
{
    /**
     * The required claims.
     *
     * @var array
     */
    protected $requiredClaims = [
        'iss',
        'iat',
        'exp',
        'nbf',
        'sub',
        'jti',
    ];

    /**
     * The refresh TTL.
     *
     * @var int
     */
    protected $refreshTTL = 20160;

    /**
     * Run the validations on the payload array.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $value
     * @return \Tymon\JWTAuth\Claims\Collection
     */
    public function check($value)
    {
        $this->validateStructure($value);

        return $this->refreshFlow ? $this->validateRefresh($value) : $this->validatePayload($value);
    }

    /**
     * Ensure the payload contains the required claims and
     * the claims have the relevant type.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $claims
     * @return void
     *
     * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
     */
    protected function validateStructure(Collection $claims)
    {
        if ($this->requiredClaims && ! $claims->hasAllClaims($this->requiredClaims)) {
            throw new TokenInvalidException('JWT payload does not contain the required claims');
        }
    }

    /**
     * Validate the payload timestamps.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $claims
     * @return \Tymon\JWTAuth\Claims\Collection
     *
     * @throws \Tymon\JWTAuth\Exceptions\TokenExpiredException
     * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
     */
    protected function validatePayload(Collection $claims)
    {
        return $claims->validate('payload');
    }

    /**
     * Check the token in the refresh flow context.
     *
     * @param  \Tymon\JWTAuth\Claims\Collection  $claims
     * @return \Tymon\JWTAuth\Claims\Collection
     *
     * @throws \Tymon\JWTAuth\Exceptions\TokenExpiredException
     */
    protected function validateRefresh(Collection $claims)
    {
        return $this->refreshTTL === null ? $claims : $claims->validate('refresh', $this->refreshTTL);
    }

    /**
     * Set the required claims.
     *
     * @param  array  $claims
     * @return $this
     */
    public function setRequiredClaims(array $claims)
    {
        $this->requiredClaims = $claims;

        return $this;
    }

    /**
     * Set the refresh ttl.
     *
     * @param  int  $ttl
     * @return $this
     */
    public function setRefreshTTL($ttl)
    {
        $this->refreshTTL = $ttl !== null ? (int) $ttl : null;

        return $this;
    }
}


================================================
FILE: src/Validators/TokenValidator.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Validators;

use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class TokenValidator extends Validator
{
    /**
     * Check the structure of the token.
     *
     * @param  string  $value
     * @return string
     */
    public function check($value)
    {
        return $this->validateStructure($value);
    }

    /**
     * @param  string  $token
     * @return string
     *
     * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
     */
    protected function validateStructure($token)
    {
        $parts = explode('.', $token);

        if (count($parts) !== 3) {
            throw new TokenInvalidException('Wrong number of segments');
        }

        $parts = array_filter(array_map('trim', $parts));

        if (count($parts) !== 3 || implode('.', $parts) !== $token) {
            throw new TokenInvalidException('Malformed token');
        }

        return $token;
    }
}


================================================
FILE: src/Validators/Validator.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Validators;

use Tymon\JWTAuth\Contracts\Validator as ValidatorContract;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Support\RefreshFlow;

abstract class Validator implements ValidatorContract
{
    use RefreshFlow;

    /**
     * Helper function to return a boolean.
     *
     * @param  array  $value
     * @return bool
     */
    public function isValid($value)
    {
        try {
            $this->check($value);
        } catch (JWTException $e) {
            return false;
        }

        return true;
    }

    /**
     * Run the validation.
     *
     * @param  array  $value
     * @return void
     */
    abstract public function check($value);
}


================================================
FILE: tests/AbstractTestCase.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test;

use Carbon\Carbon;
use Mockery;
use PHPUnit\Framework\TestCase;

abstract class AbstractTestCase extends TestCase
{
    /**
     * @var int
     */
    protected $testNowTimestamp;

    public function setUp(): void
    {
        parent::setUp();

        Carbon::setTestNow($now = Carbon::now());
        $this->testNowTimestamp = $now->getTimestamp();
    }

    public function tearDown(): void
    {
        Carbon::setTestNow();
        Mockery::close();

        parent::tearDown();
    }
}


================================================
FILE: tests/BlacklistTest.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test;

use Mockery;
use Tymon\JWTAuth\Blacklist;
use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Claims\Expiration;
use Tymon\JWTAuth\Claims\IssuedAt;
use Tymon\JWTAuth\Claims\Issuer;
use Tymon\JWTAuth\Claims\JwtId;
use Tymon\JWTAuth\Claims\NotBefore;
use Tymon\JWTAuth\Claims\Subject;
use Tymon\JWTAuth\Contracts\Providers\Storage;
use Tymon\JWTAuth\Payload;
use Tymon\JWTAuth\Validators\PayloadValidator;

class BlacklistTest extends AbstractTestCase
{
    /**
     * @var \Tymon\JWTAuth\Contracts\Providers\Storage|\Mockery\MockInterface
     */
    protected $storage;

    /**
     * @var \Tymon\JWTAuth\Blacklist
     */
    protected $blacklist;

    /**
     * @var \Mockery\MockInterface|\Tymon\JWTAuth\Validators\Validator
     */
    protected $validator;

    public function setUp(): void
    {
        parent::setUp();

        $this->storage = Mockery::mock(Storage::class);
        $this->blacklist = new Blacklist($this->storage);
        $this->validator = Mockery::mock(PayloadValidator::class);
    }

    /** @test */
    public function it_should_add_a_valid_token_to_the_blacklist()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foo'),
        ];

        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $refreshTTL = 20161;

        $this->storage->shouldReceive('get')
            ->with('foo')
            ->once()
            ->andReturn([]);

        $this->storage->shouldReceive('add')
            ->with('foo', ['valid_until' => $this->testNowTimestamp], $refreshTTL + 1)
            ->once();

        $this->blacklist->setRefreshTTL($refreshTTL)->add($payload);
    }

    /** @test */
    public function it_should_add_a_token_with_no_exp_to_the_blacklist_forever()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foo'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('forever')->with('foo', 'forever')->once();
        $this->blacklist->add($payload);
    }

    /** @test */
    public function it_should_return_true_when_adding_an_expired_token_to_the_blacklist()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp - 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foo'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator, true);

        $refreshTTL = 20161;

        $this->storage->shouldReceive('get')
            ->with('foo')
            ->once()
            ->andReturn([]);

        $this->storage->shouldReceive('add')
            ->with('foo', ['valid_until' => $this->testNowTimestamp], $refreshTTL + 1)
            ->once();

        $this->assertTrue($this->blacklist->setRefreshTTL($refreshTTL)->add($payload));
    }

    /** @test */
    public function it_should_return_true_early_when_adding_an_item_and_it_already_exists()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp - 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foo'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator, true);

        $refreshTTL = 20161;

        $this->storage->shouldReceive('get')
            ->with('foo')
            ->once()
            ->andReturn(['valid_until' => $this->testNowTimestamp]);

        $this->storage->shouldReceive('add')
            ->with('foo', ['valid_until' => $this->testNowTimestamp], $refreshTTL + 1)
            ->never();

        $this->assertTrue($this->blacklist->setRefreshTTL($refreshTTL)->add($payload));
    }

    /** @test */
    public function it_should_check_whether_a_token_has_been_blacklisted()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];

        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('get')->with('foobar')->once()->andReturn(['valid_until' => $this->testNowTimestamp]);

        $this->assertTrue($this->blacklist->has($payload));
    }

    public function blacklist_provider()
    {
        return [
            [null],
            [0],
            [''],
            [[]],
            [['valid_until' => strtotime('+1day')]],
        ];
    }

    /**
     * @test
     *
     * @dataProvider blacklist_provider
     *
     * @param  mixed  $result
     */
    public function it_should_check_whether_a_token_has_not_been_blacklisted($result)
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];

        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('get')->with('foobar')->once()->andReturn($result);
        $this->assertFalse($this->blacklist->has($payload));
    }

    /** @test */
    public function it_should_check_whether_a_token_has_been_blacklisted_forever()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('get')->with('foobar')->once()->andReturn('forever');

        $this->assertTrue($this->blacklist->has($payload));
    }

    /** @test */
    public function it_should_check_whether_a_token_has_been_blacklisted_when_the_token_is_not_blacklisted()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('get')->with('foobar')->once()->andReturn(null);

        $this->assertFalse($this->blacklist->has($payload));
    }

    /** @test */
    public function it_should_remove_a_token_from_the_blacklist()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('destroy')->with('foobar')->andReturn(true);
        $this->assertTrue($this->blacklist->remove($payload));
    }

    /** @test */
    public function it_should_set_a_custom_unique_key_for_the_blacklist()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foobar'),
        ];
        $collection = Collection::make($claims);

        $this->validator->shouldReceive('setRefreshFlow->check')->andReturn($collection);

        $payload = new Payload($collection, $this->validator);

        $this->storage->shouldReceive('get')->with(1)->once()->andReturn(['valid_until' => $this->testNowTimestamp]);

        $this->assertTrue($this->blacklist->setKey('sub')->has($payload));
        $this->assertSame(1, $this->blacklist->getKey($payload));
    }

    /** @test */
    public function it_should_empty_the_blacklist()
    {
        $this->storage->shouldReceive('flush');
        $this->assertTrue($this->blacklist->clear());
    }

    /** @test */
    public function it_should_set_and_get_the_blacklist_grace_period()
    {
        $this->assertInstanceOf(Blacklist::class, $this->blacklist->setGracePeriod(15));
        $this->assertSame(15, $this->blacklist->getGracePeriod());
    }

    /** @test */
    public function it_should_set_and_get_the_blacklist_refresh_ttl()
    {
        $this->assertInstanceOf(Blacklist::class, $this->blacklist->setRefreshTTL(15));
        $this->assertSame(15, $this->blacklist->getRefreshTTL());
    }
}


================================================
FILE: tests/Claims/ClaimTest.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test\Claims;

use Illuminate\Contracts\Support\Arrayable;
use Tymon\JWTAuth\Claims\Expiration;
use Tymon\JWTAuth\Exceptions\InvalidClaimException;
use Tymon\JWTAuth\Test\AbstractTestCase;

class ClaimTest extends AbstractTestCase
{
    /**
     * @var \Tymon\JWTAuth\Claims\Expiration
     */
    protected $claim;

    public function setUp(): void
    {
        parent::setUp();

        $this->claim = new Expiration($this->testNowTimestamp);
    }

    /** @test */
    public function it_should_throw_an_exception_when_passing_an_invalid_value()
    {
        $this->expectException(InvalidClaimException::class);
        $this->expectExceptionMessage('Invalid value provided for claim [exp]');

        $this->claim->setValue('foo');
    }

    /** @test */
    public function it_should_convert_the_claim_to_an_array()
    {
        $this->assertSame(['exp' => $this->testNowTimestamp], $this->claim->toArray());
    }

    /** @test */
    public function it_should_get_the_claim_as_a_string()
    {
        $this->assertJsonStringEqualsJsonString((string) $this->claim, $this->claim->toJson());
    }

    /** @test */
    public function it_should_get_the_object_as_json()
    {
        $this->assertJsonStringEqualsJsonString(json_encode($this->claim), $this->claim->toJson());
    }

    /** @test */
    public function it_should_implement_arrayable()
    {
        $this->assertInstanceOf(Arrayable::class, $this->claim);
    }
}


================================================
FILE: tests/Claims/CollectionTest.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test\Claims;

use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Claims\Expiration;
use Tymon\JWTAuth\Claims\IssuedAt;
use Tymon\JWTAuth\Claims\Issuer;
use Tymon\JWTAuth\Claims\JwtId;
use Tymon\JWTAuth\Claims\NotBefore;
use Tymon\JWTAuth\Claims\Subject;
use Tymon\JWTAuth\Test\AbstractTestCase;

class CollectionTest extends AbstractTestCase
{
    private function getCollection()
    {
        $claims = [
            new Subject(1),
            new Issuer('http://example.com'),
            new Expiration($this->testNowTimestamp + 3600),
            new NotBefore($this->testNowTimestamp),
            new IssuedAt($this->testNowTimestamp),
            new JwtId('foo'),
        ];

        return new Collection($claims);
    }

    /** @test */
    public function it_should_sanitize_the_claims_to_associative_array()
    {
        $collection = $this->getCollection();

        $this->assertSame(array_keys($collection->toArray()), ['sub', 'iss', 'exp', 'nbf', 'iat', 'jti']);
    }

    /** @test */
    public function it_should_determine_if_a_collection_contains_all_the_given_claims()
    {
        $collection = $this->getCollection();

        $this->assertFalse($collection->hasAllClaims(['sub', 'iss', 'exp', 'nbf', 'iat', 'jti', 'abc']));
        $this->assertFalse($collection->hasAllClaims(['foo', 'bar']));
        $this->assertFalse($collection->hasAllClaims([]));

        $this->assertTrue($collection->hasAllClaims(['sub', 'iss']));
        $this->assertTrue($collection->hasAllClaims(['sub', 'iss', 'exp', 'nbf', 'iat', 'jti']));
    }

    /** @test */
    public function it_should_get_a_claim_instance_by_name()
    {
        $collection = $this->getCollection();

        $this->assertInstanceOf(Expiration::class, $collection->getByClaimName('exp'));
        $this->assertInstanceOf(Subject::class, $collection->getByClaimName('sub'));
    }
}


================================================
FILE: tests/Claims/DatetimeClaimTest.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test\Claims;

use Carbon\Carbon;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Mockery;
use Tymon\JWTAuth\Claims\Collection;
use Tymon\JWTAuth\Claims\Expiration;
use Tymon\JWTAuth\Claims\IssuedAt;
use Tymon\JWTAuth\Claims\Issuer;
use Tymon\JWTAuth\Claims\JwtId;
use Tymon\JWTAuth\Claims\NotBefore;
use Tymon\JWTAuth\Claims\Subject;
use Tymon\JWTAuth\Payload;
use Tymon\JWTAuth\Test\AbstractTestCase;
use Tymon\JWTAuth\Validators\PayloadValidator;

class DatetimeClaimTest extends AbstractTestCase
{
    /**
     * @var \Mockery\MockInterface|\Tymon\JWTAuth\Validators\PayloadValidator
     */
    protected $validator;

    /**
     * @var array
     */
    protected $claimsTimestamp;

    public function setUp(): void
    {
        parent::setUp();

        $this->validator = Mockery::mock(PayloadValidator::class);
        $this->validator->shouldReceive('setRefreshFlow->check');

        $this->claimsTimestamp = [
            'sub' => new Subject(1),
            'iss' => new Issuer('http://example.com'),
            'exp' => new Expiration($this->testNowTimestamp + 3600),
            'nbf' => new NotBefore($this->testNowTimestamp),
            'iat' => new IssuedAt($this->testNowTimestamp),
            'jti' => new JwtId('foo'),
        ];
    }

    /** @test */
    public function it_should_handle_carbon_claims()
    {
        $testCarbon = Carbon::createFromTimestampUTC($this->testNowTimestamp);
        $testCarbonCopy = clone $testCarbon;

        $this->assertInstanceOf(Carbon::class, $testCarbon);
        $this->assertInstanceOf(Datetime::class, $testCarbon);
        $this->assertInstanceOf(DatetimeInterface::class, $testCarbon);

        $claimsDatetime = [
            'sub' => new Subject(1),
            'iss' => new Issuer('http://example.com'),
            'exp' => new Expiration($testCarbonCopy->addHour()),
            'nbf' => new NotBefore($testCarbon),
            'iat' => new IssuedAt($testCarbon),
            'jti' => new JwtId('foo'),
        ];

        $payloadTimestamp = new Payload(Collection::make($this->claimsTimestamp), $this->validator);
        $payloadDatetime = new Payload(Collection::make($claimsDatetime), $this->validator);

        $this->assertEquals($payloadTimestamp, $payloadDatetime);
    }

    /** @test */
    public function it_should_handle_datetime_claims()
    {
        $testDateTime = DateTime::createFromFormat('U', $this->testNowTimestamp);
        $testDateTimeCopy = clone $testDateTime;

        $this->assertInstanceOf(DateTime::class, $testDateTime);
        $this->assertInstanceOf(DatetimeInterface::class, $testDateTime);

        $claimsDatetime = [
            'sub' => new Subject(1),
            'iss' => new Issuer('http://example.com'),
            'exp' => new Expiration($testDateTimeCopy->modify('+3600 seconds')),
            'nbf' => new NotBefore($testDateTime),
            'iat' => new IssuedAt($testDateTime),
            'jti' => new JwtId('foo'),
        ];

        $payloadTimestamp = new Payload(Collection::make($this->claimsTimestamp), $this->validator);
        $payloadDatetime = new Payload(Collection::make($claimsDatetime), $this->validator);

        $this->assertEquals($payloadTimestamp, $payloadDatetime);
    }

    /** @test */
    public function it_should_handle_datetime_immutable_claims()
    {
        $testDateTimeImmutable = DateTimeImmutable::createFromFormat('U', (string) $this->testNowTimestamp);

        $this->assertInstanceOf(DateTimeImmutable::class, $testDateTimeImmutable);
        $this->assertInstanceOf(DatetimeInterface::class, $testDateTimeImmutable);

        $claimsDatetime = [
            'sub' => new Subject(1),
            'iss' => new Issuer('http://example.com'),
            'exp' => new Expiration($testDateTimeImmutable->modify('+3600 seconds')),
            'nbf' => new NotBefore($testDateTimeImmutable),
            'iat' => new IssuedAt($testDateTimeImmutable),
            'jti' => new JwtId('foo'),
        ];

        $payloadTimestamp = new Payload(Collection::make($this->claimsTimestamp), $this->validator);
        $payloadDatetime = new Payload(Collection::make($claimsDatetime), $this->validator);

        $this->assertEquals($payloadTimestamp, $payloadDatetime);
    }

    /** @test */
    public function it_should_handle_datetinterval_claims()
    {
        $testDateInterval = new DateInterval('PT1H');

        $this->assertInstanceOf(DateInterval::class, $testDateInterval);

        $claimsDateInterval = [
            'sub' => new Subject(1),
            'iss' => new Issuer('http://example.com'),
            'exp' => new Expiration($testDateInterval),
            'nbf' => new NotBefore($this->testNowTimestamp),
            'iat' => new IssuedAt($this->testNowTimestamp),
            'jti' => new JwtId('foo'),
        ];

        $payloadTimestamp = new Payload(Collection::make($this->claimsTimestamp), $this->validator);
        $payloadDateInterval = new Payload(Collection::make($claimsDateInterval), $this->validator);

        $this->assertEquals($payloadTimestamp, $payloadDateInterval);
    }
}


================================================
FILE: tests/Claims/FactoryTest.php
================================================
<?php

/*
 * This file is part of jwt-auth.
 *
 * (c) Sean Tymon <tymon148@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Tymon\JWTAuth\Test\Claims;

use Illuminate\Http\Request;
use Tymon\JWTAuth\Claims\Custom;
use Tymon\JWTAuth\Claims\Expiration;
use Tymon\JWTAuth\Claims\Factory;
use Tymon\JWTAuth\Claims\IssuedAt;
use Tymon\JWTAuth\Claims\Issuer;
use Tymon\JWTAuth\Claims\JwtId;
use Tymon\JWTAuth\Claims\NotBefore;
use Tymon\JWTAuth\Claims\Subject;
use Tymon\JWTAuth\Test\AbstractTestCase;
use Tymon\JWTAuth\Test\Fixtures\Foo;

class FactoryTest extends AbstractTestCase
{
    /**
     * @var \Tymon\JWTAuth\Claims\Factory
     */
    protected $factory;

    public function setUp(): void
    {
        parent::setUp();

        $this->factory = new Factory(Request::create('/foo', 'GET'));
    }

    /** @test */
    public function it_should_set_the_request()
    {
        $factory = $this->factory->setRequest(Request::create('/bar', 'GET'));
        $this->assertInstanceOf(Factory::class, $factory);
    }

    /** @test */
    public function it_should_set_the_ttl()
    {
        $this->assertInstanceOf(Factory::class, $this->factory->setTTL(30));
        $this->assertSame(30, $this->factory->getTTL());
        $this->assertInstanceOf(Factory::class, $this->factory->setTTL('60'));
        $this->assertSame(60, $this->factory->getTTL());
    }

    /** @test */
    public function it_should_set_the_leeway()
    {
        $this->assertInstanceOf(Factory::class, $this->factory->setLeeway(30));
        $this->assertSame(30, $this->factory->getLeeway());
        $this->assertInstanceOf(Factory::class, $this->factory->setLeeway('60'));
        $this->assertSame(60, $this->factory->getLeeway());
    }

    /** @test */
    public function it_should_get_a_defined_claim_instance_when_passing_a_name_and_value()
    {
        $this->assertInstanceOf(Subject::class, $this->factory->get('sub', 1));
        $this->assertInstanceOf(Issuer::class, $this->factory->get('iss', 'http://example.com'));
        $this->assertInstanceOf(Expiration::class, $this->factory->get('exp', $this->testNowTimestamp + 3600));
        $this->assertInstanceOf(NotBefore::cla
Download .txt
gitextract_f_blvbi4/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       └── phpunit.yml
├── .gitignore
├── .styleci.yml
├── LICENSE
├── README.md
├── composer.json
├── config/
│   └── config.php
├── docs/
│   ├── auth-guard.md
│   ├── configuration.md
│   ├── exception-handling.md
│   ├── index.md
│   ├── laravel-installation.md
│   ├── lumen-installation.md
│   ├── quick-start.md
│   └── resources.md
├── mkdocs.yml
├── phpunit.xml.dist
├── src/
│   ├── Blacklist.php
│   ├── Claims/
│   │   ├── Audience.php
│   │   ├── Claim.php
│   │   ├── Collection.php
│   │   ├── Custom.php
│   │   ├── DatetimeTrait.php
│   │   ├── Expiration.php
│   │   ├── Factory.php
│   │   ├── IssuedAt.php
│   │   ├── Issuer.php
│   │   ├── JwtId.php
│   │   ├── NotBefore.php
│   │   └── Subject.php
│   ├── Console/
│   │   └── JWTGenerateSecretCommand.php
│   ├── Contracts/
│   │   ├── Claim.php
│   │   ├── Http/
│   │   │   └── Parser.php
│   │   ├── JWTSubject.php
│   │   ├── Providers/
│   │   │   ├── Auth.php
│   │   │   ├── JWT.php
│   │   │   └── Storage.php
│   │   └── Validator.php
│   ├── Exceptions/
│   │   ├── InvalidClaimException.php
│   │   ├── JWTException.php
│   │   ├── PayloadException.php
│   │   ├── TokenBlacklistedException.php
│   │   ├── TokenExpiredException.php
│   │   ├── TokenInvalidException.php
│   │   └── UserNotDefinedException.php
│   ├── Facades/
│   │   ├── JWTAuth.php
│   │   ├── JWTFactory.php
│   │   └── JWTProvider.php
│   ├── Factory.php
│   ├── Http/
│   │   ├── Middleware/
│   │   │   ├── Authenticate.php
│   │   │   ├── AuthenticateAndRenew.php
│   │   │   ├── BaseMiddleware.php
│   │   │   ├── Check.php
│   │   │   └── RefreshToken.php
│   │   └── Parser/
│   │       ├── AuthHeaders.php
│   │       ├── Cookies.php
│   │       ├── InputSource.php
│   │       ├── KeyTrait.php
│   │       ├── LumenRouteParams.php
│   │       ├── Parser.php
│   │       ├── QueryString.php
│   │       └── RouteParams.php
│   ├── JWT.php
│   ├── JWTAuth.php
│   ├── JWTGuard.php
│   ├── Manager.php
│   ├── Payload.php
│   ├── Providers/
│   │   ├── AbstractServiceProvider.php
│   │   ├── Auth/
│   │   │   └── Illuminate.php
│   │   ├── JWT/
│   │   │   ├── Lcobucci.php
│   │   │   └── Provider.php
│   │   ├── LaravelServiceProvider.php
│   │   ├── LumenServiceProvider.php
│   │   └── Storage/
│   │       └── Illuminate.php
│   ├── Support/
│   │   ├── CustomClaims.php
│   │   ├── RefreshFlow.php
│   │   └── Utils.php
│   ├── Token.php
│   └── Validators/
│       ├── PayloadValidator.php
│       ├── TokenValidator.php
│       └── Validator.php
└── tests/
    ├── AbstractTestCase.php
    ├── BlacklistTest.php
    ├── Claims/
    │   ├── ClaimTest.php
    │   ├── CollectionTest.php
    │   ├── DatetimeClaimTest.php
    │   ├── FactoryTest.php
    │   ├── IssuedAtTest.php
    │   └── NotBeforeTest.php
    ├── FactoryTest.php
    ├── Fixtures/
    │   └── Foo.php
    ├── Http/
    │   └── ParserTest.php
    ├── JWTAuthTest.php
    ├── JWTGuardTest.php
    ├── ManagerTest.php
    ├── Middleware/
    │   ├── AbstractMiddlewareTest.php
    │   ├── AuthenticateAndRenewTest.php
    │   ├── AuthenticateTest.php
    │   ├── CheckTest.php
    │   └── RefreshTokenTest.php
    ├── PayloadTest.php
    ├── Providers/
    │   ├── Auth/
    │   │   └── IlluminateTest.php
    │   ├── JWT/
    │   │   ├── LcobucciTest.php
    │   │   └── ProviderTest.php
    │   ├── Keys/
    │   │   ├── id_ecdsa
    │   │   ├── id_ecdsa.pub
    │   │   ├── id_rsa
    │   │   └── id_rsa.pub
    │   └── Storage/
    │       └── IlluminateTest.php
    ├── Stubs/
    │   ├── JWTProviderStub.php
    │   ├── LaravelUserStub.php
    │   ├── TaggedStorage.php
    │   └── UserStub.php
    ├── TokenTest.php
    └── Validators/
        ├── PayloadValidatorTest.php
        └── TokenValidatorTest.php
Download .txt
SYMBOL INDEX (651 symbols across 95 files)

FILE: src/Blacklist.php
  class Blacklist (line 17) | class Blacklist
    method __construct (line 53) | public function __construct(Storage $storage)
    method add (line 64) | public function add(Payload $payload)
    method getMinutesUntilExpired (line 92) | protected function getMinutesUntilExpired(Payload $payload)
    method addForever (line 115) | public function addForever(Payload $payload)
    method has (line 128) | public function has(Payload $payload)
    method remove (line 147) | public function remove(Payload $payload)
    method clear (line 157) | public function clear()
    method getGraceTimestamp (line 170) | protected function getGraceTimestamp()
    method setGracePeriod (line 181) | public function setGracePeriod($gracePeriod)
    method getGracePeriod (line 193) | public function getGracePeriod()
    method getKey (line 204) | public function getKey(Payload $payload)
    method setKey (line 215) | public function setKey($key)
    method setRefreshTTL (line 228) | public function setRefreshTTL($ttl)
    method getRefreshTTL (line 240) | public function getRefreshTTL()

FILE: src/Claims/Audience.php
  class Audience (line 14) | class Audience extends Claim

FILE: src/Claims/Claim.php
  class Claim (line 19) | abstract class Claim implements Arrayable, ClaimContract, Jsonable, Json...
    method __construct (line 39) | public function __construct($value)
    method setValue (line 52) | public function setValue($value)
    method getValue (line 64) | public function getValue()
    method setName (line 75) | public function setName($name)
    method getName (line 87) | public function getName()
    method validateCreate (line 98) | public function validateCreate($value)
    method validatePayload (line 108) | public function validatePayload()
    method validateRefresh (line 119) | public function validateRefresh($refreshTTL)
    method matches (line 131) | public function matches($value, $strict = true)
    method jsonSerialize (line 141) | #[\ReturnTypeWillChange]
    method toArray (line 152) | public function toArray()
    method toJson (line 163) | public function toJson($options = JSON_UNESCAPED_SLASHES)
    method __toString (line 173) | public function __toString()

FILE: src/Claims/Collection.php
  class Collection (line 17) | class Collection extends IlluminateCollection
    method __construct (line 25) | public function __construct($items = [])
    method getByClaimName (line 38) | public function getByClaimName($name, ?callable $callback = null, $def...
    method validate (line 51) | public function validate($context = 'payload')
    method hasAllClaims (line 72) | public function hasAllClaims($claims)
    method toPlainArray (line 82) | public function toPlainArray()
    method getArrayableItems (line 92) | protected function getArrayableItems($items)
    method sanitizeClaims (line 103) | private function sanitizeClaims($items)

FILE: src/Claims/Custom.php
  class Custom (line 14) | class Custom extends Claim
    method __construct (line 21) | public function __construct($name, $value)

FILE: src/Claims/DatetimeTrait.php
  type DatetimeTrait (line 19) | trait DatetimeTrait
    method setValue (line 36) | public function setValue($value)
    method validateCreate (line 52) | public function validateCreate($value)
    method isFuture (line 67) | protected function isFuture($value)
    method isPast (line 78) | protected function isPast($value)
    method setLeeway (line 89) | public function setLeeway($leeway)

FILE: src/Claims/Expiration.php
  class Expiration (line 16) | class Expiration extends Claim
    method validatePayload (line 28) | public function validatePayload()

FILE: src/Claims/Factory.php
  class Factory (line 18) | class Factory
    method __construct (line 62) | public function __construct(Request $request)
    method get (line 74) | public function get($name, $value)
    method has (line 93) | public function has($name)
    method make (line 104) | public function make($name)
    method iss (line 114) | public function iss()
    method iat (line 124) | public function iat()
    method exp (line 134) | public function exp()
    method nbf (line 144) | public function nbf()
    method jti (line 154) | public function jti()
    method extend (line 166) | public function extend($name, $classPath)
    method setRequest (line 179) | public function setRequest(Request $request)
    method setTTL (line 192) | public function setTTL($ttl)
    method getTTL (line 204) | public function getTTL()
    method setLeeway (line 215) | public function setLeeway($leeway)
    method getLeeway (line 227) | public function getLeeway()

FILE: src/Claims/IssuedAt.php
  class IssuedAt (line 18) | class IssuedAt extends Claim
    method validateCreate (line 32) | public function validateCreate($value)
    method validatePayload (line 46) | public function validatePayload()
    method validateRefresh (line 56) | public function validateRefresh($refreshTTL)

FILE: src/Claims/Issuer.php
  class Issuer (line 14) | class Issuer extends Claim

FILE: src/Claims/JwtId.php
  class JwtId (line 14) | class JwtId extends Claim

FILE: src/Claims/NotBefore.php
  class NotBefore (line 16) | class NotBefore extends Claim
    method validatePayload (line 28) | public function validatePayload()

FILE: src/Claims/Subject.php
  class Subject (line 14) | class Subject extends Claim

FILE: src/Console/JWTGenerateSecretCommand.php
  class JWTGenerateSecretCommand (line 17) | class JWTGenerateSecretCommand extends Command
    method handle (line 41) | public function handle()
    method displayKey (line 87) | protected function displayKey($key)
    method isConfirmed (line 99) | protected function isConfirmed()
    method envPath (line 111) | protected function envPath()

FILE: src/Contracts/Claim.php
  type Claim (line 14) | interface Claim
    method setValue (line 24) | public function setValue($value);
    method getValue (line 31) | public function getValue();
    method setName (line 39) | public function setName($name);
    method getName (line 46) | public function getName();
    method validateCreate (line 54) | public function validateCreate($value);

FILE: src/Contracts/Http/Parser.php
  type Parser (line 16) | interface Parser
    method parse (line 24) | public function parse(Request $request);

FILE: src/Contracts/JWTSubject.php
  type JWTSubject (line 14) | interface JWTSubject
    method getJWTIdentifier (line 21) | public function getJWTIdentifier();
    method getJWTCustomClaims (line 28) | public function getJWTCustomClaims();

FILE: src/Contracts/Providers/Auth.php
  type Auth (line 14) | interface Auth
    method byCredentials (line 22) | public function byCredentials(array $credentials);
    method byId (line 30) | public function byId($id);
    method user (line 37) | public function user();

FILE: src/Contracts/Providers/JWT.php
  type JWT (line 14) | interface JWT
    method encode (line 20) | public function encode(array $payload);
    method decode (line 26) | public function decode($token);

FILE: src/Contracts/Providers/Storage.php
  type Storage (line 14) | interface Storage
    method add (line 22) | public function add($key, $value, $minutes);
    method forever (line 29) | public function forever($key, $value);
    method get (line 35) | public function get($key);
    method destroy (line 41) | public function destroy($key);
    method flush (line 46) | public function flush();

FILE: src/Contracts/Validator.php
  type Validator (line 14) | interface Validator
    method check (line 22) | public function check($value);
    method isValid (line 30) | public function isValid($value);

FILE: src/Exceptions/InvalidClaimException.php
  class InvalidClaimException (line 17) | class InvalidClaimException extends JWTException
    method __construct (line 27) | public function __construct(Claim $claim, $code = 0, ?Exception $previ...

FILE: src/Exceptions/JWTException.php
  class JWTException (line 16) | class JWTException extends Exception

FILE: src/Exceptions/PayloadException.php
  class PayloadException (line 14) | class PayloadException extends JWTException

FILE: src/Exceptions/TokenBlacklistedException.php
  class TokenBlacklistedException (line 14) | class TokenBlacklistedException extends TokenInvalidException

FILE: src/Exceptions/TokenExpiredException.php
  class TokenExpiredException (line 14) | class TokenExpiredException extends JWTException

FILE: src/Exceptions/TokenInvalidException.php
  class TokenInvalidException (line 14) | class TokenInvalidException extends JWTException

FILE: src/Exceptions/UserNotDefinedException.php
  class UserNotDefinedException (line 14) | class UserNotDefinedException extends JWTException

FILE: src/Facades/JWTAuth.php
  class JWTAuth (line 16) | class JWTAuth extends Facade
    method getFacadeAccessor (line 23) | protected static function getFacadeAccessor()

FILE: src/Facades/JWTFactory.php
  class JWTFactory (line 16) | class JWTFactory extends Facade
    method getFacadeAccessor (line 23) | protected static function getFacadeAccessor()

FILE: src/Facades/JWTProvider.php
  class JWTProvider (line 16) | class JWTProvider extends Facade
    method getFacadeAccessor (line 23) | protected static function getFacadeAccessor()

FILE: src/Factory.php
  class Factory (line 21) | class Factory
    method __construct (line 66) | public function __construct(ClaimFactory $claimFactory, PayloadValidat...
    method make (line 79) | public function make($resetClaims = false)
    method emptyClaims (line 93) | public function emptyClaims()
    method addClaims (line 106) | protected function addClaims(array $claims)
    method addClaim (line 122) | protected function addClaim($name, $value)
    method buildClaims (line 134) | protected function buildClaims()
    method resolveClaims (line 155) | protected function resolveClaims()
    method buildClaimsCollection (line 167) | public function buildClaimsCollection()
    method withClaims (line 178) | public function withClaims(Collection $claims)
    method setDefaultClaims (line 189) | public function setDefaultClaims(array $claims)
    method setTTL (line 202) | public function setTTL($ttl)
    method getTTL (line 214) | public function getTTL()
    method getDefaultClaims (line 224) | public function getDefaultClaims()
    method validator (line 234) | public function validator()
    method __call (line 246) | public function __call($method, $parameters)

FILE: src/Http/Middleware/Authenticate.php
  class Authenticate (line 17) | class Authenticate extends BaseMiddleware
    method handle (line 28) | public function handle($request, Closure $next)

FILE: src/Http/Middleware/AuthenticateAndRenew.php
  class AuthenticateAndRenew (line 17) | class AuthenticateAndRenew extends BaseMiddleware
    method handle (line 28) | public function handle($request, Closure $next)

FILE: src/Http/Middleware/BaseMiddleware.php
  class BaseMiddleware (line 20) | abstract class BaseMiddleware
    method __construct (line 35) | public function __construct(JWTAuth $auth)
    method checkForToken (line 48) | public function checkForToken(Request $request)
    method authenticate (line 63) | public function authenticate(Request $request)
    method setAuthenticationHeader (line 83) | protected function setAuthenticationHeader($response, $token = null)

FILE: src/Http/Middleware/Check.php
  class Check (line 18) | class Check extends BaseMiddleware
    method handle (line 27) | public function handle($request, Closure $next)

FILE: src/Http/Middleware/RefreshToken.php
  class RefreshToken (line 19) | class RefreshToken extends BaseMiddleware
    method handle (line 30) | public function handle($request, Closure $next)

FILE: src/Http/Parser/AuthHeaders.php
  class AuthHeaders (line 17) | class AuthHeaders implements ParserContract
    method fromAltHeaders (line 39) | protected function fromAltHeaders(Request $request)
    method parse (line 50) | public function parse(Request $request)
    method setHeaderName (line 75) | public function setHeaderName($headerName)
    method setHeaderPrefix (line 88) | public function setHeaderPrefix($headerPrefix)

FILE: src/Http/Parser/Cookies.php
  class Cookies (line 18) | class Cookies implements ParserContract
    method __construct (line 29) | public function __construct($decrypt = true)
    method parse (line 40) | public function parse(Request $request)

FILE: src/Http/Parser/InputSource.php
  class InputSource (line 17) | class InputSource implements ParserContract
    method parse (line 27) | public function parse(Request $request)

FILE: src/Http/Parser/KeyTrait.php
  type KeyTrait (line 14) | trait KeyTrait
    method setKey (line 29) | public function setKey($key)
    method getKey (line 41) | public function getKey()

FILE: src/Http/Parser/LumenRouteParams.php
  class LumenRouteParams (line 17) | class LumenRouteParams extends RouteParams
    method parse (line 25) | public function parse(Request $request)

FILE: src/Http/Parser/Parser.php
  class Parser (line 16) | class Parser
    method __construct (line 39) | public function __construct(Request $request, array $chain = [])
    method getChain (line 50) | public function getChain()
    method addParser (line 61) | public function addParser($parsers)
    method setChain (line 74) | public function setChain(array $chain)
    method setChainOrder (line 87) | public function setChainOrder(array $chain)
    method parseToken (line 98) | public function parseToken()
    method hasToken (line 112) | public function hasToken()
    method setRequest (line 123) | public function setRequest(Request $request)

FILE: src/Http/Parser/QueryString.php
  class QueryString (line 17) | class QueryString implements ParserContract
    method parse (line 27) | public function parse(Request $request)

FILE: src/Http/Parser/RouteParams.php
  class RouteParams (line 17) | class RouteParams implements ParserContract
    method parse (line 27) | public function parse(Request $request)

FILE: src/JWT.php
  class JWT (line 21) | class JWT
    method __construct (line 60) | public function __construct(Manager $manager, Parser $parser)
    method fromSubject (line 72) | public function fromSubject(JWTSubject $subject)
    method fromUser (line 85) | public function fromUser(JWTSubject $user)
    method refresh (line 97) | public function refresh($forceForever = false, $resetClaims = false)
    method invalidate (line 112) | public function invalidate($forceForever = false)
    method checkOrFail (line 129) | public function checkOrFail()
    method check (line 140) | public function check($getPayload = false)
    method getToken (line 156) | public function getToken()
    method parseToken (line 176) | public function parseToken()
    method getPayload (line 190) | public function getPayload()
    method payload (line 202) | public function payload()
    method getClaim (line 213) | public function getClaim($claim)
    method makePayload (line 224) | public function makePayload(JWTSubject $subject)
    method getClaimsArray (line 235) | protected function getClaimsArray(JWTSubject $subject)
    method getClaimsForSubject (line 250) | protected function getClaimsForSubject(JWTSubject $subject)
    method hashSubjectModel (line 263) | protected function hashSubjectModel($model)
    method checkSubjectModel (line 274) | public function checkSubjectModel($model)
    method setToken (line 289) | public function setToken($token)
    method unsetToken (line 301) | public function unsetToken()
    method requireToken (line 315) | protected function requireToken()
    method setRequest (line 328) | public function setRequest(Request $request)
    method lockSubject (line 341) | public function lockSubject($lock)
    method manager (line 353) | public function manager()
    method parser (line 363) | public function parser()
    method factory (line 373) | public function factory()
    method blacklist (line 383) | public function blacklist()
    method __call (line 397) | public function __call($method, $parameters)

FILE: src/JWTAuth.php
  class JWTAuth (line 18) | class JWTAuth extends JWT
    method __construct (line 35) | public function __construct(Manager $manager, Auth $auth, Parser $parser)
    method attempt (line 47) | public function attempt(array $credentials)
    method authenticate (line 61) | public function authenticate()
    method toUser (line 77) | public function toUser()
    method user (line 87) | public function user()

FILE: src/JWTGuard.php
  class JWTGuard (line 24) | class JWTGuard implements Guard
    method __construct (line 59) | public function __construct(JWT $jwt, UserProvider $provider, Request ...
    method user (line 69) | public function user()
    method userOrFail (line 90) | public function userOrFail()
    method validate (line 105) | public function validate(array $credentials = [])
    method attempt (line 117) | public function attempt(array $credentials = [], $login = true)
    method login (line 134) | public function login(JWTSubject $user)
    method logout (line 148) | public function logout($forceForever = false)
    method refresh (line 163) | public function refresh($forceForever = false, $resetClaims = false)
    method invalidate (line 174) | public function invalidate($forceForever = false)
    method tokenById (line 185) | public function tokenById($id)
    method once (line 198) | public function once(array $credentials = [])
    method onceUsingId (line 215) | public function onceUsingId($id)
    method byId (line 232) | public function byId($id)
    method claims (line 243) | public function claims(array $claims)
    method getPayload (line 255) | public function getPayload()
    method payload (line 265) | public function payload()
    method setToken (line 276) | public function setToken($token)
    method setTTL (line 289) | public function setTTL($ttl)
    method getProvider (line 301) | public function getProvider()
    method setProvider (line 312) | public function setProvider(UserProvider $provider)
    method getUser (line 324) | public function getUser()
    method getRequest (line 334) | public function getRequest()
    method setRequest (line 345) | public function setRequest(Request $request)
    method factory (line 357) | public function factory()
    method getLastAttempted (line 367) | public function getLastAttempted()
    method hasValidCredentials (line 379) | protected function hasValidCredentials($user, $credentials)
    method validateSubject (line 389) | protected function validateSubject()
    method requireToken (line 407) | protected function requireToken()
    method __call (line 425) | public function __call($method, $parameters)

FILE: src/Manager.php
  class Manager (line 20) | class Manager
    method __construct (line 67) | public function __construct(JWTContract $provider, Blacklist $blacklis...
    method encode (line 80) | public function encode(Payload $payload)
    method decode (line 96) | public function decode(Token $token, $checkBlacklist = true)
    method refresh (line 120) | public function refresh(Token $token, $forceForever = false, $resetCla...
    method invalidate (line 146) | public function invalidate(Token $token, $forceForever = false)
    method buildRefreshClaims (line 164) | protected function buildRefreshClaims(Payload $payload)
    method getPayloadFactory (line 187) | public function getPayloadFactory()
    method getJWTProvider (line 197) | public function getJWTProvider()
    method getBlacklist (line 207) | public function getBlacklist()
    method setBlacklistEnabled (line 218) | public function setBlacklistEnabled($enabled)
    method setPersistentClaims (line 231) | public function setPersistentClaims(array $claims)

FILE: src/Payload.php
  class Payload (line 27) | class Payload implements ArrayAccess, Arrayable, Countable, Jsonable, Js...
    method __construct (line 44) | public function __construct(Collection $claims, PayloadValidator $vali...
    method getClaims (line 54) | public function getClaims()
    method matches (line 66) | public function matches(array $values, $strict = false)
    method matchesStrict (line 89) | public function matchesStrict(array $values)
    method get (line 100) | public function get($claim = null)
    method getInternal (line 121) | public function getInternal($claim)
    method has (line 132) | public function has(Claim $claim)
    method hasKey (line 143) | public function hasKey($claim)
    method toArray (line 153) | public function toArray()
    method jsonSerialize (line 163) | #[\ReturnTypeWillChange]
    method toJson (line 175) | public function toJson($options = JSON_UNESCAPED_SLASHES)
    method __toString (line 185) | public function __toString()
    method offsetExists (line 196) | #[\ReturnTypeWillChange]
    method offsetGet (line 208) | #[\ReturnTypeWillChange]
    method offsetSet (line 222) | #[\ReturnTypeWillChange]
    method offsetUnset (line 236) | #[\ReturnTypeWillChange]
    method count (line 247) | #[\ReturnTypeWillChange]
    method __invoke (line 259) | public function __invoke($claim = null)
    method __call (line 273) | public function __call($method, $parameters)

FILE: src/Providers/AbstractServiceProvider.php
  class AbstractServiceProvider (line 39) | abstract class AbstractServiceProvider extends ServiceProvider
    method boot (line 58) | abstract public function boot();
    method register (line 65) | public function register()
    method extendAuthGuard (line 92) | protected function extendAuthGuard()
    method registerAliases (line 112) | protected function registerAliases()
    method registerJWTProvider (line 132) | protected function registerJWTProvider()
    method registerNamshiProvider (line 147) | protected function registerNamshiProvider()
    method registerLcobucciProvider (line 164) | protected function registerLcobucciProvider()
    method registerAuthProvider (line 180) | protected function registerAuthProvider()
    method registerStorageProvider (line 192) | protected function registerStorageProvider()
    method registerManager (line 204) | protected function registerManager()
    method registerTokenParser (line 223) | protected function registerTokenParser()
    method registerJWT (line 246) | protected function registerJWT()
    method registerJWTAuth (line 261) | protected function registerJWTAuth()
    method registerJWTBlacklist (line 277) | protected function registerJWTBlacklist()
    method registerPayloadValidator (line 292) | protected function registerPayloadValidator()
    method registerClaimFactory (line 306) | protected function registerClaimFactory()
    method registerPayloadFactory (line 322) | protected function registerPayloadFactory()
    method registerJWTCommand (line 337) | protected function registerJWTCommand()
    method config (line 351) | protected function config($key, $default = null)
    method getConfigInstance (line 362) | protected function getConfigInstance($key)

FILE: src/Providers/Auth/Illuminate.php
  class Illuminate (line 17) | class Illuminate implements Auth
    method __construct (line 32) | public function __construct(GuardContract $auth)
    method byCredentials (line 43) | public function byCredentials(array $credentials)
    method byId (line 54) | public function byId($id)
    method user (line 64) | public function user()

FILE: src/Providers/JWT/Lcobucci.php
  class Lcobucci (line 32) | class Lcobucci extends Provider implements JWT
    method __construct (line 53) | public function __construct($secret, $algo, array $keys, $config = null)
    method encode (line 86) | public function encode(array $payload)
    method decode (line 107) | public function decode($token)
    method getBuilderFromClaims (line 139) | protected function getBuilderFromClaims(array $payload): Builder
    method buildConfig (line 166) | protected function buildConfig(): Configuration
    method getSigner (line 196) | protected function getSigner()
    method isAsymmetric (line 214) | protected function isAsymmetric()
    method getSigningKey (line 227) | protected function getSigningKey()
    method getVerificationKey (line 251) | protected function getVerificationKey()
    method getKey (line 271) | protected function getKey(string $contents, string $passphrase = ''): Key
    method usingV4 (line 279) | protected function usingV4(): bool

FILE: src/Providers/JWT/Provider.php
  class Provider (line 16) | abstract class Provider
    method __construct (line 57) | public function __construct($secret, $algo, array $keys)
    method setAlgo (line 70) | public function setAlgo($algo)
    method getAlgo (line 82) | public function getAlgo()
    method setSecret (line 93) | public function setSecret($secret)
    method getSecret (line 105) | public function getSecret()
    method setKeys (line 116) | public function setKeys(array $keys)
    method getKeys (line 128) | public function getKeys()
    method getPublicKey (line 138) | public function getPublicKey()
    method getPrivateKey (line 148) | public function getPrivateKey()
    method getPassphrase (line 159) | public function getPassphrase()
    method getSigningKey (line 169) | protected function getSigningKey()
    method getVerificationKey (line 179) | protected function getVerificationKey()
    method isAsymmetric (line 189) | abstract protected function isAsymmetric();

FILE: src/Providers/LaravelServiceProvider.php
  class LaravelServiceProvider (line 17) | class LaravelServiceProvider extends AbstractServiceProvider
    method boot (line 22) | public function boot()
    method registerStorageProvider (line 42) | protected function registerStorageProvider()
    method aliasMiddleware (line 60) | protected function aliasMiddleware()

FILE: src/Providers/LumenServiceProvider.php
  class LumenServiceProvider (line 16) | class LumenServiceProvider extends AbstractServiceProvider
    method boot (line 21) | public function boot()

FILE: src/Providers/Storage/Illuminate.php
  class Illuminate (line 19) | class Illuminate implements Storage
    method __construct (line 51) | public function __construct(CacheContract $cache)
    method add (line 64) | public function add($key, $value, $minutes)
    method forever (line 84) | public function forever($key, $value)
    method get (line 95) | public function get($key)
    method destroy (line 106) | public function destroy($key)
    method flush (line 116) | public function flush()
    method cache (line 126) | protected function cache()
    method setLaravelVersion (line 142) | public function setLaravelVersion($version)
    method determineTagSupport (line 155) | protected function determineTagSupport()

FILE: src/Support/CustomClaims.php
  type CustomClaims (line 14) | trait CustomClaims
    method customClaims (line 29) | public function customClaims(array $customClaims)
    method claims (line 42) | public function claims(array $customClaims)
    method getCustomClaims (line 52) | public function getCustomClaims()

FILE: src/Support/RefreshFlow.php
  type RefreshFlow (line 14) | trait RefreshFlow
    method setRefreshFlow (line 29) | public function setRefreshFlow($refreshFlow = true)

FILE: src/Support/Utils.php
  class Utils (line 16) | class Utils
    method now (line 23) | public static function now()
    method timestamp (line 34) | public static function timestamp($timestamp)
    method isPast (line 46) | public static function isPast($timestamp, $leeway = 0)
    method isFuture (line 62) | public static function isFuture($timestamp, $leeway = 0)

FILE: src/Token.php
  class Token (line 16) | class Token
    method __construct (line 29) | public function __construct($value)
    method get (line 39) | public function get()
    method __toString (line 49) | public function __toString()

FILE: src/Validators/PayloadValidator.php
  class PayloadValidator (line 17) | class PayloadValidator extends Validator
    method check (line 46) | public function check($value)
    method validateStructure (line 62) | protected function validateStructure(Collection $claims)
    method validatePayload (line 78) | protected function validatePayload(Collection $claims)
    method validateRefresh (line 91) | protected function validateRefresh(Collection $claims)
    method setRequiredClaims (line 102) | public function setRequiredClaims(array $claims)
    method setRefreshTTL (line 115) | public function setRefreshTTL($ttl)

FILE: src/Validators/TokenValidator.php
  class TokenValidator (line 16) | class TokenValidator extends Validator
    method check (line 24) | public function check($value)
    method validateStructure (line 35) | protected function validateStructure($token)

FILE: src/Validators/Validator.php
  class Validator (line 18) | abstract class Validator implements ValidatorContract
    method isValid (line 28) | public function isValid($value)
    method check (line 45) | abstract public function check($value);

FILE: tests/AbstractTestCase.php
  class AbstractTestCase (line 18) | abstract class AbstractTestCase extends TestCase
    method setUp (line 25) | public function setUp(): void
    method tearDown (line 33) | public function tearDown(): void

FILE: tests/BlacklistTest.php
  class BlacklistTest (line 27) | class BlacklistTest extends AbstractTestCase
    method setUp (line 44) | public function setUp(): void
    method it_should_add_a_valid_token_to_the_blacklist (line 54) | public function it_should_add_a_valid_token_to_the_blacklist()
    method it_should_add_a_token_with_no_exp_to_the_blacklist_forever (line 86) | public function it_should_add_a_token_with_no_exp_to_the_blacklist_for...
    method it_should_return_true_when_adding_an_expired_token_to_the_blacklist (line 106) | public function it_should_return_true_when_adding_an_expired_token_to_...
    method it_should_return_true_early_when_adding_an_item_and_it_already_exists (line 137) | public function it_should_return_true_early_when_adding_an_item_and_it...
    method it_should_check_whether_a_token_has_been_blacklisted (line 168) | public function it_should_check_whether_a_token_has_been_blacklisted()
    method blacklist_provider (line 190) | public function blacklist_provider()
    method it_should_check_whether_a_token_has_not_been_blacklisted (line 208) | public function it_should_check_whether_a_token_has_not_been_blacklist...
    method it_should_check_whether_a_token_has_been_blacklisted_forever (line 230) | public function it_should_check_whether_a_token_has_been_blacklisted_f...
    method it_should_check_whether_a_token_has_been_blacklisted_when_the_token_is_not_blacklisted (line 252) | public function it_should_check_whether_a_token_has_been_blacklisted_w...
    method it_should_remove_a_token_from_the_blacklist (line 274) | public function it_should_remove_a_token_from_the_blacklist()
    method it_should_set_a_custom_unique_key_for_the_blacklist (line 295) | public function it_should_set_a_custom_unique_key_for_the_blacklist()
    method it_should_empty_the_blacklist (line 318) | public function it_should_empty_the_blacklist()
    method it_should_set_and_get_the_blacklist_grace_period (line 325) | public function it_should_set_and_get_the_blacklist_grace_period()
    method it_should_set_and_get_the_blacklist_refresh_ttl (line 332) | public function it_should_set_and_get_the_blacklist_refresh_ttl()

FILE: tests/Claims/ClaimTest.php
  class ClaimTest (line 19) | class ClaimTest extends AbstractTestCase
    method setUp (line 26) | public function setUp(): void
    method it_should_throw_an_exception_when_passing_an_invalid_value (line 34) | public function it_should_throw_an_exception_when_passing_an_invalid_v...
    method it_should_convert_the_claim_to_an_array (line 43) | public function it_should_convert_the_claim_to_an_array()
    method it_should_get_the_claim_as_a_string (line 49) | public function it_should_get_the_claim_as_a_string()
    method it_should_get_the_object_as_json (line 55) | public function it_should_get_the_object_as_json()
    method it_should_implement_arrayable (line 61) | public function it_should_implement_arrayable()

FILE: tests/Claims/CollectionTest.php
  class CollectionTest (line 23) | class CollectionTest extends AbstractTestCase
    method getCollection (line 25) | private function getCollection()
    method it_should_sanitize_the_claims_to_associative_array (line 40) | public function it_should_sanitize_the_claims_to_associative_array()
    method it_should_determine_if_a_collection_contains_all_the_given_claims (line 48) | public function it_should_determine_if_a_collection_contains_all_the_g...
    method it_should_get_a_claim_instance_by_name (line 61) | public function it_should_get_a_claim_instance_by_name()

FILE: tests/Claims/DatetimeClaimTest.php
  class DatetimeClaimTest (line 31) | class DatetimeClaimTest extends AbstractTestCase
    method setUp (line 43) | public function setUp(): void
    method it_should_handle_carbon_claims (line 61) | public function it_should_handle_carbon_claims()
    method it_should_handle_datetime_claims (line 86) | public function it_should_handle_datetime_claims()
    method it_should_handle_datetime_immutable_claims (line 110) | public function it_should_handle_datetime_immutable_claims()
    method it_should_handle_datetinterval_claims (line 133) | public function it_should_handle_datetinterval_claims()

FILE: tests/Claims/FactoryTest.php
  class FactoryTest (line 26) | class FactoryTest extends AbstractTestCase
    method setUp (line 33) | public function setUp(): void
    method it_should_set_the_request (line 41) | public function it_should_set_the_request()
    method it_should_set_the_ttl (line 48) | public function it_should_set_the_ttl()
    method it_should_set_the_leeway (line 57) | public function it_should_set_the_leeway()
    method it_should_get_a_defined_claim_instance_when_passing_a_name_and_value (line 66) | public function it_should_get_a_defined_claim_instance_when_passing_a_...
    method it_should_get_a_custom_claim_instance_when_passing_a_non_defined_name_and_value (line 77) | public function it_should_get_a_custom_claim_instance_when_passing_a_n...
    method it_should_make_a_claim_instance_with_a_value (line 83) | public function it_should_make_a_claim_instance_with_a_value()
    method it_should_extend_claim_factory_to_add_a_custom_claim (line 106) | public function it_should_extend_claim_factory_to_add_a_custom_claim()

FILE: tests/Claims/IssuedAtTest.php
  class IssuedAtTest (line 18) | class IssuedAtTest extends AbstractTestCase
    method it_should_throw_an_exception_when_passing_a_future_timestamp (line 21) | public function it_should_throw_an_exception_when_passing_a_future_tim...

FILE: tests/Claims/NotBeforeTest.php
  class NotBeforeTest (line 18) | class NotBeforeTest extends AbstractTestCase
    method it_should_throw_an_exception_when_passing_an_invalid_value (line 21) | public function it_should_throw_an_exception_when_passing_an_invalid_v...

FILE: tests/FactoryTest.php
  class FactoryTest (line 28) | class FactoryTest extends AbstractTestCase
    method setUp (line 45) | public function setUp(): void
    method it_should_return_a_payload_when_passing_an_array_of_claims (line 55) | public function it_should_return_a_payload_when_passing_an_array_of_cl...
    method it_should_return_a_payload_when_chaining_claim_methods (line 96) | public function it_should_return_a_payload_when_chaining_claim_methods()
    method it_should_return_a_payload_when_passing_miltidimensional_array_as_custom_claim_to_make_method (line 125) | public function it_should_return_a_payload_when_passing_miltidimension...
    method it_should_exclude_the_exp_claim_when_setting_ttl_to_null (line 157) | public function it_should_exclude_the_exp_claim_when_setting_ttl_to_nu...
    method it_should_exclude_claims_from_previous_payloads (line 185) | public function it_should_exclude_claims_from_previous_payloads()
    method it_should_set_the_default_claims (line 214) | public function it_should_set_the_default_claims()
    method it_should_get_payload_with_a_predefined_collection_of_claims (line 222) | public function it_should_get_payload_with_a_predefined_collection_of_...
    method it_should_get_the_validator (line 243) | public function it_should_get_the_validator()

FILE: tests/Fixtures/Foo.php
  class Foo (line 16) | class Foo extends Claim

FILE: tests/Http/ParserTest.php
  class ParserTest (line 28) | class ParserTest extends AbstractTestCase
    method it_should_return_the_token_from_the_authorization_header (line 31) | public function it_should_return_the_token_from_the_authorization_head...
    method it_should_return_the_token_from_the_prefixed_authentication_header (line 50) | public function it_should_return_the_token_from_the_prefixed_authentic...
    method it_should_return_the_token_from_the_custom_authentication_header (line 69) | public function it_should_return_the_token_from_the_custom_authenticat...
    method it_should_return_the_token_from_the_alt_authorization_headers (line 88) | public function it_should_return_the_token_from_the_alt_authorization_...
    method it_should_ignore_non_bearer_tokens (line 112) | public function it_should_ignore_non_bearer_tokens()
    method it_should_not_strip_trailing_hyphens_from_the_authorization_header (line 131) | public function it_should_not_strip_trailing_hyphens_from_the_authoriz...
    method it_should_handle_excess_whitespace_from_the_authorization_header (line 154) | public function it_should_handle_excess_whitespace_from_the_authorizat...
    method whitespaceProvider (line 172) | public function whitespaceProvider()
    method it_should_return_the_token_from_query_string (line 188) | public function it_should_return_the_token_from_query_string()
    method it_should_return_the_token_from_the_custom_query_string (line 205) | public function it_should_return_the_token_from_the_custom_query_string()
    method it_should_return_the_token_from_the_query_string_not_the_input_source (line 222) | public function it_should_return_the_token_from_the_query_string_not_t...
    method it_should_return_the_token_from_the_custom_query_string_not_the_custom_input_source (line 239) | public function it_should_return_the_token_from_the_custom_query_strin...
    method it_should_return_the_token_from_input_source (line 256) | public function it_should_return_the_token_from_input_source()
    method it_should_return_the_token_from_the_custom_input_source (line 274) | public function it_should_return_the_token_from_the_custom_input_source()
    method it_should_return_the_token_from_an_unencrypted_cookie (line 292) | public function it_should_return_the_token_from_an_unencrypted_cookie()
    method it_should_return_the_token_from_a_crypted_cookie (line 310) | public function it_should_return_the_token_from_a_crypted_cookie()
    method it_should_return_the_token_from_route (line 338) | public function it_should_return_the_token_from_route()
    method it_should_return_the_token_from_route_with_a_custom_param (line 358) | public function it_should_return_the_token_from_route_with_a_custom_pa...
    method it_should_ignore_routeless_requests (line 378) | public function it_should_ignore_routeless_requests()
    method it_should_ignore_lumen_request_arrays (line 398) | public function it_should_ignore_lumen_request_arrays()
    method it_should_accept_lumen_request_arrays_with_special_class (line 418) | public function it_should_accept_lumen_request_arrays_with_special_cla...
    method it_should_return_null_if_no_token_in_request (line 438) | public function it_should_return_null_if_no_token_in_request()
    method it_should_retrieve_the_chain (line 458) | public function it_should_retrieve_the_chain()
    method it_should_retrieve_the_chain_with_alias (line 474) | public function it_should_retrieve_the_chain_with_alias()
    method it_should_set_the_cookie_key (line 493) | public function it_should_set_the_cookie_key()
    method it_should_add_custom_parser (line 500) | public function it_should_add_custom_parser()
    method it_should_add_multiple_custom_parser (line 515) | public function it_should_add_multiple_custom_parser()
    method getRouteMock (line 532) | protected function getRouteMock($expectedParameterValue = null, $expec...

FILE: tests/JWTAuthTest.php
  class JWTAuthTest (line 28) | class JWTAuthTest extends AbstractTestCase
    method setUp (line 50) | public function setUp(): void
    method it_should_return_a_token_when_passing_a_user (line 59) | public function it_should_return_a_token_when_passing_a_user()
    method it_should_pass_provider_check_if_hash_matches (line 78) | public function it_should_pass_provider_check_if_hash_matches()
    method it_should_pass_provider_check_if_hash_matches_when_provider_is_null (line 92) | public function it_should_pass_provider_check_if_hash_matches_when_pro...
    method it_should_not_pass_provider_check_if_hash_not_match (line 106) | public function it_should_not_pass_provider_check_if_hash_not_match()
    method it_should_return_a_token_when_passing_valid_credentials_to_attempt_method (line 120) | public function it_should_return_a_token_when_passing_valid_credential...
    method it_should_return_false_when_passing_invalid_credentials_to_attempt_method (line 142) | public function it_should_return_false_when_passing_invalid_credential...
    method it_should_throw_an_exception_when_not_providing_a_token (line 154) | public function it_should_throw_an_exception_when_not_providing_a_token()
    method it_should_return_the_owning_user_from_a_token_containing_an_existing_user (line 163) | public function it_should_return_the_owning_user_from_a_token_containi...
    method it_should_return_false_when_passing_a_token_not_containing_an_existing_user (line 179) | public function it_should_return_false_when_passing_a_token_not_contai...
    method it_should_refresh_a_token (line 195) | public function it_should_refresh_a_token()
    method it_should_invalidate_a_token (line 208) | public function it_should_invalidate_a_token()
    method it_should_force_invalidate_a_token_forever (line 218) | public function it_should_force_invalidate_a_token_forever()
    method it_should_retrieve_the_token_from_the_request (line 228) | public function it_should_retrieve_the_token_from_the_request()
    method it_should_get_the_authenticated_user (line 237) | public function it_should_get_the_authenticated_user()
    method it_should_return_false_if_the_token_is_invalid (line 244) | public function it_should_return_false_if_the_token_is_invalid()
    method it_should_return_true_if_the_token_is_valid (line 253) | public function it_should_return_true_if_the_token_is_valid()
    method it_should_throw_an_exception_when_token_not_present_in_request (line 264) | public function it_should_throw_an_exception_when_token_not_present_in...
    method it_should_return_false_when_no_token_is_set (line 275) | public function it_should_return_false_when_no_token_is_set()
    method it_should_magically_call_the_manager (line 283) | public function it_should_magically_call_the_manager()
    method it_should_set_the_request (line 293) | public function it_should_set_the_request()
    method it_should_unset_the_token (line 306) | public function it_should_unset_the_token()
    method it_should_get_the_manager_instance (line 318) | public function it_should_get_the_manager_instance()
    method it_should_get_the_parser_instance (line 325) | public function it_should_get_the_parser_instance()
    method it_should_get_a_claim_value (line 332) | public function it_should_get_a_claim_value()

FILE: tests/JWTGuardTest.php
  class JWTGuardTest (line 25) | class JWTGuardTest extends AbstractTestCase
    method setUp (line 42) | public function setUp(): void
    method it_should_get_the_request (line 52) | public function it_should_get_the_request()
    method it_should_get_the_authenticated_user_if_a_valid_token_is_provided (line 58) | public function it_should_get_the_authenticated_user_if_a_valid_token_...
    method it_should_get_the_authenticated_user_if_a_valid_token_is_provided_and_not_throw_an_exception (line 90) | public function it_should_get_the_authenticated_user_if_a_valid_token_...
    method it_should_return_null_if_an_invalid_token_is_provided (line 119) | public function it_should_return_null_if_an_invalid_token_is_provided()
    method it_should_return_null_if_no_token_is_provided (line 132) | public function it_should_return_null_if_no_token_is_provided()
    method it_should_throw_an_exception_if_an_invalid_token_is_provided (line 145) | public function it_should_throw_an_exception_if_an_invalid_token_is_pr...
    method it_should_throw_an_exception_if_no_token_is_provided (line 161) | public function it_should_throw_an_exception_if_no_token_is_provided()
    method it_should_return_a_token_if_credentials_are_ok_and_user_is_found (line 177) | public function it_should_return_a_token_if_credentials_are_ok_and_use...
    method it_should_return_true_if_credentials_are_ok_and_user_is_found_when_choosing_not_to_login (line 214) | public function it_should_return_true_if_credentials_are_ok_and_user_i...
    method it_should_return_false_if_credentials_are_invalid (line 234) | public function it_should_return_false_if_credentials_are_invalid()
    method it_should_magically_call_the_jwt_instance (line 253) | public function it_should_magically_call_the_jwt_instance()
    method it_should_logout_the_user_by_invalidating_the_token (line 260) | public function it_should_logout_the_user_by_invalidating_the_token()
    method it_should_refresh_the_token (line 272) | public function it_should_refresh_the_token()
    method it_should_invalidate_the_token (line 282) | public function it_should_invalidate_the_token()
    method it_should_throw_an_exception_if_there_is_no_token_present_when_required (line 292) | public function it_should_throw_an_exception_if_there_is_no_token_pres...
    method it_should_generate_a_token_by_id (line 305) | public function it_should_generate_a_token_by_id()
    method it_should_not_generate_a_token_by_id (line 323) | public function it_should_not_generate_a_token_by_id()
    method it_should_authenticate_the_user_by_credentials_and_return_true_if_valid (line 334) | public function it_should_authenticate_the_user_by_credentials_and_ret...
    method it_should_attempt_to_authenticate_the_user_by_credentials_and_return_false_if_invalid (line 353) | public function it_should_attempt_to_authenticate_the_user_by_credenti...
    method it_should_authenticate_the_user_by_id_and_return_boolean (line 372) | public function it_should_authenticate_the_user_by_id_and_return_boole...
    method it_should_not_authenticate_the_user_by_id_and_return_false (line 386) | public function it_should_not_authenticate_the_user_by_id_and_return_f...
    method it_should_create_a_token_from_a_user_object (line 398) | public function it_should_create_a_token_from_a_user_object()
    method it_should_get_the_payload (line 418) | public function it_should_get_the_payload()
    method it_should_be_macroable (line 427) | public function it_should_be_macroable()

FILE: tests/ManagerTest.php
  class ManagerTest (line 32) | class ManagerTest extends AbstractTestCase
    method setUp (line 59) | public function setUp(): void
    method it_should_encode_a_payload (line 71) | public function it_should_encode_a_payload()
    method it_should_decode_a_token (line 95) | public function it_should_decode_a_token()
    method it_should_throw_exception_when_token_is_blacklisted (line 127) | public function it_should_throw_exception_when_token_is_blacklisted()
    method it_should_refresh_a_token (line 158) | public function it_should_refresh_a_token()
    method it_should_invalidate_a_token (line 192) | public function it_should_invalidate_a_token()
    method it_should_force_invalidate_a_token_forever (line 222) | public function it_should_force_invalidate_a_token_forever()
    method it_should_throw_an_exception_when_enable_blacklist_is_set_to_false (line 252) | public function it_should_throw_an_exception_when_enable_blacklist_is_...
    method it_should_get_the_payload_factory (line 263) | public function it_should_get_the_payload_factory()
    method it_should_get_the_jwt_provider (line 269) | public function it_should_get_the_jwt_provider()
    method it_should_get_the_blacklist (line 275) | public function it_should_get_the_blacklist()

FILE: tests/Middleware/AbstractMiddlewareTest.php
  class AbstractMiddlewareTest (line 19) | abstract class AbstractMiddlewareTest extends AbstractTestCase
    method setUp (line 31) | public function setUp(): void

FILE: tests/Middleware/AuthenticateAndRenewTest.php
  class AuthenticateAndRenewTest (line 22) | class AuthenticateAndRenewTest extends AbstractMiddlewareTest
    method setUp (line 29) | public function setUp(): void
    method it_should_authenticate_a_user_and_return_a_new_token (line 37) | public function it_should_authenticate_a_user_and_return_a_new_token()
    method it_should_throw_an_unauthorized_exception_if_token_not_provided (line 56) | public function it_should_throw_an_unauthorized_exception_if_token_not...
    method it_should_throw_an_unauthorized_exception_if_token_invalid (line 72) | public function it_should_throw_an_unauthorized_exception_if_token_inv...

FILE: tests/Middleware/AuthenticateTest.php
  class AuthenticateTest (line 21) | class AuthenticateTest extends AbstractMiddlewareTest
    method setUp (line 28) | public function setUp(): void
    method it_should_authenticate_a_user (line 36) | public function it_should_authenticate_a_user()
    method it_should_throw_an_unauthorized_exception_if_token_not_provided (line 52) | public function it_should_throw_an_unauthorized_exception_if_token_not...
    method it_should_throw_an_unauthorized_exception_if_token_invalid (line 68) | public function it_should_throw_an_unauthorized_exception_if_token_inv...
    method it_should_throw_an_unauthorized_exception_if_user_not_found (line 86) | public function it_should_throw_an_unauthorized_exception_if_user_not_...

FILE: tests/Middleware/CheckTest.php
  class CheckTest (line 20) | class CheckTest extends AbstractMiddlewareTest
    method setUp (line 27) | public function setUp(): void
    method it_should_authenticate_a_user_if_a_token_is_present (line 35) | public function it_should_authenticate_a_user_if_a_token_is_present()
    method it_should_unset_the_exception_if_a_token_is_present (line 51) | public function it_should_unset_the_exception_if_a_token_is_present()
    method it_should_do_nothing_if_a_token_is_not_present (line 67) | public function it_should_do_nothing_if_a_token_is_not_present()

FILE: tests/Middleware/RefreshTokenTest.php
  class RefreshTokenTest (line 21) | class RefreshTokenTest extends AbstractMiddlewareTest
    method setUp (line 28) | public function setUp(): void
    method it_should_refresh_a_token (line 36) | public function it_should_refresh_a_token()
    method it_should_throw_an_unauthorized_exception_if_token_not_provided (line 54) | public function it_should_throw_an_unauthorized_exception_if_token_not...
    method it_should_throw_an_unauthorized_exception_if_token_invalid (line 70) | public function it_should_throw_an_unauthorized_exception_if_token_inv...

FILE: tests/PayloadTest.php
  class PayloadTest (line 29) | class PayloadTest extends AbstractTestCase
    method setUp (line 41) | public function setUp(): void
    method getTestPayload (line 52) | private function getTestPayload(array $extraClaims = [])
    method it_should_throw_an_exception_when_trying_to_add_to_the_payload (line 76) | public function it_should_throw_an_exception_when_trying_to_add_to_the...
    method it_should_throw_an_exception_when_trying_to_remove_a_key_from_the_payload (line 85) | public function it_should_throw_an_exception_when_trying_to_remove_a_k...
    method it_should_cast_the_payload_to_a_string_as_json (line 94) | public function it_should_cast_the_payload_to_a_string_as_json()
    method it_should_allow_array_access_on_the_payload (line 101) | public function it_should_allow_array_access_on_the_payload()
    method it_should_get_properties_of_payload_via_get_method (line 109) | public function it_should_get_properties_of_payload_via_get_method()
    method it_should_get_multiple_properties_when_passing_an_array_to_the_get_method (line 123) | public function it_should_get_multiple_properties_when_passing_an_arra...
    method it_should_determine_whether_the_payload_has_a_claim (line 136) | public function it_should_determine_whether_the_payload_has_a_claim()
    method it_should_magically_get_a_property (line 143) | public function it_should_magically_get_a_property()
    method it_should_invoke_the_instance_as_a_callable (line 155) | public function it_should_invoke_the_instance_as_a_callable()
    method it_should_throw_an_exception_when_magically_getting_a_property_that_does_not_exist (line 171) | public function it_should_throw_an_exception_when_magically_getting_a_...
    method it_should_get_the_claims (line 180) | public function it_should_get_the_claims()
    method it_should_get_the_object_as_json (line 192) | public function it_should_get_the_object_as_json()
    method it_should_count_the_claims (line 198) | public function it_should_count_the_claims()
    method it_should_match_values (line 205) | public function it_should_match_values()
    method it_should_match_strict_values (line 214) | public function it_should_match_strict_values()
    method it_should_not_match_empty_values (line 223) | public function it_should_not_match_empty_values()
    method it_should_not_match_values (line 229) | public function it_should_not_match_values()
    method it_should_not_match_strict_values (line 238) | public function it_should_not_match_strict_values()
    method it_should_not_match_a_non_existing_claim (line 248) | public function it_should_not_match_a_non_existing_claim()

FILE: tests/Providers/Auth/IlluminateTest.php
  class IlluminateTest (line 19) | class IlluminateTest extends AbstractTestCase
    method setUp (line 31) | public function setUp(): void
    method it_should_return_true_if_credentials_are_valid (line 40) | public function it_should_return_true_if_credentials_are_valid()
    method it_should_return_true_if_user_is_found (line 47) | public function it_should_return_true_if_user_is_found()
    method it_should_return_false_if_user_is_not_found (line 54) | public function it_should_return_false_if_user_is_not_found()
    method it_should_return_the_currently_authenticated_user (line 61) | public function it_should_return_the_currently_authenticated_user()

FILE: tests/Providers/JWT/LcobucciTest.php
  class LcobucciTest (line 21) | class LcobucciTest extends AbstractTestCase
    method it_can_encode_claims_using_a_symmetric_key (line 24) | public function it_can_encode_claims_using_a_symmetric_key()
    method it_can_encode_and_decode_a_token_using_a_symmetric_key (line 51) | public function it_can_encode_and_decode_a_token_using_a_symmetric_key()
    method it_can_encode_and_decode_a_token_using_an_asymmetric_RS256_key (line 74) | public function it_can_encode_and_decode_a_token_using_an_asymmetric_R...
    method it_can_encode_and_decode_a_token_with_nbf_jti_and_aud_claims (line 105) | public function it_can_encode_and_decode_a_token_with_nbf_jti_and_aud_...
    method it_can_encode_and_decode_a_token_using_an_asymmetric_ES256_key (line 134) | public function it_can_encode_and_decode_a_token_using_an_asymmetric_E...
    method it_should_throw_an_invalid_exception_when_the_payload_could_not_be_encoded (line 165) | public function it_should_throw_an_invalid_exception_when_the_payload_...
    method it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded_due_to_a_bad_signature (line 183) | public function it_should_throw_a_token_invalid_exception_when_the_tok...
    method it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded_due_to_tampered_token (line 194) | public function it_should_throw_a_token_invalid_exception_when_the_tok...
    method it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded (line 205) | public function it_should_throw_a_token_invalid_exception_when_the_tok...
    method it_should_throw_an_exception_when_the_algorithm_passed_is_invalid (line 214) | public function it_should_throw_an_exception_when_the_algorithm_passed...
    method it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_encoding (line 223) | public function it_should_throw_an_exception_when_no_symmetric_key_is_...
    method it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_decoding (line 232) | public function it_should_throw_an_exception_when_no_symmetric_key_is_...
    method it_should_throw_an_exception_when_no_asymmetric_public_key_is_provided (line 241) | public function it_should_throw_an_exception_when_no_asymmetric_public...
    method it_should_throw_an_exception_when_no_asymmetric_private_key_is_provided (line 254) | public function it_should_throw_an_exception_when_no_asymmetric_privat...
    method it_should_return_the_public_key (line 267) | public function it_should_return_the_public_key()
    method it_should_return_the_keys (line 279) | public function it_should_return_the_keys()
    method getProvider (line 290) | public function getProvider($secret, $algo, array $keys = [])
    method getDummyPrivateKey (line 295) | public function getDummyPrivateKey()
    method getDummyPublicKey (line 300) | public function getDummyPublicKey()
    method getDummyEcPrivateKey (line 305) | public function getDummyEcPrivateKey()
    method getDummyEcPublicKey (line 310) | public function getDummyEcPublicKey()

FILE: tests/Providers/JWT/ProviderTest.php
  class ProviderTest (line 17) | class ProviderTest extends AbstractTestCase
    method setUp (line 24) | public function setUp(): void
    method it_should_set_the_algo (line 32) | public function it_should_set_the_algo()
    method it_should_set_the_secret (line 40) | public function it_should_set_the_secret()

FILE: tests/Providers/Storage/IlluminateTest.php
  class IlluminateTest (line 20) | class IlluminateTest extends AbstractTestCase
    method setUp (line 32) | public function setUp(): void
    method it_should_add_the_item_to_storage (line 41) | public function it_should_add_the_item_to_storage()
    method it_should_add_the_item_to_storage_forever (line 49) | public function it_should_add_the_item_to_storage_forever()
    method it_should_get_an_item_from_storage (line 57) | public function it_should_get_an_item_from_storage()
    method it_should_remove_the_item_from_storage (line 65) | public function it_should_remove_the_item_from_storage()
    method it_should_remove_all_items_from_storage (line 73) | public function it_should_remove_all_items_from_storage()
    method emulateTags (line 88) | private function emulateTags()
    method it_should_add_the_item_to_tagged_storage (line 96) | public function it_should_add_the_item_to_tagged_storage()
    method it_should_add_the_item_to_tagged_storage_forever (line 105) | public function it_should_add_the_item_to_tagged_storage_forever()
    method it_should_get_an_item_from_tagged_storage (line 114) | public function it_should_get_an_item_from_tagged_storage()
    method it_should_remove_the_item_from_tagged_storage (line 123) | public function it_should_remove_the_item_from_tagged_storage()
    method it_should_remove_all_tagged_items_from_storage (line 132) | public function it_should_remove_all_tagged_items_from_storage()

FILE: tests/Stubs/JWTProviderStub.php
  class JWTProviderStub (line 16) | class JWTProviderStub extends Provider
    method isAsymmetric (line 21) | protected function isAsymmetric()

FILE: tests/Stubs/LaravelUserStub.php
  class LaravelUserStub (line 17) | class LaravelUserStub extends UserStub implements Authenticatable, JWTSu...
    method getAuthIdentifierName (line 19) | public function getAuthIdentifierName()
    method getAuthIdentifier (line 24) | public function getAuthIdentifier()
    method getAuthPassword (line 29) | public function getAuthPassword()
    method getRememberToken (line 34) | public function getRememberToken()
    method setRememberToken (line 39) | public function setRememberToken($value)
    method getRememberTokenName (line 44) | public function getRememberTokenName()
    method getAuthPasswordName (line 49) | public function getAuthPasswordName()

FILE: tests/Stubs/TaggedStorage.php
  class TaggedStorage (line 16) | class TaggedStorage extends Storage

FILE: tests/Stubs/UserStub.php
  class UserStub (line 16) | class UserStub implements JWTSubject
    method getJWTIdentifier (line 18) | public function getJWTIdentifier()
    method getJWTCustomClaims (line 23) | public function getJWTCustomClaims()

FILE: tests/TokenTest.php
  class TokenTest (line 16) | class TokenTest extends AbstractTestCase
    method setUp (line 23) | public function setUp(): void
    method it_should_return_the_token_when_casting_to_a_string (line 31) | public function it_should_return_the_token_when_casting_to_a_string()
    method it_should_return_the_token_when_calling_get_method (line 37) | public function it_should_return_the_token_when_calling_get_method()

FILE: tests/Validators/PayloadValidatorTest.php
  class PayloadValidatorTest (line 27) | class PayloadValidatorTest extends AbstractTestCase
    method setUp (line 34) | public function setUp(): void
    method it_should_return_true_when_providing_a_valid_payload (line 42) | public function it_should_return_true_when_providing_a_valid_payload()
    method it_should_throw_an_exception_when_providing_an_expired_payload (line 59) | public function it_should_throw_an_exception_when_providing_an_expired...
    method it_should_throw_an_exception_when_providing_an_invalid_nbf_claim (line 79) | public function it_should_throw_an_exception_when_providing_an_invalid...
    method it_should_throw_an_exception_when_providing_an_invalid_iat_claim (line 99) | public function it_should_throw_an_exception_when_providing_an_invalid...
    method it_should_throw_an_exception_when_providing_an_invalid_payload (line 119) | public function it_should_throw_an_exception_when_providing_an_invalid...
    method it_should_throw_an_exception_when_providing_an_invalid_expiry (line 135) | public function it_should_throw_an_exception_when_providing_an_invalid...
    method it_should_set_the_required_claims (line 155) | public function it_should_set_the_required_claims()
    method it_should_check_the_token_in_the_refresh_context (line 168) | public function it_should_check_the_token_in_the_refresh_context()
    method it_should_return_true_if_the_refresh_ttl_is_null (line 187) | public function it_should_return_true_if_the_refresh_ttl_is_null()
    method it_should_throw_an_exception_if_the_token_cannot_be_refreshed (line 206) | public function it_should_throw_an_exception_if_the_token_cannot_be_re...

FILE: tests/Validators/TokenValidatorTest.php
  class TokenValidatorTest (line 18) | class TokenValidatorTest extends AbstractTestCase
    method setUp (line 25) | public function setUp(): void
    method it_should_return_true_when_providing_a_well_formed_token (line 33) | public function it_should_return_true_when_providing_a_well_formed_tok...
    method it_should_return_false_when_providing_a_malformed_token (line 45) | public function it_should_return_false_when_providing_a_malformed_toke...
    method it_should_throw_an_exception_when_providing_a_malformed_token (line 55) | public function it_should_throw_an_exception_when_providing_a_malforme...
    method it_should_return_false_when_providing_a_token_with_wrong_segments_number (line 68) | public function it_should_return_false_when_providing_a_token_with_wro...
    method it_should_throw_an_exception_when_providing_a_malformed_token_with_wrong_segments_number (line 78) | public function it_should_throw_an_exception_when_providing_a_malforme...
    method dataProviderMalformedTokens (line 86) | public function dataProviderMalformedTokens()
    method dataProviderTokensWithWrongSegmentsNumber (line 99) | public function dataProviderTokensWithWrongSegmentsNumber()
Condensed preview — 122 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (328K chars).
[
  {
    "path": ".editorconfig",
    "chars": 234,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\ntrim_"
  },
  {
    "path": ".gitattributes",
    "chars": 328,
    "preview": "* text=auto\n\n/tests export-ignore\n/docs export-ignore\n/.codecov.yml export-ignore\n/.editorconfig export-ignore\n/.gitattr"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 3226,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 2002,
    "preview": "# Contributors Guide\n\nPlease read and understand the contribution guide before creating an issue or pull request.\n\n## Et"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 478,
    "preview": "### Subject of the issue\nDescribe your issue here.\n\n### Your environment\n| Q                 | A\n| ----------------- | -"
  },
  {
    "path": ".github/stale.yml",
    "chars": 93,
    "preview": "daysUntilStale: 60\ndaysUntilClose: 7\nexemptLabels:\n  - pinned\n  - security\nstaleLabel: stale\n"
  },
  {
    "path": ".github/workflows/phpunit.yml",
    "chars": 2401,
    "preview": "name: PHPUnit tests\n\non:\n  push:\n  release:\n    types:\n      - published\n\njobs:\n  php-tests:\n    runs-on: ${{ matrix.os "
  },
  {
    "path": ".gitignore",
    "chars": 63,
    "preview": "/vendor\ncomposer.lock\nbuild\ncoverage.xml\n.phpunit.result.cache\n"
  },
  {
    "path": ".styleci.yml",
    "chars": 71,
    "preview": "preset: laravel\n\nenabled:\n  - no_useless_else\n  - unalign_double_arrow\n"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "The MIT License (MIT)\n\nCopyright (c) Sean Tymon\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README.md",
    "chars": 1284,
    "preview": "![jwt-auth-banner](https://cloud.githubusercontent.com/assets/1801923/9915273/119b9350-5cae-11e5-850b-c941cac60b32.png)\n"
  },
  {
    "path": "composer.json",
    "chars": 2230,
    "preview": "{\n    \"name\": \"tymon/jwt-auth\",\n    \"description\": \"JSON Web Token Authentication for Laravel and Lumen\",\n    \"keywords\""
  },
  {
    "path": "config/config.php",
    "chars": 9923,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "docs/auth-guard.md",
    "chars": 2923,
    "preview": "## Methods\n\nThe following methods are available on the Auth guard instance.\n\n### Multiple Guards\n\nIf the newly created '"
  },
  {
    "path": "docs/configuration.md",
    "chars": 331,
    "preview": "Let's review some of the options in the `config/jwt.php` file that we published earlier.\nI won't go through all of the o"
  },
  {
    "path": "docs/exception-handling.md",
    "chars": 15,
    "preview": "Coming soon...\n"
  },
  {
    "path": "docs/index.md",
    "chars": 171,
    "preview": "JSON Web Token Authentication for Laravel & Lumen\n\n![jwt-auth-banner](https://cloud.githubusercontent.com/assets/1801923"
  },
  {
    "path": "docs/laravel-installation.md",
    "chars": 1239,
    "preview": "### Install via composer\n\nRun the following command to pull in the latest version:\n\n```bash\ncomposer require tymon/jwt-a"
  },
  {
    "path": "docs/lumen-installation.md",
    "chars": 1462,
    "preview": "### Install via composer\n\nRun the following command to pull in the latest version:\n\n```bash\ncomposer require tymon/jwt-a"
  },
  {
    "path": "docs/quick-start.md",
    "chars": 5088,
    "preview": "Before continuing, make sure you have installed the package as per the installation instructions for\n[Laravel](laravel-i"
  },
  {
    "path": "docs/resources.md",
    "chars": 342,
    "preview": "- [The Anatomy of a JSON Web Token](https://scotch.io/tutorials/the-anatomy-of-a-json-web-token)\n- [jwt.io](https://jwt."
  },
  {
    "path": "mkdocs.yml",
    "chars": 362,
    "preview": "site_name: jwt-auth\npages:\n    - Home: index.md\n    - Laravel Installation: laravel-installation.md\n    - Lumen Installa"
  },
  {
    "path": "phpunit.xml.dist",
    "chars": 1457,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    backupGlobals="
  },
  {
    "path": "src/Blacklist.php",
    "chars": 5463,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Audience.php",
    "chars": 353,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Claim.php",
    "chars": 3370,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Collection.php",
    "chars": 2700,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Custom.php",
    "chars": 506,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/DatetimeTrait.php",
    "chars": 1893,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Expiration.php",
    "chars": 644,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Factory.php",
    "chars": 4234,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/IssuedAt.php",
    "chars": 1372,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Issuer.php",
    "chars": 351,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/JwtId.php",
    "chars": 350,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/NotBefore.php",
    "chars": 678,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Claims/Subject.php",
    "chars": 352,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Console/JWTGenerateSecretCommand.php",
    "chars": 3168,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Claim.php",
    "chars": 1010,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Http/Parser.php",
    "chars": 484,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/JWTSubject.php",
    "chars": 618,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Providers/Auth.php",
    "chars": 714,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Providers/JWT.php",
    "chars": 502,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Providers/Storage.php",
    "chars": 860,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Contracts/Validator.php",
    "chars": 583,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/InvalidClaimException.php",
    "chars": 746,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/JWTException.php",
    "chars": 398,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/PayloadException.php",
    "chars": 313,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/TokenBlacklistedException.php",
    "chars": 331,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/TokenExpiredException.php",
    "chars": 318,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/TokenInvalidException.php",
    "chars": 318,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Exceptions/UserNotDefinedException.php",
    "chars": 320,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Facades/JWTAuth.php",
    "chars": 517,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Facades/JWTFactory.php",
    "chars": 531,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Facades/JWTProvider.php",
    "chars": 529,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Factory.php",
    "chars": 5397,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Middleware/Authenticate.php",
    "chars": 726,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Middleware/AuthenticateAndRenew.php",
    "chars": 854,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Middleware/BaseMiddleware.php",
    "chars": 2434,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Middleware/Check.php",
    "chars": 835,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Middleware/RefreshToken.php",
    "chars": 1186,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/AuthHeaders.php",
    "chars": 2121,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/Cookies.php",
    "chars": 1055,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/InputSource.php",
    "chars": 676,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/KeyTrait.php",
    "chars": 688,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/LumenRouteParams.php",
    "chars": 884,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/Parser.php",
    "chars": 2481,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/QueryString.php",
    "chars": 676,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Http/Parser/RouteParams.php",
    "chars": 951,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/JWT.php",
    "chars": 8881,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/JWTAuth.php",
    "chars": 1962,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/JWTGuard.php",
    "chars": 9752,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Manager.php",
    "chars": 5776,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Payload.php",
    "chars": 6453,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/AbstractServiceProvider.php",
    "chars": 10323,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/Auth/Illuminate.php",
    "chars": 1323,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/JWT/Lcobucci.php",
    "chars": 8361,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/JWT/Provider.php",
    "chars": 3719,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/LaravelServiceProvider.php",
    "chars": 1715,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/LumenServiceProvider.php",
    "chars": 765,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Providers/Storage/Illuminate.php",
    "chars": 4279,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Support/CustomClaims.php",
    "chars": 1012,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Support/RefreshFlow.php",
    "chars": 630,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Support/Utils.php",
    "chars": 1539,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Token.php",
    "chars": 895,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Validators/PayloadValidator.php",
    "chars": 2913,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Validators/TokenValidator.php",
    "chars": 1151,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "src/Validators/Validator.php",
    "chars": 931,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/AbstractTestCase.php",
    "chars": 749,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/BlacklistTest.php",
    "chars": 10775,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/ClaimTest.php",
    "chars": 1689,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/CollectionTest.php",
    "chars": 2121,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/DatetimeClaimTest.php",
    "chars": 5366,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/FactoryTest.php",
    "chars": 3871,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/IssuedAtTest.php",
    "chars": 746,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Claims/NotBeforeTest.php",
    "chars": 722,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/FactoryTest.php",
    "chars": 9958,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Fixtures/Foo.php",
    "chars": 388,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Http/ParserTest.php",
    "chars": 16244,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/JWTAuthTest.php",
    "chars": 11480,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/JWTGuardTest.php",
    "chars": 15214,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/ManagerTest.php",
    "chars": 9773,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Middleware/AbstractMiddlewareTest.php",
    "chars": 819,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Middleware/AuthenticateAndRenewTest.php",
    "chars": 2997,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Middleware/AuthenticateTest.php",
    "chars": 3335,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Middleware/CheckTest.php",
    "chars": 2505,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Middleware/RefreshTokenTest.php",
    "chars": 2765,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/PayloadTest.php",
    "chars": 7254,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Providers/Auth/IlluminateTest.php",
    "chars": 1916,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Providers/JWT/LcobucciTest.php",
    "chars": 11100,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Providers/JWT/ProviderTest.php",
    "chars": 1008,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Providers/Keys/id_ecdsa",
    "chars": 227,
    "preview": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIPKNCQlkD3SP1JniCj2RXvGlzp8NO9sYyQr05hdFlGKboAoGCCqGSM49\nAwEHoUQDQgAEhXUAmmzqpHbt"
  },
  {
    "path": "tests/Providers/Keys/id_ecdsa.pub",
    "chars": 178,
    "preview": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhXUAmmzqpHbtmm4SY5ikZparlUyr\nmggNhDy8QoyNIlbrJzh6q0PFcrVb"
  },
  {
    "path": "tests/Providers/Keys/id_rsa",
    "chars": 1704,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTvwE87MtgREYL\nTL4aHhQo3ZzogmxxvMUsKnPzyxR"
  },
  {
    "path": "tests/Providers/Keys/id_rsa.pub",
    "chars": 451,
    "preview": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA078BPOzLYERGC0y+Gh4U\nKN2c6IJscbzFLCpz88sUbNWK1zkj"
  },
  {
    "path": "tests/Providers/Storage/IlluminateTest.php",
    "chars": 3762,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Stubs/JWTProviderStub.php",
    "chars": 453,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Stubs/LaravelUserStub.php",
    "chars": 902,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Stubs/TaggedStorage.php",
    "chars": 797,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Stubs/UserStub.php",
    "chars": 550,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/TokenTest.php",
    "chars": 841,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Validators/PayloadValidatorTest.php",
    "chars": 7028,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  },
  {
    "path": "tests/Validators/TokenValidatorTest.php",
    "chars": 2846,
    "preview": "<?php\n\n/*\n * This file is part of jwt-auth.\n *\n * (c) Sean Tymon <tymon148@gmail.com>\n *\n * For the full copyright and l"
  }
]

About this extraction

This page contains the full source code of the tymondesigns/jwt-auth GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 122 files (300.0 KB), approximately 78.7k tokens, and a symbol index with 651 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!