diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b7af6..01fb627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## UNRELEASED +Summary: Move refresh\_credentials functionality to dedicated hook (Refreshable); + +Details: +- Add Refreshable hook, and tie into after\_set\_user calback; +- Utilize native warden session for scoping of credentials\_refreshed\_at and refresh\_return\_url properties; +- Remove otp\_refresh\_credentials from sessions hook (no longer needed); + +## UNRELEASED + Summary: Move mandatory OTP functionality to the helper layer to ensure that it is enforced throughout application (rather than one time at log in). Details: diff --git a/lib/devise-otp.rb b/lib/devise-otp.rb index 17ea0d3..7b01010 100644 --- a/lib/devise-otp.rb +++ b/lib/devise-otp.rb @@ -24,6 +24,7 @@ module Controllers require "devise_otp_authenticatable/routes" require "devise_otp_authenticatable/engine" +require "devise_otp_authenticatable/hooks/refreshable" # # update Devise module with additions needed for DeviseOtpAuthenticatable @@ -82,6 +83,7 @@ module Otp Devise.add_module :otp_authenticatable, controller: :tokens, model: "devise_otp_authenticatable/models/otp_authenticatable", route: :otp + # # add PublicHelpers after adding Devise module to ensure that per-mapping routes from above are included # diff --git a/lib/devise_otp_authenticatable/controllers/helpers.rb b/lib/devise_otp_authenticatable/controllers/helpers.rb index 6a17ae8..fe1ea13 100644 --- a/lib/devise_otp_authenticatable/controllers/helpers.rb +++ b/lib/devise_otp_authenticatable/controllers/helpers.rb @@ -39,7 +39,6 @@ def ensure_resource! end end - # fixme do cookies and persistence need to be scoped? probably # # check if the resource needs a credentials refresh. IE, they need to be asked a password again to access # this resource. @@ -47,8 +46,8 @@ def ensure_resource! def needs_credentials_refresh?(resource) return false unless resource.class.otp_credentials_refresh - (!session[otp_scoped_refresh_property].present? || - (session[otp_scoped_refresh_property] < DateTime.now)).tap { |need| otp_set_refresh_return_url if need } + (!warden.session[otp_refresh_property].present? || + (warden.session[otp_refresh_property] < DateTime.now)).tap { |need| otp_set_refresh_return_url if need } end # @@ -56,7 +55,7 @@ def needs_credentials_refresh?(resource) # def otp_refresh_credentials_for(resource) return false unless resource.class.otp_credentials_refresh - session[otp_scoped_refresh_property] = (Time.now + resource.class.otp_credentials_refresh) + warden.session[otp_refresh_property] = (Time.now + resource.class.otp_credentials_refresh) end # @@ -85,19 +84,19 @@ def otp_set_trusted_device_for(resource) end def otp_set_refresh_return_url - session[otp_scoped_refresh_return_url_property] = request.fullpath + warden.session[otp_refresh_return_url_property] = request.fullpath end def otp_fetch_refresh_return_url - session.delete(otp_scoped_refresh_return_url_property) { :root } + warden.session.delete(otp_refresh_return_url_property) { :root } end - def otp_scoped_refresh_return_url_property - "otp_#{resource_name}refresh_return_url".to_sym + def otp_refresh_return_url_property + :refresh_return_url end - def otp_scoped_refresh_property - "otp_#{resource_name}refresh_after".to_sym + def otp_refresh_property + :credentials_refreshed_at end def otp_scoped_persistence_cookie diff --git a/lib/devise_otp_authenticatable/hooks/refreshable.rb b/lib/devise_otp_authenticatable/hooks/refreshable.rb new file mode 100644 index 0000000..a128e4d --- /dev/null +++ b/lib/devise_otp_authenticatable/hooks/refreshable.rb @@ -0,0 +1,5 @@ +# After each sign in, update credentials refreshed at time +Warden::Manager.after_set_user except: :fetch do |record, warden, options| + warden.session[:credentials_refreshed_at] = (Time.now + record.class.otp_credentials_refresh) +end + diff --git a/lib/devise_otp_authenticatable/hooks/sessions.rb b/lib/devise_otp_authenticatable/hooks/sessions.rb index 47c9ef4..d983ea6 100644 --- a/lib/devise_otp_authenticatable/hooks/sessions.rb +++ b/lib/devise_otp_authenticatable/hooks/sessions.rb @@ -16,8 +16,6 @@ def create_with_otp devise_stored_location = stored_location_for(resource) # Grab the current stored location before it gets lost by warden.logout store_location_for(resource, devise_stored_location) # Restore it since #stored_location_for removes it - otp_refresh_credentials_for(resource) - yield resource if block_given? if otp_challenge_required_on?(resource) challenge = resource.generate_otp_challenge!