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:
@@ -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');
|
||||||
|
@@ -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.
|
||||||
|
29
framework/core/src/Api/ForgotPasswordValidator.php
Normal file
29
framework/core/src/Api/ForgotPasswordValidator.php
Normal 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']
|
||||||
|
];
|
||||||
|
}
|
Reference in New Issue
Block a user