From 08a754a9340196fe122b3bfb305717b5b692d533 Mon Sep 17 00:00:00 2001 From: Jacob O'Mara Date: Thu, 10 Apr 2025 12:30:45 +0100 Subject: [PATCH] Bug 40824: Check password history for clashes when saving password --- Koha/Patron.pm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Koha/Patron.pm b/Koha/Patron.pm index 479eb3c209b..4efa4a107bd 100644 --- a/Koha/Patron.pm +++ b/Koha/Patron.pm @@ -69,6 +69,8 @@ use Koha::Result::Boolean; use Koha::Subscription::Routinglists; use Koha::Token; use Koha::Virtualshelves; +use Koha::PatronPasswordHistory; +use Koha::PatronPasswordHistories; use base qw(Koha::Object); @@ -1062,6 +1064,17 @@ sub set_password { my $action = $args->{action} || "CHANGE PASS"; unless ( $args->{skip_validation} ) { + # Check password history first + if (Koha::PatronPasswordHistories->has_used_password({ + borrowernumber => $self->borrowernumber, + password => $password, + current_password => $self->password + })) { + Koha::Exceptions::Password::UsedBefore->throw( + error => 'Password has been used before' + ); + } + my ( $is_valid, $error ) = Koha::AuthUtils::is_password_valid( $password, $self->category ); if ( !$is_valid ) { @@ -1143,6 +1156,20 @@ sub set_password { } } + # Store old password in history if there is one and it's different from the new one + if ($self->password && $self->in_storage) { + # Get the old password before it's replaced + my $old_password = $self->get_from_storage->password; + my $history_count = C4::Context->preference('PasswordHistoryCount') || 0; + + # Always store the old password, regardless of current preference + # This ensures we maintain history if the preference is increased later + my $history_record = Koha::PatronPasswordHistory->new({ + borrowernumber => $self->borrowernumber, + password => $old_password, + })->store(); + } + my $digest = Koha::AuthUtils::hash_password($password); $self->password_expiration_date( $self->category->get_password_expiry_date || undef ); -- 2.39.5