devise-rownd 1.0.2 → 1.0.3

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: ce95c890c9eaefb6188d86384d0b895d12263a54b50869202fd1913fd0137741
4
- data.tar.gz: 8cd89c98656cdeff0dd3845e69d9b8441147fe334ccaeee06ab6ed49b05f93ce
3
+ metadata.gz: d54df50c4a7815d8fe0ee291891134f7e1fbb9f9afebb935b48e6f34ec649467
4
+ data.tar.gz: 24410b4335a8e44ed8d1bb62215ce43ec8215e5d3ef949565c022ce533188f6b
5
5
  SHA512:
6
- metadata.gz: 51753f3cc575a7683641c42ccf7d6e2a019bb9dbc2e1791ff8a07149e4c84e282d7d00f0c1b8e45a310f45afaaba99a58b64a0ea48330c745323ebd010e8b8c9
7
- data.tar.gz: 35c90e573f0143dfe8ca6d3119d0b27a33b0f080c2a2e82449ba13f116d6a9b01bd4d4a67b763b8c0d3402ed5fe27825317387fdc6749502510604dca824aec9
6
+ metadata.gz: 4323c21cdf8ba62dc8d11c4c95016064987ca2d256cef7e525cc635286ad57d2fd40fc2d52708677d5d6a970ad335800cd728326befdfbc34dc9e9d8dbd535d9
7
+ data.tar.gz: c835bc2862a1338fb379c0578a4dc9493a372ff0aadf1ec4f1aebb011a383a595b401b5e1868ea53a0584cf8118c5ff3d543525216ff9d20f1148d958205780a
@@ -20,9 +20,11 @@ module Devise::Rownd
20
20
  warden.authenticate!(scope: :user)
21
21
  end
22
22
 
23
+ warden.authenticate!(scope: :user)
24
+
23
25
  render json: {
24
26
  message: 'Successfully authenticated user',
25
- should_refresh_page: new_access_token || session[:rownd_stale_data] == true,
27
+ should_refresh_page: new_access_token || session[:rownd_stale_data] == true
26
28
  }, status: :ok
27
29
  end
28
30
 
@@ -1,19 +1,25 @@
1
1
  require 'devise/rownd/api'
2
+ require 'devise/rownd/caching'
2
3
 
3
4
  module Devise
4
5
  module Rownd
5
6
  include API
6
7
 
7
8
  def app_config
8
- fetch_app_config
9
+ config = Devise::Rownd::Caching.fetch('rownd_app_config', 15.minutes) { fetch_app_config }
10
+
11
+ raise 'Failed to fetch app config' unless config
12
+
13
+ config
9
14
  end
10
15
 
11
16
  def self.fetch_app_config
12
- Rails.cache.fetch("rownd_app_config", expires_in: 15.minutes) do
13
- response = API.make_api_call('/hub/app-config', { method: 'GET',
14
- headers: { 'x-rownd-app-key' => app_key } })
15
- response.body['app'] if response.success?
16
- end
17
+ response = API.make_api_call('/hub/app-config', { method: 'GET',
18
+ headers: { 'x-rownd-app-key' => app_key } })
19
+ return response.body['app'] if response.success?
20
+
21
+ Rails.logger.error("Failed to fetch app config from Rownd: #{response.body['message']}")
22
+ nil
17
23
  end
18
24
 
19
25
  module_function :app_config
@@ -0,0 +1,30 @@
1
+ require 'async'
2
+
3
+ module Devise::Rownd
4
+ module Caching
5
+ def fetch(cache_key, ttl)
6
+ cache_val = Rails.cache.read(cache_key)
7
+
8
+ # If there's nothing in the cache, yield the value and write it to cache
9
+ if cache_val.nil?
10
+ return_value = yield
11
+ Rails.cache.write(cache_key, [return_value, Time.now]) if return_value
12
+ else
13
+ return_value = cache_val[0]
14
+ last_fetch_time = cache_val[1]
15
+
16
+ # Start a new thread to update the cached value if the TTL is exceeded
17
+ Async do
18
+ if Time.now - last_fetch_time > ttl
19
+ new_value = yield
20
+ Rails.cache.write(cache_key, [new_value, Time.now]) if new_value
21
+ end
22
+ end
23
+ end
24
+
25
+ return_value
26
+ end
27
+
28
+ module_function :fetch
29
+ end
30
+ end
@@ -2,6 +2,7 @@ require 'devise'
2
2
  require 'devise/strategies/authenticatable'
3
3
  require 'devise/rownd/user'
4
4
  require 'devise/rownd/api'
5
+ require 'devise/rownd/caching'
5
6
  require 'jose'
6
7
 
7
8
  require_relative '../../../../config/initializers/app_creds'
@@ -20,18 +21,26 @@ module Devise
20
21
  @access_token = session[:rownd_user_access_token]
21
22
  return fail!('No Access Token') unless @access_token
22
23
 
