From cf551d652c3b7af77a8c9f15f611417c4f0d7f8a Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Mon, 27 Apr 2026 21:48:32 +0100 Subject: [PATCH] CLDC-4330: Stop login count resetting on deactivation (#3321) * CLDC-4330: Add reset password on confirmation flag to be used instead of resetting sign in count to 0 * CLDC-4330: Use this new flag to determine when to show password reset * CLDC-4330: Update confirmation comment * fixup! CLDC-4330: Update confirmation comment * CLDC-4330: Rename col to force_reset_password_on_confirmation * CLDC-4330: Remove unneeded if --- app/controllers/auth/confirmations_controller.rb | 6 +++++- app/controllers/auth/passwords_controller.rb | 1 + app/models/user.rb | 2 +- ...627_add_force_reset_password_on_confirmation_to_users.rb | 5 +++++ db/schema.rb | 3 ++- 5 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20260420151627_add_force_reset_password_on_confirmation_to_users.rb diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index d3f617822..cd09d7bb6 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -5,7 +5,11 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController yield resource if block_given? if resource.errors.empty? - if resource.sign_in_count.zero? + # previously we reset sign_in_count on deactivation and had only the .zero? check here. + # this would force a password reset both if it was your very first log in, and on your first login after reactivation. + # now we have a specific flag for the latter case as resetting sign_in_count was difficult for auditing. + # note that some deactivated users will have a sign_in_count of 0 and not have this flag set if they were deactivated before we made this change. + if resource.force_reset_password_on_confirmation || resource.sign_in_count.zero? token = resource.send(:set_reset_password_token) redirect_to "#{edit_user_password_url}?reset_password_token=#{token}&confirmation=true" else diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb index e4a21675b..702e99f1f 100644 --- a/app/controllers/auth/passwords_controller.rb +++ b/app/controllers/auth/passwords_controller.rb @@ -37,6 +37,7 @@ class Auth::PasswordsController < Devise::PasswordsController if resource.errors.empty? resource.unlock_access! if resource.respond_to?(:unlock_access!) + resource.force_reset_password_on_confirmation = false if Devise.sign_in_after_reset_password set_flash_message!(:notice, password_update_flash_message) resource.after_database_authentication diff --git a/app/models/user.rb b/app/models/user.rb index ea8289e53..92fd37dc8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -179,7 +179,7 @@ class User < ApplicationRecord update!( active: false, confirmed_at: nil, - sign_in_count: 0, + force_reset_password_on_confirmation: true, initial_confirmation_sent: false, reactivate_with_organisation:, unconfirmed_email: nil, diff --git a/db/migrate/20260420151627_add_force_reset_password_on_confirmation_to_users.rb b/db/migrate/20260420151627_add_force_reset_password_on_confirmation_to_users.rb new file mode 100644 index 000000000..ad8a18980 --- /dev/null +++ b/db/migrate/20260420151627_add_force_reset_password_on_confirmation_to_users.rb @@ -0,0 +1,5 @@ +class AddForceResetPasswordOnConfirmationToUsers < ActiveRecord::Migration[7.2] + def change + add_column :users, :force_reset_password_on_confirmation, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 37e5c764e..4af47a53f 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: 2026_03_05_095832) do +ActiveRecord::Schema[7.2].define(version: 2026_04_20_151627) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -924,6 +924,7 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_05_095832) do t.datetime "discarded_at" t.string "phone_extension" t.datetime "values_updated_at" + t.boolean "force_reset_password_on_confirmation", default: false t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true t.index ["encrypted_otp_secret_key"], name: "index_users_on_encrypted_otp_secret_key", unique: true