diff --git a/app/services/user_password_expirer.rb b/app/services/user_password_expirer.rb index 2e294254e65..4a1944932ce 100644 --- a/app/services/user_password_expirer.rb +++ b/app/services/user_password_expirer.rb @@ -2,12 +2,14 @@ class UserPasswordExpirer def self.expire_user_password(user) - UserPassword.create!( - user:, - password_hash: user.password_hash, - password_salt: user.salt, - password_algorithm: user.password_algorithm, - password_expired_at: Time.zone.now, - ) + UserPassword + .where( + user:, + password_hash: user.password_hash, + password_salt: user.salt, + password_algorithm: user.password_algorithm, + ) + .first_or_initialize + .update!(password_expired_at: Time.zone.now) end end diff --git a/spec/services/user_password_expirer_spec.rb b/spec/services/user_password_expirer_spec.rb index 13f6854ad93..9498c853aac 100644 --- a/spec/services/user_password_expirer_spec.rb +++ b/spec/services/user_password_expirer_spec.rb @@ -19,5 +19,28 @@ RSpec.describe UserPasswordExpirer do expect(user_password.password_algorithm).to eq(user.password_algorithm) expect(user_password.password_expired_at).to eq_time(Time.zone.now) end + + it "should update `UserPassword#password_expired_at` if the user already has an existing UserPassword record with the same password hash, salt and algorithm" do + freeze_time(1.hour.ago) do + described_class.expire_user_password(user) + + user_password = user.passwords.first + + expect(user_password.password_expired_at).to eq_time(Time.zone.now) + end + + freeze_time do + described_class.expire_user_password(user) + + expect(user.passwords.count).to eq(1) + + user_password = user.passwords.first + + expect(user_password.password_hash).to eq(user.password_hash) + expect(user_password.password_salt).to eq(user.salt) + expect(user_password.password_algorithm).to eq(user.password_algorithm) + expect(user_password.password_expired_at).to eq_time(Time.zone.now) + end + end end end