Improve password reset validation/error handling

This commit is contained in:
Toby Zerner 2016-11-13 08:51:38 +10:30
parent 28999bfed7
commit 327949495d
3 changed files with 28 additions and 5 deletions

View File

@ -57,6 +57,7 @@ class ResetPasswordController extends AbstractHtmlController
return $this->view->make('flarum::reset')
->with('translator', $this->translator)
->with('passwordToken', $token->id)
->with('csrfToken', $request->getAttribute('session')->get('csrf_token'));
->with('csrfToken', $request->getAttribute('session')->get('csrf_token'))
->with('error', $request->getAttribute('session')->get('error'));
}
}

View File

@ -15,6 +15,8 @@ use Flarum\Core\Validator\UserValidator;
use Flarum\Forum\UrlGenerator;
use Flarum\Http\Controller\ControllerInterface;
use Flarum\Http\SessionAuthenticator;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Contracts\Validation\ValidationException;
use Psr\Http\Message\ServerRequestInterface as Request;
use Zend\Diactoros\Response\RedirectResponse;
@ -35,15 +37,23 @@ class SavePasswordController implements ControllerInterface
*/
protected $authenticator;
/**
* @var Factory
*/
protected $validatorFactory;
/**
* @param UrlGenerator $url
* @param SessionAuthenticator $authenticator
* @param UserValidator $validator
* @param Factory $validatorFactory
*/
public function __construct(UrlGenerator $url, SessionAuthenticator $authenticator, UserValidator $validator)
public function __construct(UrlGenerator $url, SessionAuthenticator $authenticator, UserValidator $validator, Factory $validatorFactory)
{
$this->url = $url;
$this->authenticator = $authenticator;
$this->validator = $validator;
$this->validatorFactory = $validatorFactory;
}
/**
@ -57,11 +67,19 @@ class SavePasswordController implements ControllerInterface
$token = PasswordToken::findOrFail(array_get($input, 'passwordToken'));
$password = array_get($input, 'password');
$confirmation = array_get($input, 'password_confirmation');
$this->validator->assertValid(compact('password'));
try {
// todo: probably shouldn't use the user validator for this,
// passwords should be validated separately
$this->validator->assertValid(compact('password'));
$validator = $this->validatorFactory->make($input, ['password' => 'required|confirmed']);
if ($validator->fails()) {
throw new ValidationException($validator);
}
} catch (ValidationException $e) {
$request->getAttribute('session')->set('error', $e->errors()->first());
if (! $password || $password !== $confirmation) {
return new RedirectResponse($this->url->toRoute('resetPassword', ['token' => $token->id]));
}

View File

@ -11,6 +11,10 @@
<body>
<h1>{{ $translator->trans('core.views.reset.title') }}</h1>
@if (! empty($error))
<p>{{ $error }}</p>
@endif
<form class="form-horizontal" role="form" method="POST" action="{{ app('Flarum\Forum\UrlGenerator')->toRoute('savePassword') }}">
<input type="hidden" name="csrfToken" value="{{ $csrfToken }}">
<input type="hidden" name="passwordToken" value="{{ $passwordToken }}">