23
- @decoded_jwt = verify_token(@access_token)
24
- @app_id = @decoded_jwt['aud'].find(/^app:.+/).first.split(':').last
24
+ begin
25
+ @decoded_jwt = verify_token(@access_token)
25
26
 
26
- configured_app_id = Devise::Rownd.app_id
27
- ok = @app_id == configured_app_id
28
- return fail!('JWT not authorized for app') unless ok
27
+ @app_id = @decoded_jwt['aud'].find(/^app:.+/).first.split(':').last
29
28
 
30
- rownd_user = Devise::Rownd::User.new(fetch_user)
29
+ configured_app_id = Devise::Rownd.app_id
30
+ ok = @app_id == configured_app_id
31
+ return fail!('JWT not authorized for app') unless ok
31
32
 
32
- return fail!(:unable_to_authenticate) unless rownd_user
33
+ user_data = fetch_user
34
+ return fail!('Failed to fetch user') unless user_data
33
35
 
34
- success!(rownd_user)
36
+ rownd_user = Devise::Rownd::User.new(user_data)
37
+
38
+ return fail!('Failed to initialize user') unless rownd_user
39
+
40
+ success!(rownd_user)
41
+ rescue StandardError => e
42
+ fail!("Unable to authenticate: #{e.message}")
43
+ end
35
44
  end
36
45
 
37
46
  def return_to_after_sign_out
@@ -42,14 +51,14 @@ module Devise
42
51
  cache_key = "rownd_user_#{@decoded_jwt['jti']}"
43
52
  if session[:rownd_stale_data] == true
44
53
  data = fetch_user_from_api
54
+ return nil unless data
55
+
45
56
  Rails.cache.write(cache_key, data, expires_in: 1.minute)
46
57
  session.delete(:rownd_stale_data) if session[:rownd_stale_data]
47
58
  return data
48
59
  end
49
60
 
50
- Rails.cache.fetch(cache_key, expires_in: 1.minute) do
51
- fetch_user_from_api
52
- end
61
+ Devise::Rownd::Caching.fetch(cache_key, 1.minute) { fetch_user_from_api }
53
62
  end
54
63
 
55
64
  def fetch_user_from_api
@@ -62,31 +71,32 @@ module Devise
62
71
  )
63
72
  return response.body['data'] if response.success?
64
73
 
65
- raise StandardError, response.body['message']
74
+ Rails.logger.error("Failed to fetch user: #{response.body['message']}")
75
+ nil
66
76
  end
67
77
 
68
78
  def verify_token(access_token)
69
- for jwk in jwks
70
- begin
71
- response = JOSE::JWT.verify_strict(jwk, ['EdDSA'], access_token)
72
- return response[1].fields if response[0]
73
- rescue StandardError => e
74
- puts "Error: #{e}"
75
- next
76
- end
77
- raise StandardError
79
+ raise StandardError, 'No JWKs' unless jwks
80
+
81
+ jwks.each do |jwk|
82
+ response = JOSE::JWT.verify_strict(jwk, ['EdDSA'], access_token)
83
+ return response[1].fields if response[0]
84
+ rescue StandardError
85
+ next
78
86
  end
87
+ raise StandardError, 'Failed to verify JWT. No matching JWKs'
79
88
  end
80
89
 
81
90
  def jwks
82
- Rails.cache.fetch('rownd_jwks', expires_in: 15.minutes) do
83
- fetch_jwks
84
- end
91
+ Devise::Rownd::Caching.fetch('rownd_jwks', 15.minutes) { fetch_jwks_from_api }
85
92
  end
86
93
 
87
- def fetch_jwks
94
+ def fetch_jwks_from_api
88
95
  response = ::Devise::Rownd::API.make_api_call('/hub/auth/keys')
89
- response.body['keys']
96
+ return response.body['keys'] if response.success?
97
+
98
+ Rails.logger.error("Failed to fetch JWKs: #{response.body['message']}")
99
+ nil
90
100
  end
91
101
  end
92
102
  end
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Rownd
3
- VERSION = '1.0.2'
3
+ VERSION = '1.0.3'
4
4
  end
5
5
  end
data/lib/devise/rownd.rb CHANGED
@@ -4,6 +4,7 @@ require 'devise/rownd/strategies'
4
4
  require 'devise/rownd/models'
5
5
  require 'devise/rownd/api'
6
6
  require 'devise/rownd/user'
7
+ require 'devise/rownd/caching'
7
8
 
8
9
  module Devise
9
10
  module Rownd
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-rownd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bobby Radford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-01 00:00:00.000000000 Z
11
+ date: 2022-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: async
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.30.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.30.2
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: devise
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -191,6 +205,7 @@ files:
191
205
  - config/routes.rb
192
206
  - lib/devise/rownd.rb
193
207
  - lib/devise/rownd/api.rb
208
+ - lib/devise/rownd/caching.rb
194
209
  - lib/devise/rownd/custom_failure.rb
195
210
  - lib/devise/rownd/engine.rb
196
211
  - lib/devise/rownd/models.rb