From 72f2894b0600ba7a1b3c5b9d6f87122651e5312c Mon Sep 17 00:00:00 2001 From: Trevor Vallender Date: Wed, 5 Jun 2024 14:34:22 +0100 Subject: [PATCH] =?UTF-8?q?Ensure=20users=20can=E2=80=99t=20be=20spammed?= =?UTF-8?q?=20with=20password=20resets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/mailers/user_mailer.rb | 3 +++ ...7_add_password_reset_last_sent_at_to_user.rb | 7 +++++++ db/schema.rb | 3 ++- test/mailers/user_mailer_test.rb | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240605132327_add_password_reset_last_sent_at_to_user.rb create mode 100644 test/mailers/user_mailer_test.rb diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 08d945f..7f83371 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -20,6 +20,9 @@ class UserMailer < ApplicationMailer @user = params[:user] @token = params[:token] + return if @user.password_reset_last_sent_at&.after?(10.minutes.ago) + + @user.update(password_reset_last_sent_at: Time.zone.now) mail(to: @user.email, subject: t(".password_reset.subject")) end end diff --git a/db/migrate/20240605132327_add_password_reset_last_sent_at_to_user.rb b/db/migrate/20240605132327_add_password_reset_last_sent_at_to_user.rb new file mode 100644 index 0000000..3121218 --- /dev/null +++ b/db/migrate/20240605132327_add_password_reset_last_sent_at_to_user.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddPasswordResetLastSentAtToUser < ActiveRecord::Migration[7.1] + def change + add_column :users, :password_reset_last_sent_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 0ffebc0..91dc70d 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_05_30_073852) do +ActiveRecord::Schema[7.1].define(version: 2024_06_05_132327) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -221,6 +221,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_30_073852) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "verified", default: false, null: false + t.datetime "password_reset_last_sent_at" t.index ["email"], name: "index_users_on_email", unique: true t.index ["username"], name: "index_users_on_username", unique: true t.index ["verified"], name: "index_users_on_verified" diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb new file mode 100644 index 0000000..2367648 --- /dev/null +++ b/test/mailers/user_mailer_test.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class UserMailerTest < ActionMailer::TestCase + test "password resets can’t be resent within 10 minutes" do + user = users(:trevor) + assert_emails(+1) do + UserMailer.with(user: user, token: user.generate_token_for(:password_reset)).password_reset.deliver_now + end + assert_emails(0) do + UserMailer.with(user: user, token: user.generate_token_for(:password_reset)).password_reset.deliver_now + end + travel 11.minutes + assert_emails(+1) do + UserMailer.with(user: user, token: user.generate_token_for(:password_reset)).password_reset.deliver_now + end + end +end