diff --git a/app/models/user.rb b/app/models/user.rb index 7ecdf88..7fabb82 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,7 +5,7 @@ class User < ApplicationRecord validates :password, length: { within: 8..128, allow_blank: true }, presence: { if: :password_required? } # Devise - devise :database_authenticatable, :rememberable, :trackable, :recoverable, :password_archivable, :session_limitable + devise :database_authenticatable, :rememberable, :trackable, :recoverable, :password_archivable, :session_limitable, :lockable # FriendlyId extend FriendlyId diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 3398577..79551f9 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -164,24 +164,24 @@ # 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 = :time # Number of authentication tries before locking an account if lock_strategy # is failed attempts. - # config.maximum_attempts = 20 + config.maximum_attempts = 10 # Time interval to unlock the account if :time is enabled as unlock_strategy. - # config.unlock_in = 1.hour + config.unlock_in = 1.hour # ==> Configuration for :recoverable # diff --git a/db/migrate/20260423112300_add_lockable_to_users.rb b/db/migrate/20260423112300_add_lockable_to_users.rb new file mode 100644 index 0000000..ebfc87c --- /dev/null +++ b/db/migrate/20260423112300_add_lockable_to_users.rb @@ -0,0 +1,8 @@ +class AddLockableToUsers < ActiveRecord::Migration[8.0] + def change + add_column :users, :failed_attempts, :integer, default: 0, null: false + add_column :users, :unlock_token, :string + add_column :users, :locked_at, :datetime + add_index :users, :unlock_token, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 8ec89d2..e1a1dbe 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[8.0].define(version: 2025_07_31_014203) do +ActiveRecord::Schema[8.0].define(version: 2026_04_23_112300) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -107,6 +107,10 @@ t.string "reset_password_token" t.datetime "reset_password_sent_at", precision: nil t.string "unique_session_id" + t.integer "failed_attempts", default: 0, null: false + t.string "unlock_token" + t.datetime "locked_at" + t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true end create_table "versions", id: :serial, force: :cascade do |t|