jwt 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/.codeclimate.yml +20 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -0
- data/README.md +29 -11
- data/Rakefile +1 -18
- data/lib/jwt.rb +19 -75
- data/lib/jwt/decode.rb +56 -0
- data/lib/jwt/error.rb +12 -0
- data/lib/jwt/json.rb +9 -25
- data/lib/jwt/verify.rb +98 -0
- data/lib/jwt/version.rb +23 -0
- data/ruby-jwt.gemspec +29 -0
- data/spec/fixtures/certs/ec256-private.pem +8 -0
- data/spec/fixtures/certs/ec256-public.pem +4 -0
- data/spec/fixtures/certs/ec256-wrong-private.pem +8 -0
- data/spec/fixtures/certs/ec256-wrong-public.pem +4 -0
- data/spec/fixtures/certs/ec384-private.pem +9 -0
- data/spec/fixtures/certs/ec384-public.pem +5 -0
- data/spec/fixtures/certs/ec384-wrong-private.pem +9 -0
- data/spec/fixtures/certs/ec384-wrong-public.pem +5 -0
- data/spec/fixtures/certs/ec512-private.pem +10 -0
- data/spec/fixtures/certs/ec512-public.pem +6 -0
- data/spec/fixtures/certs/ec512-wrong-private.pem +10 -0
- data/spec/fixtures/certs/ec512-wrong-public.pem +6 -0
- data/spec/fixtures/certs/rsa-1024-private.pem +15 -0
- data/spec/fixtures/certs/rsa-1024-public.pem +6 -0
- data/spec/fixtures/certs/rsa-2048-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-public.pem +9 -0
- data/spec/fixtures/certs/rsa-2048-wrong-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-wrong-public.pem +9 -0
- data/spec/fixtures/certs/rsa-4096-private.pem +51 -0
- data/spec/fixtures/certs/rsa-4096-public.pem +14 -0
- data/spec/jwt/verify_spec.rb +175 -0
- data/spec/jwt_spec.rb +1 -181
- data/spec/spec_helper.rb +2 -3
- metadata +145 -28
- data/jwt.gemspec +0 -34
    
        data/lib/jwt/verify.rb
    ADDED
    
    | @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            require 'jwt/error'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module JWT
         | 
| 4 | 
            +
              # JWT verify methods
         | 
| 5 | 
            +
              class Verify
         | 
| 6 | 
            +
                class << self
         | 
| 7 | 
            +
                  %w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub].each do |method_name|
         | 
| 8 | 
            +
                    define_method method_name do |payload, options|
         | 
| 9 | 
            +
                      new(payload, options).send(method_name)
         | 
| 10 | 
            +
                    end
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def initialize(payload, options)
         | 
| 15 | 
            +
                  @payload = payload
         | 
| 16 | 
            +
                  @options = options
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def verify_aud
         | 
| 20 | 
            +
                  return unless (options_aud = extract_option(:aud))
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  if @payload['aud'].is_a?(Array)
         | 
| 23 | 
            +
                    fail(
         | 
| 24 | 
            +
                      JWT::InvalidAudError,
         | 
| 25 | 
            +
                      'Invalid audience'
         | 
| 26 | 
            +
                    ) unless @payload['aud'].include?(options_aud.to_s)
         | 
| 27 | 
            +
                  else
         | 
| 28 | 
            +
                    fail(
         | 
| 29 | 
            +
                      JWT::InvalidAudError,
         | 
| 30 | 
            +
                      "Invalid audience. Expected #{options_aud}, received #{@payload['aud'] || '<none>'}"
         | 
| 31 | 
            +
                    ) unless @payload['aud'].to_s == options_aud.to_s
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def verify_expiration
         | 
| 36 | 
            +
                  return unless @payload.include?('exp')
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  if @payload['exp'].to_i < (Time.now.to_i - leeway)
         | 
| 39 | 
            +
                    fail(JWT::ExpiredSignature, 'Signature has expired')
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def verify_iat
         | 
| 44 | 
            +
                  return unless @payload.include?('iat')
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  if !(@payload['iat'].is_a?(Numeric)) || @payload['iat'].to_f > (Time.now.to_f + leeway)
         | 
| 47 | 
            +
                    fail(JWT::InvalidIatError, 'Invalid iat')
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def verify_iss
         | 
| 52 | 
            +
                  return unless (options_iss = extract_option(:iss))
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  if @payload['iss'].to_s != options_iss.to_s
         | 
| 55 | 
            +
                    fail(
         | 
| 56 | 
            +
                      JWT::InvalidIssuerError,
         | 
| 57 | 
            +
                      "Invalid issuer. Expected #{options_iss}, received #{@payload['iss'] || '<none>'}"
         | 
| 58 | 
            +
                    )
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def verify_jti
         | 
| 63 | 
            +
                  options_verify_jti = extract_option(:verify_jti)
         | 
| 64 | 
            +
                  if options_verify_jti.respond_to?(:call)
         | 
| 65 | 
            +
                    fail(JWT::InvalidJtiError, 'Invalid jti') unless options_verify_jti.call(@payload['jti'])
         | 
| 66 | 
            +
                  else
         | 
| 67 | 
            +
                    fail(JWT::InvalidJtiError, 'Missing jti') if @payload['jti'].to_s.strip.empty?
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def verify_not_before
         | 
| 72 | 
            +
                  return unless @payload.include?('nbf')
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  if @payload['nbf'].to_i > (Time.now.to_i + leeway)
         | 
| 75 | 
            +
                    fail(JWT::ImmatureSignature, 'Signature nbf has not been reached')
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def verify_sub
         | 
| 80 | 
            +
                  return unless (options_sub = extract_option(:sub))
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  fail(
         | 
| 83 | 
            +
                    JWT::InvalidSubError,
         | 
| 84 | 
            +
                    "Invalid subject. Expected #{options_sub}, received #{@payload['sub'] || '<none>'}"
         | 
| 85 | 
            +
                  ) unless @payload['sub'].to_s == options_sub.to_s
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                private
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                def extract_option(key)
         | 
