jwt_keeper 3.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +12 -5
- data/Gemfile +2 -0
- data/README.md +3 -1
- data/Rakefile +2 -0
- data/jwt_keeper.gemspec +6 -6
- data/lib/generators/templates/jwt_keeper.rb +5 -0
- data/lib/jwt_keeper.rb +0 -2
- data/lib/jwt_keeper/controller.rb +3 -3
- data/lib/jwt_keeper/datastore.rb +18 -2
- data/lib/jwt_keeper/token.rb +30 -17
- data/lib/jwt_keeper/version.rb +1 -1
- data/spec/lib/jwt_keeper/controller_spec.rb +2 -1
- data/spec/lib/jwt_keeper/token_spec.rb +43 -7
- data/spec/spec_helper.rb +2 -6
- metadata +32 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0781e4deae7439d13aadad57e1c3fa6dd224cd791c90672ee647815af2ebf70a'
|
4
|
+
data.tar.gz: 9be046da200f6d6f6e17c2f747c398e7b5abe13e1fe1517a7b288d9dec468ea8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a58d6573eb512abce406c8726a15eebac3136d5c05b5305c9b5cd8d040f2facd6c050071d86a8bb885523485ea6217b2596f6bc14771d0e5d0c878278b0bdd66
|
7
|
+
data.tar.gz: 6a1086f9933a1daf4fc48e2ea7af4c2fe8c7b26c248a84f096cde00e9e2af3302258a894cdcb88211a281756a2b847713d6a6bd87233b66d1ca10fe64b3b6459
|
data/.travis.yml
CHANGED
@@ -1,19 +1,26 @@
|
|
1
1
|
language: ruby
|
2
2
|
cache: bundler
|
3
3
|
rvm:
|
4
|
-
- 2.
|
5
|
-
- 2.3
|
4
|
+
- 2.4.5
|
5
|
+
- 2.5.3
|
6
|
+
- 2.6.1
|
6
7
|
- ruby-head
|
7
8
|
matrix:
|
8
9
|
allow_failures:
|
9
10
|
- rvm: ruby-head
|
10
|
-
addons:
|
11
|
-
code_climate:
|
12
|
-
repo_token: f69bb189f348c1d7992d8ed8690d0a2c9c885c1aac45e2f4d48732034592b37b
|
13
11
|
services:
|
14
12
|
- redis-server
|
15
13
|
env:
|
16
14
|
global:
|
17
15
|
- REDIS_URL=redis://localhost:6379
|
16
|
+
- CC_TEST_REPORTER_ID=f69bb189f348c1d7992d8ed8690d0a2c9c885c1aac45e2f4d48732034592b37b
|
17
|
+
before_script:
|
18
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
19
|
+
- chmod +x ./cc-test-reporter
|
20
|
+
- ./cc-test-reporter before-build
|
21
|
+
script:
|
22
|
+
- bundle exec rspec
|
23
|
+
after_script:
|
24
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
18
25
|
notifications:
|
19
26
|
email: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -32,11 +32,13 @@ raw_token_string = token.to_jwt
|
|
32
32
|
The designed rails token flow is to receive and respond to requests with the token being present in the `Authorization` part of the header. This is to allow us to seamlessly rotate the tokens on the fly without having to rebuff the request as part of the user flow. Automatic rotation happens as part of the `require_authentication` action, meaning that you will always get the latest token data as created by `generate_claims` in your controllers. This new token is added to the response with the `write_authentication_token` action.
|
33
33
|
|
34
34
|
```bash
|
35
|
-
|
35
|
+
rails generate jwt_keeper:install
|
36
36
|
```
|
37
37
|
|
38
38
|
```ruby
|
39
39
|
class ApplicationController < ActionController::Base
|
40
|
+
include JWTKeeper::Controller
|
41
|
+
|
40
42
|
before_action :require_authentication
|
41
43
|
|
42
44
|
def not_authenticated
|
data/Rakefile
CHANGED
data/jwt_keeper.gemspec
CHANGED
@@ -23,14 +23,14 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency 'yard'
|
24
24
|
spec.add_development_dependency 'rubocop'
|
25
25
|
spec.add_development_dependency 'dotenv'
|
26
|
+
spec.add_development_dependency 'pry'
|
26
27
|
|
27
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.8'
|
28
29
|
spec.add_development_dependency 'fuubar'
|
29
30
|
spec.add_development_dependency 'simplecov'
|
30
|
-
spec.add_development_dependency 'codeclimate-test-reporter'
|
31
31
|
|
32
|
-
spec.add_dependency 'redis'
|
33
|
-
spec.add_dependency 'rails'
|
34
|
-
spec.add_dependency 'activesupport'
|
35
|
-
spec.add_dependency 'jwt', '
|
32
|
+
spec.add_dependency 'redis'
|
33
|
+
spec.add_dependency 'rails'
|
34
|
+
spec.add_dependency 'activesupport'
|
35
|
+
spec.add_dependency 'jwt', '>= 1.5'
|
36
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
JWTKeeper.configure do |config|
|
2
4
|
# The time to expire for the tokens
|
3
5
|
# config.expiry = 1.hour
|
@@ -26,6 +28,9 @@ JWTKeeper.configure do |config|
|
|
26
28
|
|
27
29
|
# the location of redis config file
|
28
30
|
# config.redis_connection = Redis.new(connection_options)
|
31
|
+
# config.redis_connection = ConnectionPool.new(size: ENV.fetch('RAILS_MAX_THREADS', 5)) do
|
32
|
+
# Redis.new(url: ENV['REDISCLOUD_URL'] || 'redis://localhost:6379/')
|
33
|
+
# end
|
29
34
|
|
30
35
|
# A unique idenfitier for the token version.
|
31
36
|
# config.version = 1
|
data/lib/jwt_keeper.rb
CHANGED
@@ -29,7 +29,7 @@ module JWTKeeper
|
|
29
29
|
@authentication_token ||=
|
30
30
|
JWTKeeper::Token.find(
|
31
31
|
request.headers['Authorization'].split.last,
|
32
|
-
cookies.signed['jwt_keeper']
|
32
|
+
cookie_secret: defined?(cookies) && cookies.signed['jwt_keeper']
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
@@ -39,7 +39,7 @@ module JWTKeeper
|
|
39
39
|
def write_authentication_token(token)
|
40
40
|
return clear_authentication_token if token.nil?
|
41
41
|
response.headers['Authorization'] = "Bearer #{token.to_jwt}"
|
42
|
-
cookies.signed['jwt_keeper'] = token.to_cookie
|
42
|
+
defined?(cookies) && cookies.signed['jwt_keeper'] = token.to_cookie
|
43
43
|
@authentication_token = token
|
44
44
|
end
|
45
45
|
|
@@ -47,7 +47,7 @@ module JWTKeeper
|
|
47
47
|
# @return [void]
|
48
48
|
def clear_authentication_token
|
49
49
|
response.headers['Authorization'] = nil
|
50
|
-
cookies.delete('jwt_keeper')
|
50
|
+
defined?(cookies) && cookies.delete('jwt_keeper')
|
51
51
|
@authentication_token = nil
|
52
52
|
end
|
53
53
|
|
data/lib/jwt_keeper/datastore.rb
CHANGED
@@ -27,12 +27,28 @@ module JWTKeeper
|
|
27
27
|
|
28
28
|
# @!visibility private
|
29
29
|
def set_with_expiry(jti, seconds, type)
|
30
|
-
JWTKeeper.configuration.redis_connection
|
30
|
+
redis = JWTKeeper.configuration.redis_connection
|
31
|
+
|
32
|
+
if redis.is_a?(Redis)
|
33
|
+
redis.setex(jti, seconds, type)
|
34
|
+
elsif defined?(ConnectionPool) && redis.is_a?(ConnectionPool)
|
35
|
+
redis.with { |conn| conn.setex(jti, seconds, type) }
|
36
|
+
else
|
37
|
+
throw 'Bad Redis Connection'
|
38
|
+
end
|
31
39
|
end
|
32
40
|
|
33
41
|
# @!visibility private
|
34
42
|
def get(jti)
|
35
|
-
JWTKeeper.configuration.redis_connection
|
43
|
+
redis = JWTKeeper.configuration.redis_connection
|
44
|
+
|
45
|
+
if redis.is_a?(Redis)
|
46
|
+
redis.get(jti)
|
47
|
+
elsif defined?(ConnectionPool) && redis.is_a?(ConnectionPool)
|
48
|
+
redis.with { |conn| conn.get(jti) }
|
49
|
+
else
|
50
|
+
throw 'Bad Redis Connection'
|
51
|
+
end
|
36
52
|
end
|
37
53
|
end
|
38
54
|
end
|
data/lib/jwt_keeper/token.rb
CHANGED
@@ -2,40 +2,47 @@ module JWTKeeper
|
|
2
2
|
# This class acts as the main interface to wrap the concerns of JWTs. Handling everything from
|
3
3
|
# encoding to invalidation.
|
4
4
|
class Token
|
5
|
-
attr_accessor :claims, :cookie_secret
|
5
|
+
attr_accessor :claims, :secret, :cookie_secret
|
6
6
|
|
7
7
|
# Initalizes a new web token
|
8
|
-
# @param
|
9
|
-
# @param
|
8
|
+
# @param options [Hash] the custom claims to encode
|
9
|
+
# @param secret the secret to use during encoding, defaults to config
|
10
|
+
# @param cookie_secret the cookie secret to use during encoding
|
10
11
|
# @return [void]
|
11
|
-
def initialize(
|
12
|
-
@
|
12
|
+
def initialize(options = {})
|
13
|
+
@secret = options.delete(:secret) || JWTKeeper.configuration.secret
|
14
|
+
@cookie_secret = options.delete(:cookie_secret)
|
13
15
|
@claims = {
|
14
16
|
nbf: DateTime.now.to_i, # not before
|
15
17
|
iat: DateTime.now.to_i, # issued at
|
16
18
|
jti: SecureRandom.uuid # JWT ID
|
17
19
|
}
|
20
|
+
|
18
21
|
@claims.merge!(JWTKeeper.configuration.base_claims)
|
19
|
-
@claims.merge!(
|
22
|
+
@claims.merge!(options)
|
23
|
+
@claims[:exp] = @claims[:exp].to_i if @claims[:exp].is_a?(Time)
|
20
24
|
end
|
21
25
|
|
22
26
|
# Creates a new web token
|
23
|
-
# @param
|
27
|
+
# @param options [Hash] the custom claims to encode
|
28
|
+
# @param secret the secret to use during encoding, defaults to config
|
24
29
|
# @return [Token] token object
|
25
|
-
def self.create(
|
30
|
+
def self.create(options)
|
26
31
|
cookie_secret = SecureRandom.hex(16) if JWTKeeper.configuration.cookie_lock
|
27
|
-
new(
|
32
|
+
new(options.merge(cookie_secret: cookie_secret))
|
28
33
|
end
|
29
34
|
|
30
35
|
# Decodes and validates an existing token
|
31
36
|
# @param raw_token [String] the raw token
|
32
37
|
# @param cookie_secret [String] the cookie secret
|
33
38
|
# @return [Token] token object
|
34
|
-
def self.find(raw_token, cookie_secret
|
35
|
-
claims = decode(raw_token, cookie_secret)
|
39
|
+
def self.find(raw_token, secret: nil, cookie_secret: nil)
|
40
|
+
claims = decode(raw_token, secret: secret, cookie_secret: cookie_secret)
|
36
41
|
return nil if claims.nil?
|
37
42
|
|
38
|
-
new_token = new(
|
43
|
+
new_token = new(secret: secret, cookie_secret: cookie_secret)
|
44
|
+
new_token.claims = claims
|
45
|
+
|
39
46
|
return nil if new_token.revoked?
|
40
47
|
new_token
|
41
48
|
end
|
@@ -110,7 +117,11 @@ module JWTKeeper
|
|
110
117
|
# Checks if the token invalid?
|
111
118
|
# @return [Boolean]
|
112
119
|
def invalid?
|
113
|
-
self.class.decode(
|
120
|
+
self.class.decode(
|
121
|
+
encode,
|
122
|
+
secret: secret,
|
123
|
+
cookie_secret: cookie_secret
|
124
|
+
).nil? || revoked?
|
114
125
|
end
|
115
126
|
|
116
127
|
# Encodes the jwt
|
@@ -130,8 +141,10 @@ module JWTKeeper
|
|
130
141
|
end
|
131
142
|
|
132
143
|
# @!visibility private
|
133
|
-
def self.decode(raw_token, cookie_secret)
|
134
|
-
|
144
|
+
def self.decode(raw_token, secret: nil, cookie_secret: nil)
|
145
|
+
secret ||= JWTKeeper.configuration.secret
|
146
|
+
|
147
|
+
JWT.decode(raw_token, secret.to_s + cookie_secret.to_s, true,
|
135
148
|
algorithm: JWTKeeper.configuration.algorithm,
|
136
149
|
verify_iss: true,
|
137
150
|
verify_aud: true,
|
@@ -151,8 +164,8 @@ module JWTKeeper
|
|
151
164
|
|
152
165
|
# @!visibility private
|
153
166
|
def encode
|
154
|
-
JWT.encode(claims,
|
155
|
-
|
167
|
+
JWT.encode(claims.compact,
|
168
|
+
secret.to_s + cookie_secret.to_s,
|
156
169
|
JWTKeeper.configuration.algorithm
|
157
170
|
)
|
158
171
|
end
|
data/lib/jwt_keeper/version.rb
CHANGED
@@ -4,7 +4,8 @@ RSpec.describe JWTKeeper do
|
|
4
4
|
describe 'Controller' do
|
5
5
|
include_context 'initialize config'
|
6
6
|
|
7
|
-
let(:token) { JWTKeeper::Token.create(claim: "
|
7
|
+
let(:token) { JWTKeeper::Token.create(claim: "The Earth is Flat") }
|
8
|
+
|
8
9
|
subject(:test_controller) do
|
9
10
|
cookies_klass = Class.new(Hash) do
|
10
11
|
def signed
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module JWTKeeper
|
4
4
|
RSpec.describe Token do
|
5
5
|
include_context 'initialize config'
|
6
|
-
let(:private_claims) { { claim: "
|
6
|
+
let(:private_claims) { { claim: "The Earth is Flat" } }
|
7
7
|
let(:token) { described_class.create(private_claims) }
|
8
8
|
let(:raw_token) { token.to_jwt }
|
9
9
|
|
@@ -24,6 +24,15 @@ module JWTKeeper
|
|
24
24
|
it { is_expected.to be_instance_of described_class }
|
25
25
|
it { expect(subject.claims[:exp]).to eql private_claims[:exp] }
|
26
26
|
end
|
27
|
+
|
28
|
+
context 'when overriding default secret' do
|
29
|
+
subject { described_class.create(**private_claims, secret: secret) }
|
30
|
+
|
31
|
+
let(:secret) { SecureRandom.uuid }
|
32
|
+
|
33
|
+
it { is_expected.to be_instance_of described_class }
|
34
|
+
it { expect(subject.claims[:claim]).to eql private_claims[:claim] }
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
describe '.find' do
|
@@ -42,16 +51,33 @@ module JWTKeeper
|
|
42
51
|
it { is_expected.to be nil }
|
43
52
|
end
|
44
53
|
|
45
|
-
context 'with
|
46
|
-
|
47
|
-
|
54
|
+
context 'describe with cookie locking' do
|
55
|
+
before { JWTKeeper.configure(JWTKeeper::Configuration.new(config.merge(cookie_lock: true))) }
|
56
|
+
|
57
|
+
context 'with no cookie' do
|
58
|
+
subject { described_class.find(raw_token, cookie_secret: nil) }
|
59
|
+
it { is_expected.to be nil }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with bad cookie' do
|
63
|
+
subject { described_class.find(raw_token, cookie_secret: 'BAD_COOKIE') }
|
64
|
+
it { is_expected.to be nil }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with valid cookie' do
|
68
|
+
subject { described_class.find(raw_token, cookie_secret: token.cookie_secret) }
|
69
|
+
it { is_expected.to be_instance_of described_class }
|
70
|
+
end
|
48
71
|
end
|
49
72
|
|
50
|
-
context '
|
51
|
-
|
52
|
-
|
73
|
+
context 'when overriding default secret' do
|
74
|
+
subject { described_class.find(raw_token, secret: secret) }
|
75
|
+
|
76
|
+
let(:token) { described_class.create(**private_claims, secret: secret) }
|
77
|
+
let(:secret) { SecureRandom.uuid }
|
53
78
|
|
54
79
|
it { is_expected.to be_instance_of described_class }
|
80
|
+
it { expect(subject.claims[:claim]).to eql private_claims[:claim] }
|
55
81
|
end
|
56
82
|
end
|
57
83
|
|
@@ -187,6 +213,16 @@ module JWTKeeper
|
|
187
213
|
context 'when valid' do
|
188
214
|
it { is_expected.to be_valid }
|
189
215
|
end
|
216
|
+
|
217
|
+
context 'with overriden secret' do
|
218
|
+
subject { described_class.create(**private_claims, secret: secret) }
|
219
|
+
|
220
|
+
let(:secret) { SecureRandom.uuid }
|
221
|
+
|
222
|
+
context 'when valid' do
|
223
|
+
it { is_expected.to be_valid }
|
224
|
+
end
|
225
|
+
end
|
190
226
|
end
|
191
227
|
|
192
228
|
describe '#invalid?' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
+
require 'pry'
|
1
2
|
require 'dotenv'
|
2
3
|
Dotenv.load
|
3
4
|
|
4
5
|
require 'simplecov'
|
5
|
-
require 'codeclimate-test-reporter'
|
6
6
|
|
7
|
-
SimpleCov.formatter =
|
8
|
-
SimpleCov::Formatter::MultiFormatter.new([
|
9
|
-
SimpleCov::Formatter::HTMLFormatter,
|
10
|
-
CodeClimate::TestReporter::Formatter
|
11
|
-
])
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
12
8
|
SimpleCov.start do
|
13
9
|
add_filter '/spec/'
|
14
10
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_keeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Rivera
|
8
8
|
- Zane Wolfgang Pickett
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -82,35 +82,35 @@ dependencies:
|
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
85
|
+
name: pry
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
90
|
+
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
97
|
+
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
99
|
+
name: rspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '
|
104
|
+
version: '3.8'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
111
|
+
version: '3.8'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
|
-
name:
|
113
|
+
name: fuubar
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
116
|
- - ">="
|
@@ -124,7 +124,7 @@ dependencies:
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
127
|
+
name: simplecov
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
130
|
- - ">="
|
@@ -141,56 +141,56 @@ dependencies:
|
|
141
141
|
name: redis
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- - "
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version: '
|
146
|
+
version: '0'
|
147
147
|
type: :runtime
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- - "
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
|
-
version: '
|
153
|
+
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
155
|
name: rails
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
|
-
- - "
|
158
|
+
- - ">="
|
159
159
|
- !ruby/object:Gem::Version
|
160
|
-
version: '
|
160
|
+
version: '0'
|
161
161
|
type: :runtime
|
162
162
|
prerelease: false
|
163
163
|
version_requirements: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- - "
|
165
|
+
- - ">="
|
166
166
|
- !ruby/object:Gem::Version
|
167
|
-
version: '
|
167
|
+
version: '0'
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: activesupport
|
170
170
|
requirement: !ruby/object:Gem::Requirement
|
171
171
|
requirements:
|
172
|
-
- - "
|
172
|
+
- - ">="
|
173
173
|
- !ruby/object:Gem::Version
|
174
|
-
version: '
|
174
|
+
version: '0'
|
175
175
|
type: :runtime
|
176
176
|
prerelease: false
|
177
177
|
version_requirements: !ruby/object:Gem::Requirement
|
178
178
|
requirements:
|
179
|
-
- - "
|
179
|
+
- - ">="
|
180
180
|
- !ruby/object:Gem::Version
|
181
|
-
version: '
|
181
|
+
version: '0'
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
183
|
name: jwt
|
184
184
|
requirement: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
|
-
- - "
|
186
|
+
- - ">="
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '1.5'
|
189
189
|
type: :runtime
|
190
190
|
prerelease: false
|
191
191
|
version_requirements: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
|
-
- - "
|
193
|
+
- - ">="
|
194
194
|
- !ruby/object:Gem::Version
|
195
195
|
version: '1.5'
|
196
196
|
description: A managing interface layer for handling the creation and validation of
|
@@ -234,7 +234,7 @@ homepage: https://github.com/sirwolfgang/jwt_keeper
|
|
234
234
|
licenses:
|
235
235
|
- MIT
|
236
236
|
metadata: {}
|
237
|
-
post_install_message:
|
237
|
+
post_install_message:
|
238
238
|
rdoc_options: []
|
239
239
|
require_paths:
|
240
240
|
- lib
|
@@ -249,9 +249,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
249
|
- !ruby/object:Gem::Version
|
250
250
|
version: '0'
|
251
251
|
requirements: []
|
252
|
-
|
253
|
-
|
254
|
-
signing_key:
|
252
|
+
rubygems_version: 3.2.3
|
253
|
+
signing_key:
|
255
254
|
specification_version: 4
|
256
255
|
summary: JWT for Rails made easy
|
257
256
|
test_files:
|
@@ -261,4 +260,3 @@ test_files:
|
|
261
260
|
- spec/lib/jwt_keeper/token_spec.rb
|
262
261
|
- spec/lib/jwt_keeper_spec.rb
|
263
262
|
- spec/spec_helper.rb
|
264
|
-
has_rdoc:
|