1
0
mirror of https://github.com/flarum/core.git synced 2025-08-02 14:37:49 +02:00

feat: Allow additional reset password params, introduce ForgotPasswordValidator (#3671)

* feat: Allow additional reset password params, introduce 'ForgotPasswordValidator'

* Apply fixes from StyleCI

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Ian Morland
2022-11-07 15:06:00 +00:00
committed by GitHub
parent bc4b0b864c
commit 87cdb5b4d8
3 changed files with 87 additions and 38 deletions

View File

@@ -5,6 +5,7 @@ import extractText from '../../common/utils/extractText';
import Stream from '../../common/utils/Stream'; import Stream from '../../common/utils/Stream';
import Mithril from 'mithril'; import Mithril from 'mithril';
import RequestError from '../../common/utils/RequestError'; import RequestError from '../../common/utils/RequestError';
import ItemList from '../../common/utils/ItemList';
export interface IForgotPasswordModalAttrs extends IInternalModalAttrs { export interface IForgotPasswordModalAttrs extends IInternalModalAttrs {
email?: string; email?: string;
@@ -52,38 +53,55 @@ export default class ForgotPasswordModal<CustomAttrs extends IForgotPasswordModa
); );
} }
const emailLabel = extractText(app.translator.trans('core.forum.forgot_password.email_placeholder'));
return ( return (
<div className="Modal-body"> <div className="Modal-body">
<div className="Form Form--centered"> <div className="Form Form--centered">
<p className="helpText">{app.translator.trans('core.forum.forgot_password.text')}</p> <p className="helpText">{app.translator.trans('core.forum.forgot_password.text')}</p>
<div className="Form-group"> {this.fields().toArray()}
<input
className="FormControl"
name="email"
type="email"
placeholder={emailLabel}
aria-label={emailLabel}
bidi={this.email}
disabled={this.loading}
/>
</div>
<div className="Form-group">
{Button.component(
{
className: 'Button Button--primary Button--block',
type: 'submit',
loading: this.loading,
},
app.translator.trans('core.forum.forgot_password.submit_button')
)}
</div>
</div> </div>
</div> </div>
); );
} }
fields() {
const items = new ItemList();
const emailLabel = extractText(app.translator.trans('core.forum.forgot_password.email_placeholder'));
items.add(
'email',
<div className="Form-group">
<input
className="FormControl"
name="email"
type="email"
placeholder={emailLabel}
aria-label={emailLabel}
bidi={this.email}
disabled={this.loading}
/>
</div>,
50
);
items.add(
'submit',
<div className="Form-group">
{Button.component(
{
className: 'Button Button--primary Button--block',
type: 'submit',
loading: this.loading,
},
app.translator.trans('core.forum.forgot_password.submit_button')
)}
</div>,
-10
);
return items;
}
onsubmit(e: SubmitEvent) { onsubmit(e: SubmitEvent) {
e.preventDefault(); e.preventDefault();
@@ -93,7 +111,7 @@ export default class ForgotPasswordModal<CustomAttrs extends IForgotPasswordModa
.request({ .request({
method: 'POST', method: 'POST',
url: app.forum.attribute('apiUrl') + '/forgot', url: app.forum.attribute('apiUrl') + '/forgot',
body: { email: this.email() }, body: this.requestParams(),
errorHandler: this.onerror.bind(this), errorHandler: this.onerror.bind(this),
}) })
.then(() => { .then(() => {
@@ -104,6 +122,14 @@ export default class ForgotPasswordModal<CustomAttrs extends IForgotPasswordModa
.then(this.loaded.bind(this)); .then(this.loaded.bind(this));
} }
requestParams(): Record<string, unknown> {
const data = {
email: this.email(),
};
return data;
}
onerror(error: RequestError) { onerror(error: RequestError) {
if (error.status === 404 && error.alert) { if (error.status === 404 && error.alert) {
error.alert.content = app.translator.trans('core.forum.forgot_password.not_found_message'); error.alert.content = app.translator.trans('core.forum.forgot_password.not_found_message');

View File

@@ -9,11 +9,10 @@
namespace Flarum\Api\Controller; namespace Flarum\Api\Controller;
use Flarum\Api\ForgotPasswordValidator;
use Flarum\User\Job\RequestPasswordResetJob; use Flarum\User\Job\RequestPasswordResetJob;
use Illuminate\Contracts\Queue\Queue; use Illuminate\Contracts\Queue\Queue;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Validation\ValidationException;
use Laminas\Diactoros\Response\EmptyResponse; use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@@ -27,14 +26,14 @@ class ForgotPasswordController implements RequestHandlerInterface
protected $queue; protected $queue;
/** /**
* @var Factory * @var ForgotPasswordValidator
*/ */
protected $validatorFactory; protected $validator;
public function __construct(Queue $queue, Factory $validatorFactory) public function __construct(Queue $queue, ForgotPasswordValidator $validator)
{ {
$this->queue = $queue; $this->queue = $queue;
$this->validatorFactory = $validatorFactory; $this->validator = $validator;
} }
/** /**
@@ -42,16 +41,11 @@ class ForgotPasswordController implements RequestHandlerInterface
*/ */
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface
{ {
$email = Arr::get($request->getParsedBody(), 'email'); $params = $request->getParsedBody();
$validation = $this->validatorFactory->make( $this->validator->assertValid($params);
compact('email'),
['email' => 'required|email']
);
if ($validation->fails()) { $email = Arr::get($params, 'email');
throw new ValidationException($validation);
}
// Prevents leaking user existence by not throwing an error. // Prevents leaking user existence by not throwing an error.
// Prevents leaking user existence by duration by using a queued job. // Prevents leaking user existence by duration by using a queued job.

View File

@@ -0,0 +1,29 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Api;
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Foundation\AbstractValidator;
class ForgotPasswordValidator extends AbstractValidator
{
/**
* {@inheritdoc}
*/
protected $rules = [
'email' => ['required', 'email']
];
}