avocado 0.4.0 → 0.5.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 +8 -0
- data/README.md +4 -0
- data/app/controllers/avocado/affirmations_controller.rb +51 -0
- data/app/controllers/avocado/base_controller.rb +10 -0
- data/app/controllers/avocado/emails_controller.rb +48 -0
- data/app/controllers/avocado/events_controller.rb +9 -0
- data/app/controllers/avocado/passwords_controller.rb +34 -0
- data/app/views/avocado/affirmations/new.html.erb +14 -0
- data/app/views/avocado/emails/edit.html.erb +20 -0
- data/app/views/avocado/events/_event.html.erb +6 -0
- data/app/views/avocado/events/index.html.erb +17 -0
- data/app/views/avocado/mailer/email_affirmation.text.erb +3 -1
- data/app/views/avocado/mailer/email_verification.text.erb +1 -1
- data/app/views/avocado/mailer/password_reset.text.erb +1 -1
- data/app/views/avocado/passwords/edit.html.erb +16 -0
- data/app/views/avocado/recoveries/edit.html.erb +2 -2
- data/app/views/avocado/recoveries/new.html.erb +2 -2
- data/app/views/avocado/registrations/new.html.erb +1 -1
- data/app/views/avocado/sessions/new.html.erb +1 -1
- data/config/routes.rb +4 -0
- data/lib/avocado/current.rb +10 -8
- data/lib/avocado/event.rb +32 -0
- data/lib/avocado/session.rb +3 -0
- data/lib/avocado/session_callbacks.rb +34 -0
- data/lib/avocado/user.rb +10 -3
- data/lib/avocado/user_callbacks.rb +45 -0
- data/lib/avocado/user_validations.rb +22 -0
- data/lib/avocado/version.rb +1 -1
- data/lib/avocado.rb +4 -2
- metadata +15 -4
- data/lib/avocado/user_email.rb +0 -13
- data/lib/avocado/user_password.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a530ebf9605c2bb861d2da09da546513e68c4f647fc97c80686e07b32985cabe
|
4
|
+
data.tar.gz: 3be481be5c31ce2ee3bb1ea1a2d796bb7f8cbe850f7ccf2de6f296384a656bb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf3320eb985cc65c05c2da2d007697b4b9016d9a85f7ebebbd0735d744d7f8ca77096d86182c6761b63ea6f51f4b942a3c2dd363bb102ccc4ed53da6f5702c4f
|
7
|
+
data.tar.gz: f0b021b9e0f3433f2034e5cccdc751a446b50bc870474376e1a39b84e973bbabfaef95b59d96f60986bbddc7695afe88b860bd2d1568f991a17b3b654d7f3995
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.0] - 2023-07-21
|
4
|
+
|
5
|
+
- Add controller for "passwordless" email-link sign-in
|
6
|
+
- Add event class to log user auth events
|
7
|
+
- Add user-facing email and password edit pages
|
8
|
+
- Add various event logging callbacks
|
9
|
+
- Sign out all non current sessions when password changes
|
10
|
+
|
3
11
|
## [0.4.0] - 2023-07-19
|
4
12
|
|
5
13
|
- Convert the `Avocado::Mailer` module into a class
|
data/README.md
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
class AffirmationsController < BaseController
|
5
|
+
skip_before_action :authenticate
|
6
|
+
|
7
|
+
before_action :set_user, only: :show
|
8
|
+
before_action :verify_user, only: :create
|
9
|
+
|
10
|
+
def new
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
sign_in(@user)
|
15
|
+
redirect_to(root_path, notice: "Signed in successfully")
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
send_affirmation_email
|
20
|
+
redirect_to new_session_path, notice: "Check your email for sign in instructions"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def set_user
|
26
|
+
@user = user_from_signed_affirmation_token
|
27
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
28
|
+
redirect_to new_affirmation_path, alert: "That sign in link is invalid"
|
29
|
+
end
|
30
|
+
|
31
|
+
def user_from_signed_affirmation_token
|
32
|
+
::User.find_by_token_for!(:email_affirmation, params[:id])
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_user
|
36
|
+
unless user_from_params_email
|
37
|
+
redirect_to new_affirmation_path, alert: "You can't sign in until you verify your email"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_affirmation_email
|
42
|
+
mailer_for(user_from_params_email)
|
43
|
+
.email_affirmation
|
44
|
+
.deliver_later
|
45
|
+
end
|
46
|
+
|
47
|
+
def user_from_params_email
|
48
|
+
::User.verified.find_by(email: params[:email])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -4,6 +4,16 @@ module Avocado
|
|
4
4
|
class BaseController < ApplicationController
|
5
5
|
private
|
6
6
|
|
7
|
+
def verify_password_challenge
|
8
|
+
unless current_user.authenticate(params_password_challenge)
|
9
|
+
redirect_back alert: "Password challenge failed.", fallback_location: root_path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def params_password_challenge
|
14
|
+
params.dig(:user, :password_challenge)
|
15
|
+
end
|
16
|
+
|
7
17
|
def mailer_for(user)
|
8
18
|
Avocado::Mailer.with(user: user)
|
9
19
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
class EmailsController < BaseController
|
5
|
+
PERMITTED_PARAMS = [:email]
|
6
|
+
|
7
|
+
before_action :set_user
|
8
|
+
before_action :verify_password_challenge, only: :update
|
9
|
+
|
10
|
+
def edit
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
if @user.update(user_params)
|
15
|
+
process_email_update
|
16
|
+
else
|
17
|
+
render :edit, status: :unprocessable_entity
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_user
|
24
|
+
@user = current_user
|
25
|
+
end
|
26
|
+
|
27
|
+
def user_params
|
28
|
+
params
|
29
|
+
.require(:user)
|
30
|
+
.permit(PERMITTED_PARAMS)
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_email_update
|
34
|
+
if @user.email_previously_changed?
|
35
|
+
resend_email_verification
|
36
|
+
redirect_to root_path, notice: "Your email has been changed"
|
37
|
+
else
|
38
|
+
redirect_to root_path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def resend_email_verification
|
43
|
+
mailer_for(@user)
|
44
|
+
.email_verification
|
45
|
+
.deliver_later
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
class PasswordsController < BaseController
|
5
|
+
PERMITTED_PARAMS = [:password, :password_confirmation, :password_challenge]
|
6
|
+
|
7
|
+
before_action :set_user
|
8
|
+
before_action :verify_password_challenge, only: :update
|
9
|
+
|
10
|
+
def edit
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
if @user.update(user_params)
|
15
|
+
redirect_to root_path, notice: "Your password has been changed"
|
16
|
+
else
|
17
|
+
render :edit, status: :unprocessable_entity
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_user
|
24
|
+
@user = current_user
|
25
|
+
end
|
26
|
+
|
27
|
+
def user_params
|
28
|
+
params
|
29
|
+
.require(:user)
|
30
|
+
.permit(PERMITTED_PARAMS)
|
31
|
+
.with_defaults(password_challenge: "")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<h2>
|
2
|
+
Sign in without password
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
<%= link_to "Reset your password", new_recovery_path %>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<%= form_with url: affirmations_path do |form| %>
|
10
|
+
<%= form.label :email %>
|
11
|
+
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
|
+
|
13
|
+
<%= form.button "Submit", name: nil %>
|
14
|
+
<% end -%>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h2>
|
2
|
+
Change your email address
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<% if current_user.verified? %>
|
6
|
+
<p>Your email address is verified.</p>
|
7
|
+
<% else %>
|
8
|
+
<p>Your email address is not verified. Check your email and follow the instructions to confirm it's your email address.</p>
|
9
|
+
<p><%= button_to "Re-send verification email", verifications_path %></p>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<%= form_with model: @user, url: email_path, method: :patch do |form| %>
|
13
|
+
<%= form.label :email %>
|
14
|
+
<%= form.email_field :email, autocomplete: "email", required: true %>
|
15
|
+
|
16
|
+
<%= form.label :password_challenge, "Current password" %>
|
17
|
+
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
18
|
+
|
19
|
+
<%= form.button "Submit", name: nil %>
|
20
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<h2>
|
2
|
+
Events
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<table id="events">
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th scope="col">Action</th>
|
9
|
+
<th scope="col">Created</th>
|
10
|
+
<th scope="col">User Agent</th>
|
11
|
+
<th scope="col">IP Address</th>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
<tbody>
|
15
|
+
<%= render @events %>
|
16
|
+
</tbody>
|
17
|
+
</table>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<h2>
|
2
|
+
Change your password
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<%= form_with model: @user, url: password_path, method: :patch do |form| %>
|
6
|
+
<%= form.label :password_challenge, "Current password" %>
|
7
|
+
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
8
|
+
|
9
|
+
<%= form.label :password %>
|
10
|
+
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
11
|
+
|
12
|
+
<%= form.label :password_confirmation %>
|
13
|
+
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
14
|
+
|
15
|
+
<%= form.button "Submit", name: nil %>
|
16
|
+
<% end %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h2>
|
2
|
-
|
2
|
+
Change your password
|
3
3
|
</h2>
|
4
4
|
|
5
5
|
<p>
|
@@ -13,5 +13,5 @@
|
|
13
13
|
<%= form.label :password_confirmation %>
|
14
14
|
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
15
15
|
|
16
|
-
<%= form.button "
|
16
|
+
<%= form.button "Submit", name: nil %>
|
17
17
|
<% end %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h2>
|
2
|
-
|
2
|
+
Reset your password
|
3
3
|
</h2>
|
4
4
|
|
5
5
|
<p>
|
@@ -10,5 +10,5 @@
|
|
10
10
|
<%= form.label :email %>
|
11
11
|
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
12
|
|
13
|
-
<%= form.button "
|
13
|
+
<%= form.button "Submit", name: nil %>
|
14
14
|
<% end -%>
|
@@ -11,5 +11,5 @@
|
|
11
11
|
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
12
|
<%= form.label :password %>
|
13
13
|
<%= form.password_field :password, autocomplete: "current-password", required: true %>
|
14
|
-
<%= form.button "
|
14
|
+
<%= form.button "Submit", name: nil %>
|
15
15
|
<% end -%>
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
scope module: :avocado do
|
3
|
+
resource :email, only: %i[edit update]
|
4
|
+
resource :password, only: %i[edit update]
|
5
|
+
resources :affirmations, only: %i[new show create]
|
6
|
+
resources :events, only: %i[index]
|
3
7
|
resources :recoveries, only: %i[new create edit update]
|
4
8
|
resources :registrations, only: %i[new create]
|
5
9
|
resources :sessions, only: %i[index new create destroy]
|
data/lib/avocado/current.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
:
|
6
|
-
|
7
|
-
|
3
|
+
module Avocado
|
4
|
+
class Current < ActiveSupport::CurrentAttributes
|
5
|
+
attribute :session,
|
6
|
+
:user,
|
7
|
+
:user_agent,
|
8
|
+
:ip_address
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def session=(session)
|
11
|
+
super
|
12
|
+
self.user = session.user
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
module Event
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
VALID_ACTIONS = [
|
8
|
+
"email:update",
|
9
|
+
"email:verified",
|
10
|
+
"password:update",
|
11
|
+
"session:create",
|
12
|
+
"session:destroy"
|
13
|
+
]
|
14
|
+
|
15
|
+
included do
|
16
|
+
belongs_to :user
|
17
|
+
|
18
|
+
scope :newest_first, -> { order(created_at: :desc) }
|
19
|
+
|
20
|
+
validates :action, inclusion: VALID_ACTIONS
|
21
|
+
|
22
|
+
before_create :capture_request_details
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def capture_request_details
|
28
|
+
self.user_agent = Current.user_agent
|
29
|
+
self.ip_address = Current.ip_address
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/avocado/session.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
module SessionCallbacks
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_create :record_activity_create
|
9
|
+
|
10
|
+
after_destroy :record_activity_destroy
|
11
|
+
|
12
|
+
before_create :capture_request_details
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def record_activity_create
|
18
|
+
create_user_event "session:create"
|
19
|
+
end
|
20
|
+
|
21
|
+
def record_activity_destroy
|
22
|
+
create_user_event "session:destroy"
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_user_event(action)
|
26
|
+
user.events.create! action: action
|
27
|
+
end
|
28
|
+
|
29
|
+
def capture_request_details
|
30
|
+
self.user_agent = Current.user_agent
|
31
|
+
self.ip_address = Current.ip_address
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/avocado/user.rb
CHANGED
@@ -5,14 +5,21 @@ module Avocado
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
include
|
8
|
+
include UserCallbacks
|
9
9
|
include UserTokens
|
10
|
-
include
|
10
|
+
include UserValidations
|
11
11
|
|
12
|
-
|
12
|
+
has_secure_password
|
13
|
+
|
14
|
+
with_options dependent: :destroy do
|
15
|
+
has_many :events
|
16
|
+
has_many :sessions
|
17
|
+
end
|
13
18
|
|
14
19
|
scope :newest_first, -> { order(created_at: :desc) }
|
15
20
|
scope :verified, -> { where(verified: true) }
|
21
|
+
|
22
|
+
normalizes :email, with: ->(email) { email.downcase.strip }
|
16
23
|
end
|
17
24
|
end
|
18
25
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
module UserCallbacks
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
with_options if: :password_digest_previously_changed? do
|
9
|
+
after_update :destroy_non_current_sessions
|
10
|
+
after_update :record_activity_password_update
|
11
|
+
end
|
12
|
+
|
13
|
+
after_update :record_activity_email_update, if: :email_previously_changed?
|
14
|
+
after_update :record_activity_email_verified, if: %i[verified_previously_changed? verified?]
|
15
|
+
|
16
|
+
before_validation :remove_email_verification, if: :email_changed?, on: :update
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def record_activity_password_update
|
22
|
+
create_event "password:update"
|
23
|
+
end
|
24
|
+
|
25
|
+
def record_activity_email_update
|
26
|
+
create_event "email:update"
|
27
|
+
end
|
28
|
+
|
29
|
+
def record_activity_email_verified
|
30
|
+
create_event "email:verified"
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_event(action)
|
34
|
+
events.create! action: action
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_email_verification
|
38
|
+
self.verified = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def destroy_non_current_sessions
|
42
|
+
sessions.non_current.destroy_all
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Avocado
|
4
|
+
module UserValidations
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
PASSWORD_FORMAT = /\A(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*\z/x
|
8
|
+
PASSWORD_MINIMUM_LENGTH = 8
|
9
|
+
|
10
|
+
included do
|
11
|
+
validates :email,
|
12
|
+
presence: true,
|
13
|
+
uniqueness: true,
|
14
|
+
format: {with: URI::MailTo::EMAIL_REGEXP}
|
15
|
+
|
16
|
+
validates :password,
|
17
|
+
format: {with: PASSWORD_FORMAT},
|
18
|
+
length: {minimum: PASSWORD_MINIMUM_LENGTH},
|
19
|
+
allow_nil: true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/avocado/version.rb
CHANGED
data/lib/avocado.rb
CHANGED
@@ -7,10 +7,12 @@ module Avocado
|
|
7
7
|
|
8
8
|
autoload :Authentication, "avocado/authentication"
|
9
9
|
autoload :Current, "avocado/current"
|
10
|
+
autoload :Event, "avocado/event"
|
10
11
|
autoload :Mailer, "avocado/mailer"
|
11
12
|
autoload :Session, "avocado/session"
|
13
|
+
autoload :SessionCallbacks, "avocado/session_callbacks"
|
12
14
|
autoload :User, "avocado/user"
|
13
|
-
autoload :
|
15
|
+
autoload :UserCallbacks, "avocado/user_callbacks"
|
14
16
|
autoload :UserTokens, "avocado/user_tokens"
|
15
|
-
autoload :
|
17
|
+
autoload :UserValidations, "avocado/user_validations"
|
16
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: avocado
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Jankowski
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcrypt
|
@@ -80,14 +80,23 @@ files:
|
|
80
80
|
- LICENSE.txt
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
|
+
- app/controllers/avocado/affirmations_controller.rb
|
83
84
|
- app/controllers/avocado/base_controller.rb
|
85
|
+
- app/controllers/avocado/emails_controller.rb
|
86
|
+
- app/controllers/avocado/events_controller.rb
|
87
|
+
- app/controllers/avocado/passwords_controller.rb
|
84
88
|
- app/controllers/avocado/recoveries_controller.rb
|
85
89
|
- app/controllers/avocado/registrations_controller.rb
|
86
90
|
- app/controllers/avocado/sessions_controller.rb
|
87
91
|
- app/controllers/avocado/verifications_controller.rb
|
92
|
+
- app/views/avocado/affirmations/new.html.erb
|
93
|
+
- app/views/avocado/emails/edit.html.erb
|
94
|
+
- app/views/avocado/events/_event.html.erb
|
95
|
+
- app/views/avocado/events/index.html.erb
|
88
96
|
- app/views/avocado/mailer/email_affirmation.text.erb
|
89
97
|
- app/views/avocado/mailer/email_verification.text.erb
|
90
98
|
- app/views/avocado/mailer/password_reset.text.erb
|
99
|
+
- app/views/avocado/passwords/edit.html.erb
|
91
100
|
- app/views/avocado/recoveries/edit.html.erb
|
92
101
|
- app/views/avocado/recoveries/new.html.erb
|
93
102
|
- app/views/avocado/registrations/new.html.erb
|
@@ -100,12 +109,14 @@ files:
|
|
100
109
|
- lib/avocado/authentication.rb
|
101
110
|
- lib/avocado/current.rb
|
102
111
|
- lib/avocado/engine.rb
|
112
|
+
- lib/avocado/event.rb
|
103
113
|
- lib/avocado/mailer.rb
|
104
114
|
- lib/avocado/session.rb
|
115
|
+
- lib/avocado/session_callbacks.rb
|
105
116
|
- lib/avocado/user.rb
|
106
|
-
- lib/avocado/
|
107
|
-
- lib/avocado/user_password.rb
|
117
|
+
- lib/avocado/user_callbacks.rb
|
108
118
|
- lib/avocado/user_tokens.rb
|
119
|
+
- lib/avocado/user_validations.rb
|
109
120
|
- lib/avocado/version.rb
|
110
121
|
- sig/avocado.rbs
|
111
122
|
homepage: https://github.com/tcuwp/avocado
|
data/lib/avocado/user_email.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Avocado
|
4
|
-
module UserEmail
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
validates :email, presence: true, uniqueness: true, format: {with: URI::MailTo::EMAIL_REGEXP}
|
9
|
-
|
10
|
-
normalizes :email, with: ->(email) { email.downcase.strip }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Avocado
|
4
|
-
module UserPassword
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
REQUIRED_FORMAT = /\A(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*\z/x
|
8
|
-
REQUIRED_LENGTH = 8
|
9
|
-
|
10
|
-
included do
|
11
|
-
has_secure_password
|
12
|
-
|
13
|
-
validates :password, format: {with: REQUIRED_FORMAT}, length: {minimum: REQUIRED_LENGTH}, allow_nil: true
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|