minimalist_authentication 3.1.0 → 3.2.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/README.md +49 -28
- data/app/controllers/email_verifications_controller.rb +4 -3
- data/app/controllers/emails_controller.rb +1 -1
- data/app/controllers/password_resets_controller.rb +21 -12
- data/app/controllers/passwords_controller.rb +13 -8
- data/app/helpers/minimalist_authentication/application_helper.rb +68 -0
- data/app/mailers/minimalist_authentication_mailer.rb +2 -2
- data/app/views/email_verifications/show.html.erb +1 -1
- data/app/views/emails/edit.html.erb +3 -3
- data/app/views/minimalist_authentication_mailer/update_password.html.erb +3 -1
- data/app/views/minimalist_authentication_mailer/update_password.text.erb +2 -2
- data/app/views/minimalist_authentication_mailer/verify_email.html.erb +9 -3
- data/app/views/minimalist_authentication_mailer/verify_email.text.erb +3 -3
- data/app/views/password_resets/new.html.erb +5 -6
- data/app/views/passwords/edit.html.erb +9 -7
- data/app/views/sessions/_form.html.erb +7 -7
- data/app/views/sessions/new.html.erb +3 -3
- data/config/locales/minimalist_authentication.en.yml +31 -11
- data/config/routes.rb +3 -7
- data/lib/minimalist_authentication/configuration.rb +7 -3
- data/lib/minimalist_authentication/controller.rb +2 -0
- data/lib/minimalist_authentication/email_verification.rb +29 -11
- data/lib/minimalist_authentication/engine.rb +5 -0
- data/lib/minimalist_authentication/user.rb +14 -3
- data/lib/minimalist_authentication/verifiable_token.rb +21 -39
- data/lib/minimalist_authentication/version.rb +1 -1
- data/lib/minimalist_authentication.rb +6 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba64bc8499dedd0f4fe8dfca813cc0c21e2d32759bd3b3b4dd8aac3c0e77605a
|
4
|
+
data.tar.gz: 566e4b373c274fd7843469d4d225560baf877aabde97658b1aa5a66f3c97f65e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 149c5f1eb8a13319ba9d4848a7851107433d96081ed9a1bf01e43cba0366cb1e873aaa47c10eefed29aba9b973bf53076ecefd6d7b6835bb1a9300a4db8813fc
|
7
|
+
data.tar.gz: 51aae04db4c7bcdf4a26009fc1278aa716aea12d95624fe74ffd21fb9d52e0c901ec78d15751df92c2ce2882544a54b80f623e72a53703e1a67b88072662aed9
|
data/README.md
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# MinimalistAuthentication
|
2
|
-
A Rails authentication gem that takes a minimalist approach. It is designed to be simple to understand, use, and
|
2
|
+
A Rails authentication gem that takes a minimalist approach. It is designed to be simple to understand, use, and customize for your application.
|
3
3
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
Add this line to your application's Gemfile:
|
7
7
|
|
8
8
|
```ruby
|
9
|
-
gem
|
9
|
+
gem "minimalist_authentication"
|
10
10
|
```
|
11
11
|
|
12
|
-
And then
|
12
|
+
And then run:
|
13
13
|
```bash
|
14
14
|
$ bundle
|
15
15
|
```
|
@@ -61,18 +61,29 @@ class ActiveSupport::TestCase
|
|
61
61
|
end
|
62
62
|
```
|
63
63
|
|
64
|
+
|
64
65
|
## Configuration
|
65
66
|
Customize the configuration with an initializer. Create a **minimalist_authentication.rb** file in config/initializers.
|
66
67
|
```ruby
|
67
68
|
MinimalistAuthentication.configure do |configuration|
|
68
|
-
configuration.
|
69
|
+
configuration.login_redirect_path = :custom_path # default is :root_path
|
70
|
+
configuration.logout_redirect_path = :custom_path # default is :new_session_path
|
71
|
+
configuration.request_email = true # default is true
|
69
72
|
configuration.session_key = :custom_session_key # default is :user_id
|
73
|
+
configuration.user_model_name = "CustomModelName" # default is "::User"
|
70
74
|
configuration.validate_email = true # default is true
|
71
75
|
configuration.validate_email_presence = true # default is true
|
72
|
-
configuration.request_email = true # default is true
|
73
76
|
configuration.verify_email = true # default is true
|
74
|
-
|
75
|
-
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
### Example with a Person Model
|
81
|
+
```ruby
|
82
|
+
MinimalistAuthentication.configure do |configuration|
|
83
|
+
configuration.login_redirect_path = :dashboard_path
|
84
|
+
configuration.session_key = :person_id
|
85
|
+
configuration.user_model_name = "Person"
|
86
|
+
configuration.validate_email_presence = false
|
76
87
|
end
|
77
88
|
```
|
78
89
|
|
@@ -86,38 +97,44 @@ example_user:
|
|
86
97
|
```
|
87
98
|
|
88
99
|
|
89
|
-
## Verification
|
90
|
-
|
91
|
-
module. Include the module in your user class and add the verification token columns
|
92
|
-
to the database.
|
93
|
-
|
94
|
-
Include MinimalistAuthentication::VerifiableToken in your user model (app/models/user.rb)
|
100
|
+
## Email Verification
|
101
|
+
Include MinimalistAuthentication::EmailVerification in your user model (app/models/user.rb)
|
95
102
|
```ruby
|
96
103
|
class User < ApplicationRecord
|
97
104
|
include MinimalistAuthentication::User
|
98
|
-
include MinimalistAuthentication::
|
105
|
+
include MinimalistAuthentication::EmailVerification
|
99
106
|
end
|
100
107
|
```
|
101
108
|
|
102
|
-
Add the **
|
103
|
-
Create a user model with **email** for an identifier:
|
109
|
+
Add the **email_verified_at** column to your user model:
|
104
110
|
```bash
|
105
|
-
bin/rails generate migration
|
111
|
+
bin/rails generate migration AddEmailVerifiedAtToUsers email_verified_at:datetime
|
106
112
|
```
|
107
113
|
|
108
|
-
|
109
|
-
|
114
|
+
|
115
|
+
## Verification Tokens
|
116
|
+
Verification token support is provided by the ```ActiveRecord::TokenFor#generate_token_for``` method. MinimalistAuthentication includes token definitions for **password_reset** and **email_verification**. These tokens are utilized by the **update_password** and **verify_email** email messages respectively, to allow users to update their passwords and verify their email addresses.
|
117
|
+
|
118
|
+
### Update Password
|
119
|
+
The **update_password** token expires in 1 hour and is invalidated when the user's password is changed.
|
120
|
+
|
121
|
+
#### Example
|
110
122
|
```ruby
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
123
|
+
token = user.generate_token_for(:password_reset)
|
124
|
+
User.find_by_token_for(:password_reset, token) # => user
|
125
|
+
user.update!(password: "new password")
|
126
|
+
User.find_by_token_for(:password_reset, token) # => nil
|
116
127
|
```
|
117
128
|
|
118
|
-
|
119
|
-
|
120
|
-
|
129
|
+
### Email Verification
|
130
|
+
The **email_verification** token expires in 1 hour and is invalidated when the user's email is changed.
|
131
|
+
|
132
|
+
#### Example
|
133
|
+
```ruby
|
134
|
+
token = user.generate_token_for(:email_verification)
|
135
|
+
User.find_by_token_for(:email_verification, token) # => user
|
136
|
+
user.update!(email: "new_email@example.com")
|
137
|
+
User.find_by_token_for(:email_verification, token) # => nil
|
121
138
|
```
|
122
139
|
|
123
140
|
|
@@ -126,7 +143,7 @@ bin/rails generate migration AddEmailVerifiedAtToUsers email_verified_at:datetim
|
|
126
143
|
### Upgrading to Version 2.0
|
127
144
|
Pre 2.0 versions of MinimalistAuthentication supported multiple hash algorithms
|
128
145
|
and stored the hashed password and salt as separate fields in the database
|
129
|
-
(crypted_password and salt). The
|
146
|
+
(crypted_password and salt). The 2.0 version of MinimalistAuthentication
|
130
147
|
uses BCrypt to hash passwords and stores the result in the **password_hash** field.
|
131
148
|
|
132
149
|
To convert from a pre 2.0 version add the **password_hash** to your user model
|
@@ -162,5 +179,9 @@ end
|
|
162
179
|
alias_attribute :password_digest, :password_hash
|
163
180
|
```
|
164
181
|
|
182
|
+
### Upgrading to Version 3.2
|
183
|
+
The **verification_token** and **verification_token_generated_at** database columns are no longer used and can be safely removed from your user model.
|
184
|
+
|
185
|
+
|
165
186
|
## License
|
166
187
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT)..
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class EmailVerificationsController < ApplicationController
|
4
|
+
# Verifies the email of the current_user using the provided token
|
4
5
|
def show
|
5
6
|
current_user.verify_email(params[:token])
|
6
7
|
end
|
7
8
|
|
9
|
+
# Form for current_user to request an email verification email
|
8
10
|
def new
|
9
|
-
#
|
11
|
+
# new.html.erb
|
10
12
|
end
|
11
13
|
|
14
|
+
# Sends an email verification email to the current_user
|
12
15
|
def create
|
13
|
-
current_user.regenerate_verification_token
|
14
16
|
MinimalistAuthenticationMailer.with(user: current_user).verify_email.deliver_now
|
15
|
-
|
16
17
|
redirect_to dashboard_path, notice: t(".notice", email: current_user.email)
|
17
18
|
end
|
18
19
|
end
|
@@ -5,30 +5,39 @@ class PasswordResetsController < ApplicationController
|
|
5
5
|
|
6
6
|
layout "sessions"
|
7
7
|
|
8
|
-
#
|
8
|
+
# Renders form for user to request a password reset
|
9
9
|
def new
|
10
|
-
|
10
|
+
# new.html.erb
|
11
11
|
end
|
12
12
|
|
13
13
|
# Send a password update link to users with a verified email
|
14
14
|
def create
|
15
|
-
if
|
16
|
-
user
|
17
|
-
|
15
|
+
if email_valid?
|
16
|
+
send_update_password_email if user
|
17
|
+
|
18
|
+
# Always display notice to prevent leaking user emails
|
19
|
+
redirect_to new_session_path, notice: t(".notice", email:)
|
20
|
+
else
|
21
|
+
flash.now.alert = t(".alert")
|
22
|
+
render :new, status: :unprocessable_entity
|
18
23
|
end
|
19
|
-
# always display notice even if the user was not found to prevent leaking user emails
|
20
|
-
redirect_to new_session_path, notice: "Password reset instructions were mailed to #{email}"
|
21
24
|
end
|
22
25
|
|
23
26
|
private
|
24
27
|
|
25
|
-
def
|
26
|
-
|
28
|
+
def email
|
29
|
+
params.dig(:user, :email)
|
30
|
+
end
|
27
31
|
|
28
|
-
|
32
|
+
def send_update_password_email
|
33
|
+
MinimalistAuthenticationMailer.with(user:).update_password.deliver_now
|
29
34
|
end
|
30
35
|
|
31
|
-
def
|
32
|
-
|
36
|
+
def user
|
37
|
+
@user ||= MinimalistAuthentication.user_model.find_by_verified_email(email:)
|
38
|
+
end
|
39
|
+
|
40
|
+
def email_valid?
|
41
|
+
URI::MailTo::EMAIL_REGEXP.match?(email)
|
33
42
|
end
|
34
43
|
end
|
@@ -3,34 +3,39 @@
|
|
3
3
|
class PasswordsController < ApplicationController
|
4
4
|
skip_before_action :authorization_required
|
5
5
|
|
6
|
+
before_action :validate_token, only: %i[edit update]
|
7
|
+
|
6
8
|
layout "sessions"
|
7
9
|
|
8
10
|
# From for user to update password
|
9
11
|
def edit
|
10
|
-
|
11
|
-
# render passwords/edit.html.erb
|
12
|
+
# edit.html.erb
|
12
13
|
end
|
13
14
|
|
14
15
|
# Update user's password
|
15
16
|
def update
|
16
|
-
if user.
|
17
|
+
if user.update(password_params.merge(password_required: true))
|
17
18
|
redirect_to new_session_path, notice: t(".notice")
|
18
19
|
else
|
19
|
-
render :edit
|
20
|
+
render :edit, status: :unprocessable_entity
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
def
|
26
|
-
|
26
|
+
def password_params
|
27
|
+
params.require(:user).permit(:password, :password_confirmation)
|
27
28
|
end
|
28
29
|
|
29
30
|
def token
|
30
31
|
@token ||= params[:token]
|
31
32
|
end
|
32
33
|
|
33
|
-
def
|
34
|
-
|
34
|
+
def user
|
35
|
+
@user ||= MinimalistAuthentication.user_model.active.find_by_token_for(:password_reset, token)
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_token
|
39
|
+
redirect_to(new_session_path, alert: t(".invalid_token")) unless user
|
35
40
|
end
|
36
41
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MinimalistAuthentication
|
4
|
+
module ApplicationHelper
|
5
|
+
def ma_confirm_password_field(form, options = {})
|
6
|
+
form.password_field(
|
7
|
+
:password_confirmation,
|
8
|
+
options.reverse_merge(
|
9
|
+
autocomplete: "new-password",
|
10
|
+
minlength: MinimalistAuthentication.user_model.password_minimum,
|
11
|
+
placeholder: t(".password_confirmation.placeholder"),
|
12
|
+
required: true
|
13
|
+
)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def ma_email_field(form, options = {})
|
18
|
+
form.email_field(
|
19
|
+
:email,
|
20
|
+
options.reverse_merge(
|
21
|
+
autocomplete: "email",
|
22
|
+
autofocus: true,
|
23
|
+
placeholder: t(".email.placeholder", default: true),
|
24
|
+
required: true
|
25
|
+
)
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def ma_forgot_password_link
|
30
|
+
link_to(t(".forgot_password"), new_password_reset_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def ma_new_password_field(form, options = {})
|
34
|
+
form.password_field(
|
35
|
+
:password,
|
36
|
+
options.reverse_merge(
|
37
|
+
autocomplete: "new-password",
|
38
|
+
minlength: MinimalistAuthentication.user_model.password_minimum,
|
39
|
+
placeholder: t(".password.placeholder"),
|
40
|
+
required: true
|
41
|
+
)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def ma_password_field(form, options = {})
|
46
|
+
form.password_field(
|
47
|
+
:password,
|
48
|
+
options.reverse_merge(
|
49
|
+
autocomplete: "current-password",
|
50
|
+
placeholder: true,
|
51
|
+
required: true
|
52
|
+
)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def ma_username_field(form, options = {})
|
57
|
+
form.text_field(
|
58
|
+
:username,
|
59
|
+
options.reverse_merge(
|
60
|
+
autocomplete: "username",
|
61
|
+
autofocus: true,
|
62
|
+
placeholder: true,
|
63
|
+
required: true
|
64
|
+
)
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -5,11 +5,11 @@ class MinimalistAuthenticationMailer < ApplicationMailer
|
|
5
5
|
after_action :mail_user
|
6
6
|
|
7
7
|
def verify_email
|
8
|
-
@
|
8
|
+
@verify_email_url = email_verification_url(token: @user.generate_token_for(:email_verification))
|
9
9
|
end
|
10
10
|
|
11
11
|
def update_password
|
12
|
-
@
|
12
|
+
@edit_password_url = edit_password_url(token: @user.generate_token_for(:password_reset))
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
<h2>Please update your email address</h2>
|
4
4
|
|
5
|
-
<%=
|
5
|
+
<%= form_with(model: current_user, url: email_path) do |form| %>
|
6
6
|
<%= form.text_field :email %>
|
7
|
-
<%= form.submit
|
7
|
+
<%= form.submit "Update" %>
|
8
8
|
<% end %>
|
9
9
|
|
10
10
|
<p>Providing your email will allow you to receive confidential messages and reset your password.</p>
|
11
11
|
|
12
|
-
<%= link_to(
|
12
|
+
<%= link_to("Skip Email Update", dashboard_path) %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= t(
|
1
|
+
<%= t(".opening") %>
|
2
2
|
|
3
|
-
<%= @
|
3
|
+
<%= @edit_password_url %>
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<p
|
1
|
+
<p>
|
2
|
+
<%= t(".opening") %>
|
3
|
+
</p>
|
2
4
|
|
3
|
-
|
5
|
+
<p>
|
6
|
+
<%= link_to("Verify Email Address", @verify_email_url, rel: "noopener noreferrer", target: "_blank") %>
|
7
|
+
</p>
|
4
8
|
|
5
|
-
<p
|
9
|
+
<p>
|
10
|
+
<%= t(".closing") %>
|
11
|
+
</p>
|
@@ -1,13 +1,12 @@
|
|
1
|
-
<h1
|
1
|
+
<h1><%= t(".title") %></h1>
|
2
2
|
|
3
3
|
<p>
|
4
|
-
|
4
|
+
<%= t(".instructions") %>
|
5
5
|
</p>
|
6
6
|
|
7
|
-
<%=
|
7
|
+
<%= form_with scope: :user, url: password_reset_path do |form| %>
|
8
8
|
<div>
|
9
|
-
<%= form
|
10
|
-
<%= form.text_field :email %>
|
9
|
+
<%= ma_email_field(form) %>
|
11
10
|
</div>
|
12
|
-
<%= form.submit
|
11
|
+
<%= form.submit t(".submit") %>
|
13
12
|
<% end %>
|
@@ -1,15 +1,17 @@
|
|
1
|
-
<h1
|
1
|
+
<h1><%= t(".title") %></h1>
|
2
|
+
|
3
|
+
<p><%= t(".instructions") %></p>
|
2
4
|
|
3
5
|
<%= @user.errors.full_messages if @user.errors.any? %>
|
4
6
|
|
5
|
-
<%=
|
7
|
+
<%= form_with model: @user, url: password_path(token: @token) do |form| %>
|
6
8
|
<div>
|
7
|
-
<%= form.label
|
8
|
-
<%= form
|
9
|
+
<%= form.label :password %>
|
10
|
+
<%= ma_new_password_field(form) %>
|
9
11
|
</div>
|
10
12
|
<div>
|
11
|
-
<%= form.label
|
12
|
-
<%= form
|
13
|
+
<%= form.label :password_confirmation %>
|
14
|
+
<%= ma_confirm_password_field(form) %>
|
13
15
|
</div>
|
14
|
-
<%= form.submit
|
16
|
+
<%= form.submit t(".submit") %>
|
15
17
|
<% end %>
|
@@ -1,11 +1,11 @@
|
|
1
|
-
<%=
|
1
|
+
<%= form_with model: @user, url: session_path do |form| %>
|
2
2
|
<div>
|
3
|
-
<%= form.label
|
4
|
-
<%= form
|
3
|
+
<%= form.label :email %>
|
4
|
+
<%= ma_email_field(form) %>
|
5
5
|
</div>
|
6
|
-
<div>
|
7
|
-
<%= form.label
|
8
|
-
<%= form
|
6
|
+
<div style="margin-top: 8px;">
|
7
|
+
<%= form.label :password %>
|
8
|
+
<%= ma_password_field(form) %>
|
9
9
|
</div>
|
10
|
-
<%= form.submit
|
10
|
+
<%= form.submit t("sessions.new.submit") %>
|
11
11
|
<% end %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<h1
|
2
|
-
<%= render partial:
|
3
|
-
<%=
|
1
|
+
<h1><%= t(".title") %></h1>
|
2
|
+
<%= render partial: "form" %>
|
3
|
+
<%= ma_forgot_password_link %>
|
@@ -1,12 +1,38 @@
|
|
1
1
|
en:
|
2
|
-
# controllers
|
3
2
|
email_verifications:
|
4
3
|
create:
|
5
4
|
notice: Verification email sent to %{email}, follow the instructions to complete verification. Thank you!
|
6
5
|
emails:
|
7
6
|
update:
|
8
7
|
notice: Email successfully updated
|
8
|
+
minimalist_authentication_mailer:
|
9
|
+
update_password:
|
10
|
+
opening: Please click the link below to update your password.
|
11
|
+
subject: Update Password
|
12
|
+
verify_email:
|
13
|
+
closing: If you did not request email verification you can safely ignore this message.
|
14
|
+
opening: Please click the link below to complete your email verification.
|
15
|
+
subject: Email Address Verification
|
16
|
+
password_resets:
|
17
|
+
new:
|
18
|
+
email:
|
19
|
+
placeholder: Enter your email address
|
20
|
+
instructions: Enter your verified email address, and we'll send you a link to reset your password.
|
21
|
+
submit: Send Reset Link
|
22
|
+
title: Reset Your Password
|
23
|
+
create:
|
24
|
+
alert: Please provide a valid email address.
|
25
|
+
notice: We've sent password reset instructions to %{email}. If you don't receive the email within a few minutes, please check your spam folder.
|
9
26
|
passwords:
|
27
|
+
edit:
|
28
|
+
instructions: Please enter your new password.
|
29
|
+
password:
|
30
|
+
placeholder: New password
|
31
|
+
password_confirmation:
|
32
|
+
placeholder: Confirm password
|
33
|
+
submit: Reset Password
|
34
|
+
title: Reset Password
|
35
|
+
invalid_token: Your password reset link has expired. Please request a new one to continue.
|
10
36
|
update:
|
11
37
|
notice: Password successfully updated
|
12
38
|
sessions:
|
@@ -14,13 +40,7 @@ en:
|
|
14
40
|
alert: Couldn't log you in as %{identifier}
|
15
41
|
destroy:
|
16
42
|
notice: You have been logged out.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
opening: Please click the link below to update your password.
|
22
|
-
subject: Update Password
|
23
|
-
verify_email:
|
24
|
-
closing: If you did not request email verification you can safely ignore this message.
|
25
|
-
opening: Please click the link below to complete your email verification.
|
26
|
-
subject: "Email Address Verification"
|
43
|
+
new:
|
44
|
+
forgot_password: Forgot password?
|
45
|
+
title: Sign In
|
46
|
+
submit: Sign In
|
data/config/routes.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Rails.application.routes.draw do
|
4
|
-
|
5
|
-
resource :password, only: %i[edit update]
|
6
|
-
end
|
7
|
-
|
8
|
-
resource :password_reset, only: %i[new create]
|
9
|
-
|
4
|
+
resource :email_verification, only: %i[show new create]
|
10
5
|
resource :email, only: %i[edit update]
|
11
|
-
resource :
|
6
|
+
resource :password_reset, only: %i[new create]
|
7
|
+
resource :password, only: %i[edit update]
|
12
8
|
end
|
@@ -62,15 +62,19 @@ module MinimalistAuthentication
|
|
62
62
|
self.logout_redirect_path = :new_session_path
|
63
63
|
end
|
64
64
|
|
65
|
+
# Clear the user_model class
|
66
|
+
def clear_user_model
|
67
|
+
@user_model = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Display deprecation warning for email_prefix
|
65
71
|
def email_prefix=(_)
|
66
72
|
MinimalistAuthentication.deprecator.warn("The #email_prefix configuration setting is no longer supported.")
|
67
73
|
end
|
68
74
|
|
69
75
|
# Returns the user_model class
|
70
|
-
# Calling constantize on a string makes this work correctly with
|
71
|
-
# the Spring application preloader gem.
|
72
76
|
def user_model
|
73
|
-
user_model_name.constantize
|
77
|
+
@user_model ||= user_model_name.constantize
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
@@ -5,9 +5,31 @@ module MinimalistAuthentication
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
8
|
+
generates_token_for :email_verification, expires_in: 1.hour do
|
9
|
+
email
|
10
|
+
end
|
9
11
|
|
10
|
-
|
12
|
+
before_save :clear_email_verification, if: :email_changed?
|
13
|
+
|
14
|
+
scope :with_verified_email, -> { where.not(email_verified_at: nil) }
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def email_verified
|
19
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
20
|
+
Calling #email_verified is deprecated.
|
21
|
+
Call #with_verified_email instead.
|
22
|
+
MSG
|
23
|
+
with_verified_email
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_by_verified_email(email:)
|
27
|
+
active.with_verified_email.find_by(email:)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def email_verified?
|
32
|
+
email.present? && email_verified_at.present?
|
11
33
|
end
|
12
34
|
|
13
35
|
def needs_email_set?
|
@@ -18,26 +40,22 @@ module MinimalistAuthentication
|
|
18
40
|
email_verification_enabled? && email.present? && email_verified_at.blank?
|
19
41
|
end
|
20
42
|
|
21
|
-
def email_verified?
|
22
|
-
email.present? && email_verified_at.present?
|
23
|
-
end
|
24
|
-
|
25
43
|
def verify_email(token)
|
26
|
-
|
44
|
+
touch(:email_verified_at) if token_owner?(:email_verification, token)
|
27
45
|
end
|
28
46
|
|
29
47
|
private
|
30
48
|
|
31
|
-
def
|
32
|
-
|
49
|
+
def clear_email_verification
|
50
|
+
self.email_verified_at = nil
|
33
51
|
end
|
34
52
|
|
35
53
|
def email_verification_enabled?
|
36
54
|
MinimalistAuthentication.configuration.verify_email
|
37
55
|
end
|
38
56
|
|
39
|
-
def
|
40
|
-
|
57
|
+
def request_email_enabled?
|
58
|
+
MinimalistAuthentication.configuration.request_email
|
41
59
|
end
|
42
60
|
end
|
43
61
|
end
|
@@ -11,6 +11,10 @@ module MinimalistAuthentication
|
|
11
11
|
included do
|
12
12
|
has_secure_password
|
13
13
|
|
14
|
+
generates_token_for :password_reset, expires_in: 1.hour do
|
15
|
+
password_salt.last(10)
|
16
|
+
end
|
17
|
+
|
14
18
|
# Force validations for a blank password.
|
15
19
|
attribute :password_required, :boolean, default: false
|
16
20
|
|
@@ -32,6 +36,8 @@ module MinimalistAuthentication
|
|
32
36
|
|
33
37
|
# Active scope
|
34
38
|
scope :active, ->(state = true) { where(active: state) }
|
39
|
+
|
40
|
+
delegate :password_minimum, to: :class
|
35
41
|
end
|
36
42
|
|
37
43
|
module ClassMethods
|
@@ -52,6 +58,9 @@ module MinimalistAuthentication
|
|
52
58
|
def guest
|
53
59
|
new(email: GUEST_USER_EMAIL).freeze
|
54
60
|
end
|
61
|
+
|
62
|
+
# Minimum password length
|
63
|
+
def password_minimum = 12
|
55
64
|
end
|
56
65
|
|
57
66
|
# Called after a user is authenticated to determine if the user object should be returned.
|
@@ -94,9 +103,6 @@ module MinimalistAuthentication
|
|
94
103
|
update_column(:last_logged_in_at, Time.current)
|
95
104
|
end
|
96
105
|
|
97
|
-
# Minimum password length
|
98
|
-
def password_minimum = 12
|
99
|
-
|
100
106
|
# Checks for password presence
|
101
107
|
def password?
|
102
108
|
password.present?
|
@@ -111,6 +117,11 @@ module MinimalistAuthentication
|
|
111
117
|
end
|
112
118
|
end
|
113
119
|
|
120
|
+
# Return true if the user matches the owner of the provided token.
|
121
|
+
def token_owner?(purpose, token)
|
122
|
+
self.class.find_by_token_for(purpose, token) == self
|
123
|
+
end
|
124
|
+
|
114
125
|
# Require password for active users that either do no have a password hash
|
115
126
|
# stored OR are attempting to set a new password. Set **password_required**
|
116
127
|
# to true to force validations even when the password field is blank.
|
@@ -4,51 +4,33 @@ module MinimalistAuthentication
|
|
4
4
|
module VerifiableToken
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def secure_update(token, attributes)
|
15
|
-
if matches_verification_token?(token)
|
16
|
-
update(attributes) && clear_token
|
17
|
-
else
|
18
|
-
errors.add(:base, "Verification token check failed")
|
19
|
-
false
|
20
|
-
end
|
7
|
+
included do
|
8
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
9
|
+
MinimalistAuthentication::VerifiableToken is no longer required.
|
10
|
+
You can safely remove the include from your user model.
|
11
|
+
MSG
|
21
12
|
end
|
22
13
|
|
23
|
-
def matches_verification_token?(
|
24
|
-
|
14
|
+
def matches_verification_token?(_token)
|
15
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
16
|
+
Calling #matches_verification_token? is deprecated.
|
17
|
+
MSG
|
25
18
|
end
|
26
19
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def clear_token
|
36
|
-
update_token(token: nil, time: nil)
|
37
|
-
end
|
38
|
-
|
39
|
-
def update_token(token: self.class.generate_unique_secure_token, time: Time.now.utc)
|
40
|
-
update!(
|
41
|
-
verification_token: token,
|
42
|
-
verification_token_generated_at: time
|
43
|
-
)
|
20
|
+
def regenerate_verification_token
|
21
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
22
|
+
Calling #regenerate_verification_token is deprecated and no longer generates tokens.
|
23
|
+
Call #generate_token_for with an argument of :password_reset or
|
24
|
+
:email_verification instead.
|
25
|
+
MSG
|
44
26
|
end
|
45
27
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
28
|
+
def verification_token
|
29
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
30
|
+
Calling #verification_token is deprecated and no longer returns a valid token.
|
31
|
+
Call #generate_token_for with an argument of :password_reset or
|
32
|
+
:email_verification instead.
|
33
|
+
MSG
|
52
34
|
end
|
53
35
|
end
|
54
36
|
end
|
@@ -11,7 +11,11 @@ require "minimalist_authentication/sessions"
|
|
11
11
|
require "minimalist_authentication/test_helper"
|
12
12
|
|
13
13
|
module MinimalistAuthentication
|
14
|
-
|
15
|
-
|
14
|
+
class << self
|
15
|
+
delegate :user_model, to: :configuration
|
16
|
+
|
17
|
+
def deprecator
|
18
|
+
@deprecator ||= ActiveSupport::Deprecation.new("4.0", name)
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minimalist_authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Baldwin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-11-
|
12
|
+
date: 2024-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bcrypt
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- app/controllers/emails_controller.rb
|
61
61
|
- app/controllers/password_resets_controller.rb
|
62
62
|
- app/controllers/passwords_controller.rb
|
63
|
+
- app/helpers/minimalist_authentication/application_helper.rb
|
63
64
|
- app/mailers/application_mailer.rb
|
64
65
|
- app/mailers/minimalist_authentication_mailer.rb
|
65
66
|
- app/views/email_verifications/new.html.erb
|