Commit 088baf75 by Hoang Nam Nguyen

Merge branch 'forgot_password_page'

parents 28f078e1 e89b7f9f
This source diff could not be displayed because it is too large. You can view the blob instead.
class PasswordResetsController < ApplicationController
before_action :get_user, :valid_user, :check_expiration, only: [:edit, :update]
def new
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
UserMailer.password_reset(@user.id).deliver_later
flash[:info] ="Email sent with password reset instructions"
redirect_to root_path
else
flash.now[:danger]="Email address not found"
render 'new'
end
end
def edit
end
def update
if params[:user][:password].empty?
render 'edit'
elsif @user.update_attributes(user_params_edit)
flash[:success] = "Password has been reset!"
UserMailer.success_password(@user.id).deliver_later
redirect_to login_user_path
else
render 'edit'
end
end
private
def user_params_edit
params.require(:user).permit(:password, :password_confirmation)
end
def get_user
@user = User.find(params[:id])
end
def valid_user
unless (@user && @user.activated? &&
@user.authenticated?(:reset, params[:reset_digest]))
redirect_to root_url
end
end
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Password reset has expired"
redirect_to new_password_reset_path
end
end
end
......@@ -10,7 +10,7 @@ class SessionsController < ApplicationController
redirect_to my_page_path(id: user.id)
else
flash[:danger] = 'Invalid email/password combination'
render 'new'
redirect_to login_user_path
end
end
......
......@@ -25,12 +25,10 @@ class UsersController < ApplicationController
@user = User.find(params[:id])
@user.validate_name = true
@user.validate_password = true
uploadedFile = params[:user][:cv]
File.open(Rails.root.join('public','cv',uploadedFile.original_filename), 'wb') do |f|
f.write(uploadedFile.read)
end
if @user.update_attributes(user_params)
flash[:success] = "Sign up success"
@user.update_attributes(:activated => true,:activated_at => Time.zone.now)
flash[:success] = "Update success"
redirect_to my_page_path
else
render 'edit'
......
module AccountActivationsHelper
end
module PasswordResetsHelper
end
......@@ -6,4 +6,14 @@ class UserMailer < ApplicationMailer
@url = edit_user_url(@user.id)
mail to: @user.email, subject: 'Welcome to My Ventura Jobs'
end
def password_reset(user)
@user = User.find(user)
mail to: @user.email, subject: "VeNJOB Password Assistance"
end
def success_password(user_id)
@user = User.find(user_id)
mail to: @user.email, subject: "Success Password"
end
end
class User < ApplicationRecord
attr_accessor :validate_name, :validate_password, :validate_confirm
has_secure_password(validations: false)
attr_accessor :validate_name, :validate_password, :validate_confirm, :reset_token,
:remember_token, :activation_token, :password, :password_confirmation
mount_uploader :cv, CvUploader
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 200 }, if: :validate_name
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: {maximum: 255},
format: {with: VALID_EMAIL_REGEX },
uniqueness: {case_sensitive: false}
has_secure_password(validations: false)
validates :password, presence: true, length: { minimum: 5}, if: :validate_password
with_options unless: :new_record? do |opts|
opts.validates :password, presence: true, length: { maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED,minimum: 6 }
opts.validates_confirmation_of :password, allow_blank: true
end
before_save :downcase_email
before_save :set_password
before_create :create_activation_digest
def create_reset_digest
self.reset_token = generate_token
update_attributes(:reset_digest => digest(reset_token),:reset_sent_at => Time.zone.now)
end
def send_password_reset_email
UserMailer.password_reset(self.id).deliver_later
end
def digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
def set_password
self.password_digest = digest(password) if password.present?
end
def authenticated?(attribute, token)
digest = self.reset_digest
return false if digest.nil?
digest == token
end
def password_reset_expired?
reset_sent_at < 1.day.ago
end
private
def downcase_email
self.email = email.downcase
end
def create_activation_digest
self.activation_token = generate_token
self.activation_digest = digest(activation_token)
end
def generate_token
SecureRandom.urlsafe_base64
end
end
......@@ -18,9 +18,9 @@
</div>
<div class="card-body">
<h4 class="card-title text-primary"><%= @job.company.company_name %></h4>
<p class="card-texts">Location: <%= @job.cities.map {|l| l.location}.join(',') %></p>
<p class="card-texts">Location: <%= @job.cities.map(&:location).join(',') %></p>
<p class="card-text"><a href="#">Salary: </a><%= @job.salary %></p>
<p class="card-text"><%= @job.descripton.gsub("\t"," ").gsub("\n","<br/>").gsub("\r","<br/>").html_safe %></p>
<%= simple_format(@job.descripton) %>
<a class="btn btn-success text-white w-25">Apply</a>
<a class="btn btn-success text-white w-25">Favorite</a>
</div>
......
......@@ -39,10 +39,8 @@
<ul class="nav navbar-nav" id="slidebar">
<% if @current_user.nil? %>
<li>
<p class="btn btn-info distance mt-4 no-gutters">
<%= link_to confirm_email_path, class: 'btn btn-info distance mt-4 no-gutters' do %>
<i class="fa fa-user-circle-o"></i> Register
</p>
<% end %>
</li>
<% end %>
......
<% provide(:title, 'New Password') %>
<h1 class="text-primary text-center mt-5">Forgot Password</h1>
<div class="row ml-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(@user, url: password_reset_path(params.permit(:email, :id, :reset_digest))) do |f| %>
<%= render 'shared/error_messages'%>
<div class="row mt-3">
<!--set field email -->
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :email %></i></strong>
</div>
<!--set field email -->
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-user fa " aria-hidden="true"></i></span>
<%= f.email_field :email, class: 'form-control mb-5', :readonly => true %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :password, "New Password" %></i></strong>
</div>
<!--set field password -->
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-lock" aria-hidden="true"></i></span>
<%= f.password_field :password, class: 'form-control mb-5' %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :password_confirmation, "Password Confirmation" %></i></strong>
</div>
<!--set field password -->
<div class="col-md-10 mb-5">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock" aria-hidden="true"></i></span>
<%= f.password_field :password_confirmation, class: 'form-control' %>
</div>
</div>
<div class="row w-100">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<%= button_tag(type: "submit", class: "btn btn-danger btn-block") do %>
<i class="fa fa-check 4px"></i> Submit
<% end %>
</div>
</div>
<% end %>
</div>
</div>
\ No newline at end of file
<% provide(:title, "Forgot password") %>
<h1 class="text-center mt-5">Forgot Password</h1>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(:password_reset, url: password_resets_path) do |f| %>
<% flash.each do |key, value| %>
<div class="mb-5 alert alert-<%= key %>"><%= value %></div>
<% end %>
<div class="row mt-3">
<!--set field email -->
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :email %></i></strong>
</div>
<!--set field email -->
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-user fa" aria-hidden="true"></i></span>
<%= f.email_field :email, class: 'form-control mb-5' %>
</div>
</div>
</div>
<div class="row ">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<%= button_tag(type: "submit", class: "btn btn-danger btn-block") do %>
<i class="fa fa-check 4px"></i> Confirm your email
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<% provide(:title,"User login") %>
<h1 class="text-center">Log in</h1>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<!--set message errors -->
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<!--end set -->
<!--set field all -->
<%= form_for(:session, url: login_path) do |f| %>
<div class="row mt-3">
......@@ -38,9 +37,11 @@
<!--end set field password -->
</div>
<!--end set field all -->
<p class="ml-5 mt-3"><%= link_to "Forgot password ?",'#'%></p>
<div class="row ml-5" >
<p class="ml-5 mt-3"><%= link_to "Forgot password ?",new_password_reset_path %></p>
</div>
<!--set button -->
<div class="row ml-5 text-center">
<div class="row ml-5 text-center mt-5">
<div class="col-md-5 ml-5">
<%= button_tag(type: "submit", class: "btn btn-lg btn-success") do %>
<span class="fa fa-sign-in"></span> Log In
......
......@@ -13,6 +13,10 @@
</div>
<% end %>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<h1 class="text-success line_job"> Latest Jobs</h1>
<div class="row">
<%= render 'index' %>
......
<h1>Password reset</h1>
<p>We received a request to reset the password associated with this e-mail address. If you made this request, please follow the instructions below.
<p>To reset your password click the link below:</p>
<%= link_to "Reset password", edit_password_reset_url(reset_digest: @user.reset_digest,
email: @user.email,id: @user.id) %>
<p>If you did not request to have your password reset you can safely ignore this email. Rest assured your account is safe.</p>
<p>
Please also be noted that the above link is valid for 24 hours.
</p>
\ No newline at end of file
<h1> Dear <%= @user.name %> </h1>
<h1>Password reset success</h1>
<p>You have a new password!</p>
<p>Your password for signing in to VenJOB was recently changed. If you made this change, then we're all set.</p>
<p>If you did not make this change, please reset your password to secure your account. Then reply to this email to notify us.</p>
<p>Either way, feel free to reach out with any questions you might have. We're here to help.</p>
\ No newline at end of file
......@@ -3,6 +3,10 @@
<h1 class="text-success">My Page</h1>
</div>
<% flash.each do |key, value| %>
<div class="mb-5 alert alert-<%= key %>"><%= value %></div>
<% end %>
<div class="row ml-5 ct_local pl-3 pt-5 mt-5 mb-5">
<div class="col-md-10 col-md-offset-3">
......
......@@ -17,7 +17,12 @@
</div>
</div>
<!--end set email -->
<div class="text-center">
<%= f.submit "Confirm your email", class: "btn btn-primary form-control ml-3 w-50" %>
<div class="row mt-5">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<%= button_tag(type: "submit", class: "btn btn-primary form-control btn-block") do %>
<i class="fa fa-check 4px"></i> Confirm your email
<% end %>
</div>
</div>
<% end %>
\ No newline at end of file
<% end %>
require 'sidekiq/web'
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get 'users/new'
......@@ -23,5 +27,7 @@ Rails.application.routes.draw do
get '/login',controller: :sessions,action: :new,as: :login_user
post '/login',controller: :sessions,action: :create
delete '/logout',controller: :sessions,action: :destroy
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
mount Sidekiq::Web => '/sidekiq'
end
class AddResetToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :reset_digest, :string
add_column :users, :reset_sent_at, :datetime
end
end
class AddActivationToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :activantion_digest, :string
add_column :users, :activated, :boolean, default: false
add_column :users, :activated_at, :datetime
end
end
class FixColumnUser < ActiveRecord::Migration[5.1]
def change
rename_column :users, :activantion_digest, :activation_digest
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment