usps-jwt_auth 1.2.0 → 1.2.2

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: a248993ec7c0ad7e97d4bfcb7e89302f3366f7c3fd95c122f71d116f9c541bcf
4
- data.tar.gz: ef4e072d124dd0f398fbb80202523c3a99b5a25220c48dfeaf27c8a732800259
3
+ metadata.gz: 17662af2194b354229fdc800d007e1121fb3a34dbb65bcf1a8e1df2ec0011087
4
+ data.tar.gz: 7a2017a06711cb9a4714b111a4a2ee85ca3ede7c7e9d0d851e098d1dd83fa302
5
5
  SHA512:
6
- metadata.gz: f38759de429b850a32caa02b412fbbc644dca520f74422bef274fe30dc0f709b272057b81aaf411afce3a7c979bc550e1bb1531dbd228f0185fb6e12bff6ea73
7
- data.tar.gz: 57c98a347480941fbf0f7c88a27252228eb0198d91ffb11f7259b5abf5dfb79f50b4c6db7113dbbe5fe5748ffa7a90a4fdc172268123741d6b27faec0023124c
6
+ metadata.gz: 33b3ce36812329c3d25a890fd1c5d0c8b591671fef159fd602276b5217f238c021e65c60512e1ea75dc5addc07d6b1f56b0b6c2329c027cfe79362f9752752c4
7
+ data.tar.gz: e7e2aed19988c5148ad9550e20b94e018ac1fad129704badbce18a35f027d9c5da231b1570d7eb9821d08838921af238fed223cdd7412b72e5f2b9dab69a7f41
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- usps-jwt_auth (1.2.0)
4
+ usps-jwt_auth (1.2.2)
5
5
  activesupport (~> 8.0)
6
6
  colorize (~> 1.1)
7
7
  fileutils (~> 1.7)
@@ -64,14 +64,21 @@ module Usps
64
64
  end
65
65
 
66
66
  def jwt_user
67
- @jwt_user ||= JwtAuth.config.find_member.call(jwt['certificate']) if fetch_jwt
67
+ return unless fetch_jwt
68
+ # A blank certificate claim is malformed and must never resolve to a member
69
+ # (e.g. a stray blank-certificate row would otherwise authenticate as that record).
70
+ return if jwt['certificate'].blank?
71
+
72
+ @jwt_user ||= JwtAuth.config.find_member.call(jwt['certificate'])
68
73
  end
69
74
 
70
75
  def set_new_jwt
71
76
  return if params[:jwt].blank? || @set_new_jwt
72
77
 
73
78
  store_jwt(params[:jwt])
74
- ensure_valid_jwt_has_valid_member!
79
+ # An unverifiable token (e.g. a key we cannot resolve) clears the jwt and returns
80
+ # nil; fall through so the visitor is sent to login rather than into the app.
81
+ return unless ensure_valid_jwt_has_valid_member!
75
82
 
76
83
  redirect_to_path!
77
84
  @set_new_jwt = true
@@ -124,6 +131,12 @@ module Usps
124
131
  def ensure_valid_jwt_has_valid_member!
125
132
  fetch_jwt
126
133
  jwt_user
134
+ rescue JWT::DecodeError
135
+ # The token cannot be verified (e.g. an unresolvable key). Drop it and report
136
+ # "not signed in" so the caller redirects to login — never let this escape as an
137
+ # unhandled 500, which the error page would re-trigger when it re-authenticates.
138
+ clear_jwt
139
+ @current_user = nil
127
140
  rescue ActiveRecord::RecordNotFound
128
141
  reset_session
129
142
  clear_jwt
@@ -9,6 +9,10 @@ module Usps
9
9
  # Decode and validate data from a JWT
10
10
  #
11
11
  class Decode
12
+ # Keep a slow or unreachable store from tying up the caller (e.g. a web worker).
13
+ OPEN_TIMEOUT = 2
14
+ READ_TIMEOUT = 2
15
+
12
16
  def self.decode(token, audience: [], issuer: nil)
13
17
  new.decode(token, audience: audience, issuer: issuer)
14
18
  end
@@ -75,15 +79,27 @@ module Usps
75
79
  raise JWT::VerificationError, 'Fetched public key does not match token fingerprint'
76
80
  end
77
81
 
82
+ cache_key(fingerprint, pem)
83
+ key
84
+ end
85
+
86
+ # Persist the verified key so the next decode skips the fetch — but best-effort: an
87
+ # unwritable cache dir (e.g. a read-only or wrong-owner deploy) must NOT fail a token
88
+ # we have already fetched and verified. On a write error we just refetch next time.
89
+ def cache_key(fingerprint, pem)
78
90
  path = cache_path(fingerprint)
79
91
  FileUtils.mkdir_p(File.dirname(path))
80
92
  File.write(path, pem)
81
- key
93
+ rescue SystemCallError
94
+ nil
82
95
  end
83
96
 
84
97
  def http_get(url)
85
98
  uri = URI.parse(url)
86
- response = Net::HTTP.get_response(uri)
99
+ response = Net::HTTP.start(
100
+ uri.host, uri.port,
101
+ use_ssl: uri.scheme == 'https', open_timeout: OPEN_TIMEOUT, read_timeout: READ_TIMEOUT
102
+ ) { |http| http.get(uri.request_uri) }
87
103
  raise "HTTP #{response.code} for #{url}" unless response.is_a?(Net::HTTPSuccess)
88
104
 
89
105
  response.body
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module JwtAuth
5
- VERSION = '1.2.0'
5
+ VERSION = '1.2.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-jwt_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander