From c0f4e0770a61b24f3ea3226c6a953f836e384ed5 Mon Sep 17 00:00:00 2001 From: kvngjamesng Date: Sun, 25 Aug 2024 02:29:58 +0100 Subject: [PATCH] mailer --- .../account_activations_controller.rb | 2 ++ app/controllers/sessions_controller.rb | 2 +- app/controllers/users_controller.rb | 11 +++--- app/helpers/account_activations_helper.rb | 2 ++ app/mailers/application_mailer.rb | 2 +- app/mailers/user_mailer.rb | 26 ++++++++++++++ app/models/user.rb | 17 ++++++++- .../user_mailer/account_activation.html.erb | 9 +++++ .../user_mailer/account_activation.text.erb | 5 +++ app/views/user_mailer/password_reset.html.erb | 5 +++ app/views/user_mailer/password_reset.text.erb | 3 ++ app/views/users/index.html.erb | 2 +- config/environments/development.rb | 4 +++ config/routes.rb | 2 ++ .../20240806170845_add_activation_to_users.rb | 7 ++++ db/schema.rb | 5 ++- db/seeds.rb | 9 +++-- .../account_activations_controller_test.rb | 7 ++++ test/fixtures/users.yml | 36 +++++++++++++++++++ test/mailers/previews/user_mailer_preview.rb | 16 +++++++++ test/mailers/user_mailer_test.rb | 20 +++++++++++ 21 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 app/controllers/account_activations_controller.rb create mode 100644 app/helpers/account_activations_helper.rb create mode 100644 app/mailers/user_mailer.rb create mode 100644 app/views/user_mailer/account_activation.html.erb create mode 100644 app/views/user_mailer/account_activation.text.erb create mode 100644 app/views/user_mailer/password_reset.html.erb create mode 100644 app/views/user_mailer/password_reset.text.erb create mode 100644 db/migrate/20240806170845_add_activation_to_users.rb create mode 100644 test/controllers/account_activations_controller_test.rb create mode 100644 test/mailers/previews/user_mailer_preview.rb create mode 100644 test/mailers/user_mailer_test.rb diff --git a/app/controllers/account_activations_controller.rb b/app/controllers/account_activations_controller.rb new file mode 100644 index 0000000..1a96f83 --- /dev/null +++ b/app/controllers/account_activations_controller.rb @@ -0,0 +1,2 @@ +class AccountActivationsController < ApplicationController +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7c1ee6c..abfc8bc 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -12,7 +12,7 @@ def create redirect_to forwarding_url || user else flash.now[:danger] = 'Invalid Email/Password Combination' - render 'new', status: :unprocessable_entity + render 'new', status: :unprocessable_entity end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 403c612..31eb876 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -19,10 +19,13 @@ def new def create @user = User.new(user_params) if @user.save - reset_session - log_in @user - flash[:success] = "Welcome to the Sample App!" - redirect_to @user + UserMailer.account_activation(@user).deliver_now + flash[:info] = "Please check your Email to activate your account." + redirect_to root_url + # reset_session + # log_in @user + # flash[:success] = "Welcome to the Sample App!" + # redirect_to @user else render 'new', status: :unprocessable_entity end diff --git a/app/helpers/account_activations_helper.rb b/app/helpers/account_activations_helper.rb new file mode 100644 index 0000000..c4d5ac7 --- /dev/null +++ b/app/helpers/account_activations_helper.rb @@ -0,0 +1,2 @@ +module AccountActivationsHelper +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3c34c81..3116b93 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" + default from: "adesinaadewale28@yahoo.com" layout "mailer" end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000..5d6a403 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,26 @@ +class UserMailer < ApplicationMailer + default_url_options[:host] = "localhost:3000" # Use your development or production host + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.user_mailer.account_activation.subject + # + def account_activation(user) + @user = user + mail to: @user.email, subject: "Account Activation" + # @greeting = "Hi" + + # mail to: "to@example.org" + end + + # Subject can be set in your I18n file at config/locales/en.yml + # with the following lookup: + # + # en.user_mailer.password_reset.subject + # + def password_reset + @greeting = "Hi" + + mail to: "to@example.org" + end +end diff --git a/app/models/user.rb b/app/models/user.rb index b6be77d..e474360 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,8 @@ class User < ApplicationRecord before_save {email.downcase!} - attr_accessor :remember_token + attr_accessor :remember_token, :activation_token + before_save :downcase_email + before_create :create_activation_digest validates :name, presence: true, length: {maximum: 50} VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i validates :email, presence: true, length: {maximum: 255}, @@ -46,4 +48,17 @@ def authenicated?(remember_token) return false if remember_digest.nil? BCrypt::Password.new(remember_digest).is_password?(remember_token) end + +private + +# Converts email to all lowercase +def downcase_email + self.email = email.downcase +end + +# Creates and assigns the activation token and digest +def create_activation_digest + self.activation_token = User.new_token + self.activation_digest = User.digest(activation_token) +end end diff --git a/app/views/user_mailer/account_activation.html.erb b/app/views/user_mailer/account_activation.html.erb new file mode 100644 index 0000000..86cffa9 --- /dev/null +++ b/app/views/user_mailer/account_activation.html.erb @@ -0,0 +1,9 @@ +

Sample App

+ +

Hi <%= @user.name %>,

+ +

+ Welcome to the Sample App! Click on the link below to activate your account: +