| 91 | 
            +
                  @options.values_at(key.to_sym, key.to_s).compact.first
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def leeway
         | 
| 95 | 
            +
                  extract_option :leeway
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
    
        data/lib/jwt/version.rb
    ADDED
    
    | @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Moments version builder module
         | 
| 4 | 
            +
            module JWT
         | 
| 5 | 
            +
              def self.gem_version
         | 
| 6 | 
            +
                Gem::Version.new VERSION::STRING
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # Moments version builder module
         | 
| 10 | 
            +
              module VERSION
         | 
| 11 | 
            +
                # major version
         | 
| 12 | 
            +
                MAJOR = 1
         | 
| 13 | 
            +
                # minor version
         | 
| 14 | 
            +
                MINOR = 5
         | 
| 15 | 
            +
                # tiny version
         | 
| 16 | 
            +
                TINY  = 4
         | 
| 17 | 
            +
                # alpha, beta, etc. tag
         | 
| 18 | 
            +
                PRE   = nil
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # Build version string
         | 
| 21 | 
            +
                STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
    
        data/ruby-jwt.gemspec
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            lib = File.expand_path('../lib/', __FILE__)
         | 
| 2 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 3 | 
            +
            require 'jwt/version'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
              spec.name = 'jwt'
         | 
| 7 | 
            +
              spec.version = JWT.gem_version
         | 
| 8 | 
            +
              spec.authors = [
         | 
| 9 | 
            +
                'Jeff Lindsay',
         | 
| 10 | 
            +
                'Tim Rudat'
         | 
| 11 | 
            +
              ]
         | 
| 12 | 
            +
              spec.email = 'timrudat@gmail.com'
         | 
| 13 | 
            +
              spec.summary = 'JSON Web Token implementation in Ruby'
         | 
| 14 | 
            +
              spec.description = 'A pure ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.'
         | 
| 15 | 
            +
              spec.homepage = 'http://github.com/jwt/ruby-jwt'
         | 
| 16 | 
            +
              spec.license = 'MIT'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              spec.files = `git ls-files -z`.split("\x0")
         | 
| 19 | 
            +
              spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 20 | 
            +
              spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 21 | 
            +
              spec.require_paths = %w(lib)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              spec.add_development_dependency 'bundler'
         | 
| 24 | 
            +
              spec.add_development_dependency 'rake'
         | 
| 25 | 
            +
              spec.add_development_dependency 'rspec'
         | 
| 26 | 
            +
              spec.add_development_dependency 'simplecov'
         | 
| 27 | 
            +
              spec.add_development_dependency 'simplecov-json'
         | 
| 28 | 
            +
              spec.add_development_dependency 'codeclimate-test-reporter'
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BggqhkjOPQMBBw==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MHcCAQEEIJmVse5uPfj6B4TcXrUAvf9/8pJh+KrKKYLNcmOnp/vPoAoGCCqGSM49
         | 
| 6 | 
            +
            AwEHoUQDQgAEAr+WbDE5VtIDGhtYMxvEc6cMsDBc/DX1wuhIMu8dQzOLSt0tpqK9
         | 
| 7 | 
            +
            MVfXbVfrKdayVFgoWzs8MilcYq0QIhKx/w==
         | 
| 8 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BgUrgQQACg==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MHQCAQEEICfA4AaomONdmPTzeyrx5U/jugYXTERyb5U3ETTv7Hx7oAcGBSuBBAAK
         | 
| 6 | 
            +
            oUQDQgAEPmuXZT3jpJnEMVPOW6RMsmxeGLOCE1PN6fwvUwOsxv7YnyoQ5/bpo64n
         | 
| 7 | 
            +
            +Jp4slSl1aUNoCBF2oz9bS0iyBo3jg==
         | 
| 8 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BgUrgQQAIg==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MIGkAgEBBDDxOljqUKw9YNhkluSJIBAYO1YXcNtS+vckd5hpTZ5toxsOlwbmyrnU
         | 
| 6 | 
            +
            Tn+D5Xma1m2gBwYFK4EEACKhZANiAASQwYTiRvXu1hMHceSosMs/8uf50sJI3jvK
         | 
| 7 | 
            +
            kdSkvuRAPxSzhtrUvCQDnVsThFq4aOdZZY1qh2ErJGtzmrx+pEsJvJnvfOTG3NGU
         | 
| 8 | 
            +
            KRalek+LQfVqAUSvDMKlxdkz2e67tso=
         | 
| 9 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BgUrgQQAIg==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MIGkAgEBBDAfZW47dSKnC5JkSVOk1ERxCIi/IJ1p1WBnVGx4hnrNHy+dxtaZJaF+
         | 
| 6 | 
            +
            YLInFQ/QbYegBwYFK4EEACKhZANiAAQwXkx4BFBGLXbzl5yVrfxK7er8hSi38iDE
         | 
| 7 | 
            +
            K2+7cdrR137Wn5JUnL4WTwXTzkyUgfBOL3sHNozwfgU03GD/EOUEKqzsIJiz2cbP
         | 
| 8 | 
            +
            bFALd4hS+8T4szDLVC9Jl1W6k0CAtmM=
         | 
| 9 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BgUrgQQAIw==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MIHcAgEBBEIB0/+ffxEj7j62xvGaB5pvzk888e412ESO/EK/K0QlS9dSF8+Rj1rG
         | 
| 6 | 
            +
            zqpRB8fvDnoe8xdmkW/W5GKzojMyv7YQYumgBwYFK4EEACOhgYkDgYYABAEw74Yw
         | 
| 7 | 
            +
            aTbPY6TtWmxx6LJDzCX2nKWCPnKdZcEH9Ncu8g5RjRBRq2yacja3OoS6nA2YeDng
         | 
