rails_base 0.51.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 (194) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +32 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/rails_base/manifest.js +3 -0
  6. data/app/assets/images/rails_base/favicon.ico +0 -0
  7. data/app/assets/javascripts/rails_base/admin.js +2 -0
  8. data/app/assets/javascripts/rails_base/application.js +22 -0
  9. data/app/assets/javascripts/rails_base/cable.js +13 -0
  10. data/app/assets/javascripts/rails_base/mfa_auth.coffee +3 -0
  11. data/app/assets/javascripts/rails_base/secondary_authentication.coffee +3 -0
  12. data/app/assets/javascripts/rails_base/sessions.js +152 -0
  13. data/app/assets/javascripts/rails_base/user_settings.coffee +3 -0
  14. data/app/assets/stylesheets/rails_base/admin.css +4 -0
  15. data/app/assets/stylesheets/rails_base/application.scss +15 -0
  16. data/app/assets/stylesheets/rails_base/mfa_auth.scss +3 -0
  17. data/app/assets/stylesheets/rails_base/scaffolds.scss +84 -0
  18. data/app/assets/stylesheets/rails_base/secondary_authentication.scss +3 -0
  19. data/app/assets/stylesheets/rails_base/user_settings.scss +3 -0
  20. data/app/controllers/rails_base/admin_controller.rb +315 -0
  21. data/app/controllers/rails_base/application_controller.rb +153 -0
  22. data/app/controllers/rails_base/errors_controller.rb +29 -0
  23. data/app/controllers/rails_base/mfa_auth_controller.rb +50 -0
  24. data/app/controllers/rails_base/secondary_authentication_controller.rb +224 -0
  25. data/app/controllers/rails_base/switch_user_controller.rb +29 -0
  26. data/app/controllers/rails_base/user_settings_controller.rb +81 -0
  27. data/app/controllers/rails_base/users/passwords_controller.rb +19 -0
  28. data/app/controllers/rails_base/users/registrations_controller.rb +80 -0
  29. data/app/controllers/rails_base/users/sessions_controller.rb +108 -0
  30. data/app/helpers/rails_base/admin_helper.rb +107 -0
  31. data/app/helpers/rails_base/appearance_helper.rb +58 -0
  32. data/app/helpers/rails_base/application_helper.rb +26 -0
  33. data/app/helpers/rails_base/capture_reference_helper.rb +57 -0
  34. data/app/helpers/rails_base/mfa_auth_helper.rb +2 -0
  35. data/app/helpers/rails_base/secondary_authentication_helper.rb +2 -0
  36. data/app/helpers/rails_base/user_field_validators.rb +108 -0
  37. data/app/helpers/rails_base/user_settings_helper.rb +22 -0
  38. data/app/jobs/rails_base/application_job.rb +10 -0
  39. data/app/jobs/twilio_job.rb +9 -0
  40. data/app/mailers/rails_base/application_mailer.rb +9 -0
  41. data/app/mailers/rails_base/email_verification_mailer.rb +22 -0
  42. data/app/mailers/rails_base/event_mailer.rb +16 -0
  43. data/app/models/admin_action.rb +119 -0
  44. data/app/models/rails_base/application_record.rb +22 -0
  45. data/app/models/rails_base/user_constants.rb +28 -0
  46. data/app/models/secret.rb +37 -0
  47. data/app/models/short_lived_data.rb +132 -0
  48. data/app/models/user.rb +143 -0
  49. data/app/services/rails_base/admin_risky_mfa_send.rb +80 -0
  50. data/app/services/rails_base/admin_update_attribute.rb +100 -0
  51. data/app/services/rails_base/authentication/authenticate_user.rb +28 -0
  52. data/app/services/rails_base/authentication/constants.rb +60 -0
  53. data/app/services/rails_base/authentication/decision_twofa_type.rb +76 -0
  54. data/app/services/rails_base/authentication/destroy_user.rb +45 -0
  55. data/app/services/rails_base/authentication/mfa_set_encrypt_token.rb +32 -0
  56. data/app/services/rails_base/authentication/mfa_validator.rb +88 -0
  57. data/app/services/rails_base/authentication/modify_password.rb +67 -0
  58. data/app/services/rails_base/authentication/send_forgot_password.rb +26 -0
  59. data/app/services/rails_base/authentication/send_login_mfa_to_user.rb +77 -0
  60. data/app/services/rails_base/authentication/send_verification_email.rb +103 -0
  61. data/app/services/rails_base/authentication/session_token_verifier.rb +31 -0
  62. data/app/services/rails_base/authentication/single_sign_on_create.rb +44 -0
  63. data/app/services/rails_base/authentication/single_sign_on_send.rb +101 -0
  64. data/app/services/rails_base/authentication/single_sign_on_verify.rb +42 -0
  65. data/app/services/rails_base/authentication/sso_verify_email.rb +43 -0
  66. data/app/services/rails_base/authentication/update_phone_send_verification.rb +46 -0
  67. data/app/services/rails_base/authentication/verify_forgot_password.rb +46 -0
  68. data/app/services/rails_base/email_change.rb +20 -0
  69. data/app/services/rails_base/encryption.rb +87 -0
  70. data/app/services/rails_base/name_change.rb +71 -0
  71. data/app/services/rails_base/service_base.rb +65 -0
  72. data/app/services/rails_base/service_logging.rb +23 -0
  73. data/app/views/layouts/rails_base/application.html.erb +185 -0
  74. data/app/views/layouts/rails_base/mailer.html.erb +13 -0
  75. data/app/views/layouts/rails_base/mailer.text.erb +1 -0
  76. data/app/views/new.html.erb +4 -0
  77. data/app/views/rails_base/admin/history.html.erb +26 -0
  78. data/app/views/rails_base/admin/index.html.erb +149 -0
  79. data/app/views/rails_base/admin/show_config.html.erb +18 -0
  80. data/app/views/rails_base/devise/confirmations/new.html.erb +16 -0
  81. data/app/views/rails_base/devise/mailer/confirmation_instructions.html.erb +5 -0
  82. data/app/views/rails_base/devise/mailer/email_changed.html.erb +7 -0
  83. data/app/views/rails_base/devise/mailer/password_change.html.erb +3 -0
  84. data/app/views/rails_base/devise/mailer/reset_password_instructions.html.erb +8 -0
  85. data/app/views/rails_base/devise/mailer/unlock_instructions.html.erb +7 -0
  86. data/app/views/rails_base/devise/passwords/edit.html.erb +25 -0
  87. data/app/views/rails_base/devise/passwords/new.html.erb +27 -0
  88. data/app/views/rails_base/devise/registrations/edit.html.erb +43 -0
  89. data/app/views/rails_base/devise/registrations/new.html.erb +123 -0
  90. data/app/views/rails_base/devise/sessions/new.html.erb +4 -0
  91. data/app/views/rails_base/devise/shared/_error_messages.html.erb +15 -0
  92. data/app/views/rails_base/devise/shared/_links.html.erb +25 -0
  93. data/app/views/rails_base/devise/unlocks/new.html.erb +16 -0
  94. data/app/views/rails_base/email_verification_mailer/email_verification.html.erb +25 -0
  95. data/app/views/rails_base/email_verification_mailer/event.html.erb +20 -0
  96. data/app/views/rails_base/email_verification_mailer/forgot_password.html.erb +22 -0
  97. data/app/views/rails_base/errors/internal_error.html.erb +1 -0
  98. data/app/views/rails_base/errors/not_found.html.erb +1 -0
  99. data/app/views/rails_base/errors/unacceptable.html.erb +1 -0
  100. data/app/views/rails_base/event_mailer/event.html.erb +10 -0
  101. data/app/views/rails_base/mfa_auth/mfa_code.html.erb +10 -0
  102. data/app/views/rails_base/secondary_authentication/after_email_login_session_new.html.erb +3 -0
  103. data/app/views/rails_base/secondary_authentication/forgot_password.html.erb +9 -0
  104. data/app/views/rails_base/secondary_authentication/remove_me.html.erb +1 -0
  105. data/app/views/rails_base/secondary_authentication/static.html.erb +5 -0
  106. data/app/views/rails_base/shared/_admin_actions_modal.html.erb +65 -0
  107. data/app/views/rails_base/shared/_admin_config_class.html.erb +52 -0
  108. data/app/views/rails_base/shared/_admin_history.html.erb +86 -0
  109. data/app/views/rails_base/shared/_admin_modify_email.html.erb +78 -0
  110. data/app/views/rails_base/shared/_admin_modify_name.html.erb +107 -0
  111. data/app/views/rails_base/shared/_admin_modify_phone.html.erb +87 -0
  112. data/app/views/rails_base/shared/_admin_modify_text.html.erb +35 -0
  113. data/app/views/rails_base/shared/_admin_risky_change.html.erb +57 -0
  114. data/app/views/rails_base/shared/_admin_risky_mfa.html.erb +74 -0
  115. data/app/views/rails_base/shared/_admin_selector_dropdown.html.erb +70 -0
  116. data/app/views/rails_base/shared/_admin_toggle_button.html.erb +72 -0
  117. data/app/views/rails_base/shared/_admin_warning_alert.html.erb +7 -0
  118. data/app/views/rails_base/shared/_appearance_mode_selector.html.erb +183 -0
  119. data/app/views/rails_base/shared/_custom_form_validation_javascript.html.erb +129 -0
  120. data/app/views/rails_base/shared/_enable_mfa_auth_modal.html.erb +105 -0
  121. data/app/views/rails_base/shared/_error_pages.html.erb +123 -0
  122. data/app/views/rails_base/shared/_logged_in_header.html.erb +123 -0
  123. data/app/views/rails_base/shared/_logged_out_header.html.erb +14 -0
  124. data/app/views/rails_base/shared/_mfa_input_layout.html.erb +5 -0
  125. data/app/views/rails_base/shared/_mfa_input_layout_default.html.erb +97 -0
  126. data/app/views/rails_base/shared/_mfa_input_layout_fallback.html.erb +55 -0
  127. data/app/views/rails_base/shared/_modify_mfa_auth_modal.html.erb +20 -0
  128. data/app/views/rails_base/shared/_password_confirm_javascript.html.erb +71 -0
  129. data/app/views/rails_base/shared/_reset_password_form.html.erb +111 -0
  130. data/app/views/rails_base/shared/_session_create_form.html.erb +32 -0
  131. data/app/views/rails_base/shared/_session_timeout_modal.html.erb +76 -0
  132. data/app/views/rails_base/switch_user/_widget.html.erb +5 -0
  133. data/app/views/rails_base/user_settings/_confirm_destroy_user.html.erb +42 -0
  134. data/app/views/rails_base/user_settings/_destroy_user.html.erb +106 -0
  135. data/app/views/rails_base/user_settings/_modify_name.html.erb +71 -0
  136. data/app/views/rails_base/user_settings/_modify_password.html.erb +101 -0
  137. data/app/views/rails_base/user_settings/_modify_password_update_password.html.erb +2 -0
  138. data/app/views/rails_base/user_settings/index.html.erb +54 -0
  139. data/config/initializers/01_rails_config.rb +19 -0
  140. data/config/initializers/admin_action_helper.rb +88 -0
  141. data/config/initializers/browser.rb +4 -0
  142. data/config/initializers/default_logged_in_headers.rb +23 -0
  143. data/config/initializers/devise.rb +314 -0
  144. data/config/initializers/encryption.rb +2 -0
  145. data/config/initializers/switch_user.rb +58 -0
  146. data/config/initializers/switch_user_helper.rb +29 -0
  147. data/config/locales/devise.en.yml +65 -0
  148. data/config/locales/en.yml +58 -0
  149. data/config/routes.rb +114 -0
  150. data/db/migrate/20210212175453_devise_create_rails_base_users.rb +56 -0
  151. data/db/migrate/20210212190537_create_rails_base_short_lived_data.rb +19 -0
  152. data/db/migrate/20210212192645_create_rails_base_secrets.rb +11 -0
  153. data/db/migrate/20210406015744_create_rails_base_admin_actions.rb +17 -0
  154. data/db/seeds.rb +23 -0
  155. data/lib/link_decision_helper.rb +71 -0
  156. data/lib/rails_base.rb +50 -0
  157. data/lib/rails_base/admin/action_cache.rb +99 -0
  158. data/lib/rails_base/admin/action_helper.rb +134 -0
  159. data/lib/rails_base/admin/default_index_tile.rb +176 -0
  160. data/lib/rails_base/admin/index_tile.rb +186 -0
  161. data/lib/rails_base/config.rb +52 -0
  162. data/lib/rails_base/configuration/active_job.rb +38 -0
  163. data/lib/rails_base/configuration/admin.rb +231 -0
  164. data/lib/rails_base/configuration/app.rb +52 -0
  165. data/lib/rails_base/configuration/appearance.rb +131 -0
  166. data/lib/rails_base/configuration/authentication.rb +37 -0
  167. data/lib/rails_base/configuration/base.rb +209 -0
  168. data/lib/rails_base/configuration/display/background_color.rb +25 -0
  169. data/lib/rails_base/configuration/display/btn_danger.rb +25 -0
  170. data/lib/rails_base/configuration/display/btn_dark.rb +25 -0
  171. data/lib/rails_base/configuration/display/btn_info.rb +25 -0
  172. data/lib/rails_base/configuration/display/btn_light.rb +25 -0
  173. data/lib/rails_base/configuration/display/btn_primary.rb +25 -0
  174. data/lib/rails_base/configuration/display/btn_secondary.rb +25 -0
  175. data/lib/rails_base/configuration/display/btn_success.rb +25 -0
  176. data/lib/rails_base/configuration/display/btn_warning.rb +25 -0
  177. data/lib/rails_base/configuration/display/footer.rb +54 -0
  178. data/lib/rails_base/configuration/display/navbar.rb +25 -0
  179. data/lib/rails_base/configuration/display/table_body.rb +25 -0
  180. data/lib/rails_base/configuration/display/table_header.rb +25 -0
  181. data/lib/rails_base/configuration/display/text.rb +26 -0
  182. data/lib/rails_base/configuration/exceptions_app.rb +25 -0
  183. data/lib/rails_base/configuration/login_behavior.rb +17 -0
  184. data/lib/rails_base/configuration/mailer.rb +116 -0
  185. data/lib/rails_base/configuration/mfa.rb +84 -0
  186. data/lib/rails_base/configuration/owner.rb +17 -0
  187. data/lib/rails_base/configuration/redis.rb +29 -0
  188. data/lib/rails_base/configuration/user.rb +43 -0
  189. data/lib/rails_base/engine.rb +51 -0
  190. data/lib/rails_base/version.rb +10 -0
  191. data/lib/tasks/rails_base_tasks.rake +4 -0
  192. data/lib/twilio_helper.rb +26 -0
  193. data/lib/velocity_limiter.rb +91 -0
  194. metadata +619 -0
