jwt-rack 0.0.0 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bef98cd84654986f72aac0d1b8fc9a64f762bd0e784e39929e15893a3868c586
4
- data.tar.gz: 8b70bf2c4dcd2ea7b92fed3c6121c834195eb9365a320acacbd7ff639ad20f2e
3
+ metadata.gz: 75d32bd64c673a5aac017606f4599fb69dbbff77ff1bd1e2ce24539d1394c4d5
4
+ data.tar.gz: 602cf6f50f172758e1be322196091e27ccfa1dadb7b50574b2e985e60013edee
5
5
  SHA512:
6
- metadata.gz: fe5702dd93cecb195a467a1f037c67a7d052ebabb67714d131ed118e34755b6c2155bec6b13853c4df8d0ad9c49a7c578efa2d2bc4de106b1919ee5e9a286eda
7
- data.tar.gz: 28ec9ecb2e24e958cee55899054589ff55a35dc7bb86f9e80cb322e958747157de2f37e60b249878c792e454100d4b7c6608c066b1c319a5c51cc03f200d7328
6
+ metadata.gz: f5b44a1728ec958adee9246e5e59c37e975683d4bb46c6147c610bd5d0083906c38dc7811182d574ce87b78e747c574c0a4a1582ed1a7e6fd66723168d77bce7
7
+ data.tar.gz: 65eca4b7d2f3ea28d6e2ad842ed1b71b48c7c8db5834ba675b9c29213da6b258488056e1b403976587f1466160c37411d9c68a41d2e7db9555f3f317d5938743
data/.gitignore CHANGED
@@ -7,5 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ Gemfile.lock
11
+
10
12
  # rspec failure tracking
11
13
  .rspec_status
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in jwt-rack.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  This gem provides JSON Web Token (JWT) based authentication.
10
10
 
11
+ #### TODO: Mention original gem [source](https://github.com/eparreno/rack-jwt)
12
+
11
13
  ## Requirements
12
14
 
