diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index b9456d3e..16f27a59 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -8,4 +8,8 @@ class AccountsController < Devise::RegistrationsController def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :name, :address, :phone_number) } end + + def after_inactive_sign_up_path_for(resource) + new_session_path(resource) + end end diff --git a/app/models/account.rb b/app/models/account.rb index 33152432..080c2307 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -4,7 +4,7 @@ class Account < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable, :lockable + :recoverable, :rememberable, :validatable, :lockable, :confirmable enum role: { admin: 1, user: 0 }, _default: :user diff --git a/app/views/accounts/confirmations/new.html.erb b/app/views/accounts/confirmations/new.html.erb new file mode 100644 index 00000000..ce4b5fc6 --- /dev/null +++ b/app/views/accounts/confirmations/new.html.erb @@ -0,0 +1,13 @@ + +
+ <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> +
+

<%= uppercase t("accounts.confirmation_title")%>

+ <%= render "shared/error_messages", object: resource %> + <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, class:"w-100", autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> + <%= f.submit uppercase(t("accounts.resend")), class:"form-btn-submit" %> + <%= f.button uppercase(t("back")), class:"form-btn-back", onclick: "window.history.back();" %> +
+ <% end %> +
diff --git a/app/views/accounts/mailer/confirmation_instructions.html.erb b/app/views/accounts/mailer/confirmation_instructions.html.erb new file mode 100644 index 00000000..d53d7584 --- /dev/null +++ b/app/views/accounts/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

<%= t('accounts.registrations.signed_up', email: @email) %>

+ +

<%= t('accounts.registrations.confirm_email') %>

+ +

<%= link_to t('accounts.registrations.confirm_my_account'), confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index 455d2693..91511e9d 100644 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb @@ -19,5 +19,9 @@ <%= uppercase t "accounts.create"%> <% end %> + <%= link_to new_account_confirmation_path, class: "btn-redirect ms-3" do %> + <%= uppercase t("accounts.resend")%> + <% end %> + diff --git a/config/environments/test.rb b/config/environments/test.rb index 990150e0..1766d174 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -39,6 +39,17 @@ # Store uploaded files on the local file system in a temporary directory. config.active_storage.service = :test + config.action_mailer.raise_delivery_errors = true + config.action_mailer.delivery_method = :smtp + config.action_mailer.default_url_options = { host: ENV["HOST"] } + config.action_mailer.smtp_settings = { + address: "sandbox.smtp.mailtrap.io", + port: 2525, + user_name: ENV["USER_EMAIL"], + password: ENV["USER_PASSWORD"], + authentication: "plain", + enable_starttls_auto: true + } config.action_mailer.perform_caching = false diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 3ffadb8d..ae3f5bcb 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -144,15 +144,14 @@ # without confirming their account. # Default is 0.days, meaning the user cannot access the website without # confirming their account. - # config.allow_unconfirmed_access_for = 2.days - + config.allow_unconfirmed_access_for = 0.days # A period that the user is allowed to confirm their account before their # token becomes invalid. For example, if set to 3.days, the user can confirm # their account within 3 days after the mail was sent, but on the fourth day # their account can't be confirmed with the token any more. # Default is nil, meaning there is no restriction on how long a user can take # before confirming their account. - # config.confirm_within = 3.days + config.confirm_within = 3.days # If true, requires any email changes to be confirmed (exactly the same way as # initial account confirmation) to be applied. Requires additional unconfirmed_email @@ -161,7 +160,7 @@ config.reconfirmable = true # Defines which key will be used when confirming an account - # config.confirmation_keys = [:email] + config.confirmation_keys = [:email] # ==> Configuration for :rememberable # The time the user will be remembered without asking for credentials again. diff --git a/config/locales/en.yml b/config/locales/en.yml index d05deb92..a2da3445 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -72,10 +72,16 @@ en: personal_information: "Personal Information" sign_in_information: "Sign-in Information" create: "CREATE AN ACCOUNT" + resend: "Confirmation" + confirmation_title: "Resend Confirmation" login_customer: "Customers Login" login_customer_message: "If you have an account, sign in with your email address." rediect_login: "New Customers" register_customer_message: "Creating an account has many benefits: check out faster, keep more than one address, track orders and more." + registrations: + signed_up: "Welcome %{email}!" + confirm_email: "You can confirm your account email through the link below:" + confirm_my_account: "Confirm" place_holder: name: "Enter your name *" email: "Enter your email *" diff --git a/config/locales/vi.yml b/config/locales/vi.yml index eec833f1..9377c238 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -72,10 +72,16 @@ vi: personal_information: "Thông tin cá nhân" sign_in_information: "Thông tin đăng nhập" create: "TẠO TÀI KHOẢN" + resend: "xác nhận" + confirmation_title: "Gửi Lại Xác Nhận" login_customer: "Đăng nhập Khách hàng" login_customer_message: "Nếu bạn đã có tài khoản, hãy đăng nhập bằng địa chỉ email của bạn." rediect_login: "Khách hàng Mới" register_customer_message: "Tạo tài khoản mang lại nhiều lợi ích: thanh toán nhanh hơn, lưu nhiều địa chỉ hơn, theo dõi đơn hàng và nhiều hơn nữa." + registrations: + signed_up: "Chào mừng %{email}!" + confirm_email: "Bạn có thể xác nhận tài khoản email của mình thông qua liên kết dưới đây:" + confirm_my_account: "Xác nhận" place_holder: name: "Nhập tên của bạn *" email: "Nhập email của bạn *" diff --git a/db/migrate/20240405025052_devise_create_accounts.rb b/db/migrate/20240405025052_devise_create_accounts.rb index 1f5591cf..eb74594b 100644 --- a/db/migrate/20240405025052_devise_create_accounts.rb +++ b/db/migrate/20240405025052_devise_create_accounts.rb @@ -25,10 +25,10 @@ def change # t.string :last_sign_in_ip ## Confirmable - # t.string :confirmation_token - # t.datetime :confirmed_at - # t.datetime :confirmation_sent_at - # t.string :unconfirmed_email # Only if using reconfirmable + t.string :confirmation_token + t.datetime :confirmed_at + t.datetime :confirmation_sent_at + t.string :unconfirmed_email # Only if using reconfirmable # Lockable t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts @@ -41,7 +41,7 @@ def change add_index :accounts, :email, unique: true add_index :accounts, :reset_password_token, unique: true - # add_index :accounts, :confirmation_token, unique: true - # add_index :accounts, :unlock_token, unique: true + add_index :accounts, :confirmation_token, unique: true + add_index :accounts, :unlock_token, unique: true end end diff --git a/db/schema.rb b/db/schema.rb index 84a3d9d1..b60c147a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -21,13 +21,19 @@ t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" + t.string "unconfirmed_email" t.integer "failed_attempts", default: 0, null: false t.string "unlock_token" t.datetime "locked_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["confirmation_token"], name: "index_accounts_on_confirmation_token", unique: true t.index ["email"], name: "index_accounts_on_email", unique: true t.index ["reset_password_token"], name: "index_accounts_on_reset_password_token", unique: true + t.index ["unlock_token"], name: "index_accounts_on_unlock_token", unique: true end create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| diff --git a/spec/factories/accounts.rb b/spec/factories/accounts.rb index 840275b6..9f5264f2 100644 --- a/spec/factories/accounts.rb +++ b/spec/factories/accounts.rb @@ -7,5 +7,6 @@ address { Faker::Address.full_address } password { Faker::Internet.password } password_confirmation { password } + confirmed_at { Time.zone.now } end end