| 8 | 
            +
            reBJxZr376P6Ns6XcQFWDA6K/MCTrEBCsPxXZNxd8KR9vMGWhgNtWRrcKzwJfQkr
         | 
| 9 | 
            +
            suyehZkbbYyFnAWyARKHZuV7VUXmeEmRS/f93MPqVA==
         | 
| 10 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBMO+GMGk2z2Ok7VpsceiyQ8wl9pyl
         | 
| 3 | 
            +
            gj5ynWXBB/TXLvIOUY0QUatsmnI2tzqEupwNmHg54K3gScWa9++j+jbOl3EBVgwO
         | 
| 4 | 
            +
            ivzAk6xAQrD8V2TcXfCkfbzBloYDbVka3Cs8CX0JK7LsnoWZG22MhZwFsgESh2bl
         | 
| 5 | 
            +
            e1VF5nhJkUv3/dzD6lQ=
         | 
| 6 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            -----BEGIN EC PARAMETERS-----
         | 
| 2 | 
            +
            BgUrgQQAIw==
         | 
| 3 | 
            +
            -----END EC PARAMETERS-----
         | 
| 4 | 
            +
            -----BEGIN EC PRIVATE KEY-----
         | 
| 5 | 
            +
            MIHbAgEBBEG/KbA2oCbiCT6L3V8XSz2WKBy0XhGvIFbl/ZkXIXnkYt+1B7wViSVo
         | 
| 6 | 
            +
            KCHuMFsi6xU/5nE1EuDG2UsQJmKeAMkIOKAHBgUrgQQAI6GBiQOBhgAEAG0TFWe5
         | 
| 7 | 
            +
            cZ5DZIyfuysrCoQySTNxd+aT8sPIxsx7mW6YBTsuO6rEgxyegd2Auy4xtikxpzKv
         | 
| 8 | 
            +
            soMXR02999Aaus2jAAt/wxrhhr41BDP4MV0b6Zngb72hna0pcGqit5OyU8AbOJUZ
         | 
| 9 | 
            +
            +rdyowRGsOY+aPbOyVhdNcsEdxYC8GdIyCQLBC1H
         | 
| 10 | 
            +
            -----END EC PRIVATE KEY-----
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAbRMVZ7lxnkNkjJ+7KysKhDJJM3F3
         | 
| 3 | 
            +
            5pPyw8jGzHuZbpgFOy47qsSDHJ6B3YC7LjG2KTGnMq+ygxdHTb330Bq6zaMAC3/D
         | 
| 4 | 
            +
            GuGGvjUEM/gxXRvpmeBvvaGdrSlwaqK3k7JTwBs4lRn6t3KjBEaw5j5o9s7JWF01
         | 
| 5 | 
            +
            ywR3FgLwZ0jIJAsELUc=
         | 
| 6 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            -----BEGIN RSA PRIVATE KEY-----
         | 
| 2 | 
            +
            MIICXgIBAAKBgQDO/ahgFDvniFoQ1dm+MdnkBi+Ts5W9AtQNgw4ZHIdPnqEzSgW7
         | 
| 3 | 
            +
            0opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6bth1cYRI+YJlR3BbPGOIL6YbJ
         | 
| 4 | 
            +
            ud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZlnr1z7HTm7nIIVBvuQIDAQAB
         | 
| 5 | 
            +
            AoGBAMzFQAccvU6GI6O4C5sOsiHUxMh3xtCftaxQVGgfQvVPVuXoeteep1Q0ewFl
         | 
| 6 | 
            +
            IV4vnkO5pH8pTtVTWG9x5KIy6QCql4qvr2jkOm4mo9uogrpNklvBl2lN4Lxubj0N
         | 
| 7 | 
            +
            mGRXaM3hckZl8+JT6uzfBfjy+pd8AOigJGPQCOZn4gmANW7pAkEA82Nh4wpj6ZRU
         | 
| 8 | 
            +
            NBiBq3ONZuH4xJm59MI2FWRJsGUFUYdSaFwyKKim52/13d8iUb7v9utWQFRatCXz
         | 
| 9 | 
            +
            Lqw9fQyVrwJBANm3dBOVxpUPrYEQsG0q2rdP+u6U3woylxwtQgJxImZKZmmJlPr8
         | 
| 10 | 
            +
            9v23rhydvCe1ERPYe7EjF4RGWVPN3KLdExcCQDdzNfL3BApMS97OkoRQQC/nXbjU
         | 
| 11 | 
            +
            2SPlN1MqVQuGCG8pqGG0V40h11y1CkvxMS10ldEojq77SOrwFnZUsXGS82sCQQC6
         | 
| 12 | 
            +
            XdO7QCaxSq5XIRYlHN4EtS40NLOIYy3/LK6osHel4GIyTVd+UjSLk0QzssJxqwln
         | 
| 13 | 
            +
            V5TqWQO0cxPcLQiFUYEZAkEA2G84ilb9QXOgbNyoE1VifNk49hhodbSskLb86uwY
         | 
| 14 | 
            +
            Vgtzq1ZsqoPBCasr4WRiXt270n+mo5dNYRlZwiUn9lH78Q==
         | 
| 15 | 
            +
            -----END RSA PRIVATE KEY-----
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO/ahgFDvniFoQ1dm+MdnkBi+T
         | 
| 3 | 
            +
            s5W9AtQNgw4ZHIdPnqEzSgW70opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6b
         | 
| 4 | 
            +
            th1cYRI+YJlR3BbPGOIL6YbJud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZ
         | 
| 5 | 
            +
            lnr1z7HTm7nIIVBvuQIDAQAB
         | 
| 6 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            -----BEGIN RSA PRIVATE KEY-----
         | 
| 2 | 
            +
            MIIEpAIBAAKCAQEA4GzZTLU48c4WbyvHi+QKrB71x+T0eq5hqDbQqnlYjhD1Ika7
         | 
| 3 | 
            +
            io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lgCZr4+8UHbr1qf0Eu5HZSpszs2YxY
         | 