13
15
  - Ruby 2.3.8 or greater
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "jwt/rack"
4
+ require 'bundler/setup'
5
+ require 'jwt/rack'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "jwt/rack"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,41 +1,44 @@
1
- lib = File.expand_path("lib", __dir__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "jwt/rack/version"
5
+ require 'jwt/rack/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "jwt-rack"
7
- spec.version = Jwt::Rack::VERSION
8
- spec.authors = ["Yaroslav Savchuk"]
9
- spec.email = ["savchukyarpolk@gmail.com"]
8
+ spec.name = 'jwt-rack'
9
+ spec.version = JWT::Rack::VERSION
10
+ spec.authors = ['Yaroslav Savchuk']
11
+ spec.email = ['savchukyarpolk@gmail.com']
10
12
 
11
- spec.summary = %q{Rack middleware that provides authentication based on JSON Web Tokens.}
12
- spec.description = %q{Rack middleware that provides authentication based on JSON Web Tokens.}
13
- spec.homepage = "https://github.com/ysv/jwt-rack"
14
- spec.license = "MIT"
13
+ spec.summary = 'Rack middleware that provides authentication based on JSON Web Tokens.'
14
+ spec.description = 'Rack middleware that provides authentication based on JSON Web Tokens.'
15
+ spec.homepage = 'https://github.com/ysv/jwt-rack'
16
+ spec.license = 'MIT'
15
17
 
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/ysv/jwt-rack"
18
- spec.metadata["changelog_uri"] = "https://github.com/ysv/jwt-rack/blob/master/CHANGELOG.md"
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/ysv/jwt-rack'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/ysv/jwt-rack/blob/master/CHANGELOG.md'
19
21
 
20
22
  # Specify which files should be added to the gem when it is released.
21
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
26
  end
25
- spec.bindir = "exe"
27
+ spec.bindir = 'exe'
26
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
29
+ spec.require_paths = ['lib']
28
30
 
29
31
  spec.platform = Gem::Platform::RUBY
30
32
  spec.required_ruby_version = '>= 2.3.8'
31
33
 
32
- spec.add_development_dependency 'bundler', '>= 1.16.2'
33
- spec.add_development_dependency 'rake', '>= 12.0.0'
34
+ spec.add_development_dependency 'bundler', '>= 1.16.2'
35
+ spec.add_development_dependency 'pry-byebug', '~> 3.7'
34
36
  spec.add_development_dependency 'rack-test', '>= 1.0.0'
37
+ spec.add_development_dependency 'rake', '>= 12.0.0'
38
+ spec.add_development_dependency 'rbnacl', '>= 6.0.1'
35
39
  spec.add_development_dependency 'rspec', '>= 3.8.0'
36
40
  spec.add_development_dependency 'simplecov', '>= 0.16.0'
37
- spec.add_development_dependency 'rbnacl', '>= 6.0.1'
38
41
 
42
+ spec.add_runtime_dependency 'jwt', '~> 2.1.0'
39
43
  spec.add_runtime_dependency 'rack'
40
- spec.add_runtime_dependency 'jwt', '~> 2.1.0'
41
44
  end
@@ -1,8 +1,10 @@
1
- require "jwt/rack/version"
1
+ # frozen_string_literal: true
2
2
 
3
- module Jwt
3
+ require 'jwt/rack/version'
4
+
5
+ module JWT
4
6
  module Rack
5
- class Error < StandardError; end
6
- # Your code goes here...
7
+ autoload :Auth, 'jwt/rack/auth'
8
+ autoload :Token, 'jwt/rack/token'
7
9
  end
8
10
  end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+
5
+ module JWT
6
+ module Rack
7
+ # Authentication middleware
8
+ class Auth
9
+ attr_reader :secret
10
+ attr_reader :verify
11
+ attr_reader :options
12
+ attr_reader :exclude
13
+
14
+ SUPPORTED_ALGORITHMS = [
15
+ 'none',
16
+ 'HS256',
17
+ 'HS384',
18
+ 'HS512',
19
+ 'RS256',
20
+ 'RS384',
21
+ 'RS512',
22
+ 'ES256',
23
+ 'ES384',
24
+ 'ES512',
25
+ ('ED25519' if defined?(RbNaCl))
26
+ ].compact.freeze
27
+
28
+ DEFAULT_ALGORITHM = 'HS256'
29
+
30
+ # The last segment gets dropped for 'none' algorithm since there is no
31
+ # signature so both of these patterns are valid. All character chunks
32
+ # are base64url format and periods.
33
+ # Bearer abc123.abc123.abc123
34
+ # Bearer abc123.abc123.
35
+ BEARER_TOKEN_REGEX = %r{
36
+ ^Bearer\s{1}( # starts with Bearer and a single space
37
+ [a-zA-Z0-9\-\_]+\. # 1 or more chars followed by a single period
38
+ [a-zA-Z0-9\-\_]+\. # 1 or more chars followed by a single period
39
+ [a-zA-Z0-9\-\_]* # 0 or more chars, no trailing chars
40
+ )$
41
+ }x.freeze
42
+
43
+ JWT_DECODE_ERRORS = [
44
+ ::JWT::DecodeError,
45
+ ::JWT::VerificationError,
46
+ ::JWT::ExpiredSignature,
47
+ ::JWT::IncorrectAlgorithm,
48
+ ::JWT::ImmatureSignature,
49
+ ::JWT::InvalidIssuerError,
50
+ ::JWT::InvalidIatError,
51
+ ::JWT::InvalidAudError,
52
+ ::JWT::InvalidSubError,
53
+ ::JWT::InvalidJtiError,
54
+ ::JWT::InvalidPayload
55
+ ].freeze
56
+
57
+ MissingAuthHeader = Class.new(StandardError)
58
+ InvalidAuthHeaderFormat = Class.new(StandardError)
59
+
60
+ ERRORS_TO_RESCUE = (JWT_DECODE_ERRORS + [MissingAuthHeader, InvalidAuthHeaderFormat]).freeze
61
+
62
+ # Initialization should fail fast with an ArgumentError
63
+ # if any args are invalid.
64
+ def initialize(app, opts = {})
65
+ @app = app
66
+ @secret = opts.fetch(:secret, nil)
67
+ @verify = opts.fetch(:verify, true)
68
+ @options = opts.fetch(:options, {})
69
+ @exclude = opts.fetch(:exclude, [])
70
+
71
+ @on_error = opts.fetch(:on_error, method(:default_on_error))
72
+
73
+ @secret = @secret.strip if @secret.is_a?(String)
74
+ @options[:algorithm] = DEFAULT_ALGORITHM if @options[:algorithm].nil?
75
+
76
+ check_secret_type!
77
+ check_secret!
78
+ check_secret_and_verify_for_none_alg!
79
+ check_verify_type!
80
+ check_options_type!
81
+ check_valid_algorithm!
82
+ check_exclude_type!
83
+ check_on_error_callable!
84
+ end
85
+
86
+ def call(env)
87
+ if path_matches_excluded_path?(env)
88
+ @app.call(env)
89
+ else
90
+ verify_token(env)
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def verify_token(env)
97
+ raise MissingAuthHeader if missing_auth_header?(env)
98
+ raise InvalidAuthHeaderFormat if invalid_auth_header?(env)
99
+
100
+ # extract the token from the Authorization: Bearer header
101
+ # with a regex capture group.
102
+ token = BEARER_TOKEN_REGEX.match(env['HTTP_AUTHORIZATION'])[1]
103
+
104
+ decoded_token = Token.decode(token, @secret, @verify, @options)
105
+ env['jwt.payload'] = decoded_token.first
106
+ env['jwt.header'] = decoded_token.last
107
+ @app.call(env)
108
+ rescue *ERRORS_TO_RESCUE => e
109
+ @on_error.call(e)
110
+ end
111
+
112
+ def check_secret_type!
113
+ unless Token.secret_of_valid_type?(@secret)
114
+ raise ArgumentError, 'secret argument must be a valid type'
115
+ end
116
+ end
117
+
118
+ def check_secret!
119
+ if @secret.nil? || (@secret.is_a?(String) && @secret.empty?)
120
+ unless @options[:algorithm] == 'none'
121
+ raise ArgumentError, 'secret argument can only be nil/empty for the "none" algorithm'
122
+ end
123
+ end
124
+ end
125
+
126
+ def check_secret_and_verify_for_none_alg!
127
+ if @options && @options[:algorithm] && @options[:algorithm] == 'none'
128
+ unless @secret.nil? && @verify.is_a?(FalseClass)
129
+ raise ArgumentError, 'when "none" the secret must be "nil" and verify "false"'
130
+ end
131
+ end
132
+ end
133
+
134
+ def check_verify_type!
135
+ unless verify.is_a?(TrueClass) || verify.is_a?(FalseClass)
136
+ raise ArgumentError, 'verify argument must be true or false'
137
+ end
138
+ end
139
+
140
+ def check_options_type!
141
+ raise ArgumentError, 'options argument must be a Hash' unless options.is_a?(Hash)
142
+ end
143
+
144
+ def check_valid_algorithm!
145
+ unless @options &&
146
+ @options[:algorithm] &&
147
+ SUPPORTED_ALGORITHMS.include?(@options[:algorithm])
148
+ raise ArgumentError, 'algorithm argument must be a supported type'
149
+ end
150
+ end
151
+
152
+ def check_exclude_type!
153
+ raise ArgumentError, 'exclude argument must be an Array' unless @exclude.is_a?(Array)
154
+
155
+ @exclude.each do |x|
156
+ raise ArgumentError, 'each exclude Array element must be a String' unless x.is_a?(String)
157
+
158
+ raise ArgumentError, 'each exclude Array element must not be empty' if x.empty?
159
+
160
+ unless x.start_with?('/')
161
+ raise ArgumentError, 'each exclude Array element must start with a /'
162
+ end
163
+ end
164
+ end
165
+
166
+ def check_on_error_callable!
167
+ unless @on_error.respond_to?(:call)
168
+ raise ArgumentError, 'on_error argument must respond to call'
169
+ end
170
+ end
171
+
172
+ def path_matches_excluded_path?(env)
173
+ @exclude.any? { |ex| env['PATH_INFO'].start_with?(ex) }
174
+ end
175
+
176
+ def valid_auth_header?(env)
177
+ env['HTTP_AUTHORIZATION'] =~ BEARER_TOKEN_REGEX
178
+ end
179
+
180
+ def invalid_auth_header?(env)
181
+ !valid_auth_header?(env)
182
+ end
183
+
184
+ def missing_auth_header?(env)
185
+ env['HTTP_AUTHORIZATION'].nil? || env['HTTP_AUTHORIZATION'].strip.empty?
186
+ end
187
+
188
+ def default_on_error(error)
189
+ error_message = {
190
+ ::JWT::DecodeError => 'Invalid JWT token : Decode Error',
191
+ ::JWT::VerificationError => 'Invalid JWT token : Signature Verification Error',
192
+ ::JWT::ExpiredSignature => 'Invalid JWT token : Expired Signature (exp)',
193
+ ::JWT::IncorrectAlgorithm => 'Invalid JWT token : Incorrect Key Algorithm',
194
+ ::JWT::ImmatureSignature => 'Invalid JWT token : Immature Signature (nbf)',
195
+ ::JWT::InvalidIssuerError => 'Invalid JWT token : Invalid Issuer (iss)',
196
+ ::JWT::InvalidIatError => 'Invalid JWT token : Invalid Issued At (iat)',
197
+ ::JWT::InvalidAudError => 'Invalid JWT token : Invalid Audience (aud)',
198
+ ::JWT::InvalidSubError => 'Invalid JWT token : Invalid Subject (sub)',
199
+ ::JWT::InvalidJtiError => 'Invalid JWT token : Invalid JWT ID (jti)',
200
+ ::JWT::InvalidPayload => 'Invalid JWT token : Invalid Payload',
201
+ MissingAuthHeader => 'Missing Authorization header',
202
+ InvalidAuthHeaderFormat => 'Invalid Authorization header format'
203
+ }
204
+ message = error_message.fetch(error.class)
205
+ body = { error: message }.to_json
206
+ headers = { 'Content-Type' => 'application/json', 'Content-Length' => body.bytesize.to_s }
207
+
208
+ [401, headers, [body]]
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
4
+ module Rack
5
+ # Token encoding and decoding
6
+ class Token
7
+ # abc123.abc123.abc123 (w/ signature)
8
+ # abc123.abc123. ('none')
9
+ TOKEN_REGEX = /\A([a-zA-Z0-9\-\_\~\+\\]+\.[a-zA-Z0-9\-\_\~\+\\]+\.[a-zA-Z0-9\-\_\~\+\\]*)\z/.freeze
10
+ DEFAULT_HEADERS = { typ: 'JWT' }.freeze
11
+
12
+ def self.encode(payload, secret, alg = 'HS256')
13
+ raise 'Invalid payload. Must be a Hash.' unless payload.is_a?(Hash)
14
+ raise 'Invalid secret type.' unless secret_of_valid_type?(secret)
15
+ raise 'Unsupported algorithm' unless algorithm_supported?(alg)
16
+
17
+ # if using an unsigned token ('none' alg) you *must* set the `secret`
18
+ # to `nil` in which case any user provided `secret` will be ignored.
19
+ if alg == 'none'
20
+ ::JWT.encode(payload, nil, alg, DEFAULT_HEADERS)
21
+ else
22
+ ::JWT.encode(payload, secret, alg, DEFAULT_HEADERS)
23
+ end
24
+ end
25
+
26
+ def self.decode(token, secret, verify, options = {})
27
+ raise 'Invalid token format.' unless valid_token_format?(token)
28
+ raise 'Invalid secret type.' unless secret_of_valid_type?(secret)
29
+ raise 'Unsupported verify value.' unless verify_of_valid_type?(verify)
30
+
31
+ options[:algorithm] = 'HS256' if options[:algorithm].nil?
32
+ raise 'Unsupported algorithm' unless algorithm_supported?(options[:algorithm])
33
+
34
+ # If using an unsigned 'none' algorithm token you *must* set the
35
+ # `secret` to `nil` and `verify` to `false` or it won't work per
36
+ # the ruby-jwt docs. Using 'none' is probably not recommended.
37
+ if options[:algorithm] == 'none'
38
+ ::JWT.decode(token, nil, false, options)
39
+ else
40
+ ::JWT.decode(token, secret, verify, options)
41
+ end
42
+ end
43
+
44
+ def self.secret_of_valid_type?(secret)
45
+ secret.nil? ||
46
+ secret.is_a?(String) ||
47
+ secret.is_a?(OpenSSL::PKey::RSA) ||
48
+ secret.is_a?(OpenSSL::PKey::EC) ||
49
+ (defined?(RbNaCl) && secret.is_a?(RbNaCl::Signatures::Ed25519::SigningKey)) ||
50
+ (defined?(RbNaCl) && secret.is_a?(RbNaCl::Signatures::Ed25519::VerifyKey))
51
+ end
52
+
53
+ # Private Utility Class Methods
54
+ # See : https://gist.github.com/Integralist/bb8760d11a03c88da151
55
+
56
+ def self.valid_token_format?(token)
57
+ token =~ TOKEN_REGEX
58
+ end
59
+ private_class_method :valid_token_format?
60
+
61
+ def self.algorithm_supported?(alg)
62
+ JWT::Rack::Auth::SUPPORTED_ALGORITHMS.include?(alg)
63
+ end
64
+ private_class_method :algorithm_supported?
65
+
66
+ def self.verify_of_valid_type?(verify)
67
+ verify.nil? || verify.is_a?(FalseClass) || verify.is_a?(TrueClass)
68
+ end
69
+ private_class_method :verify_of_valid_type?
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,7 @@
1
- module Jwt
1
+ # frozen_string_literal: true
2
+
3
+ module JWT
2
4
  module Rack
3
- VERSION = "0.0.0"
5
+ VERSION = '0.1.0'
4
6
  end
5
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt-rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Savchuk
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.16.2
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: pry-byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 12.0.0
33
+ version: '3.7'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 12.0.0
40
+ version: '3.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack-test
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,61 +53,61 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.0.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: rspec
56
+ name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 3.8.0
61
+ version: 12.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 3.8.0
68
+ version: 12.0.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: simplecov
70
+ name: rbnacl
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 0.16.0
75
+ version: 6.0.1
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 0.16.0
82
+ version: 6.0.1
83
83
  - !ruby/object:Gem::Dependency
84
- name: rbnacl
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 6.0.1
89
+ version: 3.8.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 6.0.1
96
+ version: 3.8.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: rack
98
+ name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :runtime
103
+ version: 0.16.0
104
+ type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: 0.16.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: jwt
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: 2.1.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rack
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: Rack middleware that provides authentication based on JSON Web Tokens.
126
140
  email:
127
141
  - savchukyarpolk@gmail.com
@@ -141,6 +155,8 @@ files:
141
155
  - bin/setup
142
156
  - jwt-rack.gemspec
143
157
  - lib/jwt/rack.rb
158
+ - lib/jwt/rack/auth.rb
159
+ - lib/jwt/rack/token.rb
144
160
  - lib/jwt/rack/version.rb
145
161
  homepage: https://github.com/ysv/jwt-rack
146
162
  licenses:
@@ -164,7 +180,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
180
  - !ruby/object:Gem::Version
165
181
  version: '0'
166
182
  requirements: []
167
- rubygems_version: 3.0.3
183
+ rubyforge_project:
184
+ rubygems_version: 2.7.8
168
185
  signing_key:
169
186
  specification_version: 4
170
187
  summary: Rack middleware that provides authentication based on JSON Web Tokens.