From: Aidan Cornelius-Bell Date: Mon, 7 Oct 2024 22:30:03 +0000 (+1030) Subject: Lock accounts after wrong password attempts X-Git-Url: https://gitweb.mndrdr.org/?a=commitdiff_plain;h=fdeb500335bf724c4ea3f4a1f91571b29c45620c;p=arelpe.git Lock accounts after wrong password attempts --- diff --git a/app/models/user.rb b/app/models/user.rb index 9c650ff..4fd5fc6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,7 +3,7 @@ class User < ApplicationRecord # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, - :confirmable + :confirmable, :lockable validates :first_name, presence: true validates :last_name, presence: true diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d2bd87b..545e8c6 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -90,7 +90,7 @@ Devise.setup do |config| # It will change confirmation, password recovery and other workflows # to behave the same regardless if the e-mail provided was right or wrong. # Does not affect registerable. - # config.paranoid = true + config.paranoid = true # By default Devise will store the user in session. You can skip storage for # particular strategies by setting this option. @@ -129,10 +129,10 @@ Devise.setup do |config| # config.pepper = '41751fba075b9a85d3e00434e37cfcc6c9876bb90de77e6f5100bd4593fc3c6aafa1aac5ed603bde47df4983b91bd51dfd04f2a5b4a78a482b05f41a3540c59a' # Send a notification to the original email when the user's email is changed. - # config.send_email_changed_notification = false + config.send_email_changed_notification = true # Send a notification email when the user's password is changed. - # config.send_password_change_notification = false + config.send_password_change_notification = true # ==> Configuration for :confirmable # A period that the user is allowed to access the website even without @@ -143,7 +143,7 @@ Devise.setup do |config| # 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.hours + 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 @@ -151,7 +151,7 @@ Devise.setup do |config| # 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 = 5.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 @@ -164,7 +164,7 @@ Devise.setup do |config| # ==> Configuration for :rememberable # The time the user will be remembered without asking for credentials again. - # config.remember_for = 2.weeks + config.remember_for = 1.week # Invalidates all the remember me tokens when the user signs out. config.expire_all_remember_me_on_sign_out = true @@ -178,7 +178,7 @@ Devise.setup do |config| # ==> Configuration for :validatable # Range for password length. - config.password_length = 6..128 + config.password_length = 9..128 # Email regex used to validate email formats. It simply asserts that # one (and only one) @ exists in the given string. This is mainly @@ -194,21 +194,21 @@ Devise.setup do |config| # Defines which strategy will be used to lock an account. # :failed_attempts = Locks an account after a number of failed attempts to sign in. # :none = No lock strategy. You should handle locking by yourself. - # config.lock_strategy = :failed_attempts + config.lock_strategy = :failed_attempts # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [:email] + config.unlock_keys = [:email] # Defines which strategy will be used to unlock an account. # :email = Sends an unlock link to the user email # :time = Re-enables login after a certain amount of time (see :unlock_in below) # :both = Enables both strategies # :none = No unlock strategy. You should handle unlocking by yourself. - # config.unlock_strategy = :both + config.unlock_strategy = :email # Number of authentication tries before locking an account if lock_strategy # is failed attempts. - # config.maximum_attempts = 20 + config.maximum_attempts = 6 # Time interval to unlock the account if :time is enabled as unlock_strategy. # config.unlock_in = 1.hour diff --git a/db/migrate/20241007220924_add_lockable_to_user.rb b/db/migrate/20241007220924_add_lockable_to_user.rb new file mode 100644 index 0000000..3268a0b --- /dev/null +++ b/db/migrate/20241007220924_add_lockable_to_user.rb @@ -0,0 +1,7 @@ +class AddLockableToUser < ActiveRecord::Migration[7.2] + def change + add_column :users, :failed_attempts, :integer, default: 0 + add_column :users, :unlock_token, :string # Only if unlock strategy is :email or :both + add_column :users, :locked_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 4bb6322..f4a8b33 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.2].define(version: 2024_09_23_002439) do +ActiveRecord::Schema[7.2].define(version: 2024_10_07_220924) do create_table "api_keys", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "key" t.datetime "created_at", null: false @@ -58,6 +58,9 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_23_002439) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" + t.integer "failed_attempts", default: 0 + t.string "unlock_token" + t.datetime "locked_at" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true