| 4 | 
            +
            8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldHH/eazwnc3F/hgNsV0xjScVilejgo
         | 
| 5 | 
            +
            cJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y0HFyrMsPoQyLuCUpr6ulOfrkr7ZO
         | 
| 6 | 
            +
            dhAIG8r1HcjOp/AUjM15vfXcbUZjkM/VloifX1YitU3upMGJ8/DpFGffMOImrn5r
         | 
| 7 | 
            +
            6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgVQQIDAQABAoIBAEH0Ozgr2fxWEInD
         | 
| 8 | 
            +
            V/VooypKPvjr9F1JejGxSkmPN9MocKIOH3dsbZ1uEXa3ItBUxan4XlK06SNgp+tH
         | 
| 9 | 
            +
            xULfF/Y6sQlsse59hBq50Uoa69dRShn1AP6JgZVvkduMPBNxUYL5zrs6emsQXb9Q
         | 
| 10 | 
            +
            DglDRQfEAJ7vyxSIqQDxYcyT8uSUF70dqFe+E9B2VE3D6ccHc98k41pJrAFAUFH1
         | 
| 11 | 
            +
            wwvDhfyYr7/Ultut9wzpZvU1meF3Vna3GOUHfxrG6wu1G+WIWHGjouzThsc1qiVI
         | 
| 12 | 
            +
            BtMCJxuCt5fOXRbU4STbMqhB6sZHiOh6J/dZU6JwRYt+IS8FB6kCNFSEWZWQledJ
         | 
| 13 | 
            +
            XqtYSQECgYEA9nmnFTRj3fTBq9zMXfCRujkSy6X2bOb39ftNXzHFuc+I6xmv/3Bs
         | 
| 14 | 
            +
            P9tDdjueP/SnCb7i/9hXkpEIcxjrjiqgcvD2ym1hE4q+odMzRAXYMdnmzI34SVZE
         | 
| 15 | 
            +
            U5hYJcYsXNKrTTleba7QgqdORmyJ9FwqLO40udvmrZMY223XDwgRkOkCgYEA6RkO
         | 
| 16 | 
            +
            5wjjrWWp/G1YN3KXZTS1m2/eGrUThohXKAfAjbWWiouNLW2msXrxEWsPRL6xKiHu
         | 
| 17 | 
            +
            X9cwZwzi3MstAgk+bphUGUVUkGKNDjWHJA25tDYjbPtkd6xbL4eCHsKpNL3HNYr9
         | 
| 18 | 
            +
            N0CIvgn7qjaHRBem0iK7T6keY4axaSVddEwYapkCgYEA13K5qaB1F4Smcpt8DTWH
         | 
| 19 | 
            +
            vPe8xUUaZlFzOJLmLCsuwmB2N8Ppg2j7RspcaxJsH021YaB5ftjWm+ipMSr8ZPY/
         | 
| 20 | 
            +
            8JlPsNzxuYpTXtNmAbT2KYVm6THEch61dTk6/DIBf1YrpUJbl5by7vJeStL/uBmE
         | 
| 21 | 
            +
            SGgksL5XIyzs0opuLdaIvFkCgYAyBLWE8AxjFfCvAQuwAj/ocLITo6KmWnrRIIqL
         | 
| 22 | 
            +
            RXaVMgUWv7FQsTnW1cnK8g05tC2yG8vZ9wQk6Mf5lwOWb0NdWgSZ0528ydj41pWk
         | 
| 23 | 
            +
            L+nMeN2LMjqxz2NVxJ8wWJcUgTCxFZ0WcRumo9/D+6V1ABpE9zz4cBLcSnfhVypB
         | 
| 24 | 
            +
            nV6T6QKBgQCSZNCQ9HPxjAgYcsqc5sjNwuN1GHQZSav3Tye3k6zHENe1lsteT9K8
         | 
| 25 | 
            +
            xciGIuhybKZBvB4yImIIHCtnH+AS+mHAGqHarjNDMfvjOq0dMibPx4+bkIiHdBIH
         | 
| 26 | 
            +
            Xz+j5kmntvFiUnzr0Z/Tcqo+r8FvyCo1YWgwqGP8XoFrswD7gy7cZw==
         | 
| 27 | 
            +
            -----END RSA PRIVATE KEY-----
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4GzZTLU48c4WbyvHi+QK
         | 
| 3 | 
            +
            rB71x+T0eq5hqDbQqnlYjhD1Ika7io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lg
         | 
| 4 | 
            +
            CZr4+8UHbr1qf0Eu5HZSpszs2YxY8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldH
         | 
| 5 | 
            +
            H/eazwnc3F/hgNsV0xjScVilejgocJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y
         | 
| 6 | 
            +
            0HFyrMsPoQyLuCUpr6ulOfrkr7ZOdhAIG8r1HcjOp/AUjM15vfXcbUZjkM/Vloif
         | 
| 7 | 
            +
            X1YitU3upMGJ8/DpFGffMOImrn5r6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgV
         | 
| 8 | 
            +
            QQIDAQAB
         | 
| 9 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            -----BEGIN RSA PRIVATE KEY-----
         | 
| 2 | 
            +
            MIIEpAIBAAKCAQEAzHAVGaW9j4l3/b4ngcjjoIoIcnsQEWOMqErb5VhLZMGIq1gE
         | 
| 3 | 
            +
            O5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNUYkYWgYITNGeSifrnVqQugd5Fh1L8
         | 
| 4 | 
            +
            K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu0eu0xZK3To+YkDcWOk92rmNgmUSQ
         | 
| 5 | 
            +
            C/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v/hMLyQLzwRY/Qfty1FTIDyTv2dch
         | 
| 6 | 
            +
            47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YGxrYasUt1b0um64bscxoIiCu8yLL8
         | 
| 7 | 
            +
            jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6arJwIDAQABAoIBAGFR4dmJusl/qW1T
         | 
