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,26 @@
1
+ module RailsBase::ApplicationHelper
2
+
3
+ TIMEZONE_OFFSET_COOKIE = "_#{Rails.application.class.parent_name}_timeoffset"
4
+ TIMEZONE_SESSION_NAME = TIMEZONE_THREAD_NAME = :tz_info
5
+
6
+ def browser
7
+ @browser ||= Browser.new(request.user_agent)
8
+ end
9
+
10
+ def is_mobile?
11
+ browser.mobile?
12
+ end
13
+
14
+ def is_safari?
15
+ browser.safari?
16
+ end
17
+
18
+ def mfa_fallback?
19
+ is_mobile? # && is_safari?
20
+ end
21
+
22
+ def admin_reset_session!
23
+ session.delete(RailsBase::Authentication::Constants::ADMIN_REMEMBER_REASON)
24
+ session.delete(RailsBase::Authentication::Constants::ADMIN_REMEMBER_USERID_KEY)
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ module RailsBase
2
+ module CaptureReferenceHelper
3
+ CAPTURE_CONTROLLER_PATH = :referer_controller_path
4
+ CAPTURE_ACTION_NAME = :referer_action_name
5
+ CAPTURE_REFERRED_PATH = :referer_referred_path
6
+
7
+ def authenticate_user!
8
+ # only if request is a get and not authenticated
9
+ capture_reference if request.method == 'GET' && !warden.authenticated?
10
+ super()
11
+ end
12
+
13
+ def capture_reference
14
+ return unless use_capture_reference?
15
+
16
+ session[CAPTURE_CONTROLLER_PATH] = controller_path
17
+ session[CAPTURE_ACTION_NAME] = action_name
18
+ session[CAPTURE_REFERRED_PATH] = request.path
19
+ end
20
+
21
+ def capture_clear_reference_from_sesssion!
22
+ session[CAPTURE_CONTROLLER_PATH] = nil
23
+ session[CAPTURE_ACTION_NAME] = nil
24
+ session[CAPTURE_REFERRED_PATH] = nil
25
+ end
26
+
27
+ def use_capture_reference?
28
+ return false if skip_capture_reference?
29
+
30
+ RailsBase.config.login_behavior.fallback_to_referred
31
+ end
32
+
33
+ def skip_capture_reference!
34
+ @__skip_capture_reference = true
35
+ end
36
+
37
+ def skip_capture_reference?
38
+ @__skip_capture_reference.presence
39
+ end
40
+
41
+ def reference_redirect
42
+ { controller: session[CAPTURE_CONTROLLER_PATH], action: session[CAPTURE_ACTION_NAME], path: session[CAPTURE_REFERRED_PATH] }
43
+ end
44
+
45
+ def capture_and_clear_reference_redirect!
46
+ temp = reference_redirect
47
+ capture_clear_reference_from_sesssion!
48
+ temp[:path]
49
+ end
50
+
51
+ def redirect_from_reference
52
+ return nil unless use_capture_reference?
53
+
54
+ capture_and_clear_reference_redirect!
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,2 @@
1
+ module RailsBase::MfaAuthHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module RailsBase::SecondaryAuthenticationHelper
2
+ end
@@ -0,0 +1,108 @@
1
+ module RailsBase::UserFieldValidators
2
+ # allows us to use standard functionality of logging shit
3
+ def self.included klass
4
+ klass.class_eval do
5
+ include RailsBase::ServiceLogging
6
+ end
7
+ end
8
+
9
+ def validate_complement?(user_params:)
10
+ status = { status: true, errors: {} }
11
+ if user_params[:first_name]
12
+ validator = validate_name?(name: user_params[:first_name])
13
+ unless validator[:status]
14
+ status[:status] = false
15
+ status[:errors][:first_name] = "First Name validation: #{validator[:msg]}"
16
+ end
17
+ end
18
+
19
+ if user_params[:last_name]
20
+ validator = validate_name?(name: user_params[:last_name])
21
+ unless validator[:status]
22
+ status[:status] = false
23
+ status[:errors][:last_name] = "Last Name validation: #{validator[:msg]}"
24
+ end
25
+ end
26
+
27
+ if user_params[:password] && user_params[:password_confirmation]
28
+ validator = validate_password?(password: user_params[:password], password_confirmation: user_params[:password_confirmation])
29
+ unless validator[:status]
30
+ status[:status] = false
31
+ status[:errors][:password] = "Password validation: #{validator[:msg]}"
32
+ end
33
+ end
34
+ status
35
+ end
36
+
37
+ def validate_full_name?(first_name:, last_name:)
38
+ status = { status: true, errors: {} }
39
+ if first_name
40
+ validator = validate_name?(name: first_name)
41
+ unless validator[:status]
42
+ status[:status] = false
43
+ status[:errors][:first_name] = "First Name validation: #{validator[:msg]}"
44
+ end
45
+ end
46
+
47
+ if last_name
48
+ validator = validate_name?(name: last_name)
49
+ unless validator[:status]
50
+ status[:status] = false
51
+ status[:errors][:last_name] = "Last Name validation: #{validator[:msg]}"
52
+ end
53
+ end
54
+ status
55
+ end
56
+
57
+ def validate_name?(name:)
58
+ unacceptable_chars = name.tr("a-zA-Z '",'')
59
+ if unacceptable_chars.length > 0
60
+ log(level: :warn, msg: "name #{name} contains unacceptable_chars [#{unacceptable_chars}]")
61
+ return { status: false, msg: "Value can not contain #{unacceptable_chars}" }
62
+ end
63
+
64
+ if name.length > RailsBase::Authentication::Constants::MAX_NAME
65
+ log(level: :warn, msg: "name #{name} contains too many characters. Max allowed is #{RailsBase::Authentication::Constants::MAX_NAME}")
66
+ return { status: false, msg: "Too many characters. Max allowed is #{RailsBase::Authentication::Constants::MAX_NAME}" }
67
+ end
68
+
69
+ if name.length < RailsBase::Authentication::Constants::MIN_NAME
70
+ log(level: :warn, msg: "name #{name} contains too few characters. MIN allowed is #{RailsBase::Authentication::Constants::MIN_NAME}")
71
+ return { status: false, msg: "Too few characters. Max allowed is #{RailsBase::Authentication::Constants::MIN_NAME}" }
72
+ end
73
+ { status: true }
74
+ end
75
+
76
+ def validate_password?(password:, password_confirmation:)
77
+ if password != password_confirmation
78
+ log(level: :warn, msg: 'User password inputs do not match. Must retry flow')
79
+ return { status: false, msg: 'Passwords do not match. Retry password flow' }
80
+ end
81
+
82
+ if password.length < RailsBase::Authentication::Constants::MP_MIN_LENGTH
83
+ log(level: :warn, msg: RailsBase::Authentication::Constants::MP_REQ_MESSAGE)
84
+ return { status: false, msg: RailsBase::Authentication::Constants::MP_REQ_MESSAGE }
85
+ end
86
+
87
+ number_count = password.scan(/\d/).join('').length
88
+ char_count = password.scan(/[a-zA-Z]/).join('').length
89
+ unacceptable_chars = password.scan(/\W/).join('')
90
+
91
+ if char_count < RailsBase::Authentication::Constants::MP_MIN_ALPHA
92
+ log(level: :warn, msg: "User password does not have enough numbers. Req: #{RailsBase::Authentication::Constants::MP_MIN_ALPHA}. Given: #{char_count}")
93
+ return { status: false, msg: "Password must contain at least #{RailsBase::Authentication::Constants::MP_MIN_ALPHA} characters [a-z,A-Z]" }
94
+ end
95
+
96
+ if number_count < RailsBase::Authentication::Constants::MP_MIN_NUMS
97
+ log(level: :warn, msg: "User password does not have enough numbers. Req: #{RailsBase::Authentication::Constants::MP_MIN_NUMS}. Given: #{number_count}")
98
+ return { status: false, msg: "Password must contain at least #{RailsBase::Authentication::Constants::MP_MIN_NUMS} numbers [0-9]" }
99
+ end
100
+
101
+ if unacceptable_chars.length > 0
102
+ log(level: :warn, msg: "User password contains unacceptable_chars. Received: #{unacceptable_chars}")
103
+ return { status: false, msg: "Unaccepted characters received. Characters must be in [0-9a-zA-Z] exclusively. Received #{unacceptable_chars}" }
104
+ end
105
+
106
+ { status: true }
107
+ end
108
+ end
@@ -0,0 +1,22 @@
1
+ module RailsBase::UserSettingsHelper
2
+ CONFIRM_PASSWORD_FLOW = {
3
+ password_flow: 'rails_base/user_settings/modify_password_update_password',
4
+ destroy_user: 'rails_base/user_settings/confirm_destroy_user'
5
+ }
6
+
7
+ DATUM_LENGTH = 36
8
+ DATUM_TTL = 30.seconds
9
+ DATUM_REASON = :confirm_password
10
+
11
+
12
+ def datum
13
+ params = {
14
+ user: current_user,
15
+ max_use: 1,
16
+ reason: DATUM_REASON,
17
+ ttl: DATUM_TTL,
18
+ length: DATUM_LENGTH,
19
+ }
20
+ ShortLivedData.create_data_key(params)
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ module RailsBase
2
+ class ApplicationJob < ActiveJob::Base
3
+
4
+ # Automatically retry jobs that encountered a deadlock
5
+ # retry_on ActiveRecord::Deadlocked
6
+
7
+ # Most jobs are safe to ignore if the underlying records are no longer available
8
+ # discard_on ActiveJob::DeserializationError
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'twilio_helper'
2
+
3
+ class TwilioJob < RailsBase::ApplicationJob
4
+ queue_as RailsBase.config.mfa.active_job_queue
5
+
6
+ def perform(message:, to:)
7
+ TwilioHelper.send_sms(message: message, to: to)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class RailsBase::ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+
5
+ CONTACT_URL = [
6
+ RailsBase.config.app.base_url,
7
+ RailsBase.config.app.base_port,
8
+ ].compact.join(':')
9
+ end
@@ -0,0 +1,22 @@
1
+ class RailsBase::EmailVerificationMailer < RailsBase::ApplicationMailer
2
+ default from: Rails.configuration.mail_from
3
+
4
+ def email_verification(user:, url:)
5
+ @user = user
6
+ @sso_url_for_user = url
7
+ mail(to: @user.email, subject: "Welcome to #{Rails.application.class.parent_name}")
8
+ end
9
+
10
+ def forgot_password(user:, url:)
11
+ @user = user
12
+ @sso_url_for_user = url
13
+ mail(to: @user.email, subject: "#{Rails.application.class.parent_name}: Forgot Password")
14
+ end
15
+
16
+ def event(user:, event:, msg: nil)
17
+ @user = user
18
+ @event = event
19
+ @msg = msg
20
+ mail(to: @user.email, subject: "#{Rails.application.class.parent_name}: #{event}")
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ class RailsBase::EventMailer < RailsBase::ApplicationMailer
2
+ default from: Rails.configuration.mail_from
3
+
4
+ def send_sso(user:, message:)
5
+ @user = user
6
+ @message = message
7
+ mail(to: user.email, subject: "#{Rails.application.class.parent_name}: SSO login", template_name: 'event')
8
+ # event(user: user, event: 'SSO login', message: message)
9
+ end
10
+
11
+ def event(user:, event:, message:)
12
+ @user = user
13
+ @message = message
14
+ mail(to: @user.email, subject: "#{Rails.application.class.parent_name}: #{event}", template_name: 'event')
15
+ end
16
+ end
@@ -0,0 +1,119 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: admin_actions
4
+ #
5
+ # id :bigint not null, primary key
6
+ # admin_user_id :bigint not null
7
+ # user_id :bigint
8
+ # action :string(255) not null
9
+ # change_from :string(255)
10
+ # change_to :string(255)
11
+ # long_action :text(65535)
12
+ # created_at :datetime not null
13
+ # updated_at :datetime not null
14
+ #
15
+ class AdminAction < RailsBase::ApplicationRecord
16
+ DEFAULT_PAGE_COUNT = 5
17
+ DEFAULT_PAGE_COUNT_SELECT_RANGE = (0..50).select { |x| x%5 == 0 && x != 0 }
18
+ DEFAULT_PAGE_RANGE = 2
19
+
20
+
21
+ class << self
22
+ include ActionView::Helpers::DateHelper
23
+ def action(admin_user:, action:, user: nil, original_attribute: nil, new_attribute: nil, long_action: nil)
24
+ params = { admin_user_id: admin_user.id, action: action }
25
+ params[:user_id] = user.id if user
26
+ params[:change_from] = original_attribute.to_s unless original_attribute.nil?
27
+ params[:change_to] = new_attribute.to_s unless new_attribute.nil?
28
+ params[:long_action] = long_action unless long_action.nil?
29
+ begin
30
+ instance = AdminAction.create!(params)
31
+ ship_to_cache!(instance: instance, user: user, created_at: Time.zone.now) if user
32
+ instance
33
+ rescue StandardError => e
34
+ Rails.logger.error(e.message)
35
+ Rails.logger.error("Unable to save admin action [#{action}]: [#{params}]")
36
+ nil
37
+ end
38
+ end
39
+
40
+ def repopulate_cache!(max_items: 1000)
41
+ objects = order(created_at: :desc).where.not(user_id: nil).limit(max_items)
42
+ count = 0
43
+ objects.in_batches(of: 500) do |group|
44
+ group.each do |instance|
45
+ count += 1
46
+ user = instance.user
47
+ msg = instance.readable(with_occurred: false)
48
+ RailsBase::Admin::ActionCache.instance.add_action(user: user, msg: msg, occured: instance.created_at)
49
+ end
50
+ end
51
+ count
52
+ end
53
+
54
+ def get_cache_items(user:, time: Time.zone.now, use_lv: false, alltime: false, delete: false, update_lv: false)
55
+ if use_lv
56
+ Rails.logger.warn { "Using Last Viewed admin actions for user #{user.id}" }
57
+ temp = RailsBase::Admin::ActionCache.instance.get_last_viewed(user: user)
58
+ time = temp.nil? ? time : (Time.at(temp) rescue time)
59
+ end
60
+
61
+ objects = RailsBase::Admin::ActionCache.instance.actions_since(user: user, time: time, alltime: alltime)
62
+
63
+ admin_messages = objects.map do |object|
64
+ msg = object[0]
65
+ in_words = distance_of_time_in_words(Time.zone.now, object[1], include_seconds: true)
66
+ [msg, "~ #{in_words.humanize} ago"]
67
+ end
68
+
69
+ if delete
70
+ Rails.logger.warn { "Deleting admin actions for user #{user.id}" }
71
+ RailsBase::Admin::ActionCache.instance.delete_actions_since!(user: user, time: time)
72
+ end
73
+
74
+ if update_lv
75
+ Rails.logger.warn { "Udating Last Viewed admin actions for user #{user.id}" }
76
+ RailsBase::Admin::ActionCache.instance.update_last_viewed(user: user, time: time)
77
+ end
78
+
79
+ admin_messages
80
+ end
81
+
82
+ def ship_to_cache!(instance:, user:, created_at: nil)
83
+ msg = instance.readable(with_occurred: false)
84
+ RailsBase::Admin::ActionCache.instance.add_action(user: user, msg: msg, occured: instance.created_at)
85
+ end
86
+
87
+ def paginate_records(page:, user_id: nil, admin_id: nil, count_on_page: DEFAULT_PAGE_COUNT, count: false)
88
+ params = {}
89
+ params[:user_id] = user_id if user_id && user_id.positive?
90
+ params[:admin_user_id] = admin_id if admin_id && admin_id.positive?
91
+ offset = (page - 1) * count_on_page
92
+ if count
93
+ where(params).count
94
+ else
95
+ where(params).order(created_at: :desc).offset(offset).limit(count_on_page)
96
+ end
97
+ end
98
+ end
99
+
100
+ def admin_user
101
+ @admin_user ||= User.find admin_user_id
102
+ end
103
+
104
+ def user
105
+ @user ||= user_id ? User.find(user_id) : nil
106
+ end
107
+
108
+ def readable(long: false, with_occurred: true)
109
+ msg = "[#{admin_user.full_name}(#{admin_user_id})]: #{ long ? long_action : action}."
110
+ msg += " Changed from [#{change_from}]." unless change_from.nil?
111
+ msg += " Changed to [#{change_to}]." unless change_to.nil?
112
+ msg += " Occured at #{created_at}." if with_occurred
113
+ msg
114
+ end
115
+
116
+ private
117
+
118
+ end
119
+
@@ -0,0 +1,22 @@
1
+ module RailsBase
2
+ class ApplicationRecord < ::ApplicationRecord
3
+ self.abstract_class = true
4
+
5
+ def self._magically_defined_time_objects
6
+ columns.each do |column|
7
+ next unless [:datetime].include?(column.type)
8
+
9
+ # This is actually pretty cool. If you set the thrad corectly, you can
10
+ define_method("#{column.name}") do
11
+ thread_tz = Thread.current[RailsBase::ApplicationController::TIMEZONE_THREAD_NAME]
12
+ return super() if thread_tz.nil?
13
+ time = self[column.name].in_time_zone(thread_tz) rescue self[column.name]
14
+
15
+ Rails.logger.debug { "#{self.class.name}.#{column.name} intercepted :datetime [#{self[column.name]}] and returned [#{time}] - tz[#{thread_tz}]" }
16
+
17
+ time
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end