xref: /webtrees/app/Http/RequestHandlers/PasswordRequestAction.php (revision 0b4092ed8e31e3588eb143d0ade6c4a411367da8)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Http\RequestHandlers;
19
20use Fig\Http\Message\RequestMethodInterface;
21use Fig\Http\Message\StatusCodeInterface;
22use Fisharebest\Webtrees\Carbon;
23use Fisharebest\Webtrees\FlashMessages;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Log;
26use Fisharebest\Webtrees\Services\MailService;
27use Fisharebest\Webtrees\Services\UserService;
28use Fisharebest\Webtrees\SiteUser;
29use Fisharebest\Webtrees\User;
30use Illuminate\Support\Str;
31use Psr\Http\Message\ResponseInterface;
32use Psr\Http\Message\ServerRequestInterface;
33use Psr\Http\Server\RequestHandlerInterface;
34use function e;
35use function redirect;
36use function route;
37use function view;
38
39/**
40 * Request a new password.
41 */
42class PasswordRequestAction implements RequestHandlerInterface, StatusCodeInterface, RequestMethodInterface
43{
44    const TOKEN_LENGTH = 40;
45
46    /** @var MailService */
47    private $mail_service;
48
49    /** @var UserService */
50    private $user_service;
51
52    /**
53     * PasswordRequestForm constructor.
54     *
55     * @param MailService $mail_service
56     * @param UserService $user_service
57     */
58    public function __construct(MailService $mail_service, UserService $user_service)
59    {
60        $this->user_service = $user_service;
61        $this->mail_service = $mail_service;
62    }
63
64    /**
65     * @param ServerRequestInterface $request
66     *
67     * @return ResponseInterface
68     */
69    public function handle(ServerRequestInterface $request): ResponseInterface
70    {
71        $email = $request->getParsedBody()['email'] ?? '';
72        $user  = $this->user_service->findByEmail($email);
73
74        if ($user instanceof User) {
75            $token  = Str::random(self::TOKEN_LENGTH);
76            $expire = (string) Carbon::now()->addHour()->timestamp;
77            $url    = route('password-reset', ['token' => $token]);
78
79            $user->setPreference('password-token', $token);
80            $user->setPreference('password-token-expire', $expire);
81
82            $this->mail_service->send(
83                new SiteUser(),
84                $user,
85                new SiteUser(),
86                I18N::translate('Request a new password'),
87                view('emails/password-request-text', ['url' => $url, 'user' => $user]),
88                view('emails/password-request-html', ['url' => $url, 'user' => $user])
89            );
90
91            Log::addAuthenticationLog('Password request for user: ' . $user->userName());
92
93            $message1 = I18N::translate('A password reset link has been sent to “%s”.', e($email));
94            $message2 = I18N::translate('This link is valid for one hour.');
95            FlashMessages::addMessage($message1 . '<br>' . $message2, 'success');
96        } else {
97            $message = I18N::translate('There is no user account with the email “%s”.', e($email));
98            FlashMessages::addMessage($message, 'danger');
99        }
100
101        return redirect(route('password-request'));
102    }
103}
104