@@ -0,0 +1,123 @@
1
+ <nav class="navbar navbar-expand-lg navbar-light bg-light">
2
+ <a class="navbar-brand" href="#"><%= RailsBase.config.app.web_title_logged_in(current_user)%></a>
3
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
4
+ <span class="navbar-toggler-icon"></span>
5
+ </button>
6
+
7
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
8
+ <ul class="navbar-nav mr-auto">
9
+ <% Rails.application.config.n_logged_in.each_with_index do |link_helper, index| %>
10
+ <% next unless link_helper.display?(current_user) %>
11
+ <li class="nav-item <%= 'active' if index==0 %>">
12
+ <a class="nav-link" href="<%= link_helper.url %>" <%= "target='_blank'" if link_helper.blank? %> >
13
+ <%= link_helper.title %>
14
+ <% if index==0 %>
15
+ <span class="sr-only">(current)</span>
16
+ <% end %>
17
+ </a>
18
+ </li>
19
+ <% end %>
20
+ </ul>
21
+ <% if defined?(@error_page)%>
22
+ <button onclick="goBack()" class="btn btn_warning">
23
+ &#8592; Return to Previous page
24
+ </button>
25
+ <%else%>
26
+ <button type="button" class="btn btn_secondary" data-toggle="modal" data-target="#settings_modal">
27
+ My Settings
28
+ </button>
29
+ <%end%>
30
+ </div>
31
+ </nav>
32
+
33
+ <!-- Modal -->
34
+ <div class="modal fade" id="settings_modal" tabindex="-1" role="dialog" aria-labelledby="appearance_mode_selectorTitle" aria-hidden="true">
35
+ <div class="modal-dialog modal-dialog-centered" role="document">
36
+ <div class="modal-content">
37
+ <div class="modal-header">
38
+ <h5 class="modal-title" id="appearance_mode_selectorTitle">My Settings</h5>
39
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
40
+ <span aria-hidden="true">&times;</span>
41
+ </button>
42
+ </div>
43
+ <div class="modal-body ">
44
+ <div class='row'>
45
+ <div class='col'>
46
+ <% if RailsBase.config.mfa.enable? %>
47
+ <% if current_user.mfa_enabled %>
48
+ <button type="button" class="btn btn-block btn_info close-me" data-toggle="modal" data-target="#modifyMfamodal">
49
+ Modify 2fa Auth
50
+ </button>
51
+ <% else %>
52
+ <button type="button" class="btn btn-block btn_info close-me" data-toggle="modal" data-target="#enableMfamodal">
53
+ Enable 2fa Auth
54
+ </button>
55
+ <% end %>
56
+ <% end %>
57
+ </div>
58
+ </div>
59
+ </br>
60
+ <div class='row'>
61
+ <div class='col'>
62
+ <a class="btn btn_info btn-block" href="<%=RailsBase.url_routes.user_settings_path%>" role="button">Modify User</a>
63
+ </div>
64
+ </div>
65
+ </br>
66
+ <div class='row'>
67
+ <div class='col'>
68
+ <%= render partial: 'rails_base/shared/appearance_mode_selector', locals: { btn: 'btn-block', display: true } %>
69
+ </div>
70
+ </div>
71
+ </br>
72
+ <div class="dropdown-divider"></div>
73
+ <div class='row'>
74
+ <div class='col'>
75
+ <%= button_to 'Logout', RailsBase.url_routes.signout_path, method: :delete, class: 'btn btn_danger btn-block' %>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+
83
+ <% if RailsBase.config.mfa.enable? %>
84
+ <% if current_user.mfa_enabled %>
85
+ <%= render partial: 'rails_base/shared/modify_mfa_auth_modal'%>
86
+ <% else %>
87
+ <%= render partial: 'rails_base/shared/enable_mfa_auth_modal'%>
88
+ <% end %>
89
+ <% end %>
90
+
91
+ <% if @__admin_actions_array && @__admin_actions_array.present? %>
92
+ <%= render partial: 'rails_base/shared/admin_actions_modal'%>
93
+ <% end %>
94
+
95
+ <% if session[RailsBase::Authentication::Constants::ADMIN_REMEMBER_REASON].present? %>
96
+ <div class="alert alert-warning" role="alert">
97
+ <%= render partial: 'rails_base/shared/admin_warning_alert' %>
98
+ </div>
99
+ <% end %>
100
+
101
+ <% if RailsBase.config.auth.session_timeout %>
102
+ <% show_warning = RailsBase.config.auth.session_timeout_warning %>
103
+ <% if show_warning %>
104
+ <%= render partial: 'rails_base/shared/session_timeout_modal'%>
105
+ <% end %>
106
+ <script type="text/javascript">
107
+ <%
108
+ # this is to account for the delay
109
+ timeout = RailsBase.config.auth.session_timeout
110
+ %>
111
+ sessionManager.init(<%= timeout %>, '<%= RailsBase.url_routes.heartbeat_without_auth_path %>', '<%= RailsBase.url_routes.heartbeat_with_auth_path %>' ,$('meta[name="csrf-token"]').attr('content'), <%= show_warning %>)
112
+
113
+ $('.close-me').on('click', function (e) {
114
+ $("#settings_modal").modal('hide');
115
+ })
116
+ $('#settings_modal').on('shown.bs.modal', function (e) {
117
+ $('.navbar-collapse').collapse('hide');
118
+ });
119
+ </script>
120
+ <% end%>
121
+
122
+
123
+
@@ -0,0 +1,14 @@
1
+ <nav class="navbar navbar-expand-lg navbar-light bg-light">
2
+ <a class="navbar-brand" href="#"><%= RailsBase.config.app.web_title_logged_out %></a>
3
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
4
+ <span class="navbar-toggler-icon"></span>
5
+ </button>
6
+
7
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
8
+ <div class="mr-auto">
9
+ </div>
10
+ <a class="btn btn_primary my-2 my-sm-0" href="<%=Rails.application.routes.url_helpers.new_user_registration_path%>" role="button">Sign Up</a>
11
+ </div>
12
+ </nav>
13
+
14
+ <%= render partial: 'rails_base/shared/appearance_mode_selector', locals: { btn: 'btn', display: false } %>
@@ -0,0 +1,5 @@
1
+ <% if !mfa_fallback? %>
2
+ <%= render partial: 'rails_base/shared/mfa_input_layout_fallback', locals: { url: url, size: size, masked_phone: masked_phone}%>
3
+ <% else %>
4
+ <%= render partial: 'rails_base/shared/mfa_input_layout_default', locals: { url: url, size: size, masked_phone: masked_phone}%>
5
+ <% end %>
@@ -0,0 +1,97 @@
1
+ <%= form_for :mfa, url: url do |f| %>
2
+ <div class="form-group text-center">
3
+ <div class="text-center" style="font-size: <%= size %>px">
4
+ Please enter the MFA code you received at <%= masked_phone %>
5
+ </div>
6
+ <span>
7
+ <div class style="font-size: <%= size %>px;">
8
+ <% RailsBase::Authentication::Constants::MFA_LENGTH.times do |index| %>
9
+ <%= f.text_field "#{RailsBase::Authentication::Constants::MV_BASE_NAME}#{index}", type: "tel", style: "caret-color: transparent; text-align: center;", class: "numbersOnly digit mfa-validator", size: 1, maxlength: 1, autofocus: index==0 %>
10
+ <% end %>
11
+ </div>
12
+ </span>
13
+ </div>
14
+ <div class="text-center">
15
+ <% unless defined?(disable) %>
16
+ <%= f.submit "submit", class: "submit-mfa btn btn_success", style: "width: 50%;", disabled: true %>
17
+ <%end%>
18
+ </div>
19
+ <% end %>
20
+
21
+
22
+ <script type="text/javascript">
23
+ $('.mfa-validator').keyup(function(event){
24
+ this.value = this.value.replace(/[^0-9\.]/g,'');
25
+ var valid_char = this.value != '';
26
+ if(valid_char){
27
+ var next_mfa_id = get_next_mfa($(this).attr('id'));
28
+ if(next_mfa_id==undefined){
29
+ $(this).focus();
30
+ return
31
+ }
32
+ $(`#${next_mfa_id}`).focus();
33
+ } else {
34
+ $(this).focus();
35
+ }
36
+ submit_button_prop();
37
+ })
38
+
39
+ $(".mfa-validator").click(function(event){
40
+ var next_mfa_id = $(this).attr('id');
41
+ $(`#${next_mfa_id}`).val('');
42
+ while (next_mfa_id = get_next_mfa(next_mfa_id)) {
43
+ $(`#${next_mfa_id}`).val('');
44
+ }
45
+ $('.submit-mfa').prop('disabled', true);
46
+ });
47
+
48
+ function submit_button_prop(){
49
+ var disabled = false
50
+ var inputs = $(".mfa-validator");
51
+ for(var i = 0; i < inputs.length; i++){
52
+ if($(inputs[i]).val().length==0){
53
+ disabled = true;
54
+ break;
55
+ }
56
+ }
57
+ $('.submit-mfa').prop('disabled', disabled);
58
+ }
59
+
60
+ function get_next_mfa(elem_id) {
61
+ var max_length = <%= RailsBase::Authentication::Constants::MFA_LENGTH %>;
62
+ var elem_array = elem_id.split('_');
63
+ var last_elem = elem_array.pop();
64
+ if(isNaN(last_elem)){
65
+ return undefined
66
+ }
67
+ var last_elem_as_int = parseInt(last_elem)
68
+ if(last_elem_as_int>=max_length){
69
+ return undefined
70
+ }
71
+ elem_array.push(last_elem_as_int + 1)
72
+ return elem_array.join('_')
73
+ }
74
+
75
+ function paste_mfa_input(pastedData){
76
+ var pastedDataOg = e.originalEvent.clipboardData.getData('text');
77
+ if(pastedDataOg.length != <%= RailsBase::Authentication::Constants::MFA_LENGTH %>){
78
+ return;
79
+ }
80
+ pastedData = pastedDataOg.split('');
81
+ pastedDataIsNotANumber = pastedData.every(function (pos) {
82
+ return isNaN(pos)
83
+ });
84
+
85
+ if(pastedDataIsNotANumber) {
86
+ return;
87
+ }
88
+
89
+ <% # We know pasted data is correct length %>
90
+ <% # We know pasted data is all numbers %>
91
+ <% # Paste it into the correct boxes %>
92
+
93
+ <% RailsBase::Authentication::Constants::MFA_LENGTH.times do |index| %>
94
+ $("#<%= "mfa_#{RailsBase::Authentication::Constants::MV_BASE_NAME}#{index}"%>").val(pastedData[<%= index %>])
95
+ <% end %>
96
+ }
97
+ </script>
@@ -0,0 +1,55 @@
1
+ <%= form_for :mfa, url: url, html: { class: 'mfa_submission', novalidate: true} do |f| %>
2
+ <div class="form-group text-center">
3
+ <div class="text-center" style="font-size: <%= size %>px">
4
+ Please enter the MFA code you received at <%= masked_phone %>
5
+ </div>
6
+ <div class='row justify-content-center' style="font-size: <%= size %>px;">
7
+ <div class="col-xs-2">
8
+ <%= text_field_tag 'alternate_mfa', nil, maxlength: RailsBase::Authentication::Constants::MFA_LENGTH, class: 'text-center form-control', autofocus: true, type: "tel", style: "font-size:#{size}px;" %>
9
+ <div class="invalid-feedback">
10
+ 2FA code must be <%= RailsBase::Authentication::Constants::MFA_LENGTH %> numbers
11
+ </div>
12
+ </div>
13
+ </div>
14
+ <% RailsBase::Authentication::Constants::MFA_LENGTH.times do |index| %>
15
+ <%= f.hidden_field "#{RailsBase::Authentication::Constants::MV_BASE_NAME}#{index}", style: "caret-color: transparent; text-align: center;", class: "numbersOnly digit mfa-validator form-control", size: 1, maxlength: 1, autofocus: index==0 %>
16
+ <% end %>
17
+ </div>
18
+ <div class="text-center">
19
+ <%= f.submit "submit", class: "submit-mfa btn btn_success", style: "width: 50%;"%>
20
+ </div>
21
+ <% end %>
22
+
23
+ <script type="text/javascript">
24
+ $('.mfa_submission').submit(function( event ) {
25
+ console.log($('#alternate_mfa').val())
26
+ var length_match = $('#alternate_mfa').val().length === <%= RailsBase::Authentication::Constants::MFA_LENGTH %>;
27
+ var valid_data = !invalidate_data($('#alternate_mfa').val());
28
+ if (length_match && valid_data){
29
+ set_values($('#alternate_mfa').val())
30
+ return
31
+ }
32
+
33
+ event.preventDefault();
34
+ event.stopPropagation();
35
+ $('#alternate_mfa').addClass('is-invalid');
36
+ $('#alternate_mfa').val('')
37
+ $('#alternate_mfa').focus();
38
+ });
39
+
40
+ function set_values(data) {
41
+ var dataArr = data.split('')
42
+ <% RailsBase::Authentication::Constants::MFA_LENGTH.times do |index| %>
43
+ $('#<%="mfa_#{RailsBase::Authentication::Constants::MV_BASE_NAME}#{index}"%>').val(data[<%=index%>])
44
+ <% end %>
45
+ }
46
+
47
+ function invalidate_data(data) {
48
+ dataArr = data.split('');
49
+ var dataIsNotANumber = dataArr.every(function (pos) {
50
+ return isNaN(pos)
51
+ });
52
+ console.log(dataIsNotANumber)
53
+ return dataIsNotANumber
54
+ }
55
+ </script>
@@ -0,0 +1,20 @@
1
+ <% confirm = "Disabling 2fa on your account will make it more vulnerable. Are you sure you want to disable two factor authentication via SMS text?" %>
2
+
3
+ <div class="modal fade" id="modifyMfamodal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
4
+ <div class="modal-dialog modal-lg" role="document">
5
+ <div class="modal-content">
6
+ <div class="modal-header">
7
+ <h5 class="modal-title" id="exampleModalLabel">Disable MFA via SMS</h5>
8
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
9
+ <span aria-hidden="true">&times;</span>
10
+ </button>
11
+ </div>
12
+ <div class="modal-body">
13
+ <%= button_to "Disable 2fa", RailsBase.url_routes.remove_phone_registration_mfa_path, data: { confirm: confirm }, method: :delete, class: "btn btn_danger btn-block" %>
14
+ </div>
15
+ <div class="modal-footer">
16
+ <button type="button" class="mr-auto btn btn_secondary" data-dismiss="modal">Close</button>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
@@ -0,0 +1,71 @@
1
+ <script type="text/javascript">
2
+ function user_password_validity(){
3
+ var value = $('#<%= id_password %>').val()
4
+ if (value < <%= RailsBase::Authentication::Constants::MP_MIN_LENGTH %>){
5
+ return false
6
+ }
7
+
8
+ var numbers = value.replace(/[a-zA-Z]/g,'')
9
+ if(numbers.length < <%= RailsBase::Authentication::Constants::MP_MIN_NUMS %>){
10
+ return false
11
+ }
12
+
13
+ var chars = value.replace(/[0-9]/g,'')
14
+ if(chars.length < <%= RailsBase::Authentication::Constants::MP_MIN_ALPHA %>){
15
+ return false
16
+ }
17
+
18
+ var unknown = value.replace(/[0-9a-zA-Z]/g,'')
19
+ if(unknown.length > 0) {
20
+ return false
21
+ }
22
+ true
23
+ };
24
+
25
+ $('#<%= id_password %>').focus(function() {
26
+ if(<%= enable_submit %>){
27
+ $('.<%= submit_klass %>').prop('disabled', false);
28
+ };
29
+ $('#<%= id_password_conf %>').val('')
30
+ $('#<%= id_password_conf %>').removeClass('is-invalid')
31
+ $('#<%= id_password_conf %>').removeClass('is-valid')
32
+ $('#<%= id_password %>').removeClass('is-valid')
33
+ $('#<%= id_password %>').removeClass('is-invalid')
34
+ });
35
+
36
+ $('#<%= id_password %>').blur(function() {
37
+ if (user_password_validity() === false) {
38
+ $('#<%= id_password %>').focus();
39
+ $('#<%= id_password %>').val('');
40
+ $('#<%= id_password %>').addClass('is-invalid');
41
+ } else {
42
+ $('#<%= id_password %>').removeClass('is-invalid');
43
+ if(<%= enable_submit %>){
44
+ $('.<%= submit_klass %>').prop('disabled', false);
45
+ };
46
+ }
47
+ });
48
+
49
+ $('.<%= form_klass %>').submit(function( event ) {
50
+ if ($('#<%= id_password_conf %>').val() === $('#<%= id_password %>').val()){
51
+ return
52
+ }
53
+
54
+ event.preventDefault();
55
+ event.stopPropagation();
56
+ $('#<%= id_password_conf %>').addClass('is-invalid');
57
+ $('#<%= id_password_conf %>').val('')
58
+ $('#<%= id_password_conf %>').focus();
59
+ });
60
+
61
+ $('#<%= id_password_conf %>').keyup(function(event){
62
+ if ($('#<%= id_password_conf %>').val() === $('#<%= id_password %>').val()){
63
+ $('#<%= id_password_conf %>').addClass('is-valid');
64
+ $('#<%= id_password_conf %>').removeClass('is-invalid');
65
+ $('#<%= id_password %>').addClass('is-valid');
66
+ } else {
67
+ $('#<%= id_password_conf %>').removeClass('is-valid')
68
+ $('#<%= id_password %>').removeClass('is-valid');
69
+ }
70
+ });
71
+ </script>
@@ -0,0 +1,111 @@
1
+ <%= form_for(:user, as: :user, url: url, html: { method: :post, class: 'password-reset-needs-validation', id: 'password-reset-confirmation', novalidate: true }) do |f| %>
2
+ <div class="field form-group row">
3
+ <div class="col-md-10 offset-md-1">
4
+ <%= f.password_field :password, autofocus: true, autocomplete: "new-password", placeholder: "Password", class: 'form-control', required: true %>
5
+ <div class="invalid-feedback">
6
+ <%= RailsBase::Authentication::Constants::MP_REQ_MESSAGE %>
7
+ </div>
8
+ </div>
9
+ </div>
10
+ <div class="field form-group row">
11
+ <div class="col-md-10 offset-md-1">
12
+ <%= f.password_field :password_confirmation, autocomplete: "new-password", placeholder: "Password Confirmation", class: 'form-control', required: true %>
13
+ <div class="invalid-feedback">
14
+ Password Confirmation does not match Password
15
+ </div>
16
+ <div class="valid-feedback">
17
+ Password and Password Confirmation match!
18
+ </div>
19
+ </div>
20
+ </div>
21
+
22
+ <% if sign_in_flow %>
23
+ <div class="actions row">
24
+ <div class="col-md-10 offset-md-1 text-center">
25
+ <div class="row">
26
+ <div class="col-md-9">
27
+ <%= f.submit "Reset Password", class: "reset-password-submit btn btn_success btn-block", disabled: true %>
28
+ </div>
29
+ <div class="col-md-3">
30
+ <a class="btn btn_primary btn-block" href="<%=RailsBase.url_routes.new_user_session_path%>" role="button">Sign in</a>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ <% else %>
36
+ <div class="actions row">
37
+ <div class="col-md-10 offset-md-1 text-center">
38
+ <%= f.submit "Reset Password", class: "btn btn_success btn-block" %>
39
+ </div>
40
+ </div>
41
+ <% end %>
42
+ <% end %>
43
+
44
+
45
+ <script type="text/javascript">
46
+ function user_password_validity(){
47
+ var value = $('#user_password').val()
48
+ if (value < <%= RailsBase::Authentication::Constants::MP_MIN_LENGTH %>){
49
+ return false
50
+ }
51
+
52
+ var numbers = value.replace(/[a-zA-Z]/g,'')
53
+ if(numbers.length < <%= RailsBase::Authentication::Constants::MP_MIN_NUMS %>){
54
+ return false
55
+ }
56
+
57
+ var chars = value.replace(/[0-9]/g,'')
58
+ if(chars.length < <%= RailsBase::Authentication::Constants::MP_MIN_ALPHA %>){
59
+ return false
60
+ }
61
+
62
+ var unknown = value.replace(/[0-9a-zA-Z]/g,'')
63
+ if(unknown.length > 0) {
64
+ return false
65
+ }
66
+ true
67
+ };
68
+
69
+ $('#user_password').focus(function() {
70
+ $('.reset-password-submit').prop('disabled', true);
71
+ $('#user_password_confirmation').val('')
72
+ $('#user_password_confirmation').removeClass('is-invalid')
73
+ $('#user_password_confirmation').removeClass('is-valid')
74
+ $('#user_password').removeClass('is-valid')
75
+ $('#user_password').removeClass('is-invalid')
76
+ });
77
+
78
+ $('#user_password').blur(function() {
79
+ if (user_password_validity() === false) {
80
+ $('#user_password').focus();
81
+ $('#user_password').val('');
82
+ $('#user_password').addClass('is-invalid');
83
+ } else {
84
+ $('#user_password').removeClass('is-invalid');
85
+ $('.reset-password-submit').prop('disabled', false);
86
+ }
87
+ });
88
+
89
+ $('.password-reset-needs-validation').submit(function( event ) {
90
+ if ($('#user_password_confirmation').val() === $('#user_password').val()){
91
+ return
92
+ }
93
+
94
+ event.preventDefault();
95
+ event.stopPropagation();
96
+ $('#user_password_confirmation').addClass('is-invalid');
97
+ $('#user_password_confirmation').val('')
98
+ $('#user_password_confirmation').focus();
99
+ });
100
+
101
+ $("#user_password_confirmation").keyup(function(event){
102
+ if ($('#user_password_confirmation').val() === $('#user_password').val()){
103
+ $('#user_password_confirmation').addClass('is-valid');
104
+ $('#user_password_confirmation').removeClass('is-invalid');
105
+ $('#user_password').addClass('is-valid');
106
+ } else {
107
+ $('#user_password_confirmation').removeClass('is-valid')
108
+ $('#user_password').removeClass('is-valid');
109
+ }
110
+ });
111
+ </script>