jwt_signed_request 2.5.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +95 -19
- data/lib/jwt_signed_request.rb +10 -10
- data/lib/jwt_signed_request/key_store.rb +18 -10
- data/lib/jwt_signed_request/middlewares/faraday.rb +12 -14
- data/lib/jwt_signed_request/middlewares/rack.rb +21 -22
- data/lib/jwt_signed_request/sign.rb +21 -7
- data/lib/jwt_signed_request/verify.rb +11 -6
- data/lib/jwt_signed_request/version.rb +1 -1
- metadata +23 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a232713f444aa93fe62190f100a0ee0b74550c5f8426095c131b79ec035c1260
|
4
|
+
data.tar.gz: df9755b248452d267d2a0631ea16af0d81476a501dde8367b980fe53e6b9c210
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e8ca9735e699cb864d1a73869d8b09cfda8e8decebae2b7343bd2168f1f4fe2baed43c02ee52e7d76c761de3af66aacdf69667805a097d14ae04f4896db238a
|
7
|
+
data.tar.gz: ffb84c36f824f1e8d4ad22718136fa4350ea56a28e842c098f7038abd9c31e3c3b1e168f0546ed281018cd54c91abfbd24add657cf2f705ba230db87f89ab17c
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ $ bundle
|
|
19
19
|
|
20
20
|
## Generating EC Keys
|
21
21
|
|
22
|
-
We should be using a public key encryption
|
22
|
+
We should be using a public key encryption algorithm such as **ES256**. To generate your public/private key pair using **ES256** run:
|
23
23
|
|
24
24
|
```sh
|
25
25
|
$ openssl ecparam -genkey -name prime256v1 -noout -out myprivatekey.pem
|
@@ -30,24 +30,32 @@ Store and encrypt these in your application secrets.
|
|
30
30
|
|
31
31
|
## Configuration
|
32
32
|
|
33
|
-
You can add signing and verification keys to
|
33
|
+
You can add signing and verification keys to one or more key stores as your application needs them.
|
34
|
+
|
35
|
+
For example, given the following keys:
|
34
36
|
|
35
37
|
```ruby
|
36
|
-
private_key = <<-
|
38
|
+
private_key = <<-PEM.gsub(/^\s+/, "")
|
37
39
|
-----BEGIN EC PRIVATE KEY-----
|
38
40
|
MHcCAQEEIBOQ3YIILYMV1glTKbF9oeZWzHe3SNQjAx4IbPIxNygQoAoGCCqGSM49
|
39
41
|
AwEHoUQDQgAEuOC3ufTTnW0hVmCPNERb4LxaDE/OexDdlmXEjHYaixzYIduluGXd
|
40
42
|
3cjg4H2gjqsY/NCpJ9nM8/AAINSrq+qPuA==
|
41
43
|
-----END EC PRIVATE KEY-----
|
42
|
-
|
44
|
+
PEM
|
43
45
|
|
44
|
-
public_key = <<-
|
46
|
+
public_key = <<-PEM.gsub(/^\s+/, "")
|
45
47
|
-----BEGIN PUBLIC KEY-----
|
46
48
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuOC3ufTTnW0hVmCPNERb4LxaDE/O
|
47
49
|
exDdlmXEjHYaixzYIduluGXd3cjg4H2gjqsY/NCpJ9nM8/AAINSrq+qPuA==
|
48
50
|
-----END PUBLIC KEY-----
|
49
|
-
|
51
|
+
PEM
|
52
|
+
```
|
53
|
+
|
54
|
+
### Single key store
|
50
55
|
|
56
|
+
If your application only needs a single key store, configure it like so:
|
57
|
+
|
58
|
+
```ruby
|
51
59
|
require 'openssl'
|
52
60
|
|
53
61
|
JWTSignedRequest.configure_keys do |config|
|
@@ -65,9 +73,35 @@ JWTSignedRequest.configure_keys do |config|
|
|
65
73
|
end
|
66
74
|
```
|
67
75
|
|
76
|
+
### Multiple key stores
|
77
|
+
|
78
|
+
If your application requires multiple key stores, configure them like so:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
key_store_id = 'widget_admin'
|
82
|
+
|
83
|
+
JWTSignedRequest.configure_keys(key_store_id) do |config|
|
84
|
+
config.add_signing_key(
|
85
|
+
key_id: 'client_a',
|
86
|
+
key: OpenSSL::PKey::EC.new(private_key),
|
87
|
+
algorithm: 'ES256',
|
88
|
+
)
|
89
|
+
|
90
|
+
config.add_verification_key(
|
91
|
+
key_id: 'client_a',
|
92
|
+
key: OpenSSL::PKey::EC.new(public_key),
|
93
|
+
algorithm: 'ES256',
|
94
|
+
)
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
68
98
|
## Signing Requests
|
69
99
|
|
70
|
-
If you have added your signing keys to
|
100
|
+
If you have added your signing keys to a key store, you will only need to
|
101
|
+
specify the `key_id` you are signing the requests with.
|
102
|
+
|
103
|
+
If you are using multiple key stores, you will also need to pass the
|
104
|
+
appropriate `key_store_id`.
|
71
105
|
|
72
106
|
### Using net/http
|
73
107
|
|
@@ -86,6 +120,7 @@ jwt_token = JWTSignedRequest.sign(
|
|
86
120
|
body: "",
|
87
121
|
key_id: 'my-key-id', # used for looking up key and kid header
|
88
122
|
lookup_key_id: 'my-alt-key-id', # optionally override lookup key
|
123
|
+
key_store_id: 'widget_admin', # optionally specify named key store ID
|
89
124
|
issuer: 'my-issuer' # optional
|
90
125
|
additional_headers_to_sign: ['X-AUTH'] # optional
|
91
126
|
)
|
@@ -97,7 +132,7 @@ res = Net::HTTP.start(uri.hostname, uri.port) {|http|
|
|
97
132
|
}
|
98
133
|
```
|
99
134
|
|
100
|
-
### Using
|
135
|
+
### Using Faraday
|
101
136
|
|
102
137
|
```ruby
|
103
138
|
require 'faraday'
|
@@ -105,11 +140,14 @@ require 'openssl'
|
|
105
140
|
require 'jwt_signed_request/middlewares/faraday'
|
106
141
|
|
107
142
|
conn = Faraday.new(url: URI.parse('http://example.com')) do |faraday|
|
108
|
-
faraday.use
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
143
|
+
faraday.use(
|
144
|
+
JWTSignedRequest::Middlewares::Faraday,
|
145
|
+
key_id: 'my-key-id',
|
146
|
+
key_store_id: 'my-key-store-id', # optional
|
147
|
+
issuer: 'my-issuer', # optional
|
148
|
+
additional_headers_to_sign: ['X-AUTH'], # optional
|
149
|
+
bearer_schema: true, # optional
|
150
|
+
)
|
113
151
|
|
114
152
|
faraday.adapter Faraday.default_adapter
|
115
153
|
end
|
@@ -134,8 +172,9 @@ Determines whether to use the [Bearer schema](https://auth0.com/docs/jwt#how-do-
|
|
134
172
|
|
135
173
|
## Verifying Requests
|
136
174
|
|
137
|
-
Please make sure you have added your verification keys to the key
|
138
|
-
|
175
|
+
Please make sure you have added your verification keys to the appropriate key
|
176
|
+
store. Doing so will allow the server to verify requests signed by different
|
177
|
+
signing keys.
|
139
178
|
|
140
179
|
## Using Rails
|
141
180
|
|
@@ -149,7 +188,11 @@ class APIController < ApplicationController
|
|
149
188
|
|
150
189
|
def verify_request
|
151
190
|
begin
|
152
|
-
JWTSignedRequest.verify(
|
191
|
+
JWTSignedRequest.verify(
|
192
|
+
request: request,
|
193
|
+
# Use optional `key_store_id` kwarg when working with multiple key stores, eg:
|
194
|
+
key_store_id: 'widget_admin',
|
195
|
+
)
|
153
196
|
|
154
197
|
rescue JWTSignedRequest::UnauthorizedRequestError => e
|
155
198
|
render :json => {}, :status => :unauthorized
|
@@ -171,9 +214,12 @@ JWT tokens contain an expiry timestamp. If communication delays are large (or sy
|
|
171
214
|
|
172
215
|
```ruby
|
173
216
|
class Server < Sinatra::Base
|
174
|
-
use
|
175
|
-
|
176
|
-
|
217
|
+
use(
|
218
|
+
JWTSignedRequest::Middlewares::Rack,
|
219
|
+
exclude_paths: /public|health/, # optional regex
|
220
|
+
leeway: 100, # optional
|
221
|
+
key_store_id: 'my-key-store-id', # optional
|
222
|
+
)
|
177
223
|
end
|
178
224
|
```
|
179
225
|
|
@@ -223,3 +269,33 @@ For bug fixes, documentation changes, and small features:
|
|
223
269
|
5. Create a new Pull Request
|
224
270
|
|
225
271
|
For larger new features: Do everything as above, but first also make contact with the project maintainers to be sure your change fits with the project direction and you won't be wasting effort going in the wrong direction
|
272
|
+
|
273
|
+
### Compatibility
|
274
|
+
|
275
|
+
Compatibility with multiple versions of the [JWT gem] is tested via the [appraisal gem].
|
276
|
+
|
277
|
+
Configured versions are defined in [Appraisals](./Appraisals), which at time of writing looked like this:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
# Latest JWT minor versions
|
281
|
+
# Source: https://rubygems.org/gems/jwt/versions
|
282
|
+
%w[
|
283
|
+
1.5.6
|
284
|
+
2.0.0
|
285
|
+
2.1.0
|
286
|
+
2.2.1
|
287
|
+
].each do |jwt_version|
|
288
|
+
```
|
289
|
+
|
290
|
+
Run the test suite like this:
|
291
|
+
|
292
|
+
```sh
|
293
|
+
# Test all configured versions
|
294
|
+
bundle exec appraisal rspec
|
295
|
+
|
296
|
+
# Target a specific configured version
|
297
|
+
bundle exec appraisal jwt-1.5.6 rspec
|
298
|
+
```
|
299
|
+
|
300
|
+
[JWT gem]: https://github.com/jwt/ruby-jwt
|
301
|
+
[appraisal gem]: https://github.com/thoughtbot/appraisal
|
data/lib/jwt_signed_request.rb
CHANGED
@@ -9,22 +9,22 @@ require 'jwt_signed_request/errors'
|
|
9
9
|
module JWTSignedRequest
|
10
10
|
extend self
|
11
11
|
|
12
|
-
DEFAULT_ALGORITHM = 'ES256'
|
13
|
-
EMPTY_BODY =
|
12
|
+
DEFAULT_ALGORITHM = 'ES256'
|
13
|
+
EMPTY_BODY = ''
|
14
14
|
|
15
|
-
def configure_keys
|
16
|
-
yield(
|
15
|
+
def configure_keys(key_store_id = nil)
|
16
|
+
yield KeyStore.find(key_store_id)
|
17
17
|
end
|
18
18
|
|
19
|
-
def key_store
|
20
|
-
|
19
|
+
def key_store(id = nil)
|
20
|
+
KeyStore.find(id)
|
21
21
|
end
|
22
22
|
|
23
|
-
def sign(
|
24
|
-
Sign.call(
|
23
|
+
def sign(**args)
|
24
|
+
Sign.call(**args)
|
25
25
|
end
|
26
26
|
|
27
|
-
def verify(
|
28
|
-
Verify.call(
|
27
|
+
def verify(**args)
|
28
|
+
Verify.call(**args)
|
29
29
|
end
|
30
30
|
end
|
@@ -2,25 +2,33 @@
|
|
2
2
|
|
3
3
|
module JWTSignedRequest
|
4
4
|
class KeyStore
|
5
|
+
def self.find(id)
|
6
|
+
all[id]
|
7
|
+
end
|
8
|
+
|
9
|
+
private_class_method def self.all
|
10
|
+
@all ||= Hash.new { |result, key| result[key] = KeyStore.new }
|
11
|
+
end
|
12
|
+
|
5
13
|
def initialize
|
6
14
|
@signing_keys = {}
|
7
15
|
@verification_keys = {}
|
8
16
|
end
|
9
17
|
|
10
18
|
def add_signing_key(key_id:, key:, algorithm:)
|
11
|
-
@signing_keys.store(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
19
|
+
@signing_keys.store(
|
20
|
+
key_id,
|
21
|
+
key: key,
|
22
|
+
algorithm: algorithm,
|
23
|
+
)
|
16
24
|
end
|
17
25
|
|
18
26
|
def add_verification_key(key_id:, key:, algorithm:)
|
19
|
-
@verification_keys.store(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
27
|
+
@verification_keys.store(
|
28
|
+
key_id,
|
29
|
+
key: key,
|
30
|
+
algorithm: algorithm,
|
31
|
+
)
|
24
32
|
end
|
25
33
|
|
26
34
|
def get_signing_key(key_id:)
|
@@ -6,18 +6,22 @@ require 'jwt_signed_request'
|
|
6
6
|
module JWTSignedRequest
|
7
7
|
module Middlewares
|
8
8
|
class Faraday < Faraday::Middleware
|
9
|
-
def initialize(app, options)
|
9
|
+
def initialize(app, bearer_schema: nil, **options)
|
10
|
+
@bearer_schema = bearer_schema
|
10
11
|
@options = options
|
11
|
-
|
12
|
+
|
13
|
+
initializer_args_requires_options? ? super(app, options) : super(app)
|
12
14
|
end
|
13
15
|
|
14
16
|
def call(env)
|
17
|
+
env[:body] ||= ::JWTSignedRequest::EMPTY_BODY
|
18
|
+
|
15
19
|
@jwt_token = ::JWTSignedRequest.sign(
|
16
20
|
method: env[:method],
|
17
21
|
path: env[:url].request_uri,
|
18
22
|
headers: env[:request_headers],
|
19
|
-
body: env
|
20
|
-
**
|
23
|
+
body: env[:body],
|
24
|
+
**options,
|
21
25
|
)
|
22
26
|
|
23
27
|
env[:request_headers].store("Authorization", authorization_header)
|
@@ -27,24 +31,18 @@ module JWTSignedRequest
|
|
27
31
|
|
28
32
|
private
|
29
33
|
|
30
|
-
attr_reader :app, :env, :options, :jwt_token
|
34
|
+
attr_reader :app, :env, :bearer_schema, :options, :jwt_token
|
31
35
|
|
32
36
|
def authorization_header
|
33
37
|
bearer_schema? ? "Bearer #{jwt_token}" : jwt_token
|
34
38
|
end
|
35
39
|
|
36
40
|
def bearer_schema?
|
37
|
-
|
41
|
+
bearer_schema == true
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
41
|
-
|
42
|
-
secret_key: options[:secret_key],
|
43
|
-
algorithm: options[:algorithm],
|
44
|
-
additional_headers_to_sign: options[:additional_headers_to_sign],
|
45
|
-
key_id: options[:key_id],
|
46
|
-
issuer: options[:issuer],
|
47
|
-
}.reject { |_, value| value.nil? }
|
44
|
+
def initializer_args_requires_options?
|
45
|
+
Gem::Version.new(::Faraday::VERSION) >= Gem::Version.new('1.2.0')
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -8,41 +8,40 @@ module JWTSignedRequest
|
|
8
8
|
class Rack
|
9
9
|
UNAUTHORIZED_STATUS_CODE = 401
|
10
10
|
|
11
|
-
def initialize(app,
|
11
|
+
def initialize(app, secret_key: nil, algorithm: nil, leeway: nil, exclude_paths: nil, key_store_id: nil)
|
12
12
|
@app = app
|
13
|
-
@secret_key =
|
14
|
-
@algorithm =
|
15
|
-
@leeway =
|
16
|
-
@exclude_paths =
|
13
|
+
@secret_key = secret_key
|
14
|
+
@algorithm = algorithm
|
15
|
+
@leeway = leeway
|
16
|
+
@exclude_paths = exclude_paths
|
17
|
+
@key_store_id = key_store_id
|
17
18
|
end
|
18
19
|
|
19
20
|
def call(env)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
secret_key: secret_key,
|
25
|
-
algorithm: algorithm,
|
26
|
-
leeway: leeway
|
27
|
-
}.reject { |_, value| value.nil? }
|
28
|
-
|
29
|
-
::JWTSignedRequest.verify(**args)
|
30
|
-
end
|
31
|
-
|
32
|
-
app.call(env)
|
33
|
-
rescue ::JWTSignedRequest::UnauthorizedRequestError => e
|
34
|
-
[UNAUTHORIZED_STATUS_CODE, {'Content-Type' => 'application/json'} , []]
|
35
|
-
end
|
21
|
+
::JWTSignedRequest.verify(**verification_args(env)) unless excluded_path?(env)
|
22
|
+
app.call(env)
|
23
|
+
rescue ::JWTSignedRequest::UnauthorizedRequestError
|
24
|
+
[UNAUTHORIZED_STATUS_CODE, {'Content-Type' => 'application/json'}, []]
|
36
25
|
end
|
37
26
|
|
38
27
|
private
|
39
28
|
|
40
|
-
attr_reader :app, :secret_key, :algorithm, :leeway, :exclude_paths
|
29
|
+
attr_reader :app, :secret_key, :algorithm, :leeway, :exclude_paths, :key_store_id
|
41
30
|
|
42
31
|
def excluded_path?(env)
|
43
32
|
!exclude_paths.nil? &&
|
44
33
|
env['PATH_INFO'].match(exclude_paths)
|
45
34
|
end
|
35
|
+
|
36
|
+
def verification_args(env)
|
37
|
+
{
|
38
|
+
request: ::Rack::Request.new(env),
|
39
|
+
secret_key: secret_key,
|
40
|
+
algorithm: algorithm,
|
41
|
+
leeway: leeway,
|
42
|
+
key_store_id: key_store_id,
|
43
|
+
}
|
44
|
+
end
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
@@ -4,8 +4,8 @@ require 'jwt_signed_request/claims'
|
|
4
4
|
|
5
5
|
module JWTSignedRequest
|
6
6
|
class Sign
|
7
|
-
def self.call(
|
8
|
-
new(
|
7
|
+
def self.call(**args)
|
8
|
+
new(**args).call
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(
|
@@ -18,7 +18,8 @@ module JWTSignedRequest
|
|
18
18
|
key_id: nil,
|
19
19
|
lookup_key_id: key_id,
|
20
20
|
issuer: nil,
|
21
|
-
additional_headers_to_sign: nil
|
21
|
+
additional_headers_to_sign: nil,
|
22
|
+
key_store_id: nil
|
22
23
|
)
|
23
24
|
@method = method
|
24
25
|
@path = path
|
@@ -30,6 +31,7 @@ module JWTSignedRequest
|
|
30
31
|
@lookup_key_id = lookup_key_id
|
31
32
|
@issuer = issuer
|
32
33
|
@additional_headers_to_sign = additional_headers_to_sign
|
34
|
+
@key_store_id = key_store_id
|
33
35
|
end
|
34
36
|
|
35
37
|
def call
|
@@ -38,12 +40,24 @@ module JWTSignedRequest
|
|
38
40
|
|
39
41
|
private
|
40
42
|
|
41
|
-
attr_reader
|
42
|
-
:method,
|
43
|
-
:
|
43
|
+
attr_reader(
|
44
|
+
:method,
|
45
|
+
:path,
|
46
|
+
:body,
|
47
|
+
:headers,
|
48
|
+
:key_id,
|
49
|
+
:lookup_key_id,
|
50
|
+
:issuer,
|
51
|
+
:additional_headers_to_sign,
|
52
|
+
:key_store_id,
|
53
|
+
)
|
44
54
|
|
45
55
|
def stored_key
|
46
|
-
@stored_key ||=
|
56
|
+
@stored_key ||= key_store.get_signing_key(key_id: lookup_key_id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def key_store
|
60
|
+
KeyStore.find(key_store_id)
|
47
61
|
end
|
48
62
|
|
49
63
|
def secret_key
|
@@ -6,17 +6,18 @@ require 'jwt/version'
|
|
6
6
|
|
7
7
|
module JWTSignedRequest
|
8
8
|
class Verify
|
9
|
-
def self.call(
|
10
|
-
new(
|
9
|
+
def self.call(**args)
|
10
|
+
new(**args).call
|
11
11
|
end
|
12
12
|
|
13
13
|
# TODO: secret_key & algorithm is deprecated and will be removed in future.
|
14
|
-
# For now we will support its
|
15
|
-
def initialize(request:, secret_key: nil, algorithm: nil, leeway: nil)
|
14
|
+
# For now we will support its functionality
|
15
|
+
def initialize(request:, secret_key: nil, algorithm: nil, leeway: nil, key_store_id: nil)
|
16
16
|
@request = request
|
17
17
|
@secret_key = secret_key
|
18
18
|
@algorithm = algorithm
|
19
19
|
@leeway = leeway
|
20
|
+
@key_store_id = key_store_id
|
20
21
|
end
|
21
22
|
|
22
23
|
def call
|
@@ -29,19 +30,23 @@ module JWTSignedRequest
|
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
attr_reader :request, :leeway
|
33
|
+
attr_reader :request, :leeway, :key_store_id
|
33
34
|
|
34
35
|
def stored_key
|
35
36
|
_body, jwt_header = ::JWT.decode(jwt_token, nil, false)
|
36
37
|
key_id = jwt_header.fetch('kid') { raise MissingKeyIdError }
|
37
38
|
signed_algorithm = jwt_header.fetch('alg')
|
38
|
-
|
39
|
+
key_store.get_verification_key(key_id: key_id).tap do |key|
|
39
40
|
if signed_algorithm != key[:algorithm]
|
40
41
|
raise AlgorithmMismatchError
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
46
|
+
def key_store
|
47
|
+
KeyStore.find(key_store_id)
|
48
|
+
end
|
49
|
+
|
45
50
|
def algorithm
|
46
51
|
@algorithm ||= stored_key.fetch(:algorithm) { raise MissingAlgorithmError }
|
47
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_signed_request
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Envato
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.5.0
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 2.2.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +24,6 @@ dependencies:
|
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.5.0
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 2.2.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: rack
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,7 +39,7 @@ dependencies:
|
|
45
39
|
- !ruby/object:Gem::Version
|
46
40
|
version: '0'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
42
|
+
name: appraisal
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
50
44
|
requirements:
|
51
45
|
- - ">="
|
@@ -59,7 +53,21 @@ dependencies:
|
|
59
53
|
- !ruby/object:Gem::Version
|
60
54
|
version: '0'
|
61
55
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack-test
|
63
71
|
requirement: !ruby/object:Gem::Requirement
|
64
72
|
requirements:
|
65
73
|
- - ">="
|
@@ -73,7 +81,7 @@ dependencies:
|
|
73
81
|
- !ruby/object:Gem::Version
|
74
82
|
version: '0'
|
75
83
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
84
|
+
name: rake
|
77
85
|
requirement: !ruby/object:Gem::Requirement
|
78
86
|
requirements:
|
79
87
|
- - ">="
|
@@ -138,7 +146,7 @@ metadata:
|
|
138
146
|
bug_tracker_uri: https://github.com/envato/jwt_signed_request/issues
|
139
147
|
changelog_uri: https://github.com/envato/jwt_signed_request/blob/master/CHANGELOG.md
|
140
148
|
source_code_uri: https://github.com/envato/jwt_signed_request
|
141
|
-
post_install_message:
|
149
|
+
post_install_message:
|
142
150
|
rdoc_options: []
|
143
151
|
require_paths:
|
144
152
|
- lib
|
@@ -153,9 +161,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
161
|
- !ruby/object:Gem::Version
|
154
162
|
version: '0'
|
155
163
|
requirements: []
|
156
|
-
|
157
|
-
|
158
|
-
signing_key:
|
164
|
+
rubygems_version: 3.1.2
|
165
|
+
signing_key:
|
159
166
|
specification_version: 4
|
160
167
|
summary: JWT request signing and verification for Internal APIs
|
161
168
|
test_files: []
|