| 8 | 
            +
            fj8cQLAFxaupxaZhe24J5NAyzgEy2Dqo9ariIwkB78UM66ozjEqAgOvcP+NTw5m8
         | 
| 9 | 
            +
            kD/VapA1yTTxlO7XdzzUAhiOo80S4IphCMZRZNPLMmluGtdf3lIUr1pXBrn0TCBX
         | 
| 10 | 
            +
            H5o9jaREzpNXGof9d6T/dEdh2J9+uE/p1xE5GSxQfaPheZzCG7636La/DcArg/UR
         | 
| 11 | 
            +
            +TusPqp62BEmk96pE/KKJRmEeH+WnPfSh6sMpLxi3hkEU7AynpliGT6Z6xV4csBI
         | 
| 12 | 
            +
            S/rdpkcj5DWpbnQzkwdrnL2Q+POEq/vlx5/NlezvtQPNLvQWDyY4yBCoMKGb3EbX
         | 
| 13 | 
            +
            xrxP7MECgYEA/kwe4P0Mqk+087IyhjDBGPfcMt8gfYc9nzNfIYSWdSwuSag/hqHq
         | 
| 14 | 
            +
            I4GwHQzUV9ix3iM6w5hin10yAzWxCYZg9hquV+lSvNNpGB76FX6oOqwuAhyQMRwv
         | 
| 15 | 
            +
            eW+VUyfFXeJugwL5JuIaNTvwPpQVDHYtELLifie+uzJ5HC6dhg/XchcCgYEAzc5/
         | 
| 16 | 
            +
            +IXjOlExd/mBgFk/5Y87ifA0ZOgbaJXifYgU0aNSgz1piHxU3n2p4jJ9lSdwwCl2
         | 
| 17 | 
            +
            Fb5EN7666t20PL5QcXJ5ZdaTRLzRlYiqTWzfYHBgttbB1Jl3Ed9GsKuzRgaRqGFC
         | 
| 18 | 
            +
            ANJSqZlKG0NZ3keRtuKdFwq+IVOnsQr9g0TZiXECgYEAqUgtCiMKCloTIGMQpSnR
         | 
| 19 | 
            +
            cXiWWjsUmturls4Q1vQ3YHrvuVLKLyqb/dT4Uu5WcMAs765OESThCit0/pQAbVHK
         | 
| 20 | 
            +
            PCpYwubskAzAGjGM00BEZwJ1gixXhIm5xMIWCowgI7Z3ULlq+IptXeCvtkjHlksZ
         | 
| 21 | 
            +
            BtO+WLLGkkEwRCV38WWcSzMCgYA/Xxqgl/mD94RYAQgTUWgPc69Nph08BQyLg7ue
         | 
| 22 | 
            +
            E8z1UGkT6FEaqc4oRGGPOSTaTK63PQ0TXOb8k0pTD7l0CtYSWMFwzkXCoLGYbeCi
         | 
| 23 | 
            +
            vqd5tqDRLAe7QxYa9rl5pSUqptMrGeeNATZa6sya4H5Hp5oCyny8n54z/OJh7ZRq
         | 
| 24 | 
            +
            W0TwwQKBgQDDP7ksm2pcqadaVAmODdOlaDHbaEcxp8wN7YVz0lM3UpJth96ukbj7
         | 
| 25 | 
            +
            S39eJhXYWOn6oJQb/lN9fGOYqjg3y6IchGZDp67ATvWYvn/NY0R7mt4K4oHx5TuN
         | 
| 26 | 
            +
            rSQlP3WmOGv8Kemw892uRfW/jZyBEHhsfS213WDttVPn9F635GdNWw==
         | 
| 27 | 
            +
            -----END RSA PRIVATE KEY-----
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzHAVGaW9j4l3/b4ngcjj
         | 
| 3 | 
            +
            oIoIcnsQEWOMqErb5VhLZMGIq1gEO5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNU
         | 
| 4 | 
            +
            YkYWgYITNGeSifrnVqQugd5Fh1L8K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu
         | 
| 5 | 
            +
            0eu0xZK3To+YkDcWOk92rmNgmUSQC/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v
         | 
| 6 | 
            +
            /hMLyQLzwRY/Qfty1FTIDyTv2dch47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YG
         | 
| 7 | 
            +
            xrYasUt1b0um64bscxoIiCu8yLL8jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6ar
         | 
| 8 | 
            +
            JwIDAQAB
         | 
| 9 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            -----BEGIN RSA PRIVATE KEY-----
         | 
| 2 | 
            +
            MIIJJwIBAAKCAgEAqETmgWBi5rCmb7euJplA/9xs65+bncc9Yvs5zjyycXSW82Jf
         | 
| 3 | 
            +
            RuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJWADVFNr+2V2r6i57/OMLruRpn3p2
         | 
| 4 | 
            +
            r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/xkS14nLOWFf96hrXPlXJC+VMVKVZm
         | 
| 5 | 
            +
            A8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8wwe4TBy/z/f+rhFD1w8rxlYjallee/
         | 
| 6 | 
            +
            ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h/7uJ7iRwvTFERkTdwWP/0BeKBeIt
         | 
| 7 | 
            +
            BR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB7j9SZFzQiRtes4BYETpX1xl2mgIq
         | 
| 8 | 
            +
            5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1zXPr4+Id6L0sJLxPCaXnTmNtasSw
         | 
| 9 | 
            +
            yedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6YxK3zJ59jTE6Pkvqjq183f2PGHVR
         | 
| 10 | 
            +
            vgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd6ei1vl3DpPk+h8iExx6AzbohfqZ+
         | 
| 11 | 
            +
            5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcVuO3m2KqVUj+K1uYBy3KBCUMBbckp
         | 
| 12 | 
            +
            EWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRww+oLsbzF8J3dxeDbKNF9JDsCAwEA
         | 
| 13 | 
            +
            AQKCAgBJF8TZJjlP5CQoGy227pNhkSpvH6HFY6qyuFZf09XfmrmHd4/Tiy41bRUx
         | 
