Skip to content

Commit 61d8996

Browse files
committed
Add account activation
1 parent 6ec0615 commit 61d8996

25 files changed

+282
-33
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class AccountActivationsController < ApplicationController
2+
3+
def edit
4+
user = User.find_by(email: params[:email])
5+
if user && !user.activated? && user.authenticated?(:activation, params[:id])
6+
user.activate
7+
log_in user
8+
flash[:success] = "Account activated!"
9+
redirect_to user
10+
else
11+
flash[:danger] = "Invalid activation link"
12+
redirect_to root_url
13+
end
14+
end
15+
end

app/controllers/sessions_controller.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ def new
66
def create
77
user = User.find_by(email: params[:session][:email].downcase)
88
if user && user.authenticate(params[:session][:password])
9-
forwarding_url = session[:forwarding_url]
10-
reset_session
11-
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
12-
log_in user
13-
redirect_to forwarding_url || user
9+
if user.activated?
10+
forwarding_url = session[:forwarding_url]
11+
reset_session
12+
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
13+
log_in user
14+
redirect_to forwarding_url || user
15+
else
16+
message = "Account not activated. "
17+
message += "Check your email for the activation link."
18+
flash[:warning] = message
19+
redirect_to root_url
20+
end
1421
else
1522
flash.now[:danger] = 'Invalid email/password combination'
1623
render 'new', status: :unprocessable_entity

app/controllers/users_controller.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ def new
1818
def create
1919
@user = User.new(user_params)
2020
if @user.save
21-
reset_session
22-
log_in @user
23-
flash[:success] = "Welcome to the Sample App!"
24-
redirect_to @user
21+
@user.send_activation_email
22+
flash[:info] = "Please check your email to activate your account."
23+
redirect_to root_url
2524
else
2625
render 'new', status: :unprocessable_entity
2726
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module AccountActivationsHelper
2+
end

app/helpers/sessions_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def current_user
2424
end
2525
elsif (user_id = cookies.encrypted[:user_id])
2626
user = User.find_by(id: user_id)
27-
if user && user.authenticated?(cookies[:remember_token])
27+
if user && user.authenticated?(:remember, cookies[:remember_token])
2828
log_in user
2929
@current_user = user
3030
end

app/mailers/application_mailer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
class ApplicationMailer < ActionMailer::Base
2-
default from: "from@example.com"
2+
default from: "user@realdomain.com"
33
layout "mailer"
44
end

app/mailers/user_mailer.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class UserMailer < ApplicationMailer
2+
3+
def account_activation(user)
4+
@user = user
5+
mail to: user.email, subject: "Account activation"
6+
end
7+
8+
def password_reset
9+
@greeting = "Hi"
10+
11+
mail to: "[email protected]"
12+
end
13+
end

app/models/user.rb

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class User < ApplicationRecord
2-
attr_accessor :remember_token
3-
before_save { self.email = email.downcase }
2+
attr_accessor :remember_token, :activation_token
3+
before_save :downcase_email
4+
before_create :create_activation_digest
45
validates :name, presence: true, length: { maximum: 50 }
56
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
67
validates :email, presence: true, length: { maximum: 255 },
@@ -35,13 +36,38 @@ def session_token
3536
end
3637

3738
# Returns true if the given token matches the digest.
38-
def authenticated?(remember_token)
39-
return false if remember_digest.nil?
40-
BCrypt::Password.new(remember_digest).is_password?(remember_token)
39+
def authenticated?(attribute, token)
40+
digest = send("#{attribute}_digest")
41+
return false if digest.nil?
42+
BCrypt::Password.new(digest).is_password?(token)
4143
end
4244

4345
# Forgets a user.
4446
def forget
4547
update_attribute(:remember_digest, nil)
4648
end
49+
50+
# Activates an account.
51+
def activate
52+
update_attribute(:activated, true)
53+
update_attribute(:activated_at, Time.zone.now)
54+
end
55+
56+
# Sends activation email.
57+
def send_activation_email
58+
UserMailer.account_activation(self).deliver_now
59+
end
60+
61+
private
62+
63+
# Converts email to all lowercase.
64+
def downcase_email
65+
self.email = email.downcase
66+
end
67+
68+
# Creates and assigns the activation token and digest.
69+
def create_activation_digest
70+
self.activation_token = User.new_token
71+
self.activation_digest = User.digest(activation_token)
72+
end
4773
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<h1>Sample App</h1>
2+
3+
<p>Hi <%= @user.name %>,</p>
4+
5+
<p>
6+
Welcome to the Sample App! Click on the link below to activate your account:
7+
</p>
8+
9+
<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
10+
email: @user.email) %>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Hi <%= @user.name %>,
2+
3+
Welcome to the Sample App! Click on the link below to activate your account:
4+
5+
<%= edit_account_activation_url(@user.activation_token, email: @user.email) %>

0 commit comments

Comments
 (0)