Commit 87570223 by Mai Hoang Thai Ha

fail

parent 0921c4b8
...@@ -66,3 +66,4 @@ gem 'httparty', '~> 0.18.1' ...@@ -66,3 +66,4 @@ gem 'httparty', '~> 0.18.1'
gem 'active_storage_validations', '~> 0.9.5' gem 'active_storage_validations', '~> 0.9.5'
gem 'devise', '~> 4.8' gem 'devise', '~> 4.8'
gem 'jquery-rails', '~> 4.4' gem 'jquery-rails', '~> 4.4'
gem 'devise_invitable', '~> 2.0', '>= 2.0.5'
\ No newline at end of file
...@@ -109,6 +109,9 @@ GEM ...@@ -109,6 +109,9 @@ GEM
railties (>= 4.1.0) railties (>= 4.1.0)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
devise_invitable (2.0.5)
actionmailer (>= 5.0)
devise (>= 4.6)
erubi (1.10.0) erubi (1.10.0)
ffi (1.15.3) ffi (1.15.3)
globalid (0.4.2) globalid (0.4.2)
...@@ -290,6 +293,7 @@ DEPENDENCIES ...@@ -290,6 +293,7 @@ DEPENDENCIES
byebug byebug
capybara (>= 3.26) capybara (>= 3.26)
devise (~> 4.8) devise (~> 4.8)
devise_invitable (~> 2.0, >= 2.0.5)
httparty (~> 0.18.1) httparty (~> 0.18.1)
jbuilder (~> 2.7) jbuilder (~> 2.7)
jquery-rails (~> 4.4) jquery-rails (~> 4.4)
......
...@@ -8,7 +8,7 @@ class ApplicationController < ActionController::Base ...@@ -8,7 +8,7 @@ class ApplicationController < ActionController::Base
protected protected
def configure_permitted_parameters def configure_permitted_parameters
devise_parameter_sanitizer.permit :sign_up, keys: %i[name address phone email password] # devise_parameter_sanitizer.permit :sign_up, keys: %i[name address phone email password]
devise_parameter_sanitizer.permit :account_update, keys: %i[name email address phone password current_password] devise_parameter_sanitizer.permit :account_update, keys: %i[name email address phone password current_password]
end end
......
# frozen_string_literal: true
class Users::ConfirmationsController < Devise::ConfirmationsController
# GET /resource/confirmation/new
# def new
# super
# end
# POST /resource/confirmation
# def create
# super
# end
# GET /resource/confirmation?confirmation_token=abcdef
# def show
# super
# end
protected
def after_confirmation_path_for(resource_name, resource)
token = resource.send(:set_reset_password_token)
edit_password_path(resource, reset_password_token: token)
end
end
# frozen_string_literal: true
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
# You should configure your model like this:
# devise :omniauthable, omniauth_providers: [:twitter]
# You should also create an action method in this controller like this:
# def twitter
# end
# More info at:
# https://github.com/heartcombo/devise#omniauth
# GET|POST /resource/auth/twitter
# def passthru
# super
# end
# GET|POST /users/auth/twitter/callback
# def failure
# super
# end
# protected
# The path used when OmniAuth fails
# def after_omniauth_failure_path_for(scope)
# super(scope)
# end
end
# frozen_string_literal: true
class Users::PasswordsController < Devise::PasswordsController
# GET /resource/password/new
# def new
# super
# end
# POST /resource/password
# def create
# super
# end
# GET /resource/password/edit?reset_password_token=abcdef
# def edit
# super
# end
# PUT /resource/password
# def update
# super
# end
# protected
# def after_resetting_password_path_for(resource)
# super(resource)
# end
# The path used after sending reset password instructions
# def after_sending_reset_password_instructions_path_for(resource_name)
# super(resource_name)
# end
end
# frozen_string_literal: true
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# GET /resource/sign_up
# def new
# super
# end
# POST /resource
# def create
# super
# end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_up_params
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
# end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
# frozen_string_literal: true
class Users::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
# GET /resource/sign_in
# def new
# super
# end
# POST /resource/sign_in
# def create
# super
# end
# DELETE /resource/sign_out
# def destroy
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_in_params
# devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
# end
end
# frozen_string_literal: true
class Users::UnlocksController < Devise::UnlocksController
# GET /resource/unlock/new
# def new
# super
# end
# POST /resource/unlock
# def create
# super
# end
# GET /resource/unlock?unlock_token=abcdef
# def show
# super
# end
# protected
# The path used after sending unlock password instructions
# def after_sending_unlock_instructions_path_for(resource)
# super(resource)
# end
# The path used after unlocking the resource
# def after_unlock_path_for(resource)
# super(resource)
# end
end
class User < ApplicationRecord class User < ApplicationRecord
# Include default devise modules. Others available are: # Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable, devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable :recoverable, :rememberable, :validatable, :confirmable
has_many :apply_jobs, dependent: :destroy has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs, dependent: :destroy has_many :history_jobs, dependent: :destroy
has_one_attached :cv has_one_attached :cv
protected
def password_required?
confirmed? ? super : false
end
end end
<h2><%= t "devise.invitations.edit.header" %></h2>
<%= form_for(resource, as: resource_name, url: invitation_path(resource_name), html: { method: :put }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<%= f.hidden_field :invitation_token, readonly: true %>
<% if f.object.class.require_password_on_accepting %>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<% end %>
<div class="actions">
<%= f.submit t("devise.invitations.edit.submit_button") %>
</div>
<% end %>
<h2><%= t "devise.invitations.new.header" %></h2>
<%= form_for(resource, as: resource_name, url: invitation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<% resource.class.invite_key_fields.each do |field| -%>
<div class="field">
<%= f.label field %><br />
<%= f.text_field field %>
</div>
<% end -%>
<div class="actions">
<%= f.submit t("devise.invitations.new.submit_button") %>
</div>
<% end %>
<p><%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %></p>
<p><%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %></p>
<p><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token) %></p>
<% if @resource.invitation_due_at %>
<p><%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %></p>
<% end %>
<p><%= t("devise.mailer.invitation_instructions.ignore") %></p>
<%= t("devise.mailer.invitation_instructions.hello", email: @resource.email) %>
<%= t("devise.mailer.invitation_instructions.someone_invited_you", url: root_url) %>
<%= accept_invitation_url(@resource, invitation_token: @token) %>
<% if @resource.invitation_due_at %>
<%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :'devise.mailer.invitation_instructions.accept_until_format')) %>
<% end %>
<%= t("devise.mailer.invitation_instructions.ignore") %>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.row.justify-content-center .row.justify-content-center
.col-6 .col-6
h2.text-center.my-5 h2.text-center.my-5
| Change your password | Set your password
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
= render 'users/shared/error_messages', resource: resource = render 'users/shared/error_messages', resource: resource
= f.hidden_field :reset_password_token = f.hidden_field :reset_password_token
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
span.form-msg span.form-msg
.actions.row.justify-content-end .actions.row.justify-content-end
.col-8 .col-8
= f.submit 'Change my password', class: 'btn btn-primary w-50 my-4', data: { disable_with: false } = f.submit 'Set my password', class: 'btn btn-primary w-50 my-4', data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
form: '#new_user', form: '#new_user',
......
...@@ -11,31 +11,31 @@ ...@@ -11,31 +11,31 @@
= f.label :email, class: 'form-label' = f.label :email, class: 'form-label'
br br
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
.field / .field
= f.label :name, class: 'form-label' / = f.label :name, class: 'form-label'
br / br
= f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control mb-2' / = f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control mb-2'
.field / .field
= f.label :address, class: 'form-label' / = f.label :address, class: 'form-label'
br / br
= f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control mb-2' / = f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control mb-2'
.field / .field
= f.label :phone, class: 'form-label' / = f.label :phone, class: 'form-label'
br / br
= f.text_field :phone, autofocus: true, autocomplete: 'phone', class: 'form-control mb-2' / = f.text_field :phone, autofocus: true, autocomplete: 'phone', class: 'form-control mb-2'
.field / .field
= f.label :password, class: 'form-label' / = f.label :password, class: 'form-label'
- if @minimum_password_length / - if @minimum_password_length
em / em
| ( / | (
= @minimum_password_length / = @minimum_password_length
| characters minimum) / | characters minimum)
br / br
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2' / = f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
.field / .field
= f.label :password_confirmation, class: 'form-label' / = f.label :password_confirmation, class: 'form-label'
br / br
= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2' / = f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2'
.actions .actions
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5' = f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
= render 'users/shared/links' = render 'users/shared/links'
\ No newline at end of file
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
= link_to 'Forgot your password?', new_password_path(resource_name), class: 'text-decoration-none' = link_to 'Forgot your password?', new_password_path(resource_name), class: 'text-decoration-none'
br/ br/
- if devise_mapping.confirmable? && controller_name != 'confirmations' - if devise_mapping.confirmable? && controller_name != 'confirmations'
= link_to 'Didn't receive confirmation instructions?', new_confirmation_path(resource_name), class: 'text-decoration-none' = link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
br/ br/
- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' - if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
= link_to 'Didn't receive unlock instructions?', new_unlock_path(resource_name), class: 'text-decoration-none' = link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: 'text-decoration-none'
br/ br/
- if devise_mapping.omniauthable? - if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider| - resource_class.omniauth_providers.each do |provider|
= link_to 'Sign in with #{OmniAuth::Utils.camelize(provider)}', omniauth_authorize_path(resource_name, provider), method: :post, class: 'text-decoration-none' = link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post, class: 'text-decoration-none'
br/ br/
...@@ -134,6 +134,55 @@ Devise.setup do |config| ...@@ -134,6 +134,55 @@ Devise.setup do |config|
# Send a notification email when the user's password is changed. # Send a notification email when the user's password is changed.
# config.send_password_change_notification = false # config.send_password_change_notification = false
# ==> Configuration for :invitable
# The period the generated invitation token is valid.
# After this period, the invited resource won't be able to accept the invitation.
# When invite_for is 0 (the default), the invitation won't expire.
config.invite_for = 24.hours
# Number of invitations users can send.
# - If invitation_limit is nil, there is no limit for invitations, users can
# send unlimited invitations, invitation_limit column is not used.
# - If invitation_limit is 0, users can't send invitations by default.
# - If invitation_limit n > 0, users can send n invitations.
# You can change invitation_limit column for some users so they can send more
# or less invitations, even with global invitation_limit = 0
# Default: nil
# config.invitation_limit = 5
# The key to be used to check existing users when sending an invitation
# and the regexp used to test it when validate_on_invite is not set.
# config.invite_key = { email: /\A[^@]+@[^@]+\z/ }
# config.invite_key = { email: /\A[^@]+@[^@]+\z/, username: nil }
# Ensure that invited record is valid.
# The invitation won't be sent if this check fails.
# Default: false
# config.validate_on_invite = true
# Resend invitation if user with invited status is invited again
# Default: true
# config.resend_invitation = false
# The class name of the inviting model. If this is nil,
# the #invited_by association is declared to be polymorphic.
# Default: nil
# config.invited_by_class_name = 'User'
# The foreign key to the inviting model (if invited_by_class_name is set)
# Default: :invited_by_id
# config.invited_by_foreign_key = :invited_by_id
# The column name used for counter_cache column. If this is nil,
# the #invited_by association is declared without counter_cache.
# Default: nil
# config.invited_by_counter_cache = :invitations_count
# Auto-login after the user accepts the invite. If this is false,
# the user will need to manually log in after accepting the invite.
# Default: true
# config.allow_insecure_sign_in_after_accept = false
# ==> Configuration for :confirmable # ==> Configuration for :confirmable
# A period that the user is allowed to access the website even without # A period that the user is allowed to access the website even without
# confirming their account. For instance, if set to 2.days, the user will be # confirming their account. For instance, if set to 2.days, the user will be
...@@ -224,7 +273,7 @@ Devise.setup do |config| ...@@ -224,7 +273,7 @@ Devise.setup do |config|
# Time interval you can reset your password with a reset password key. # Time interval you can reset your password with a reset password key.
# Don't put a too small interval or your users won't have the time to # Don't put a too small interval or your users won't have the time to
# change their passwords. # change their passwords.
config.reset_password_within = 6.hours config.reset_password_within = 24.hours
# When set to false, does not sign a user in automatically after their password is # When set to false, does not sign a user in automatically after their password is
# reset. Defaults to true, so a user is signed in automatically after a reset. # reset. Defaults to true, so a user is signed in automatically after a reset.
......
en:
devise:
failure:
invited: "You have a pending invitation, accept it to finish creating your account."
invitations:
send_instructions: "An invitation email has been sent to %{email}."
invitation_token_invalid: "The invitation token provided is not valid!"
updated: "Your password was set successfully. You are now signed in."
updated_not_active: "Your password was set successfully."
no_invitations_remaining: "No invitations remaining"
invitation_removed: "Your invitation was removed."
new:
header: "Send invitation"
submit_button: "Send an invitation"
edit:
header: "Set your password"
submit_button: "Set my password"
mailer:
invitation_instructions:
subject: "Invitation instructions"
hello: "Hello %{email}"
someone_invited_you: "Someone has invited you to %{url}, you can accept it through the link below."
accept: "Accept invitation"
accept_until: "This invitation will be due in %{due_date}."
ignore: "If you don't want to accept the invitation, please ignore this email. Your account won't be created until you access the link above and set your password."
time:
formats:
devise:
mailer:
invitation_instructions:
accept_until_format: "%B %d, %Y %I:%M %p"
Rails.application.routes.draw do Rails.application.routes.draw do
devise_for :users devise_for :users, controllers: {
sessions: 'users/sessions', confirmations: 'users/confirmations'
}
devise_scope :user do devise_scope :user do
get '/login', to: 'devise/sessions#new', as: :login get '/login', to: 'devise/sessions#new', as: :login
get '/my/info', to: 'devise/registrations#edit', as: :edit_profile get '/my/info', to: 'devise/registrations#edit', as: :edit_profile
......
...@@ -21,7 +21,7 @@ class AddDeviseToUsers < ActiveRecord::Migration[6.1] ...@@ -21,7 +21,7 @@ class AddDeviseToUsers < ActiveRecord::Migration[6.1]
# t.string :current_sign_in_ip # t.string :current_sign_in_ip
# t.string :last_sign_in_ip # t.string :last_sign_in_ip
## Confirmable # # Confirmable
# t.string :confirmation_token # t.string :confirmation_token
# t.datetime :confirmed_at # t.datetime :confirmed_at
# t.datetime :confirmation_sent_at # t.datetime :confirmation_sent_at
......
class DeviseInvitableAddToUsers < ActiveRecord::Migration[6.1]
def up
change_table :users do |t|
t.string :invitation_token
t.datetime :invitation_created_at
t.datetime :invitation_sent_at
t.datetime :invitation_accepted_at
t.integer :invitation_limit
t.references :invited_by, polymorphic: true
t.integer :invitations_count, default: 0
t.index :invitation_token, unique: true # for invitable
t.index :invited_by_id
end
end
def down
change_table :users do |t|
t.remove_references :invited_by, polymorphic: true
t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
end
end
end
class AddConfirmableToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
add_column :users, :unconfirmed_email, :string
add_index :users, :confirmation_token, unique: true
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_08_05_105601) do ActiveRecord::Schema.define(version: 2021_08_20_093814) do
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
...@@ -138,7 +138,23 @@ ActiveRecord::Schema.define(version: 2021_08_05_105601) do ...@@ -138,7 +138,23 @@ ActiveRecord::Schema.define(version: 2021_08_05_105601) do
t.datetime "remember_created_at" t.datetime "remember_created_at"
t.string "phone" t.string "phone"
t.string "address" t.string "address"
t.string "invitation_token"
t.datetime "invitation_created_at"
t.datetime "invitation_sent_at"
t.datetime "invitation_accepted_at"
t.integer "invitation_limit"
t.string "invited_by_type"
t.bigint "invited_by_id"
t.integer "invitations_count", default: 0
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true t.index ["email"], name: "index_users_on_email", unique: true
t.index ["invitation_token"], name: "index_users_on_invitation_token", unique: true
t.index ["invited_by_id"], name: "index_users_on_invited_by_id"
t.index ["invited_by_type", "invited_by_id"], name: "index_users_on_invited_by"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
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