| 14 | 
            +
            FO90iR7t8hFWYHqjf/k9eCtDdi164MGukYJqgVoQG6kYLLgCfI21DMlJk9otLFtu
         | 
| 15 | 
            +
            gnroRcP05EWhk9dpYONJgcGLMHSKj6n4x7nGTHe41HkbfcrB6ukiT7l4o4q5BAxb
         | 
| 16 | 
            +
            cFadMtoXr/ZvxJrIZgkddJ7snGHjBcP5DCkgM7MZy6aoilWv1/UNrOF9MdgNA9zz
         | 
| 17 | 
            +
            rrD3b136x7/XvqC6pS+bxuvJ8YK4R4qeu42NYT07GOcK/pk8lz0JWTodIt2eevqV
         | 
| 18 | 
            +
            6lGFj7c2mv7PCpJRVgbVGL/RTVVap/+jbcRVLdnYKsII/dANG7iXnfwRgkLWet5D
         | 
| 19 | 
            +
            OOsPuvIuyiSaJIwcdRE3SSO+tZhKLt+gh/oLxBPw5Ex0FwsVTtYn3Q/X3EAx+Wph
         | 
| 20 | 
            +
            eFcRr3TVkDg0MfdWWkgk16DvYB5cWc29coTaH1g+2juadNHbtVAigwJorKc6sxH3
         | 
| 21 | 
            +
            QGsW0WQJ8ZRZgJkSUuu3nr7QD3ZrgHptONQAh1RWGnIWi6OlMfaPdMo+SDnnL5SG
         | 
| 22 | 
            +
            mpOPjWadDc1XvMFnKQYMYB5GWU/ZNmnZmDLyg1Pc0Y+qRUc0s83nZFHN60KnUrSz
         | 
| 23 | 
            +
            0MZDspSFtr0fMx0b2/EB4EbuXd3QjQURF6P6HtWBu6oFnzu1AQKCAQEA2R9BKJgJ
         | 
| 24 | 
            +
            vNP+DUu8NBzwmi0cKlAiaxt+w90i5DWq1XWPKgi+RVLkaQSJqHoYQVNgEwL/cWxp
         | 
| 25 | 
            +
            s2r3GCMNIdOrGdcm8dX/6UYFpRaFcViTycVEA7cwZOMppgqr2Q+ZYX42K7HObUVL
         | 
| 26 | 
            +
            JGvdEWWWfSsynUGsrG87DC1gl94ANxCdqkZdbW5d3X0w5v7M/1tlrmAeskZSZpeT
         | 
| 27 | 
            +
            8BwwM6REb0U/B4/i8TLtLi/PGmMTOIxW41uKS/S6kq/gwyv+jNNO0ljhPt25iSbV
         | 
| 28 | 
            +
            K5ZHS4YuPKLl0tZMaOkPco9s6t4ES/Y317zQoTzUkAAkkFO4QPzRZL0ESqVBNR0h
         | 
| 29 | 
            +
            Ao7FLmFZzFHpoQKCAQEAxmZBn0UrJLXkD7bw66y4RwzjQYmxLlkEl3uvjrvVSuL1
         | 
| 30 | 
            +
            mAHDW58aGIpFFZ8QSTtNewIBQYNifp/cdFHAagqtl/iMGEegaOpJAKu/ykrkfZUp
         | 
| 31 | 
            +
            7mYDNng4ZWpypeKaGMAQoNzZiUpF+BDnqbeb/kgYu6sNlh9gRHR79rgAuZQxZ/1B
         | 
| 32 | 
            +
            tE8WcUFi4CnTq2QLqX4LwMuZHWXAJQoMoW3K5av+J544lIM6GdMJuIONtBBkKVQD
         | 
| 33 | 
            +
            ErrJ0bqYeykrFS6pKl/NBCZLGo5xFFRiYEdZ1GlA3uW3EGKppz6PS7194+x5UVts
         | 
| 34 | 
            +
            xZPUfkgdFjWCczkl4JDoWfaNn5sgXtiVbGh1n3gYWwKCAQB7vHEg1kyuXU4qe5/d
         | 
| 35 | 
            +
            PyTraIvlnVeQHNJIgy0QS3l5Pw8A0IzG6y+anehpqHNMP1zAWPQEytkOVAZPriIc
         | 
| 36 | 
            +
            xgl7p37dUa0PX0V2SPhxmR5YXeCeEXc197PTmb9H67jos8nhauqOoW/qaMJK2M9D
         | 
| 37 | 
            +
            tCubLUNf3eAT14R16CHNP93qnUE/TSeXQ3JsIofne0neb47u4F6zcuzvaNEbjSEn
         | 
| 38 | 
            +
            HJqID7sw5GoA6WQo0I+yqWAXICMXmHf/gtYfxGHEFeSUwexULH5BKG1R8sncw7J0
         | 
| 39 | 
            +
            Ag3h8xkGrNON4SkcTLy8Iay/eS6YxRcKndo4mk2mU65tr77TX4xi3Z/jWkQLY5WO
         | 
| 40 | 
            +
            eJwhAoIBABO17wkSxyGDjJ/fDfpsE3bDmgRV2KuBHoqqOBvXH26sM7ghXLZKjT4o
         | 
| 41 | 
            +
            5ooqXmTYJm91GIjYs71exnkr8hDW9L4nbEuxOgeSVyRg69H+NMshOaQ8sE8GDJxO
         | 
| 42 | 
            +
            wgsnAyY4Vq6UomwYW/E0RL/AxRezM/nZGaVzgo3qgLJXP4MwbOQm7hMq1FD2LQuW
         | 
| 43 | 
            +
            PDhH3Ty+kA5ca97W0Asd/3k+Pi0pNDvdZUOj8e7E369cKoTcKAdPGGsQ8aILhsCd
         | 
