rails_base 0.75.6 → 0.81.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails_base/rails_base_query_checker.js +36 -0
  3. data/app/controllers/rails_base/admin_controller.rb +54 -9
  4. data/app/controllers/rails_base/mfa/evaluation_controller.rb +59 -0
  5. data/app/controllers/rails_base/mfa/register/sms_controller.rb +45 -0
  6. data/app/controllers/rails_base/mfa/register/totp_controller.rb +42 -0
  7. data/app/controllers/rails_base/mfa/validate/sms_controller.rb +83 -0
  8. data/app/controllers/rails_base/mfa/validate/totp_controller.rb +35 -0
  9. data/app/controllers/rails_base/secondary_authentication_controller.rb +40 -96
  10. data/app/controllers/rails_base/user_settings_controller.rb +11 -1
  11. data/app/controllers/rails_base/users/registrations_controller.rb +1 -1
  12. data/app/controllers/rails_base/users/sessions_controller.rb +17 -11
  13. data/app/controllers/rails_base_application_controller.rb +96 -1
  14. data/app/jobs/twilio_job.rb +1 -1
  15. data/app/mailers/rails_base/email_verification_mailer.rb +6 -4
  16. data/app/mailers/rails_base/event_mailer.rb +4 -2
  17. data/app/mailers/rails_base/mailer_kwarg_inject.rb +31 -0
  18. data/app/models/rails_base/user_constants.rb +6 -3
  19. data/app/models/rails_base/user_helper/totp/backup_method_options.rb +33 -0
  20. data/app/models/rails_base/user_helper/totp/class_options.rb +35 -0
  21. data/app/models/rails_base/user_helper/totp/consume_method_options.rb +60 -0
  22. data/app/models/rails_base/user_helper/totp.rb +41 -0
  23. data/app/models/user.rb +28 -13
  24. data/app/services/rails_base/authentication/constants.rb +1 -1
  25. data/app/services/rails_base/authentication/decision_twofa_type.rb +63 -30
  26. data/app/services/rails_base/authentication/send_forgot_password.rb +0 -1
  27. data/app/services/rails_base/authentication/single_sign_on_send.rb +1 -1
  28. data/app/services/rails_base/authentication/sso_verify_email.rb +3 -1
  29. data/app/services/rails_base/authentication/update_phone_send_verification.rb +2 -2
  30. data/app/services/rails_base/authentication/verify_forgot_password.rb +8 -11
  31. data/app/services/rails_base/mfa/decision.rb +70 -0
  32. data/app/services/rails_base/mfa/encrypt_token.rb +34 -0
  33. data/app/services/rails_base/mfa/sms/remove.rb +35 -0
  34. data/app/services/rails_base/{authentication/send_login_mfa_to_user.rb → mfa/sms/send.rb} +19 -13
  35. data/app/services/rails_base/mfa/sms/validate.rb +105 -0
  36. data/app/services/rails_base/mfa/strategy/base.rb +44 -0
  37. data/app/services/rails_base/mfa/strategy/every_request.rb +14 -0
  38. data/app/services/rails_base/mfa/strategy/skip_every_request.rb +14 -0
  39. data/app/services/rails_base/mfa/strategy/time_based.rb +24 -0
  40. data/app/services/rails_base/mfa/totp/helper.rb +21 -0
  41. data/app/services/rails_base/mfa/totp/otp_metadata.rb +19 -0
  42. data/app/services/rails_base/mfa/totp/remove.rb +40 -0
  43. data/app/services/rails_base/mfa/totp/validate_code.rb +52 -0
  44. data/app/services/rails_base/mfa/totp/validate_temporary_code.rb +37 -0
  45. data/app/services/rails_base/mfa.rb +18 -0
  46. data/app/services/rails_base/name_change.rb +3 -3
  47. data/app/views/layouts/rails_base/application.html.erb +10 -6
  48. data/app/views/rails_base/devise/passwords/new.html.erb +1 -1
  49. data/app/views/rails_base/mfa/_switch_mfa_type.html.erb +17 -0
  50. data/app/views/rails_base/mfa/validate/sms/sms_event_input.html.erb +2 -0
  51. data/app/views/rails_base/mfa/validate/totp/totp_event_input.html.erb +1 -0
  52. data/app/views/rails_base/secondary_authentication/reset_password_input.html.erb +4 -0
  53. data/app/views/rails_base/shared/_enable_mfa_auth_modal.html.erb +1 -1
  54. data/app/views/rails_base/shared/_logged_in_header.html.erb +1 -25
  55. data/app/views/rails_base/shared/_modify_mfa_auth_modal.html.erb +102 -3
  56. data/app/views/rails_base/shared/_request_link_alert.html.erb +48 -0
  57. data/app/views/rails_base/shared/mfa/sms/_login_input.html.erb +13 -0
  58. data/app/views/rails_base/shared/mfa/totp/_login_input.html.erb +22 -0
  59. data/app/views/rails_base/shared/totp/_add_authenticator.html.erb +76 -0
  60. data/app/views/rails_base/shared/totp/_add_authenticator_modal.html.erb +25 -0
  61. data/app/views/rails_base/shared/totp/_confirm_code.html.erb +31 -0
  62. data/app/views/rails_base/shared/totp/_confirm_code_ajax.html.erb +3 -0
  63. data/app/views/rails_base/shared/totp/_confirm_code_rest.html.erb +5 -0
  64. data/app/views/rails_base/shared/totp/_remove_authenticator_modal.html.erb +50 -0
  65. data/app/views/rails_base/user_settings/index.html.erb +102 -3
  66. data/config/initializers/admin_action_helper.rb +44 -8
  67. data/config/routes.rb +42 -7
  68. data/db/migrate/20240808013706_add_totp_to_users.rb +9 -0
  69. data/db/migrate/20240825012724_reconfigure_mfa_variable_names.rb +10 -0
  70. data/lib/rails_base/admin/action_helper.rb +0 -1
  71. data/lib/rails_base/admin/default_index_tile.rb +3 -3
  72. data/lib/rails_base/config.rb +26 -22
  73. data/lib/rails_base/configuration/admin.rb +5 -5
  74. data/lib/rails_base/configuration/base.rb +1 -0
  75. data/lib/rails_base/configuration/mfa.rb +27 -60
  76. data/lib/rails_base/configuration/totp.rb +82 -0
  77. data/lib/rails_base/configuration/twilio.rb +85 -0
  78. data/lib/rails_base/mfa_event.rb +186 -0
  79. data/lib/rails_base/request_link.rb +27 -0
  80. data/lib/rails_base/version.rb +3 -3
  81. data/lib/rails_base.rb +2 -0
  82. data/lib/twilio_helper.rb +3 -3
  83. metadata +131 -64
  84. data/app/controllers/rails_base/mfa_auth_controller.rb +0 -50
  85. data/app/services/rails_base/authentication/mfa_set_encrypt_token.rb +0 -32
  86. data/app/services/rails_base/authentication/mfa_validator.rb +0 -88
  87. data/app/views/rails_base/mfa_auth/mfa_code.html.erb +0 -11
  88. data/app/views/rails_base/secondary_authentication/forgot_password.html.erb +0 -9
