rack-jwt-verifier 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +101 -0
- data/README.md +136 -80
- data/lib/rack-jwt-verifier.rb +5 -0
- data/lib/rack_jwt_verifier/errors.rb +8 -0
- data/lib/rack_jwt_verifier/in_process_cache.rb +13 -7
- data/lib/rack_jwt_verifier/jwt_helper.rb +22 -31
- data/lib/rack_jwt_verifier/key_source.rb +299 -0
- data/lib/rack_jwt_verifier/middleware.rb +158 -30
- data/lib/rack_jwt_verifier/verifier.rb +110 -62
- data/lib/rack_jwt_verifier/version.rb +1 -1
- data/lib/rack_jwt_verifier.rb +7 -11
- metadata +27 -90
- data/.rspec_status +0 -26
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -63
|
@@ -1,21 +1,43 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "jwt"
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
require_relative "errors"
|
|
5
|
+
require_relative "in_process_cache"
|
|
6
|
+
require_relative "key_source"
|
|
6
7
|
|
|
7
8
|
module RackJwtVerifier
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# and
|
|
9
|
+
# Decodes and verifies JWTs against key material from a configured source:
|
|
10
|
+
# a static PEM, a PEM served at a URL, or a JWKS endpoint. Handles caching,
|
|
11
|
+
# key rotation and claim enforcement so the middleware does not have to.
|
|
11
12
|
class Verifier
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
# Kept under the old constant so existing `rescue Verifier::KeyFetchError`
|
|
14
|
+
# code keeps working.
|
|
15
|
+
KeyFetchError = RackJwtVerifier::KeyFetchError
|
|
16
|
+
|
|
17
|
+
# Cache namespace for a fetched PEM; the full key also carries a digest of the URL.
|
|
18
|
+
PUBLIC_KEY_CACHE_KEY = KeySource::RemotePem::CACHE_KEY_PREFIX
|
|
19
|
+
# Cache namespace for a fetched JWKS; the full key also carries a digest of the URL.
|
|
20
|
+
JWKS_CACHE_KEY = KeySource::RemoteJwks::CACHE_KEY_PREFIX
|
|
21
|
+
# The default TTL for cached key material (5 minutes)
|
|
22
|
+
CACHE_TTL_SECONDS = KeySource::Remote::DEFAULT_CACHE_TTL
|
|
23
|
+
# Default open/read timeout (seconds) for fetching key material
|
|
24
|
+
DEFAULT_HTTP_TIMEOUT = KeySource::Remote::DEFAULT_HTTP_TIMEOUT
|
|
25
|
+
# Largest response body (bytes) accepted as key material
|
|
26
|
+
MAX_KEY_RESPONSE_BYTES = KeySource::Remote::MAX_RESPONSE_BYTES
|
|
27
|
+
# Minimum gap (seconds) between rotation-triggered refetches
|
|
28
|
+
DEFAULT_REFETCH_INTERVAL = KeySource::Remote::DEFAULT_REFETCH_INTERVAL
|
|
29
|
+
|
|
30
|
+
# Exactly one of these tells the Verifier where its key comes from.
|
|
31
|
+
KEY_SOURCE_OPTIONS = %i[public_key public_key_url jwks_url].freeze
|
|
32
|
+
|
|
33
|
+
# ruby-jwt only validates an expected claim value (e.g. `iss: "..."`) when
|
|
34
|
+
# the matching `verify_*` flag is also set. Map each claim to its flag so we
|
|
35
|
+
# can switch the flag on automatically whenever a value is supplied.
|
|
36
|
+
CLAIM_VERIFY_FLAGS = {
|
|
37
|
+
iss: :verify_iss,
|
|
38
|
+
aud: :verify_aud,
|
|
39
|
+
sub: :verify_sub
|
|
40
|
+
}.freeze
|
|
19
41
|
|
|
20
42
|
# Default options for JWT decoding to ensure strict security compliance
|
|
21
43
|
DEFAULT_DECODE_OPTIONS = {
|
|
@@ -23,77 +45,103 @@ module RackJwtVerifier
|
|
|
23
45
|
# THIS MUST BE TRUE: Ensures the 'exp' claim is checked during decoding
|
|
24
46
|
verify_expiration: true,
|
|
25
47
|
verify_not_before: true,
|
|
26
|
-
leeway: 60
|
|
27
|
-
# 'iss' validation will be added later when we configure the Verifier.
|
|
28
|
-
# verify_iss: true
|
|
48
|
+
leeway: 60 # Allow a 60-second clock skew for "exp" and "nbf" claims
|
|
29
49
|
}.freeze
|
|
30
50
|
|
|
31
51
|
# @param options [Hash] Configuration options.
|
|
32
|
-
# @option options [String] :
|
|
52
|
+
# @option options [String, OpenSSL::PKey] :public_key A static PEM public key or X.509 certificate.
|
|
53
|
+
# @option options [String] :public_key_url The https:// URL serving a PEM public key or certificate.
|
|
54
|
+
# @option options [String] :jwks_url The https:// URL serving a JSON Web Key Set.
|
|
55
|
+
# @option options [Array<String>] :algorithms Accepted signing algorithms (default: ["RS256"]).
|
|
56
|
+
# @option options [Boolean] :allow_insecure_http Permit a plain http:// URL (development only).
|
|
57
|
+
# @option options [Numeric] :http_timeout Open/read timeout in seconds for the key fetch.
|
|
58
|
+
# @option options [Integer] :cache_ttl Seconds to cache fetched key material.
|
|
59
|
+
# @option options [Numeric] :refetch_interval Minimum seconds between rotation-triggered refetches.
|
|
33
60
|
# @option options [Object] :cache_store Optional custom cache object (must respond to #read and #write).
|
|
61
|
+
# @option options [Logger] :logger Where cache-store failures are reported (default: silent).
|
|
34
62
|
# @option options [Hash] :decode_options Custom options for JWT.decode.
|
|
35
63
|
def initialize(options = {})
|
|
36
|
-
@
|
|
37
|
-
|
|
38
|
-
# Inject cache store, defaulting to the simple InProcessCache.
|
|
39
|
-
# This allows users to pass in a Redis/Memcached client that responds to #read and #write.
|
|
40
|
-
@cache = options.fetch(:cache_store, InProcessCache.new)
|
|
41
|
-
|
|
42
|
-
# Merge default options over any user-provided options
|
|
43
|
-
@decode_options = DEFAULT_DECODE_OPTIONS.merge(options.fetch(:decode_options, {}))
|
|
64
|
+
@key_source = build_key_source(options)
|
|
65
|
+
@decode_options = build_decode_options(options.fetch(:decode_options, {}), options[:algorithms])
|
|
44
66
|
end
|
|
45
67
|
|
|
46
68
|
# Decodes and verifies the JWT.
|
|
47
69
|
# @param token [String] The JWT string from the Authorization header.
|
|
48
70
|
# @return [Hash] The decoded payload (the user claims).
|
|
49
71
|
# @raise [JWT::DecodeError] If the token is invalid, expired, or signature fails.
|
|
72
|
+
# @raise [KeyFetchError] If the key material could not be obtained.
|
|
50
73
|
def verify(token)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
payload
|
|
74
|
+
decode(token)
|
|
75
|
+
rescue JWT::VerificationError
|
|
76
|
+
# A signature mismatch may mean the provider rotated its key. Refresh
|
|
77
|
+
# once (rate-limited) and retry; if nothing was refreshed, or the retry
|
|
78
|
+
# fails too, the token is simply bad.
|
|
79
|
+
raise unless @key_source.refresh!
|
|
80
|
+
|
|
81
|
+
decode(token)
|
|
60
82
|
end
|
|
61
83
|
|
|
62
84
|
private
|
|
63
85
|
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
# Performs the cryptographic verification and claim validation. The `true`
|
|
87
|
+
# is required to enable verification checks; only the payload is returned.
|
|
88
|
+
def decode(token)
|
|
89
|
+
payload, _header =
|
|
90
|
+
if @key_source.jwks?
|
|
91
|
+
JWT.decode(token, nil, true, @decode_options.merge(jwks: @key_source.jwks_loader))
|
|
92
|
+
else
|
|
93
|
+
JWT.decode(token, @key_source.verification_key, true, @decode_options)
|
|
94
|
+
end
|
|
95
|
+
payload
|
|
96
|
+
end
|
|
73
97
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
def build_key_source(options)
|
|
99
|
+
given = KEY_SOURCE_OPTIONS.select { |name| options[name] }
|
|
100
|
+
unless given.size == 1
|
|
101
|
+
raise ArgumentError,
|
|
102
|
+
"exactly one of #{KEY_SOURCE_OPTIONS.map(&:inspect).join(', ')} must be given" \
|
|
103
|
+
"#{" (got #{given.map(&:inspect).join(' and ')})" unless given.empty?}"
|
|
104
|
+
end
|
|
77
105
|
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
case given.first
|
|
107
|
+
when :public_key
|
|
108
|
+
KeySource::Static.new(options[:public_key])
|
|
109
|
+
when :public_key_url
|
|
110
|
+
KeySource::RemotePem.new(url: options[:public_key_url], **remote_options(options))
|
|
111
|
+
when :jwks_url
|
|
112
|
+
KeySource::RemoteJwks.new(url: options[:jwks_url], **remote_options(options))
|
|
80
113
|
end
|
|
114
|
+
end
|
|
81
115
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
def remote_options(options)
|
|
117
|
+
{
|
|
118
|
+
# Inject cache store, defaulting to the simple InProcessCache. This
|
|
119
|
+
# allows users to pass in a cache store that responds to #read and #write.
|
|
120
|
+
cache: options.fetch(:cache_store) { InProcessCache.new },
|
|
121
|
+
cache_ttl: options.fetch(:cache_ttl, CACHE_TTL_SECONDS),
|
|
122
|
+
http_timeout: options.fetch(:http_timeout, DEFAULT_HTTP_TIMEOUT),
|
|
123
|
+
refetch_interval: options.fetch(:refetch_interval, DEFAULT_REFETCH_INTERVAL),
|
|
124
|
+
allow_insecure_http: options.fetch(:allow_insecure_http, false),
|
|
125
|
+
logger: options[:logger]
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Merge default options over any user-provided options, then:
|
|
130
|
+
# - apply a top-level :algorithms list, and drop our :algorithm default
|
|
131
|
+
# whenever a list is in play — ruby-jwt consults :algorithm first, so the
|
|
132
|
+
# default would otherwise silently override the user's list;
|
|
133
|
+
# - make sure an expected claim value is actually enforced: `iss: "x"` on
|
|
134
|
+
# its own is a no-op in ruby-jwt unless `verify_iss: true` accompanies
|
|
135
|
+
# it. An explicit `verify_*: false` from the user is left untouched.
|
|
136
|
+
def build_decode_options(user_options, algorithms)
|
|
137
|
+
merged = DEFAULT_DECODE_OPTIONS.merge(user_options)
|
|
138
|
+
merged[:algorithms] = Array(algorithms) if algorithms
|
|
139
|
+
merged.delete(:algorithm) if merged.key?(:algorithms) && !user_options.key?(:algorithm)
|
|
140
|
+
|
|
141
|
+
CLAIM_VERIFY_FLAGS.each do |claim, flag|
|
|
142
|
+
merged[flag] = true if merged.key?(claim) && !merged.key?(flag)
|
|
143
|
+
end
|
|
144
|
+
merged
|
|
97
145
|
end
|
|
98
146
|
end
|
|
99
147
|
end
|
data/lib/rack_jwt_verifier.rb
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
#
|
|
3
|
+
# Entry point for the gem: `require "rack_jwt_verifier"` loads everything.
|
|
4
|
+
# (`require "rack-jwt-verifier"`, the gem's name, works too.)
|
|
5
5
|
|
|
6
6
|
require_relative "rack_jwt_verifier/version"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# `lib/rack_jwt_verifier/` directory.
|
|
11
|
-
require_relative "rack_jwt_verifier/jwt_helper"
|
|
7
|
+
require_relative "rack_jwt_verifier/errors"
|
|
8
|
+
require_relative "rack_jwt_verifier/in_process_cache"
|
|
9
|
+
require_relative "rack_jwt_verifier/key_source"
|
|
12
10
|
require_relative "rack_jwt_verifier/verifier"
|
|
13
11
|
require_relative "rack_jwt_verifier/middleware"
|
|
14
|
-
require_relative "rack_jwt_verifier/
|
|
15
|
-
|
|
12
|
+
require_relative "rack_jwt_verifier/jwt_helper"
|
|
16
13
|
|
|
17
|
-
#
|
|
18
|
-
# Middleware) are now accessible via RackJwtVerifier::ClassName.
|
|
14
|
+
# Namespace for the gem: Middleware, Verifier, KeySource, InProcessCache, JwtHelper.
|
|
19
15
|
module RackJwtVerifier
|
|
20
16
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-jwt-verifier
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniele Frisanco
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-09-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jwt
|
|
@@ -25,121 +25,57 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.8'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: logger
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '1.4'
|
|
34
34
|
type: :runtime
|
|
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: '
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: bundler
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '2.0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '2.0'
|
|
40
|
+
version: '1.4'
|
|
55
41
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '13.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '13.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rspec
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3.0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '3.0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: webmock
|
|
42
|
+
name: rack
|
|
85
43
|
requirement: !ruby/object:Gem::Requirement
|
|
86
44
|
requirements:
|
|
87
|
-
- - "
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '3.0'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - "~>"
|
|
45
|
+
- - ">="
|
|
95
46
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
97
|
-
-
|
|
98
|
-
name: timecop
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - "~>"
|
|
47
|
+
version: '2.2'
|
|
48
|
+
- - "<"
|
|
102
49
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '
|
|
104
|
-
type: :
|
|
50
|
+
version: '4'
|
|
51
|
+
type: :runtime
|
|
105
52
|
prerelease: false
|
|
106
53
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - "~>"
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0.9'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: rack-test
|
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
|
114
54
|
requirements:
|
|
115
55
|
- - ">="
|
|
116
56
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
118
|
-
|
|
119
|
-
prerelease: false
|
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - ">="
|
|
57
|
+
version: '2.2'
|
|
58
|
+
- - "<"
|
|
123
59
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
125
|
-
description: Verifies JWT
|
|
126
|
-
|
|
127
|
-
|
|
60
|
+
version: '4'
|
|
61
|
+
description: Verifies JWT signatures against a JWKS endpoint, a PEM URL or a static
|
|
62
|
+
key, enforces exp/nbf/iss/aud claims, caches key material, handles key rotation,
|
|
63
|
+
and exposes the verified claims to the application through the Rack environment.
|
|
128
64
|
email:
|
|
129
65
|
- daniele.frisanco@gmail.com
|
|
130
66
|
executables: []
|
|
131
67
|
extensions: []
|
|
132
68
|
extra_rdoc_files: []
|
|
133
69
|
files:
|
|
134
|
-
- ".rspec_status"
|
|
135
70
|
- CHANGELOG.md
|
|
136
|
-
- Gemfile
|
|
137
|
-
- Gemfile.lock
|
|
138
71
|
- LICENSE.md
|
|
139
72
|
- README.md
|
|
73
|
+
- lib/rack-jwt-verifier.rb
|
|
140
74
|
- lib/rack_jwt_verifier.rb
|
|
75
|
+
- lib/rack_jwt_verifier/errors.rb
|
|
141
76
|
- lib/rack_jwt_verifier/in_process_cache.rb
|
|
142
77
|
- lib/rack_jwt_verifier/jwt_helper.rb
|
|
78
|
+
- lib/rack_jwt_verifier/key_source.rb
|
|
143
79
|
- lib/rack_jwt_verifier/middleware.rb
|
|
144
80
|
- lib/rack_jwt_verifier/verifier.rb
|
|
145
81
|
- lib/rack_jwt_verifier/version.rb
|
|
@@ -150,7 +86,8 @@ metadata:
|
|
|
150
86
|
allowed_push_host: https://rubygems.org
|
|
151
87
|
homepage_uri: https://github.com/danielefrisanco/rack_jwt_verifier
|
|
152
88
|
source_code_uri: https://github.com/danielefrisanco/rack_jwt_verifier
|
|
153
|
-
changelog_uri: https://github.com/danielefrisanco/rack_jwt_verifier/CHANGELOG.md
|
|
89
|
+
changelog_uri: https://github.com/danielefrisanco/rack_jwt_verifier/blob/main/CHANGELOG.md
|
|
90
|
+
rubygems_mfa_required: 'true'
|
|
154
91
|
post_install_message:
|
|
155
92
|
rdoc_options: []
|
|
156
93
|
require_paths:
|
|
@@ -159,16 +96,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
159
96
|
requirements:
|
|
160
97
|
- - ">="
|
|
161
98
|
- !ruby/object:Gem::Version
|
|
162
|
-
version:
|
|
99
|
+
version: '3.0'
|
|
163
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
101
|
requirements:
|
|
165
102
|
- - ">="
|
|
166
103
|
- !ruby/object:Gem::Version
|
|
167
104
|
version: '0'
|
|
168
105
|
requirements: []
|
|
169
|
-
rubygems_version: 3.
|
|
106
|
+
rubygems_version: 3.3.26
|
|
170
107
|
signing_key:
|
|
171
108
|
specification_version: 4
|
|
172
|
-
summary:
|
|
173
|
-
|
|
109
|
+
summary: Rack middleware that authenticates requests with JWTs from an external identity
|
|
110
|
+
provider.
|
|
174
111
|
test_files: []
|
data/.rspec_status
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
example_id | status | run_time |
|
|
2
|
-
---------------------------------------------------- | ------ | --------------- |
|
|
3
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:1:1] | passed | 0.06296 seconds |
|
|
4
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:2:1] | passed | 0.05566 seconds |
|
|
5
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:2:2] | passed | 0.03186 seconds |
|
|
6
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:3:1:1] | passed | 0.04063 seconds |
|
|
7
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:3:2:1] | passed | 0.06923 seconds |
|
|
8
|
-
./spec/rack_jwt_verifier/jwt_helper_spec.rb[1:3:3:1] | passed | 0.03564 seconds |
|
|
9
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:1:1] | passed | 0.02249 seconds |
|
|
10
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:2:1:1] | passed | 0.05022 seconds |
|
|
11
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:2:1:2] | passed | 0.02597 seconds |
|
|
12
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:2:2:1] | passed | 0.02197 seconds |
|
|
13
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:2:3:1] | passed | 0.03074 seconds |
|
|
14
|
-
./spec/rack_jwt_verifier/middleware_spec.rb[1:2:4:1] | passed | 0.02496 seconds |
|
|
15
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:1:1] | passed | 0.01668 seconds |
|
|
16
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:1:2] | passed | 0.00633 seconds |
|
|
17
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:1:3] | passed | 0.05474 seconds |
|
|
18
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:1:4] | passed | 0.04057 seconds |
|
|
19
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:2:1] | passed | 0.03279 seconds |
|
|
20
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:2:2] | passed | 0.04898 seconds |
|
|
21
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:2:3:1] | passed | 0.03709 seconds |
|
|
22
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:2:3:2] | passed | 0.01822 seconds |
|
|
23
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:3:1] | passed | 0.01993 seconds |
|
|
24
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:3:2] | passed | 0.01473 seconds |
|
|
25
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:3:3] | passed | 0.03322 seconds |
|
|
26
|
-
./spec/rack_jwt_verifier/verifier_spec.rb[1:3:4] | passed | 0.01368 seconds |
|
data/Gemfile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
source "https://rubygems.org"
|
|
4
|
-
|
|
5
|
-
# Specify your gem's dependencies in rack_jwt_verifier.gemspec
|
|
6
|
-
gemspec
|
|
7
|
-
|
|
8
|
-
# Dependencies for development and testing
|
|
9
|
-
group :development, :test do
|
|
10
|
-
gem "rack"
|
|
11
|
-
gem "rspec", "~> 3.12"
|
|
12
|
-
gem "rack-test"
|
|
13
|
-
gem "webmock", "~> 3.14" # Added for mocking network requests in Verifier
|
|
14
|
-
end
|
data/Gemfile.lock
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
rack-jwt-verifier (0.1.0)
|
|
5
|
-
jwt (~> 2.8)
|
|
6
|
-
rack (>= 2.0)
|
|
7
|
-
|
|
8
|
-
GEM
|
|
9
|
-
remote: https://rubygems.org/
|
|
10
|
-
specs:
|
|
11
|
-
addressable (2.8.7)
|
|
12
|
-
public_suffix (>= 2.0.2, < 7.0)
|
|
13
|
-
base64 (0.2.0)
|
|
14
|
-
bigdecimal (3.1.8)
|
|
15
|
-
crack (1.0.0)
|
|
16
|
-
bigdecimal
|
|
17
|
-
rexml
|
|
18
|
-
diff-lcs (1.6.2)
|
|
19
|
-
hashdiff (1.1.0)
|
|
20
|
-
jwt (2.8.2)
|
|
21
|
-
base64
|
|
22
|
-
public_suffix (5.1.1)
|
|
23
|
-
rack (3.2.3)
|
|
24
|
-
rack-test (2.2.0)
|
|
25
|
-
rack (>= 1.3)
|
|
26
|
-
rake (13.2.1)
|
|
27
|
-
rexml (3.3.2)
|
|
28
|
-
strscan
|
|
29
|
-
rspec (3.13.1)
|
|
30
|
-
rspec-core (~> 3.13.0)
|
|
31
|
-
rspec-expectations (~> 3.13.0)
|
|
32
|
-
rspec-mocks (~> 3.13.0)
|
|
33
|
-
rspec-core (3.13.5)
|
|
34
|
-
rspec-support (~> 3.13.0)
|
|
35
|
-
rspec-expectations (3.13.5)
|
|
36
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
37
|
-
rspec-support (~> 3.13.0)
|
|
38
|
-
rspec-mocks (3.13.6)
|
|
39
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
40
|
-
rspec-support (~> 3.13.0)
|
|
41
|
-
rspec-support (3.13.6)
|
|
42
|
-
strscan (3.1.0)
|
|
43
|
-
timecop (0.9.10)
|
|
44
|
-
webmock (3.23.1)
|
|
45
|
-
addressable (>= 2.8.0)
|
|
46
|
-
crack (>= 0.3.2)
|
|
47
|
-
hashdiff (>= 0.4.0, < 2.0.0)
|
|
48
|
-
|
|
49
|
-
PLATFORMS
|
|
50
|
-
x86_64-linux
|
|
51
|
-
|
|
52
|
-
DEPENDENCIES
|
|
53
|
-
bundler (~> 2.0)
|
|
54
|
-
rack
|
|
55
|
-
rack-jwt-verifier!
|
|
56
|
-
rack-test
|
|
57
|
-
rake (~> 13.0)
|
|
58
|
-
rspec (~> 3.12)
|
|
59
|
-
timecop (~> 0.9)
|
|
60
|
-
webmock (~> 3.14)
|
|
61
|
-
|
|
62
|
-
BUNDLED WITH
|
|
63
|
-
2.4.22
|