| 44 | 
            +
            q3EUTKwwDl8+KrH9utBJPejQzeTjfBVo/xH6q145QeVFcy9ku/zQN3M9p5vQMEuX
         | 
| 45 | 
            +
            j1lBMTkpTFw7uYBE2idyHw5BJoZsWQcCggEADfZTChqnOncItSflzGoaAACrr4/x
         | 
| 46 | 
            +
            KyT/4A+cPMCs11JN9J+EWsCezya2o1l/NF7YPcBR4qjCmFMEiq5GxH5fGLQp0aa7
         | 
| 47 | 
            +
            V13mHA8XBQ25OW2K7BGJhMHdbuvTnl6jsOfC4+t7P2bUAYxoP6/ncxTzZ5OlBN5k
         | 
| 48 | 
            +
            aMv9firWl1kSKK75ww9DWn6j0rQ4dBetwX45EMcs+iKIdydg0fmJxR2EJ+uQsCFy
         | 
| 49 | 
            +
            xcWBEDqV7qLUi6UrAPL3v/DXUv9wKcKOTbKw/aNE8+YTWMUO330GCJ5cVU1eTL5t
         | 
| 50 | 
            +
            UrcNKOJkFIj7jJUCzv6vcy++hMJEbNXnnTVRnky6e9C2vwzMl33njntapg==
         | 
| 51 | 
            +
            -----END RSA PRIVATE KEY-----
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            -----BEGIN PUBLIC KEY-----
         | 
| 2 | 
            +
            MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqETmgWBi5rCmb7euJplA
         | 
| 3 | 
            +
            /9xs65+bncc9Yvs5zjyycXSW82JfRuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJ
         | 
| 4 | 
            +
            WADVFNr+2V2r6i57/OMLruRpn3p2r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/x
         | 
| 5 | 
            +
            kS14nLOWFf96hrXPlXJC+VMVKVZmA8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8ww
         | 
| 6 | 
            +
            e4TBy/z/f+rhFD1w8rxlYjallee/ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h
         | 
| 7 | 
            +
            /7uJ7iRwvTFERkTdwWP/0BeKBeItBR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB
         | 
| 8 | 
            +
            7j9SZFzQiRtes4BYETpX1xl2mgIq5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1
         | 
| 9 | 
            +
            zXPr4+Id6L0sJLxPCaXnTmNtasSwyedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6
         | 
| 10 | 
            +
            YxK3zJ59jTE6Pkvqjq183f2PGHVRvgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd
         | 
| 11 | 
            +
            6ei1vl3DpPk+h8iExx6AzbohfqZ+5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcV
         | 
| 12 | 
            +
            uO3m2KqVUj+K1uYBy3KBCUMBbckpEWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRw
         | 
| 13 | 
            +
            w+oLsbzF8J3dxeDbKNF9JDsCAwEAAQ==
         | 
| 14 | 
            +
            -----END PUBLIC KEY-----
         | 
| @@ -0,0 +1,175 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'jwt/verify'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module JWT
         | 
| 5 | 
            +
              RSpec.describe Verify do
         | 
| 6 | 
            +
                let(:base_payload) { { 'user_id' => 'some@user.tld' } }
         | 
| 7 | 
            +
                let(:options) {  { leeway: 0} }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                context '.verify_aud(payload, options)' do
         | 
| 10 | 
            +
                  let(:scalar_aud) { 'ruby-jwt-audience' }
         | 
| 11 | 
            +
                  let(:array_aud) { %w(ruby-jwt-aud test-aud ruby-ruby-ruby) }
         | 
| 12 | 
            +
                  let(:scalar_payload) { base_payload.merge('aud' => scalar_aud) }
         | 
| 13 | 
            +
                  let(:array_payload) { base_payload.merge('aud' => array_aud) }
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  it 'must raise JWT::InvalidAudError when the singular audience does not match' do
         | 
| 16 | 
            +
                    expect do
         | 
| 17 | 
            +
                      Verify.verify_aud(scalar_payload, options.merge(aud: 'no-match'))
         | 
| 18 | 
            +
                    end.to raise_error JWT::InvalidAudError
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  it 'must raise JWT::InvalidAudError when the payload has an array and none match the supplied value' do
         | 
| 22 | 
            +
                    expect do
         | 
| 23 | 
            +
                      Verify.verify_aud(array_payload, options.merge(aud: 'no-match'))
         | 
| 24 | 
            +
                    end.to raise_error JWT::InvalidAudError
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  it 'must raise JWT::InvalidAudError when the singular audience does not match and the options aud key is a string' do
         | 
| 28 | 
            +
                    expect do
         | 
| 29 | 
            +
                      Verify.verify_aud(scalar_payload, options.merge('aud' => 'no-match'))
         | 
| 30 | 
            +
                    end.to raise_error JWT::InvalidAudError
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  it 'must allow a matching singular audience to pass' do
         | 
| 34 | 
            +
                    Verify.verify_aud(scalar_payload, options.merge(aud: scalar_aud))
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  it 'must allow a matching audence to pass when the options key is a string' do
         | 
| 38 | 
            +
                    Verify.verify_aud(scalar_payload, options.merge('aud' => scalar_aud))
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  it 'must allow an array with any value matching the one in the options' do
         | 
| 42 | 
            +
                    Verify.verify_aud(array_payload, options.merge(aud: array_aud.first))
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  it 'must allow an array with any value matching the one in the options with a string options key' do
         | 
| 46 | 
            +
                    Verify.verify_aud(array_payload, options.merge('aud' => array_aud.first))
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                context '.verify_expiration(payload, options)' do
         | 
| 51 | 
            +
                  let(:leeway) { 10 }
         | 
| 52 | 
            +
                  let(:payload) { base_payload.merge('exp' => (Time.now.to_i - 5)) }
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  it 'must raise JWT::ExpiredSignature when the token has expired' do
         | 
| 55 | 
            +
                    expect do
         | 
| 56 | 
            +
                      Verify.verify_expiration(payload, options)
         | 
