searls-auth 0.1.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +16 -1
- data/LICENSE.txt +1 -1
- data/README.md +185 -1
- 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 +61 -35
- 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 +37 -53
- 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 +13 -2
- 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 +29 -25
- data/app/views/searls/auth/login_link_mailer/login_link.text.erb +9 -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/app/views/searls/auth/verifications/show.html.erb +20 -20
- 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 +246 -10
- 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 +3 -3
- data/lib/searls/auth/emails_verification.rb +33 -0
- data/lib/searls/auth/parses_time_safely.rb +34 -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 +63 -13
- data/script/setup +1 -6
- data/script/test +1 -1
- metadata +24 -2
@@ -0,0 +1,18 @@
|
|
1
|
+
module Searls
|
2
|
+
module Auth
|
3
|
+
class DeliversPasswordReset
|
4
|
+
Result = Struct.new(:success?, keyword_init: true)
|
5
|
+
|
6
|
+
def deliver(user:, redirect_path: nil, redirect_subdomain: nil)
|
7
|
+
token = Searls::Auth.config.password_reset_token_generator.call(user)
|
8
|
+
PasswordResetMailer.with(
|
9
|
+
user:,
|
10
|
+
token:,
|
11
|
+
redirect_path:,
|
12
|
+
redirect_subdomain:
|
13
|
+
).password_reset.deliver_later
|
14
|
+
Result.new(success?: true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Searls
|
2
2
|
module Auth
|
3
3
|
class EmailsLink
|
4
|
-
def email(user:,
|
4
|
+
def email(user:, email_otp:, redirect_path: nil, redirect_subdomain: nil)
|
5
5
|
LoginLinkMailer.with(
|
6
6
|
user:,
|
7
|
-
token: generate_token!(user),
|
8
|
-
|
7
|
+
token: (Searls::Auth.config.auth_methods.include?(:email_link) ? generate_token!(user) : nil),
|
8
|
+
email_otp: (Searls::Auth.config.auth_methods.include?(:email_otp) ? email_otp : nil),
|
9
9
|
redirect_path:,
|
10
10
|
redirect_subdomain:
|
11
11
|
).login_link.deliver_later
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Searls
|
2
|
+
module Auth
|
3
|
+
class EmailsVerification
|
4
|
+
def email(user:, redirect_path: nil, redirect_subdomain: nil)
|
5
|
+
EmailVerificationMailer.with(
|
6
|
+
user:,
|
7
|
+
token: generate_token!(user),
|
8
|
+
redirect_path:,
|
9
|
+
redirect_subdomain:
|
10
|
+
).verification_email.deliver_later
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def generate_token!(user)
|
16
|
+
Searls::Auth.config.token_generator.call(user)
|
17
|
+
rescue KeyError => e
|
18
|
+
raise Error, <<~MSG
|
19
|
+
Secure token generation for user failed!
|
20
|
+
|
21
|
+
Message: #{e.message}
|
22
|
+
User: #{user.inspect}
|
23
|
+
|
24
|
+
This can probably be fixed by adding a line like this to your #{user.class.name} class:
|
25
|
+
|
26
|
+
generates_token_for :email_auth, expires_in: 30.minutes
|
27
|
+
|
28
|
+
Otherwise, you may want to override searls-auth's "token_generator" setting with a proc of your own.
|
29
|
+
MSG
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
else
|
18
|
+
parse_string(input.to_s)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
rescue ArgumentError, TypeError, NoMethodError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_string(s)
|
28
|
+
if !(stripped = s.strip).empty?
|
29
|
+
Time.zone.parse(stripped)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
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
|
@@ -12,6 +18,8 @@ module Searls
|
|
12
18
|
class Error < StandardError; end
|
13
19
|
|
14
20
|
DEFAULT_CONFIG = {
|
21
|
+
auth_methods: [:email_link, :email_otp],
|
22
|
+
email_verification_mode: :none,
|
15
23
|
# Data setup
|
16
24
|
user_finder_by_email: ->(email) { User.find_by(email:) },
|
17
25
|
user_finder_by_id: ->(id) { User.find_by(id:) },
|
@@ -19,34 +27,52 @@ module Searls
|
|
19
27
|
user_initializer: ->(params) { User.new(email: params[:email]) },
|
20
28
|
user_name_method: "name",
|
21
29
|
token_generator: ->(user) { user.generate_token_for(:email_auth) },
|
22
|
-
|
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? },
|
23
40
|
# Controller setup
|
24
41
|
preserve_session_keys_after_logout: [],
|
25
|
-
|
42
|
+
max_allowed_email_otp_attempts: 10,
|
26
43
|
# View setup
|
27
44
|
layout: "application",
|
28
45
|
register_view: "searls/auth/registrations/show",
|
29
46
|
login_view: "searls/auth/logins/show",
|
30
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",
|
31
51
|
mail_layout: "searls/auth/layouts/mailer",
|
32
52
|
mail_login_template_path: "searls/auth/login_link_mailer",
|
33
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",
|
34
58
|
# Route setup
|
35
59
|
redirect_path_after_register: ->(user, params, request, routes) {
|
36
60
|
# Not every app defines a root_path, so guarding here:
|
37
61
|
routes.respond_to?(:root_path) ? routes.root_path : "/"
|
38
62
|
},
|
39
|
-
|
63
|
+
redirect_path_after_login: ->(user, params, request, routes) {
|
40
64
|
# Not every app defines a root_path, so guarding here:
|
41
65
|
routes.respond_to?(:root_path) ? routes.root_path : "/"
|
42
66
|
},
|
67
|
+
redirect_path_after_settings_change: ->(user, params, request, routes) {
|
68
|
+
routes.respond_to?(:edit_settings_path) ? routes.edit_settings_path : "/settings"
|
69
|
+
},
|
43
70
|
# Hook setup
|
44
71
|
validate_registration: ->(user, params, errors) { errors },
|
45
|
-
after_login_success:
|
72
|
+
after_login_success: ->(user) {},
|
46
73
|
# Branding setup
|
47
74
|
app_name: nil,
|
48
75
|
app_url: nil,
|
49
|
-
support_email_address: nil,
|
50
76
|
email_background_color: "#d8d7ed",
|
51
77
|
email_button_color: "#c664f3",
|
52
78
|
email_banner_image_path: nil,
|
@@ -55,23 +81,47 @@ module Searls
|
|
55
81
|
flash_error_after_register_attempt: ->(error_messages, login_path, params) { error_messages },
|
56
82
|
flash_notice_after_login_attempt: ->(user, params) { "Login details sent to #{params[:email]}" },
|
57
83
|
flash_error_after_login_attempt_unknown_email: ->(register_path, params) {
|
58
|
-
"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."
|
59
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." },
|
60
100
|
flash_notice_after_logout: "You've been logged out",
|
61
|
-
|
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." },
|
62
106
|
flash_error_after_verify_attempt_exceeds_limit: "Too many verification attempts. Please login again to generate a new code",
|
63
|
-
|
64
|
-
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
|
65
113
|
|
66
114
|
}.freeze
|
67
115
|
|
68
|
-
|
69
|
-
def self.configure
|
70
|
-
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
|
71
121
|
end
|
72
122
|
|
73
123
|
def self.config
|
74
|
-
|
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
|
75
125
|
end
|
76
126
|
end
|
77
127
|
end
|
data/script/setup
CHANGED
@@ -5,10 +5,5 @@ set -e
|
|
5
5
|
bundle
|
6
6
|
|
7
7
|
cd example/simple_app
|
8
|
-
|
9
|
-
bin/rake db:setup
|
10
|
-
export PLAYWRIGHT_CLI_VERSION=$(bundle exec ruby -e 'require "playwright"; puts Playwright::COMPATIBLE_PLAYWRIGHT_VERSION.strip')
|
11
|
-
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 yarn add -D "playwright@$PLAYWRIGHT_CLI_VERSION"
|
12
|
-
yarn run playwright install chromium
|
13
|
-
|
8
|
+
./script/setup
|
14
9
|
cd ../..
|
data/script/test
CHANGED
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.0
|
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
|
@@ -84,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
106
|
- !ruby/object:Gem::Version
|
85
107
|
version: '0'
|
86
108
|
requirements: []
|
87
|
-
rubygems_version: 3.6.
|
109
|
+
rubygems_version: 3.6.9
|
88
110
|
specification_version: 4
|
89
111
|
summary: Searls-flavored login for Rails apps
|
90
112
|
test_files: []
|