%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2026 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) %# %# %# LICENSE: %# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. %# %# This work is distributed in the hope that it will be useful, but %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. %# %# You should have received a copy of the GNU General Public License %# along with this program; if not, write to the Free Software %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA %# 02110-1301 or visit their web page on the internet at %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. %# %# %# CONTRIBUTION SUBMISSION POLICY: %# %# (The following paragraph is not intended to limit the rights granted %# to you to modify and distribute this software under the terms of %# the GNU General Public License and is only of importance to you if %# you choose to contribute your changes and enhancements to the %# community by submitting them to Best Practical Solutions, LLC.) %# %# By intentionally submitting any modifications, corrections or %# derivatives to this work, or any other work intended for use with %# Request Tracker, to Best Practical Solutions, LLC, you confirm that %# you are the copyright holder for those contributions and you grant %# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, %# royalty-free, perpetual, license to use, copy, create derivative %# works based on those contributions, and sublicense and distribute %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} <& /Elements/Header, Title => $title, RichText => 0 &>
<& /Elements/ListActions, actions => \@actions &> <&| /Widgets/TitleBox, title => $title, hideable => 0, class => 'mx-auto max-width-lg', content_class => 'mx-auto w-100 max-width-sm' &> % if ($sent) { % if ( $Mode eq 'create' ) {

<&|/l&>RT has sent you an email message with instructions about how to set your password.

% } % else {

<&|/l&>RT has sent you an email message with instructions about how to reset your password.

% }

<&|/l&>Please check your email and follow the link.

% } else { % if ( $Mode eq 'create' ) {

<&|/l&>Enter your email address to create a new account.

% } % else {

<&|/l&>Enter your email address and RT will send you a link to reset your password.

% }
<&| /Elements/LabeledValue, Label => loc('Email address') &>
% } <& /Elements/Footer, Menu => 0 &> <%init> if ( RT->Config->Get('DisableResetPasswordOnLogin') ) { RT::Interface::Web::Redirect( RT->Config->Get('WebURL') ); } my @actions; my $sent; my $title = loc("Reset your password"); if ( $Mode eq 'create' ) { $title = loc("Create account"); } if ( $r->method eq 'POST' && $ARGS{'Email'} ) { my $valid_nonce = $session{ResetPasswordNonce} && ( $ARGS{nonce} // '' ) eq $session{ResetPasswordNonce}; RT::Interface::Web::Session::Delete( Key => 'ResetPasswordNonce' ); if ( !$valid_nonce ) { push @actions, loc('Invalid request. Please try again.'); } else { require Time::HiRes; my $started = Time::HiRes::time(); $ARGS{'Email'} =~ s/^\s+|\s+$//g; my $u = RT::User->new( RT->SystemUser ); $u->LoadByCols( EmailAddress => $ARGS{'Email'} ); # If the user exists, has a password, and is not disabled, allow reset if ( $u->id and $u->HasPassword and !$u->Disabled ) { my ( $status, $msg ) = $u->CreateTokenAndResetPassword; if ($status) { $sent = 1; RT->Logger->info( "Password reset token sent to " . $u->EmailAddress ); } else { push @actions, loc("Failed to send password reset token, please contact your RT administrator."); RT->Logger->error( "Failed to send password reset token to " . $u->EmailAddress . ": $msg" ); } } # Disabled users cannot reset elsif ( $u->id and $u->Disabled ) { push @actions, loc("You can't reset your password because your user is disabled."); RT->Logger->warning( "Disabled user " . $u->Name . " attempted to reset password" ); } # User exists but has no password - check config elsif ( $u->id ) { if ( RT->Config->Get('ResetPasswordAllowUsersWithoutPassword') ) { my ( $status, $msg ) = $u->CreateTokenAndResetPassword; if ($status) { $sent = 1; RT->Logger->info( "Password reset token sent to " . $u->EmailAddress ); } else { push @actions, loc("Unable to send new password email, contact your RT administrator for more assistance"); RT->Logger->error( "Failed to send password reset token to " . $u->EmailAddress . ": $msg" ); } } else { push @actions, loc("Unable to send new password email, contact your RT administrator for more assistance"); RT->Logger->warning( "User " . $u->Name . " attempted to reset their password without having an existing password" ); } } # User does not exist - check if new-account creation is enabled else { if ( RT->Config->Get('ResetPasswordCreateNewUserAndSetPassword') ) { my ( $status, $msg ) = $u->Create( Privileged => RT->Config->Get('ResetPasswordCreateNewUserAsPrivileged') || 0, EmailAddress => $ARGS{'Email'}, ); if ($status) { ( $status, $msg ) = $u->CreateTokenAndResetPassword; if ($status) { $sent = 1; RT->Logger->info( "Password reset token sent to " . $u->EmailAddress ); } else { push @actions, loc("Unable to send new password email, contact your RT administrator for more assistance"); RT->Logger->error( "Failed to send password reset token to " . $u->EmailAddress . ": $msg" ); } } else { RT->Logger->error("Failed to create user for " . $ARGS{'Email'} . ": $msg"); push @actions, loc("Unable to send new password email, contact your RT administrator for more assistance"); } } else { push @actions, loc("Unable to send new password email, contact your RT administrator for more assistance"); RT->Logger->warning( "Password reset attempted for non-existent user " . $ARGS{'Email'} ); } } if ( RT->Config->Get('HidePasswordResetErrors') ) { @actions = (); $sent = 1; # Only active accounts are sent an email; pad every response to # the same minimum so the send time doesn't reveal which those are. my $left = 1 - ( Time::HiRes::time() - $started ); Time::HiRes::sleep($left) if $left > 0; } } } # Generate a fresh CSRF nonce for the form RT::Interface::Web::Session::Set( Key => 'ResetPasswordNonce', Value => RT::Util::random_hex(32) ); <%args> $Mode => 'reset'