@@ -1,88 +0,0 @@
1
- module RailsBase::Authentication
2
- class MfaValidator < RailsBase::ServiceBase
3
- delegate :params, to: :context
4
- delegate :session_mfa_user_id, to: :context
5
- delegate :current_user, to: :context
6
- delegate :input_reason, to: :context
7
-
8
- def call
9
- array = convert_to_array
10
- if array.length != Constants::MFA_LENGTH
11
- log(level: :warn, msg: "Not enough params for MFA code. Given #{array}. Expected of length #{Constants::MFA_LENGTH}")
12
- context.fail!(message: Constants::MV_FISHY, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :alert)
13
- end
14
-
15
- mfa_code = array.join
16
- log(level: :info, msg: "mfa code received: #{mfa_code}")
17
- datum = get_short_lived_datum(mfa_code)
18
- log(level: :info, msg: "Datum returned with: #{datum}")
19
-
20
- validate_datum?(datum)
21
- validate_user_consistency?(datum)
22
- validate_current_user?(datum) if current_user
23
-
24
- context.user = datum[:user]
25
- end
26
-
27
- def validate_current_user?(datum)
28
- return true if current_user.id == datum[:user].id
29
-
30
- # User MFA for a different user matched the session token
31
- # However, those did not match the current user signed in
32
- # Something is very 🐟
33
- log(level: :error, msg: "Someone is a teapot. Current logged in user does not equal mfa code.")
34
- context.fail!(message: 'You are a teapot', redirect_url: Constants::URL_HELPER.signout_path, level: :warn)
35
- end
36
-
37
- def validate_datum?(datum)
38
- return true if datum[:valid]
39
-
40
- if datum[:found]
41
- # MFA is either expired or the incorrect reason. Either way it does not match
42
- msg = "Errors with MFA: #{datum[:invalid_reason].join(", ")}. Please login again"
43
- log(level: :warn, msg: msg)
44
- context.fail!(message: msg, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :warn)
45
- end
46
-
47
- # MFA does not exist for any reason type
48
- log(level: :warn, msg: "Could not find MFA code. Incorrect MFA code")
49
-
50
- context.fail!(message: "Incorrect MFA code.", redirect_url: Constants::URL_HELPER.mfa_code_path, level: :warn)
51
- end
52
-
53
- def validate_user_consistency?(datum)
54
- return true if datum[:user].id == session_mfa_user_id.to_i
55
- log(level: :warn, msg: "Datum user does not match session user. [#{datum[:user].id}, #{session_mfa_user_id.to_i}]")
56
-
57
- # MFA session token user does not match the datum user
58
- # Something is very 🐟
59
- context.fail!(message: Constants::MV_FISHY, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :alert)
60
- end
61
-
62
- def get_short_lived_datum(mfa_code)
63
- log(level: :debug, msg: "Looking for #{mfa_code} with reason #{reason}")
64
- ShortLivedData.find_datum(data: mfa_code, reason: reason)
65
- end
66
-
67
- def convert_to_array
68
- array = []
69
- return array unless params.dig(:mfa).respond_to? :keys
70
-
71
- Constants::MFA_LENGTH.times do |index|
72
- var_name = "#{Constants::MV_BASE_NAME}#{index}".to_sym
73
- array << params[:mfa][var_name]
74
- end
75
-
76
- array.compact
77
- end
78
-
79
- def reason
80
- input_reason || Constants::MFA_REASON
81
- end
82
-
83
- def validate!
84
- raise 'Expected the params passed' if params.nil?
85
- raise 'session_mfa_user_id is not present' if session_mfa_user_id.nil?
86
- end
87
- end
88
- end
@@ -1,11 +0,0 @@
1
-
2
- <div class="row" >
3
- <div class="col-md-8 offset-md-2" style="position: absolute; top:25%">
4
- <%= render partial: 'rails_base/shared/mfa_input_layout', locals: { url: RailsBase.url_routes.mfa_code_verify_path, size: 30, masked_phone: @masked_phone }%>
5
- <br>
6
- <div class="text-center">
7
- <%= button_to 'Resend MFA', RailsBase.url_routes.resend_mfa_path, method: :post, class: 'btn btn_warning', style: 'width: 25%;' %>
8
- </div>
9
- </div>
10
- </div>
11
-
@@ -1,9 +0,0 @@
1
-
2
- <% if @mfa_flow %>
3
- <h3 class='text-center'>If you did not receive a text with instructions, please go through the flow again</h2>
4
- <%= render partial: 'rails_base/shared/mfa_input_layout', locals: { url: RailsBase.url_routes.forgot_password_with_mfa_auth_path(data: @data), size: 30, masked_phone: @user.masked_phone }%>
5
- <% else %>
6
- <h2 class='text-center'>Reset your password <%= @user.full_name%></h2>
7
- <%= render partial: 'rails_base/shared/reset_password_form', locals: { sign_in_flow: true, url: RailsBase.url_routes.reset_password_auth_path(data: @data) }%>
8
- <% end %>
9
-