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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +32 -0
- data/Rakefile +32 -0
- data/app/assets/config/rails_base/manifest.js +3 -0
- data/app/assets/images/rails_base/favicon.ico +0 -0
- data/app/assets/javascripts/rails_base/admin.js +2 -0
- data/app/assets/javascripts/rails_base/application.js +22 -0
- data/app/assets/javascripts/rails_base/cable.js +13 -0
- data/app/assets/javascripts/rails_base/mfa_auth.coffee +3 -0
- data/app/assets/javascripts/rails_base/secondary_authentication.coffee +3 -0
- data/app/assets/javascripts/rails_base/sessions.js +152 -0
- data/app/assets/javascripts/rails_base/user_settings.coffee +3 -0
- data/app/assets/stylesheets/rails_base/admin.css +4 -0
- data/app/assets/stylesheets/rails_base/application.scss +15 -0
- data/app/assets/stylesheets/rails_base/mfa_auth.scss +3 -0
- data/app/assets/stylesheets/rails_base/scaffolds.scss +84 -0
- data/app/assets/stylesheets/rails_base/secondary_authentication.scss +3 -0
- data/app/assets/stylesheets/rails_base/user_settings.scss +3 -0
- data/app/controllers/rails_base/admin_controller.rb +315 -0
- data/app/controllers/rails_base/application_controller.rb +153 -0
- data/app/controllers/rails_base/errors_controller.rb +29 -0
- data/app/controllers/rails_base/mfa_auth_controller.rb +50 -0
- data/app/controllers/rails_base/secondary_authentication_controller.rb +224 -0
- data/app/controllers/rails_base/switch_user_controller.rb +29 -0
- data/app/controllers/rails_base/user_settings_controller.rb +81 -0
- data/app/controllers/rails_base/users/passwords_controller.rb +19 -0
- data/app/controllers/rails_base/users/registrations_controller.rb +80 -0
- data/app/controllers/rails_base/users/sessions_controller.rb +108 -0
- data/app/helpers/rails_base/admin_helper.rb +107 -0
- data/app/helpers/rails_base/appearance_helper.rb +58 -0
- data/app/helpers/rails_base/application_helper.rb +26 -0
- data/app/helpers/rails_base/capture_reference_helper.rb +57 -0
- data/app/helpers/rails_base/mfa_auth_helper.rb +2 -0
- data/app/helpers/rails_base/secondary_authentication_helper.rb +2 -0
- data/app/helpers/rails_base/user_field_validators.rb +108 -0
- data/app/helpers/rails_base/user_settings_helper.rb +22 -0
- data/app/jobs/rails_base/application_job.rb +10 -0
- data/app/jobs/twilio_job.rb +9 -0
- data/app/mailers/rails_base/application_mailer.rb +9 -0
- data/app/mailers/rails_base/email_verification_mailer.rb +22 -0
- data/app/mailers/rails_base/event_mailer.rb +16 -0
- data/app/models/admin_action.rb +119 -0
- data/app/models/rails_base/application_record.rb +22 -0
- data/app/models/rails_base/user_constants.rb +28 -0
- data/app/models/secret.rb +37 -0
- data/app/models/short_lived_data.rb +132 -0
- data/app/models/user.rb +143 -0
- data/app/services/rails_base/admin_risky_mfa_send.rb +80 -0
- data/app/services/rails_base/admin_update_attribute.rb +100 -0
- data/app/services/rails_base/authentication/authenticate_user.rb +28 -0
- data/app/services/rails_base/authentication/constants.rb +60 -0
- data/app/services/rails_base/authentication/decision_twofa_type.rb +76 -0
- data/app/services/rails_base/authentication/destroy_user.rb +45 -0
- data/app/services/rails_base/authentication/mfa_set_encrypt_token.rb +32 -0
- data/app/services/rails_base/authentication/mfa_validator.rb +88 -0
- data/app/services/rails_base/authentication/modify_password.rb +67 -0
- data/app/services/rails_base/authentication/send_forgot_password.rb +26 -0
- data/app/services/rails_base/authentication/send_login_mfa_to_user.rb +77 -0
- data/app/services/rails_base/authentication/send_verification_email.rb +103 -0
- data/app/services/rails_base/authentication/session_token_verifier.rb +31 -0
- data/app/services/rails_base/authentication/single_sign_on_create.rb +44 -0
- data/app/services/rails_base/authentication/single_sign_on_send.rb +101 -0
- data/app/services/rails_base/authentication/single_sign_on_verify.rb +42 -0
- data/app/services/rails_base/authentication/sso_verify_email.rb +43 -0
- data/app/services/rails_base/authentication/update_phone_send_verification.rb +46 -0
- data/app/services/rails_base/authentication/verify_forgot_password.rb +46 -0
- data/app/services/rails_base/email_change.rb +20 -0
- data/app/services/rails_base/encryption.rb +87 -0
- data/app/services/rails_base/name_change.rb +71 -0
- data/app/services/rails_base/service_base.rb +65 -0
- data/app/services/rails_base/service_logging.rb +23 -0
- data/app/views/layouts/rails_base/application.html.erb +185 -0
- data/app/views/layouts/rails_base/mailer.html.erb +13 -0
- data/app/views/layouts/rails_base/mailer.text.erb +1 -0
- data/app/views/new.html.erb +4 -0
- data/app/views/rails_base/admin/history.html.erb +26 -0
- data/app/views/rails_base/admin/index.html.erb +149 -0
- data/app/views/rails_base/admin/show_config.html.erb +18 -0
- data/app/views/rails_base/devise/confirmations/new.html.erb +16 -0
- data/app/views/rails_base/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/rails_base/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/rails_base/devise/mailer/password_change.html.erb +3 -0
- data/app/views/rails_base/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/rails_base/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/rails_base/devise/passwords/edit.html.erb +25 -0
- data/app/views/rails_base/devise/passwords/new.html.erb +27 -0
- data/app/views/rails_base/devise/registrations/edit.html.erb +43 -0
- data/app/views/rails_base/devise/registrations/new.html.erb +123 -0
- data/app/views/rails_base/devise/sessions/new.html.erb +4 -0
- data/app/views/rails_base/devise/shared/_error_messages.html.erb +15 -0
- data/app/views/rails_base/devise/shared/_links.html.erb +25 -0
- data/app/views/rails_base/devise/unlocks/new.html.erb +16 -0
- data/app/views/rails_base/email_verification_mailer/email_verification.html.erb +25 -0
- data/app/views/rails_base/email_verification_mailer/event.html.erb +20 -0
- data/app/views/rails_base/email_verification_mailer/forgot_password.html.erb +22 -0
- data/app/views/rails_base/errors/internal_error.html.erb +1 -0
- data/app/views/rails_base/errors/not_found.html.erb +1 -0
- data/app/views/rails_base/errors/unacceptable.html.erb +1 -0
- data/app/views/rails_base/event_mailer/event.html.erb +10 -0
- data/app/views/rails_base/mfa_auth/mfa_code.html.erb +10 -0
- data/app/views/rails_base/secondary_authentication/after_email_login_session_new.html.erb +3 -0
- data/app/views/rails_base/secondary_authentication/forgot_password.html.erb +9 -0
- data/app/views/rails_base/secondary_authentication/remove_me.html.erb +1 -0
- data/app/views/rails_base/secondary_authentication/static.html.erb +5 -0
- data/app/views/rails_base/shared/_admin_actions_modal.html.erb +65 -0
- data/app/views/rails_base/shared/_admin_config_class.html.erb +52 -0
- data/app/views/rails_base/shared/_admin_history.html.erb +86 -0
- data/app/views/rails_base/shared/_admin_modify_email.html.erb +78 -0
- data/app/views/rails_base/shared/_admin_modify_name.html.erb +107 -0
- data/app/views/rails_base/shared/_admin_modify_phone.html.erb +87 -0
- data/app/views/rails_base/shared/_admin_modify_text.html.erb +35 -0
- data/app/views/rails_base/shared/_admin_risky_change.html.erb +57 -0
- data/app/views/rails_base/shared/_admin_risky_mfa.html.erb +74 -0
- data/app/views/rails_base/shared/_admin_selector_dropdown.html.erb +70 -0
- data/app/views/rails_base/shared/_admin_toggle_button.html.erb +72 -0
- data/app/views/rails_base/shared/_admin_warning_alert.html.erb +7 -0
- data/app/views/rails_base/shared/_appearance_mode_selector.html.erb +183 -0
- data/app/views/rails_base/shared/_custom_form_validation_javascript.html.erb +129 -0
- data/app/views/rails_base/shared/_enable_mfa_auth_modal.html.erb +105 -0
- data/app/views/rails_base/shared/_error_pages.html.erb +123 -0
- data/app/views/rails_base/shared/_logged_in_header.html.erb +123 -0
- data/app/views/rails_base/shared/_logged_out_header.html.erb +14 -0
- data/app/views/rails_base/shared/_mfa_input_layout.html.erb +5 -0
- data/app/views/rails_base/shared/_mfa_input_layout_default.html.erb +97 -0
- data/app/views/rails_base/shared/_mfa_input_layout_fallback.html.erb +55 -0
- data/app/views/rails_base/shared/_modify_mfa_auth_modal.html.erb +20 -0
- data/app/views/rails_base/shared/_password_confirm_javascript.html.erb +71 -0
- data/app/views/rails_base/shared/_reset_password_form.html.erb +111 -0
- data/app/views/rails_base/shared/_session_create_form.html.erb +32 -0
- data/app/views/rails_base/shared/_session_timeout_modal.html.erb +76 -0
- data/app/views/rails_base/switch_user/_widget.html.erb +5 -0
- data/app/views/rails_base/user_settings/_confirm_destroy_user.html.erb +42 -0
- data/app/views/rails_base/user_settings/_destroy_user.html.erb +106 -0
- data/app/views/rails_base/user_settings/_modify_name.html.erb +71 -0
- data/app/views/rails_base/user_settings/_modify_password.html.erb +101 -0
- data/app/views/rails_base/user_settings/_modify_password_update_password.html.erb +2 -0
- data/app/views/rails_base/user_settings/index.html.erb +54 -0
- data/config/initializers/01_rails_config.rb +19 -0
- data/config/initializers/admin_action_helper.rb +88 -0
- data/config/initializers/browser.rb +4 -0
- data/config/initializers/default_logged_in_headers.rb +23 -0
- data/config/initializers/devise.rb +314 -0
- data/config/initializers/encryption.rb +2 -0
- data/config/initializers/switch_user.rb +58 -0
- data/config/initializers/switch_user_helper.rb +29 -0
- data/config/locales/devise.en.yml +65 -0
- data/config/locales/en.yml +58 -0
- data/config/routes.rb +114 -0
- data/db/migrate/20210212175453_devise_create_rails_base_users.rb +56 -0
- data/db/migrate/20210212190537_create_rails_base_short_lived_data.rb +19 -0
- data/db/migrate/20210212192645_create_rails_base_secrets.rb +11 -0
- data/db/migrate/20210406015744_create_rails_base_admin_actions.rb +17 -0
- data/db/seeds.rb +23 -0
- data/lib/link_decision_helper.rb +71 -0
- data/lib/rails_base.rb +50 -0
- data/lib/rails_base/admin/action_cache.rb +99 -0
- data/lib/rails_base/admin/action_helper.rb +134 -0
- data/lib/rails_base/admin/default_index_tile.rb +176 -0
- data/lib/rails_base/admin/index_tile.rb +186 -0
- data/lib/rails_base/config.rb +52 -0
- data/lib/rails_base/configuration/active_job.rb +38 -0
- data/lib/rails_base/configuration/admin.rb +231 -0
- data/lib/rails_base/configuration/app.rb +52 -0
- data/lib/rails_base/configuration/appearance.rb +131 -0
- data/lib/rails_base/configuration/authentication.rb +37 -0
- data/lib/rails_base/configuration/base.rb +209 -0
- data/lib/rails_base/configuration/display/background_color.rb +25 -0
- data/lib/rails_base/configuration/display/btn_danger.rb +25 -0
- data/lib/rails_base/configuration/display/btn_dark.rb +25 -0
- data/lib/rails_base/configuration/display/btn_info.rb +25 -0
- data/lib/rails_base/configuration/display/btn_light.rb +25 -0
- data/lib/rails_base/configuration/display/btn_primary.rb +25 -0
- data/lib/rails_base/configuration/display/btn_secondary.rb +25 -0
- data/lib/rails_base/configuration/display/btn_success.rb +25 -0
- data/lib/rails_base/configuration/display/btn_warning.rb +25 -0
- data/lib/rails_base/configuration/display/footer.rb +54 -0
- data/lib/rails_base/configuration/display/navbar.rb +25 -0
- data/lib/rails_base/configuration/display/table_body.rb +25 -0
- data/lib/rails_base/configuration/display/table_header.rb +25 -0
- data/lib/rails_base/configuration/display/text.rb +26 -0
- data/lib/rails_base/configuration/exceptions_app.rb +25 -0
- data/lib/rails_base/configuration/login_behavior.rb +17 -0
- data/lib/rails_base/configuration/mailer.rb +116 -0
- data/lib/rails_base/configuration/mfa.rb +84 -0
- data/lib/rails_base/configuration/owner.rb +17 -0
- data/lib/rails_base/configuration/redis.rb +29 -0
- data/lib/rails_base/configuration/user.rb +43 -0
- data/lib/rails_base/engine.rb +51 -0
- data/lib/rails_base/version.rb +10 -0
- data/lib/tasks/rails_base_tasks.rake +4 -0
- data/lib/twilio_helper.rb +26 -0
- data/lib/velocity_limiter.rb +91 -0
- 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,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,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
|