minimalist_authentication 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|