devise-otp 0.6.0 → 0.7.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +0 -2
  3. data/.gitignore +3 -1
  4. data/CHANGELOG.md +51 -8
  5. data/README.md +8 -2
  6. data/app/controllers/devise_otp/devise/otp_credentials_controller.rb +46 -27
  7. data/app/controllers/devise_otp/devise/otp_tokens_controller.rb +24 -6
  8. data/app/views/devise/otp_credentials/show.html.erb +6 -6
  9. data/app/views/devise/otp_tokens/_token_secret.html.erb +3 -4
  10. data/app/views/devise/otp_tokens/edit.html.erb +26 -0
  11. data/app/views/devise/otp_tokens/show.html.erb +7 -14
  12. data/config/locales/en.yml +23 -14
  13. data/devise-otp.gemspec +1 -2
  14. data/lib/devise/strategies/database_authenticatable.rb +64 -0
  15. data/lib/devise-otp/version.rb +1 -1
  16. data/lib/devise-otp.rb +31 -11
  17. data/lib/devise_otp_authenticatable/controllers/helpers.rb +9 -10
  18. data/lib/devise_otp_authenticatable/controllers/public_helpers.rb +39 -0
  19. data/lib/devise_otp_authenticatable/controllers/url_helpers.rb +10 -0
  20. data/lib/devise_otp_authenticatable/engine.rb +2 -5
  21. data/lib/devise_otp_authenticatable/hooks/refreshable.rb +5 -0
  22. data/lib/devise_otp_authenticatable/models/otp_authenticatable.rb +22 -20
  23. data/lib/devise_otp_authenticatable/routes.rb +3 -1
  24. data/test/dummy/app/controllers/admin_posts_controller.rb +85 -0
  25. data/test/dummy/app/controllers/application_controller.rb +0 -1
  26. data/test/dummy/app/controllers/base_controller.rb +6 -0
  27. data/test/dummy/app/models/admin.rb +25 -0
  28. data/test/dummy/app/views/admin_posts/_form.html.erb +25 -0
  29. data/test/dummy/app/views/admin_posts/edit.html.erb +6 -0
  30. data/test/dummy/app/views/admin_posts/index.html.erb +25 -0
  31. data/test/dummy/app/views/admin_posts/new.html.erb +5 -0
  32. data/test/dummy/app/views/admin_posts/show.html.erb +15 -0
  33. data/test/dummy/app/views/base/home.html.erb +1 -0
  34. data/test/dummy/config/application.rb +0 -2
  35. data/test/dummy/config/routes.rb +4 -1
  36. data/test/dummy/db/migrate/20240604000001_create_admins.rb +9 -0
  37. data/test/dummy/db/migrate/20240604000002_add_devise_to_admins.rb +52 -0
  38. data/test/dummy/db/migrate/20240604000003_devise_otp_add_to_admins.rb +28 -0
  39. data/test/integration/disable_token_test.rb +53 -0
  40. data/test/integration/enable_otp_form_test.rb +57 -0
  41. data/test/integration/persistence_test.rb +3 -6
  42. data/test/integration/refresh_test.rb +32 -0
  43. data/test/integration/reset_token_test.rb +45 -0
  44. data/test/integration/sign_in_test.rb +10 -14
  45. data/test/integration/trackable_test.rb +50 -0
  46. data/test/integration_tests_helper.rb +24 -6
  47. data/test/models/otp_authenticatable_test.rb +62 -27
  48. data/test/test_helper.rb +1 -71
  49. metadata +26 -23
  50. data/lib/devise_otp_authenticatable/hooks/sessions.rb +0 -58
  51. data/lib/devise_otp_authenticatable/hooks.rb +0 -11
  52. data/test/integration/token_test.rb +0 -30
@@ -1,58 +0,0 @@
1
- module DeviseOtpAuthenticatable::Hooks
2
- module Sessions
3
- extend ActiveSupport::Concern
4
- include DeviseOtpAuthenticatable::Controllers::UrlHelpers
5
-
6
- included do
7
- alias_method :create, :create_with_otp
8
- end
9
-
10
- #
11
- # replaces Devise::SessionsController#create
12
- #
13
- def create_with_otp
14
- resource = warden.authenticate!(auth_options)
15
-
16
- devise_stored_location = stored_location_for(resource) # Grab the current stored location before it gets lost by warden.logout
17
- store_location_for(resource, devise_stored_location) # Restore it since #stored_location_for removes it
18
-
19
- otp_refresh_credentials_for(resource)
20
-
21
- yield resource if block_given?
22
- if otp_challenge_required_on?(resource)
23
- challenge = resource.generate_otp_challenge!
24
- warden.logout
25
- store_location_for(resource, devise_stored_location) # restore the stored location
26
- respond_with resource, location: otp_credential_path_for(resource, {challenge: challenge})
27
- elsif otp_mandatory_on?(resource) # if mandatory, log in user but send him to the must activate otp
28
- set_flash_message(:notice, :signed_in_but_otp) if is_navigational_format?
29
- sign_in(resource_name, resource)
30
- respond_with resource, location: otp_token_path_for(resource)
31
- else
32
- sign_in(resource_name, resource)
33
- respond_with resource, location: after_sign_in_path_for(resource)
34
- end
35
- end
36
-
37
- private
38
-
39
- #
40
- # resource should be challenged for otp
41
- #
42
- def otp_challenge_required_on?(resource)
43
- return false unless resource.respond_to?(:otp_enabled) && resource.respond_to?(:otp_auth_secret)
44
-
45
- resource.otp_enabled && !is_otp_trusted_browser_for?(resource)
46
- end
47
-
48
- #
49
- # the resource -should- have otp turned on, but it isn't
50
- #
51
- def otp_mandatory_on?(resource)
52
- return true if resource.class.otp_mandatory && !resource.otp_enabled
53
- return false unless resource.respond_to?(:otp_mandatory)
54
-
55
- resource.otp_mandatory && !resource.otp_enabled
56
- end
57
- end
58
- end
@@ -1,11 +0,0 @@
1
- module DeviseOtpAuthenticatable
2
- module Hooks
3
- autoload :Sessions, "devise_otp_authenticatable/hooks/sessions.rb"
4
-
5
- class << self
6
- def apply
7
- ::Devise::SessionsController.send(:include, Hooks::Sessions)
8
- end
9
- end
10
- end
11
- end
@@ -1,30 +0,0 @@
1
- require "test_helper"
2
- require "integration_tests_helper"
3
-
4
- class TokenTest < ActionDispatch::IntegrationTest
5
- def teardown
6
- Capybara.reset_sessions!
7
- end
8
-
9
- test "disabling OTP after successfully enabling" do
10
- # log in 1fa
11
- user = enable_otp_and_sign_in
12
- assert_equal user_otp_credential_path, current_path
13
-
14
- # otp 2fa
15
- fill_in "user_token", with: ROTP::TOTP.new(user.otp_auth_secret).at(Time.now)
16
- click_button "Submit Token"
17
- assert_equal root_path, current_path
18
-
19
- # disable OTP
20
- disable_otp
21
-
22
- # logout
23
- sign_out
24
-
25
- # log back in 1fa
26
- sign_user_in(user)
27
-
28
- assert_equal root_path, current_path
29
- end
30
- end