searls-auth 0.2.0 → 1.0.1
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 +4 -4
- data/CHANGELOG.md +16 -1
- data/README.md +162 -0
- data/app/controllers/searls/auth/base_controller.rb +42 -21
- data/app/controllers/searls/auth/email_verifications_controller.rb +57 -0
- data/app/controllers/searls/auth/logins_controller.rb +60 -39
- data/app/controllers/searls/auth/registrations_controller.rb +84 -32
- data/app/controllers/searls/auth/requests_password_resets_controller.rb +55 -0
- data/app/controllers/searls/auth/resets_passwords_controller.rb +73 -0
- data/app/controllers/searls/auth/settings_controller.rb +83 -0
- data/app/controllers/searls/auth/verifications_controller.rb +31 -61
- data/app/helpers/searls/auth/application_helper.rb +9 -5
- data/app/mailers/searls/auth/base_mailer.rb +1 -1
- data/app/mailers/searls/auth/email_verification_mailer.rb +29 -0
- data/app/mailers/searls/auth/login_link_mailer.rb +3 -3
- data/app/mailers/searls/auth/password_reset_mailer.rb +29 -0
- data/app/views/searls/auth/email_verification_mailer/verification_email.html.erb +23 -0
- data/app/views/searls/auth/email_verification_mailer/verification_email.text.erb +6 -0
- data/app/views/searls/auth/login_link_mailer/login_link.html.erb +5 -5
- data/app/views/searls/auth/login_link_mailer/login_link.text.erb +4 -5
- data/app/views/searls/auth/logins/show.html.erb +12 -4
- data/app/views/searls/auth/password_reset_mailer/password_reset.html.erb +23 -0
- data/app/views/searls/auth/password_reset_mailer/password_reset.text.erb +6 -0
- data/app/views/searls/auth/registrations/pending_email_verification.html.erb +12 -0
- data/app/views/searls/auth/registrations/show.html.erb +1 -2
- data/app/views/searls/auth/requests_password_resets/show.html.erb +17 -0
- data/app/views/searls/auth/resets_passwords/show.html.erb +26 -0
- data/app/views/searls/auth/settings/edit.html.erb +31 -0
- data/app/views/searls/auth/shared/_login_fields.html.erb +11 -0
- data/app/views/searls/auth/shared/_register_fields.html.erb +15 -0
- data/config/routes.rb +11 -0
- data/lib/searls/auth/authenticates_user.rb +54 -10
- data/lib/searls/auth/builds_target_redirect_url.rb +72 -0
- data/lib/searls/auth/config.rb +259 -12
- data/lib/searls/auth/creates_user.rb +12 -4
- data/lib/searls/auth/delivers_password_reset.rb +18 -0
- data/lib/searls/auth/emails_link.rb +2 -2
- data/lib/searls/auth/emails_verification.rb +33 -0
- data/lib/searls/auth/parses_time_safely.rb +32 -0
- data/lib/searls/auth/railtie.rb +0 -1
- data/lib/searls/auth/resets_password.rb +41 -0
- data/lib/searls/auth/updates_settings.rb +149 -0
- data/lib/searls/auth/version.rb +1 -1
- data/lib/searls/auth.rb +62 -13
- metadata +23 -1
@@ -0,0 +1,32 @@
|
|
1
|
+
require "active_support/time"
|
2
|
+
|
3
|
+
module Searls
|
4
|
+
module Auth
|
5
|
+
class ParsesTimeSafely
|
6
|
+
def parse(input)
|
7
|
+
return nil if input.nil?
|
8
|
+
|
9
|
+
case input
|
10
|
+
when String
|
11
|
+
parse_string(input)
|
12
|
+
when Integer, Float
|
13
|
+
Time.at(input).in_time_zone
|
14
|
+
else
|
15
|
+
if input.respond_to?(:in_time_zone)
|
16
|
+
input.in_time_zone
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue ArgumentError, TypeError, NoMethodError
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse_string(s)
|
26
|
+
if !(stripped = s.strip).empty?
|
27
|
+
Time.zone.parse(stripped)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/searls/auth/railtie.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Searls
|
2
|
+
module Auth
|
3
|
+
class ResetsPassword
|
4
|
+
Result = Struct.new(:success?, :errors, :user, keyword_init: true)
|
5
|
+
|
6
|
+
def reset(user:, password:, password_confirmation:)
|
7
|
+
configuration = Searls::Auth.config
|
8
|
+
|
9
|
+
if password.blank?
|
10
|
+
message = configuration.resolve(:flash_error_after_password_reset_password_blank, {})
|
11
|
+
return Result.new(success?: false, errors: Array(message), user: user)
|
12
|
+
end
|
13
|
+
|
14
|
+
if password != password_confirmation
|
15
|
+
message = configuration.resolve(:flash_error_after_password_reset_password_mismatch, {})
|
16
|
+
return Result.new(success?: false, errors: Array(message), user: user)
|
17
|
+
end
|
18
|
+
|
19
|
+
configuration.password_setter.call(user, password)
|
20
|
+
if user.respond_to?(:password_confirmation=)
|
21
|
+
user.password_confirmation = password_confirmation
|
22
|
+
end
|
23
|
+
|
24
|
+
if user.save
|
25
|
+
configuration.after_login_success.call(user)
|
26
|
+
Result.new(success?: true, user: user, errors: [])
|
27
|
+
else
|
28
|
+
Result.new(success?: false, user: user, errors: simplified_error_messages(user))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def simplified_error_messages(model)
|
35
|
+
model.errors.details.keys.map { |attr|
|
36
|
+
model.errors.full_messages_for(attr).first
|
37
|
+
}.compact
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Searls
|
2
|
+
module Auth
|
3
|
+
class UpdatesSettings
|
4
|
+
Result = Struct.new(
|
5
|
+
:success?,
|
6
|
+
:errors,
|
7
|
+
:user,
|
8
|
+
:password_changed?,
|
9
|
+
keyword_init: true
|
10
|
+
)
|
11
|
+
|
12
|
+
def initialize(user:, params:)
|
13
|
+
@user = user
|
14
|
+
@params = params || {}
|
15
|
+
@errors = []
|
16
|
+
@password_changed = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
enforce_current_password_requirement
|
21
|
+
|
22
|
+
handle_password_change if errors.empty?
|
23
|
+
|
24
|
+
return failure_result unless errors.empty?
|
25
|
+
|
26
|
+
if changes_applied?
|
27
|
+
if user.save
|
28
|
+
Result.new(
|
29
|
+
success?: true,
|
30
|
+
user: user,
|
31
|
+
errors: [],
|
32
|
+
password_changed?: @password_changed
|
33
|
+
)
|
34
|
+
else
|
35
|
+
Result.new(
|
36
|
+
success?: false,
|
37
|
+
user: user,
|
38
|
+
errors: simplified_error_messages(user)
|
39
|
+
)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
Result.new(success?: true, user: user, errors: [], password_changed?: false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :user, :params, :errors
|
49
|
+
|
50
|
+
def enforce_current_password_requirement
|
51
|
+
return unless password_present?
|
52
|
+
return unless password_change_requested?
|
53
|
+
|
54
|
+
if current_password.blank?
|
55
|
+
errors << array_wrap(Searls::Auth.config.resolve(:flash_error_after_settings_current_password_missing, {}))
|
56
|
+
errors.flatten!
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
verified = Searls::Auth.config.password_verifier.call(user, current_password)
|
62
|
+
rescue NameError
|
63
|
+
errors << array_wrap(Searls::Auth.config.resolve(:flash_error_after_password_misconfigured, {}))
|
64
|
+
errors.flatten!
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
68
|
+
unless verified
|
69
|
+
errors << array_wrap(Searls::Auth.config.resolve(:flash_error_after_settings_current_password_invalid, {}))
|
70
|
+
errors.flatten!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def handle_password_change
|
75
|
+
return unless password_change_requested?
|
76
|
+
|
77
|
+
if new_password.blank?
|
78
|
+
errors << array_wrap(Searls::Auth.config.resolve(:flash_error_after_password_reset_password_blank, {}))
|
79
|
+
errors.flatten!
|
80
|
+
return
|
81
|
+
end
|
82
|
+
|
83
|
+
if new_password != new_password_confirmation
|
84
|
+
errors << array_wrap(Searls::Auth.config.resolve(:flash_error_after_password_reset_password_mismatch, {}))
|
85
|
+
errors.flatten!
|
86
|
+
return
|
87
|
+
end
|
88
|
+
|
89
|
+
Searls::Auth.config.password_setter.call(user, new_password)
|
90
|
+
if user.respond_to?(:password_confirmation=)
|
91
|
+
user.password_confirmation = new_password_confirmation
|
92
|
+
end
|
93
|
+
@password_changed = true
|
94
|
+
end
|
95
|
+
|
96
|
+
def password_present?
|
97
|
+
Searls::Auth.config.password_present?(user)
|
98
|
+
end
|
99
|
+
|
100
|
+
def password_change_requested?
|
101
|
+
new_password.present? || new_password_confirmation.present?
|
102
|
+
end
|
103
|
+
|
104
|
+
def current_password
|
105
|
+
param(:current_password).to_s
|
106
|
+
end
|
107
|
+
|
108
|
+
def new_password
|
109
|
+
param(:password)
|
110
|
+
end
|
111
|
+
|
112
|
+
def new_password_confirmation
|
113
|
+
param(:password_confirmation)
|
114
|
+
end
|
115
|
+
|
116
|
+
def param(key)
|
117
|
+
params[key] || params[key.to_s]
|
118
|
+
end
|
119
|
+
|
120
|
+
def changes_applied?
|
121
|
+
@password_changed
|
122
|
+
end
|
123
|
+
|
124
|
+
def failure_result
|
125
|
+
flattened = errors.flatten.compact_blank
|
126
|
+
Result.new(success?: false, user: user, errors: flattened.presence || simplified_error_messages(user))
|
127
|
+
end
|
128
|
+
|
129
|
+
def array_wrap(value)
|
130
|
+
case value
|
131
|
+
when Array
|
132
|
+
value
|
133
|
+
when nil
|
134
|
+
[]
|
135
|
+
else
|
136
|
+
[value]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def simplified_error_messages(model)
|
141
|
+
return [] unless model.respond_to?(:errors)
|
142
|
+
|
143
|
+
model.errors.details.keys.map do |attr|
|
144
|
+
model.errors.full_messages_for(attr).first
|
145
|
+
end.compact
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/searls/auth/version.rb
CHANGED
data/lib/searls/auth.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
require_relative "auth/authenticates_user"
|
2
|
+
require_relative "auth/parses_time_safely"
|
2
3
|
require_relative "auth/config"
|
4
|
+
require_relative "auth/builds_target_redirect_url" if defined?(Rails)
|
3
5
|
require_relative "auth/creates_user" if defined?(Rails)
|
4
6
|
require_relative "auth/emails_link"
|
7
|
+
require_relative "auth/emails_verification"
|
5
8
|
require_relative "auth/engine" if defined?(Rails)
|
6
9
|
require_relative "auth/railtie" if defined?(Rails)
|
7
10
|
require_relative "auth/resets_session"
|
11
|
+
require_relative "auth/delivers_password_reset"
|
12
|
+
require_relative "auth/resets_password"
|
13
|
+
require_relative "auth/updates_settings"
|
8
14
|
require_relative "auth/version"
|
9
15
|
|
10
16
|
module Searls
|
@@ -13,6 +19,7 @@ module Searls
|
|
13
19
|
|
14
20
|
DEFAULT_CONFIG = {
|
15
21
|
auth_methods: [:email_link, :email_otp],
|
22
|
+
email_verification_mode: :none,
|
16
23
|
# Data setup
|
17
24
|
user_finder_by_email: ->(email) { User.find_by(email:) },
|
18
25
|
user_finder_by_id: ->(id) { User.find_by(id:) },
|
@@ -20,34 +27,52 @@ module Searls
|
|
20
27
|
user_initializer: ->(params) { User.new(email: params[:email]) },
|
21
28
|
user_name_method: "name",
|
22
29
|
token_generator: ->(user) { user.generate_token_for(:email_auth) },
|
23
|
-
|
30
|
+
email_otp_expiry_minutes: 30,
|
31
|
+
password_verifier: ->(user, password) { user.authenticate(password) },
|
32
|
+
password_setter: ->(user, password) { user.password = password },
|
33
|
+
password_reset_token_generator: ->(user) { user.generate_token_for(:password_reset) },
|
34
|
+
password_reset_token_finder: ->(token) { User.find_by_token_for(:password_reset, token) },
|
35
|
+
before_password_reset: ->(user, params, controller) { true },
|
36
|
+
password_reset_enabled: true,
|
37
|
+
email_verified_predicate: ->(user) { user.respond_to?(:email_verified_at) && user.email_verified_at.present? },
|
38
|
+
email_verified_setter: ->(user, time = Time.current) { user.respond_to?(:email_verified_at) ? user.update!(email_verified_at: time) : true },
|
39
|
+
password_present_predicate: ->(user) { user.respond_to?(:password_digest) && user.password_digest.present? },
|
24
40
|
# Controller setup
|
25
41
|
preserve_session_keys_after_logout: [],
|
26
|
-
|
42
|
+
max_allowed_email_otp_attempts: 10,
|
27
43
|
# View setup
|
28
44
|
layout: "application",
|
29
45
|
register_view: "searls/auth/registrations/show",
|
30
46
|
login_view: "searls/auth/logins/show",
|
31
47
|
verify_view: "searls/auth/verifications/show",
|
48
|
+
pending_email_verification_view: "searls/auth/registrations/pending_email_verification",
|
49
|
+
password_reset_request_view: "searls/auth/requests_password_resets/show",
|
50
|
+
password_reset_edit_view: "searls/auth/resets_passwords/show",
|
32
51
|
mail_layout: "searls/auth/layouts/mailer",
|
33
52
|
mail_login_template_path: "searls/auth/login_link_mailer",
|
34
53
|
mail_login_template_name: "login_link",
|
54
|
+
mail_password_reset_template_path: "searls/auth/password_reset_mailer",
|
55
|
+
mail_password_reset_template_name: "password_reset",
|
56
|
+
mail_email_verification_template_path: "searls/auth/email_verification_mailer",
|
57
|
+
mail_email_verification_template_name: "verification_email",
|
35
58
|
# Route setup
|
36
59
|
redirect_path_after_register: ->(user, params, request, routes) {
|
37
60
|
# Not every app defines a root_path, so guarding here:
|
38
61
|
routes.respond_to?(:root_path) ? routes.root_path : "/"
|
39
62
|
},
|
40
|
-
|
63
|
+
redirect_path_after_login: ->(user, params, request, routes) {
|
41
64
|
# Not every app defines a root_path, so guarding here:
|
42
65
|
routes.respond_to?(:root_path) ? routes.root_path : "/"
|
43
66
|
},
|
67
|
+
redirect_path_after_settings_change: ->(user, params, request, routes) {
|
68
|
+
routes.respond_to?(:edit_settings_path) ? routes.edit_settings_path : "/settings"
|
69
|
+
},
|
44
70
|
# Hook setup
|
45
71
|
validate_registration: ->(user, params, errors) { errors },
|
46
|
-
after_login_success:
|
72
|
+
after_login_success: ->(user) {},
|
47
73
|
# Branding setup
|
48
74
|
app_name: nil,
|
49
75
|
app_url: nil,
|
50
|
-
support_email_address: nil,
|
51
76
|
email_background_color: "#d8d7ed",
|
52
77
|
email_button_color: "#c664f3",
|
53
78
|
email_banner_image_path: nil,
|
@@ -56,23 +81,47 @@ module Searls
|
|
56
81
|
flash_error_after_register_attempt: ->(error_messages, login_path, params) { error_messages },
|
57
82
|
flash_notice_after_login_attempt: ->(user, params) { "Login details sent to #{params[:email]}" },
|
58
83
|
flash_error_after_login_attempt_unknown_email: ->(register_path, params) {
|
59
|
-
"We don't know that email. <a href=\"#{register_path}\">Sign up</a> instead?"
|
84
|
+
"We don't know that email. <a href=\"#{register_path}\">Sign up</a> instead?"
|
85
|
+
},
|
86
|
+
flash_error_after_login_attempt_invalid_password: ->(params) { "Invalid password. Try again?" },
|
87
|
+
flash_error_after_login_attempt_unverified_email: ->(resend_path, params) {
|
88
|
+
"You must verify your email before logging in. <a href=\"#{resend_path}\" data-turbo-method=\"patch\">Resend verification email</a>"
|
89
|
+
},
|
90
|
+
flash_notice_after_login_with_unverified_email: ->(resend_path, params) {
|
91
|
+
"You are now logged in, but your email is still unverified. <a href=\"#{resend_path}\" data-turbo-method=\"patch\">Resend verification email</a>"
|
92
|
+
},
|
93
|
+
flash_error_after_password_misconfigured: ->(params) {
|
94
|
+
"Password authentication misconfigured. Add `bcrypt` to your Gemfile or override password hooks."
|
60
95
|
},
|
96
|
+
flash_error_after_password_reset_token_invalid: ->(params) { "That password reset link is no longer valid. Try again?" },
|
97
|
+
flash_error_after_password_reset_password_mismatch: ->(params) { "Passwords must match. Try again?" },
|
98
|
+
flash_error_after_password_reset_password_blank: ->(params) { "Password can't be blank. Try again?" },
|
99
|
+
flash_error_after_password_reset_not_enabled: ->(params) { "Password resets are unavailable." },
|
61
100
|
flash_notice_after_logout: "You've been logged out",
|
62
|
-
|
101
|
+
flash_notice_after_login: "You are now logged in",
|
102
|
+
flash_notice_after_verification_email_resent: "Verification email sent",
|
103
|
+
flash_notice_after_email_verified: "Email verified",
|
104
|
+
flash_notice_after_password_reset_email: ->(params) { "If that email exists, password reset instructions are on the way." },
|
105
|
+
flash_notice_after_password_reset: ->(user, params) { "Your password has been reset." },
|
63
106
|
flash_error_after_verify_attempt_exceeds_limit: "Too many verification attempts. Please login again to generate a new code",
|
64
|
-
|
65
|
-
flash_error_after_verify_attempt_invalid_link: "We weren't able to log you in with that link. Try again?"
|
107
|
+
flash_error_after_verify_attempt_incorrect_email_otp: "We weren't able to log you in with that code. Try again?",
|
108
|
+
flash_error_after_verify_attempt_invalid_link: "We weren't able to log you in with that link. Try again?",
|
109
|
+
flash_notice_after_settings_update: ->(user, params) { "Settings updated." },
|
110
|
+
flash_error_after_settings_current_password_missing: ->(params) { "Enter your current password to make changes." },
|
111
|
+
flash_error_after_settings_current_password_invalid: ->(params) { "That current password doesn't match our records." },
|
112
|
+
auto_login_after_password_reset: true
|
66
113
|
|
67
114
|
}.freeze
|
68
115
|
|
69
|
-
|
70
|
-
def self.configure
|
71
|
-
yield
|
116
|
+
C_O_N_F_I_G__D_O_N_T_R_E_F_E_R_E_N_C_E__T_H_I_S__D_I_R_E_C_T_L_Y_L_O_L = Config.new(**DEFAULT_CONFIG)
|
117
|
+
def self.configure
|
118
|
+
yield C_O_N_F_I_G__D_O_N_T_R_E_F_E_R_E_N_C_E__T_H_I_S__D_I_R_E_C_T_L_Y_L_O_L
|
119
|
+
C_O_N_F_I_G__D_O_N_T_R_E_F_E_R_E_N_C_E__T_H_I_S__D_I_R_E_C_T_L_Y_L_O_L.validate!
|
120
|
+
C_O_N_F_I_G__D_O_N_T_R_E_F_E_R_E_N_C_E__T_H_I_S__D_I_R_E_C_T_L_Y_L_O_L
|
72
121
|
end
|
73
122
|
|
74
123
|
def self.config
|
75
|
-
|
124
|
+
C_O_N_F_I_G__D_O_N_T_R_E_F_E_R_E_N_C_E__T_H_I_S__D_I_R_E_C_T_L_Y_L_O_L.dup.freeze
|
76
125
|
end
|
77
126
|
end
|
78
127
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searls-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Searls
|
@@ -35,30 +35,52 @@ files:
|
|
35
35
|
- README.md
|
36
36
|
- Rakefile
|
37
37
|
- app/controllers/searls/auth/base_controller.rb
|
38
|
+
- app/controllers/searls/auth/email_verifications_controller.rb
|
38
39
|
- app/controllers/searls/auth/logins_controller.rb
|
39
40
|
- app/controllers/searls/auth/registrations_controller.rb
|
41
|
+
- app/controllers/searls/auth/requests_password_resets_controller.rb
|
42
|
+
- app/controllers/searls/auth/resets_passwords_controller.rb
|
43
|
+
- app/controllers/searls/auth/settings_controller.rb
|
40
44
|
- app/controllers/searls/auth/verifications_controller.rb
|
41
45
|
- app/helpers/searls/auth/application_helper.rb
|
42
46
|
- app/javascript/controllers/searls_auth_login_controller.js
|
43
47
|
- app/javascript/controllers/searls_auth_otp_controller.js
|
44
48
|
- app/mailers/searls/auth/base_mailer.rb
|
49
|
+
- app/mailers/searls/auth/email_verification_mailer.rb
|
45
50
|
- app/mailers/searls/auth/login_link_mailer.rb
|
51
|
+
- app/mailers/searls/auth/password_reset_mailer.rb
|
52
|
+
- app/views/searls/auth/email_verification_mailer/verification_email.html.erb
|
53
|
+
- app/views/searls/auth/email_verification_mailer/verification_email.text.erb
|
46
54
|
- app/views/searls/auth/layouts/mailer.html.erb
|
47
55
|
- app/views/searls/auth/login_link_mailer/login_link.html.erb
|
48
56
|
- app/views/searls/auth/login_link_mailer/login_link.text.erb
|
49
57
|
- app/views/searls/auth/logins/show.html.erb
|
58
|
+
- app/views/searls/auth/password_reset_mailer/password_reset.html.erb
|
59
|
+
- app/views/searls/auth/password_reset_mailer/password_reset.text.erb
|
60
|
+
- app/views/searls/auth/registrations/pending_email_verification.html.erb
|
50
61
|
- app/views/searls/auth/registrations/show.html.erb
|
62
|
+
- app/views/searls/auth/requests_password_resets/show.html.erb
|
63
|
+
- app/views/searls/auth/resets_passwords/show.html.erb
|
64
|
+
- app/views/searls/auth/settings/edit.html.erb
|
65
|
+
- app/views/searls/auth/shared/_login_fields.html.erb
|
66
|
+
- app/views/searls/auth/shared/_register_fields.html.erb
|
51
67
|
- app/views/searls/auth/verifications/show.html.erb
|
52
68
|
- config/importmap.rb
|
53
69
|
- config/routes.rb
|
54
70
|
- lib/searls/auth.rb
|
55
71
|
- lib/searls/auth/authenticates_user.rb
|
72
|
+
- lib/searls/auth/builds_target_redirect_url.rb
|
56
73
|
- lib/searls/auth/config.rb
|
57
74
|
- lib/searls/auth/creates_user.rb
|
75
|
+
- lib/searls/auth/delivers_password_reset.rb
|
58
76
|
- lib/searls/auth/emails_link.rb
|
77
|
+
- lib/searls/auth/emails_verification.rb
|
59
78
|
- lib/searls/auth/engine.rb
|
79
|
+
- lib/searls/auth/parses_time_safely.rb
|
60
80
|
- lib/searls/auth/railtie.rb
|
81
|
+
- lib/searls/auth/resets_password.rb
|
61
82
|
- lib/searls/auth/resets_session.rb
|
83
|
+
- lib/searls/auth/updates_settings.rb
|
62
84
|
- lib/searls/auth/version.rb
|
63
85
|
- script/setup
|
64
86
|
- script/setup_ci
|