Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@
config/settings.local.yml
config/settings/*.local.yml
config/environments/*.local.yml

# Ignore application configuration
/config/application.yml
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ gem "bootstrap-will_paginate", "1.0.0"
gem "coffee-rails", "~> 4.2"
gem "config"
gem "faker", "1.9.1"
gem "figaro"
gem "jbuilder", "~> 2.5"
gem "jquery-rails", "~> 4.3", ">= 4.3.3"
gem "puma", "~> 3.11"
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ GEM
faker (1.9.1)
i18n (>= 0.7)
ffi (1.9.25)
figaro (1.1.1)
thor (~> 0.14)
globalid (0.4.1)
activesupport (>= 4.2.0)
i18n (1.0.1)
Expand Down Expand Up @@ -238,6 +240,7 @@ DEPENDENCIES
coffee-rails (~> 4.2)
config
faker (= 1.9.1)
figaro
jbuilder (~> 2.5)
jquery-rails (~> 4.3, >= 4.3.3)
listen (>= 3.0.5, < 3.2)
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/account_activations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AccountActivationsController < ApplicationController
def edit
user = User.find_by email: params[:email]
if user && !user.activated? && user.authenticated?(:activation, params[:id])
user.activated
log_in user
flash[:success] = t "account_activated"
redirect_to user
else
flash[:danger] = t "account_activate_invalid"
redirect_to root_url
end
end
end
13 changes: 10 additions & 3 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ def new; end
def create
@user = User.find_by email: params[:session][:email].downcase
if @user&.authenticate params[:session][:password]
log_in @user
remember_me
redirect_back_or @user
if @user.activated?
log_in @user
remember_me
redirect_back_or @user
else
message = t "activation_message1"
message += t "activation_message2"
flash[:warning] = message
redirect_to root_url
end
else
flash.now[:danger] = t ".error_login"
render :new
Expand Down
12 changes: 7 additions & 5 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class UsersController < ApplicationController
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
@users = User.paginate page: params[:page],
@users = User.where(activated: true).paginate page: params[:page],
per_page: Settings.total_user_per_page
end

Expand All @@ -15,15 +15,17 @@ def new
def create
@user = User.new user_params
if @user.save
log_in @user
flash[:success] = t ".title_sample"
redirect_to @user
@user.send_activation_email
flash[:info] = t "activation_mesage"
redirect_to root_url
else
render :new
end
end

def show; end
def show
redirect_to(root_url) && return unless @user.activated == true
end

def edit; end

Expand Down
2 changes: 2 additions & 0 deletions app/helpers/account_activations_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module AccountActivationsHelper
end
2 changes: 1 addition & 1 deletion app/helpers/sessions_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def current_user
@current_user ||= User.find_by id: user_id
elsif user_id = cookies.signed[:user_id]
user = User.find_by id: user_id
if user&.authenticated? cookies[:remember_token]
if user&.authenticated?(:remember, cookies[:remember_token])
log_in user
@current_user = user
end
Expand Down
2 changes: 1 addition & 1 deletion app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
default from: "duong147nguyen@gmail.com"
layout "mailer"
end
12 changes: 12 additions & 0 deletions app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class UserMailer < ApplicationMailer
def account_activation user
@user = user
mail to: user.email, subject: t("account_activation")
end

def password_reset
@greeting = "Hi"

mail to: "to@example.org"
end
end
22 changes: 19 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
class User < ApplicationRecord
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
attr_reader :remember_token
attr_accessor :activation_token
before_save :email_downcase
before_create :create_activation_digest
has_secure_password

validates :name, presence: true,
Expand All @@ -18,9 +20,10 @@ def remember
update_attributes remember_digest: User.digest(remember_token)
end

def authenticated? remember_token
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
def authenticated? attribute, token
digest = send "#{attribute}_digest"
return false if digest.nil?
BCrypt::Password.new(digest).is_password? token
end

def forget
Expand All @@ -31,6 +34,14 @@ def current_user? user
user == self
end

def activated
update_columns activated: true, activated_at: Time.zone.now
end

def send_activation_email
UserMailer.account_activation(self).deliver_now
end

class << self
def digest string
cost = if ActiveModel::SecurePassword.min_cost
Expand All @@ -51,4 +62,9 @@ def new_token
def email_downcase
self.email = email.downcase
end

def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest activation_token
end
end
8 changes: 8 additions & 0 deletions app/views/user_mailer/account_activation.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1><%= t ".title" %></h1>

<p><%= t ".hi" %><%= @user.name %>,</p>

<p><%= t ".welcome" %></p>

<%= link_to t(".active"), edit_account_activation_url(id: @user.activation_token,
email: @user.email) %>
5 changes: 5 additions & 0 deletions app/views/user_mailer/account_activation.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= t ".hi" %><%= @user.name %>,

<%= t ".welcome" %>

<%= edit_account_activation_url(id: @user.activation_token, email: @user.email) %>
5 changes: 5 additions & 0 deletions app/views/user_mailer/password_reset.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>User#password_reset</h1>

<p>
<%= @greeting %>, find me in app/views/user_mailer/password_reset.html.erb
</p>
3 changes: 3 additions & 0 deletions app/views/user_mailer/password_reset.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
User#password_reset

<%= @greeting %>, find me in app/views/user_mailer/password_reset.text.erb
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ class Application < Rails::Application
config.load_defaults 5.2
config.i18n.default_locale = :vi
config.generators.system_tests = nil

end
end
46 changes: 18 additions & 28 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,51 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = false

# Show full error reports.
config.consider_all_requests_local = true

# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist?
if Rails.root.join("tmp", "caching-dev.txt").exist?
config.action_controller.perform_caching = true

config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
"Cache-Control" => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false

config.cache_store = :null_store
end

# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false

config.action_mailer.perform_caching = false
# Don"t care if the mailer can"t send.
config.action_mailer.raise_delivery_errors = true
host = "localhost:3000" # Local server
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { host: host, protocol: "http" }
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: "587",
authentication: :plain,
user_name: ENV["mail_username"],
password: ENV["mail_password"],
enable_starttls_auto: true,
domain: "gmail.com"
}

config.action_mailer.perform_caching = true

# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log

# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load

# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true

# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true

# Suppress logger output for asset requests.
config.assets.quiet = true

# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true

# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end
13 changes: 13 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ en:
delete_mesage_success: "User deleted"
delete_mesage_failed: "User delete failed"
login_message: "Please log in."
account_activation: "Account activation"
account_activated: "Account activated!"
account_activate_invalid: "Invalid activation link"
activation_message1: "Account not activated. "
activation_message2: "Check your email for the activation link."
activation_mesage: "Please check your email to activate your account."
static_pages:
home:
title: "Home"
Expand Down Expand Up @@ -95,3 +101,10 @@ en:
new_user: "New user ?"
create:
error_login: "Invalid email/password combination"
user_mailer:
account_activation:
title: "Sample App"
hi: "Hi "
welcome: "Welcome to the Sample App! Click on the link below to activate your account:"
active: "Activate"

12 changes: 12 additions & 0 deletions config/locales/vi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ vi:
delete_mesage_success: "Người dùng đã xóa"
delete_mesage_failed: "Người dùng chưa được xóa"
login_message: "Làm ơn hay đăng nhập."
account_activation: "Kích hoạt tài khoản"
account_activated: "Tài khoản đã được kích hoạt!"
account_activate_invalid: "Đường dẫn kích hoạt không đúng"
activation_message1: "Tài khoản chưa được kích hoạt. "
activation_message2: "Kiểm trai thư của bạn để có thể kích hoạt."
activation_mesage: "Vui lòng kiểm tra email của bạn để kích hoạt tài khoản của bạn."
will_paginate:
next_label: "Sau"
previous_label: "Trước"
Expand Down Expand Up @@ -114,3 +120,9 @@ vi:
new_user: "Người dùng mới ?"
create:
error_login: "Email không tồn tại/mật khẩu sai"
user_mailer:
account_activation:
title: "Ứng dụng mẫu"
hi: "Chào "
welcome: "Chào mừng bạn đến với Ứng dụng mẫu! Nhấp vào liên kết bên dưới để kích hoạt tài khoản của bạn:"
active: "Kích hoạt"
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
post "/login", to: "sessions#create"
delete "/logout", to: "sessions#destroy"
resources :users
resources :account_activations, only: [:edit]
end
end
7 changes: 7 additions & 0 deletions db/migrate/20180722125049_add_activation_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddActivationToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :activation_digest, :string
add_column :users, :activated, :boolean, default: false
add_column :users, :activated_at, :datetime
end
end
5 changes: 4 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2018_07_20_021324) do
ActiveRecord::Schema.define(version: 2018_07_22_125049) do

create_table "users", force: :cascade do |t|
t.string "name"
Expand All @@ -20,6 +20,9 @@
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.index ["email"], name: "index_users_on_email", unique: true
end

Expand Down
8 changes: 6 additions & 2 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
email: "example@railstutorial.org",
password: "foobar",
password_confirmation: "foobar",
admin: true)
admin: true,
activated: true,
activated_at: Time.zone.now)

99.times do |n|
name = Faker::Name.name
Expand All @@ -11,5 +13,7 @@
User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
password_confirmation: password,
activated: true,
activated_at: Time.zone.now)
end