N°8545 - Standardize return message from password reset (#812)

* N°8545 - Standardize return message from password reset

* N°8545 - Change log severity depending on the error source

* Add copyrights

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Avoid using dictionary entries in logs

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Stephen Abello
2026-02-19 16:12:34 +01:00
committed by GitHub
parent d2f67dcb3c
commit 9fd0ffd84e
5 changed files with 49 additions and 17 deletions

View File

@@ -0,0 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ForgotPasswordApplicationException extends Exception
{
}

View File

@@ -0,0 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ForgotPasswordUserInputException extends Exception
{
}

View File

@@ -221,16 +221,16 @@ class LoginWebPage extends NiceWebPage
if ($oUser != null) {
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token')) {
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
}
if (!$oUser->CanChangePassword()) {
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
}
throw new ForgotPasswordUserInputException('External accounts do not allow password reset');
}
if (!$oUser->CanChangePassword()) {
throw new ForgotPasswordUserInputException('The account does not allow password reset');
}
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
if ($sTo == '') {
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
}
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
if ($sTo == '') {
throw new ForgotPasswordUserInputException('Missing email address for this account');
}
// This token allows the user to change the password without knowing the previous one
$sToken = bin2hex(random_bytes(32));
@@ -255,17 +255,21 @@ class LoginWebPage extends NiceWebPage
case EMAIL_SEND_ERROR:
default:
IssueLog::Error('Failed to send the email with the NEW password for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
throw new ForgotPasswordApplicationException('Failed to send the password reset email for ' . $oUser->Get('friendlyname') . ': ' . implode(', ', $aIssues));
}
}
$oTwigContext = new LoginTwigRenderer();
$aVars = $oTwigContext->GetDefaultVars();
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
} catch (Exception $e) {
$this->DisplayForgotPwdForm(true, $e->getMessage());
} catch (ForgotPasswordApplicationException $e) {
IssueLog::Error('Failed to process the forgot password request for user "' . $sAuthUser . '" [reason=' . get_class($e) . ']: ' . $e->getMessage());
} catch (ForgotPasswordUserInputException $e) {
IssueLog::Info('Failed to process the forgot password request for user "' . $sAuthUser . '" [reason=' . get_class($e) . ']: ' . $e->getMessage());
} catch (\Throwable $e) {
IssueLog::Error('Unexpected error while processing the forgot password request for user "' . $sAuthUser . '": ' . $e->getMessage());
}
$oTwigContext = new LoginTwigRenderer();
$aVars = $oTwigContext->GetDefaultVars();
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
}
public function DisplayResetPwdForm($sErrorMessage = null)

View File

@@ -744,6 +744,8 @@ return array(
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => $vendorDir . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
'ForgotPasswordApplicationException' => $baseDir . '/application/exceptions/ForgotPasswordApplicationException.php',
'ForgotPasswordUserInputException' => $baseDir . '/application/exceptions/ForgotPasswordUserInputException.php',
'FunctionExpression' => $baseDir . '/core/oql/expression.class.inc.php',
'FunctionOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
'GraphEdge' => $baseDir . '/core/simplegraph.class.inc.php',

View File

@@ -127,6 +127,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
),
'Symfony\\Polyfill\\Php80\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
@@ -1103,6 +1107,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
'ForgotPasswordApplicationException' => __DIR__ . '/../..' . '/application/exceptions/ForgotPasswordApplicationException.php',
'ForgotPasswordUserInputException' => __DIR__ . '/../..' . '/application/exceptions/ForgotPasswordUserInputException.php',
'FunctionExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'FunctionOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
'GraphEdge' => __DIR__ . '/../..' . '/core/simplegraph.class.inc.php',
@@ -3542,7 +3548,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'privUITransactionFile' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
'privUITransactionSession' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
'utils' => __DIR__ . '/../..' . '/application/utils.inc.php',
'©' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
'©' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
);
public static function getInitializer(ClassLoader $loader)