+ +<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %> diff --git a/app/views/user_mailer/account_activation.text.erb b/app/views/user_mailer/account_activation.text.erb new file mode 100644 index 0000000..81a1e76 --- /dev/null +++ b/app/views/user_mailer/account_activation.text.erb @@ -0,0 +1,5 @@ +Hi <%= @user.name %>, + +Welcome to the Sample App! click on the link below to activate your account: + +<%= edit_account_activation_url(@user.activation_token, email: @user.email) %> diff --git a/app/views/user_mailer/password_reset.html.erb b/app/views/user_mailer/password_reset.html.erb new file mode 100644 index 0000000..6dec984 --- /dev/null +++ b/app/views/user_mailer/password_reset.html.erb @@ -0,0 +1,5 @@ +

User#password_reset

+ +

+ <%= @greeting %>, find me in app/views/user_mailer/password_reset.html.erb +

diff --git a/app/views/user_mailer/password_reset.text.erb b/app/views/user_mailer/password_reset.text.erb new file mode 100644 index 0000000..5ba80cc --- /dev/null +++ b/app/views/user_mailer/password_reset.text.erb @@ -0,0 +1,3 @@ +User#password_reset + +<%= @greeting %>, find me in app/views/user_mailer/password_reset.text.erb diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 2f201c3..3c1cbae 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -5,4 +5,4 @@
<%= paginate @users %> -
\ No newline at end of file + \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 2e7fb48..19cf35f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -39,6 +39,10 @@ # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false + host = 'localhost:3000' #local server + + config.action_mailer.default_url_options = {host: 'localhost:3000', protocol: 'http'} + config.action_mailer.perform_caching = false # Print deprecation notices to the Rails logger. diff --git a/config/routes.rb b/config/routes.rb index 8cd3297..3f08f2a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,8 @@ post "/login", to: "sessions#create" delete "/logout", to: "sessions#destroy" resources :users + resources :account_activations, only: [:edit] + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. diff --git a/db/migrate/20240806170845_add_activation_to_users.rb b/db/migrate/20240806170845_add_activation_to_users.rb new file mode 100644 index 0000000..c3f1e50 --- /dev/null +++ b/db/migrate/20240806170845_add_activation_to_users.rb @@ -0,0 +1,7 @@ +class AddActivationToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :activation_digest, :string + add_column :users, :activated, :boolean, default: false + add_column :users, :activated_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 995cd99..0739749 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_08_01_172600) do +ActiveRecord::Schema[7.1].define(version: 2024_08_06_170845) do create_table "users", force: :cascade do |t| t.string "name" t.string "email" @@ -19,6 +19,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 diff --git a/db/seeds.rb b/db/seeds.rb index b100f96..0e86372 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -11,7 +11,10 @@ User.create!(name: "James", email: "sample1@example.com", password: "test123", - password_confirmation: "test123") + password_confirmation: "test123", + admin: true, + activated: true, + activated_at: Time.zone.now) # Generate a bunch of additional users 99.times do |n| @@ -21,5 +24,7 @@ User.create!(name: name, email: email, password: password, - password_confirmation: password) + password_confirmation: password, + activated: true, + activated_at: Time.zone.now) end diff --git a/test/controllers/account_activations_controller_test.rb b/test/controllers/account_activations_controller_test.rb new file mode 100644 index 0000000..bcd2199 --- /dev/null +++ b/test/controllers/account_activations_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class AccountActivationsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 335574f..6f0aa88 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -12,3 +12,39 @@ michael: name: Michael Example email: michael@example.com password_digest: <%= User.digest('password') %> +admin: true +activated: true +activated_at: <%= Time.zone.now%> + +archer: +name: Archer Example +email: archer@example.com +password_digest: <%= User.digest('password') %> +admin: true +activated: true +activated_at: <%= Time.zone.now%> + +lana: +name: Lana Example +email: lana@example.com +password_digest: <%= User.digest('password') %> +admin: true +activated: true +activated_at: <%= Time.zone.now%> + +malory: +name: Malory Example +email: malory@example.com +password_digest: <%= User.digest('password') %> +admin: true +activated: true +activated_at: <%= Time.zone.now%> + +<% 30.times do |n| %> +user_<%= n %>: +name: <%= "User #{n}" %> +email: <%= user-#{n}@example.com" %> +password_digest: <%= User.digest('password') %> +activated: true +activated_at: <%= Time.zone.now %> +<% end %> \ No newline at end of file diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb new file mode 100644 index 0000000..7ab931c --- /dev/null +++ b/test/mailers/previews/user_mailer_preview.rb @@ -0,0 +1,16 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user_mailer +class UserMailerPreview < ActionMailer::Preview + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation + def account_activation + user = User.first + user.activation_token = User.new_token + UserMailer.account_activation(user) + end + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/password_reset + def password_reset + UserMailer.password_reset + end + +end diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb new file mode 100644 index 0000000..e5775ec --- /dev/null +++ b/test/mailers/user_mailer_test.rb @@ -0,0 +1,20 @@ +require "test_helper" + +class UserMailerTest < ActionMailer::TestCase + test "account_activation" do + mail = UserMailer.account_activation + assert_equal "Account activation", mail.subject + assert_equal ["to@example.org"], mail.to + assert_equal ["from@example.com"], mail.from + assert_match "Hi", mail.body.encoded + end + + test "password_reset" do + mail = UserMailer.password_reset + assert_equal "Password reset", mail.subject + assert_equal ["to@example.org"], mail.to + assert_equal ["from@example.com"], mail.from + assert_match "Hi", mail.body.encoded + end + +end