| 57 | 
            +
                    end.to raise_error JWT::ExpiredSignature
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  it 'must allow some leeway in the expiration when configured' do
         | 
| 61 | 
            +
                    Verify.verify_expiration(payload, options.merge(leeway: 10))
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                context '.verify_iat(payload, options)' do
         | 
| 66 | 
            +
                  let(:iat) { Time.now.to_f }
         | 
| 67 | 
            +
                  let(:payload) { base_payload.merge('iat' => iat) }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  it 'must allow a valid iat' do
         | 
| 70 | 
            +
                    Verify.verify_iat(payload, options)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  it 'must allow configured leeway' do
         | 
| 74 | 
            +
                    Verify.verify_iat(payload.merge('iat' => (iat + 60)), options.merge(leeway: 70))
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  it 'must properly handle integer times' do
         | 
| 78 | 
            +
                    Verify.verify_iat(payload.merge('iat' => Time.now.to_i), options)
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  it 'must raise JWT::InvalidIatError when the iat value is not Numeric' do
         | 
| 82 | 
            +
                    expect do
         | 
| 83 | 
            +
                      Verify.verify_iat(payload.merge('iat' => 'not a number'), options)
         | 
| 84 | 
            +
                    end.to raise_error JWT::InvalidIatError
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  it 'must raise JWT::InvalidIatError when the iat value is in the future' do
         | 
| 88 | 
            +
                    expect do
         | 
| 89 | 
            +
                      Verify.verify_iat(payload.merge('iat' => (iat + 120)), options)
         | 
| 90 | 
            +
                    end.to raise_error JWT::InvalidIatError
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                context '.verify_iss(payload, options)' do
         | 
| 95 | 
            +
                  let(:iss) { 'ruby-jwt-gem' }
         | 
| 96 | 
            +
                  let(:payload) { base_payload.merge('iss' => iss) }
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  let(:invalid_token) { JWT.encode base_payload, payload[:secret] }
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  it 'must raise JWT::InvalidIssuerError when the configured issuer does not match the payload issuer' do
         | 
| 101 | 
            +
                    expect do
         | 
| 102 | 
            +
                      Verify.verify_iss(payload, options.merge(iss: 'mismatched-issuer'))
         | 
| 103 | 
            +
                    end.to raise_error JWT::InvalidIssuerError
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  it 'must raise JWT::InvalidIssuerError when the payload does not include an issuer' do
         | 
| 107 | 
            +
                    expect do
         | 
| 108 | 
            +
                      Verify.verify_iss(base_payload, options.merge(iss: iss))
         | 
| 109 | 
            +
                    end.to raise_error(JWT::InvalidIssuerError, /received <none>/)
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  it 'must allow a matching issuer to pass' do
         | 
| 113 | 
            +
                    Verify.verify_iss(payload, options.merge(iss: iss))
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                context '.verify_jti(payload, options)' do
         | 
| 118 | 
            +
                  let(:payload) { base_payload.merge('jti' => 'some-random-uuid-or-whatever') }
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                  it 'must allow any jti when the verfy_jti key in the options is truthy but not a proc' do
         | 
| 121 | 
            +
                    Verify.verify_jti(payload, options.merge(verify_jti: true))
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  it 'must raise JWT::InvalidJtiError when the jti is missing' do
         | 
| 125 | 
            +
                    expect do
         | 
| 126 | 
            +
                      Verify.verify_jti(base_payload, options)
         | 
| 127 | 
            +
                    end.to raise_error JWT::InvalidJtiError, /missing/i
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                  it 'must raise JWT::InvalidJtiError when the jti is an empty string' do
         | 
| 131 | 
            +
                    expect do
         | 
| 132 | 
            +
                      Verify.verify_jti(base_payload.merge('jti' => '   '), options)
         | 
| 133 | 
            +
                    end.to raise_error JWT::InvalidJtiError, /missing/i
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                  it 'must raise JWT::InvalidJtiError when verify_jti proc returns false' do
         | 
| 137 | 
            +
                    expect do
         | 
| 138 | 
            +
                      Verify.verify_jti(payload, options.merge(verify_jti: ->(jti) { false }))
         | 
| 139 | 
            +
                    end.to raise_error JWT::InvalidJtiError, /invalid/i
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                  it 'true proc should not raise JWT::InvalidJtiError' do
         | 
| 143 | 
            +
                    Verify.verify_jti(payload, options.merge(verify_jti: ->(jti) { true }))
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
                end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                context '.verify_not_before(payload, options)' do
         | 
| 148 | 
            +
                  let(:payload) { base_payload.merge('nbf' => (Time.now.to_i + 5)) }
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  it 'must raise JWT::ImmatureSignature when the nbf in the payload is in the future' do
         | 
| 151 | 
            +
                    expect do
         | 
| 152 | 
            +
                      Verify.verify_not_before(payload, options)
         | 
| 153 | 
            +
                    end.to raise_error JWT::ImmatureSignature
         | 
| 154 | 
            +
                  end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  it 'must allow some leeway in the token age when configured' do
         | 
| 157 | 
            +
                    Verify.verify_not_before(payload, options.merge(leeway: 10))
         | 
| 158 | 
            +
                  end
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                context '.verify_sub(payload, options)' do
         | 
| 162 | 
            +
                  let(:sub) { 'ruby jwt subject' }
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                  it 'must raise JWT::InvalidSubError when the subjects do not match' do
         | 
| 165 | 
            +
                    expect do
         | 
| 166 | 
            +
                      Verify.verify_sub(base_payload.merge('sub' => 'not-a-match'), options.merge(sub: sub))
         | 
| 167 | 
            +
                    end.to raise_error JWT::InvalidSubError
         | 
| 168 | 
            +
                  end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                  it 'must allow a matching sub' do
         | 
| 171 | 
            +
                    Verify.verify_sub(base_payload.merge('sub' => sub), options.merge(sub: sub))
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
              end
         | 
| 175 | 
            +
            end
         |