summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2019-10-08 16:17:06 +0200
committerIgor Scheller <igor.scheller@igorshp.de>2019-10-08 16:17:06 +0200
commitdd0366296893a0e8da8ae0365387dd4823d53451 (patch)
treea095514373384ebdaeba7b5809cbcb9bbcfd19d8 /src
parent8f8130634e40f6a24295b7bab449a43ed7c5aa80 (diff)
Rebuild password reset
Diffstat (limited to 'src')
-rw-r--r--src/Controllers/PasswordResetController.php167
-rw-r--r--src/Middleware/LegacyMiddleware.php6
2 files changed, 167 insertions, 6 deletions
diff --git a/src/Controllers/PasswordResetController.php b/src/Controllers/PasswordResetController.php
new file mode 100644
index 00000000..505ed8eb
--- /dev/null
+++ b/src/Controllers/PasswordResetController.php
@@ -0,0 +1,167 @@
+<?php
+
+namespace Engelsystem\Controllers;
+
+use Engelsystem\Http\Exceptions\HttpNotFound;
+use Engelsystem\Http\Request;
+use Engelsystem\Http\Response;
+use Engelsystem\Mail\EngelsystemMailer;
+use Engelsystem\Models\User\PasswordReset;
+use Engelsystem\Models\User\User;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+
+class PasswordResetController extends BaseController
+{
+ /** @var LoggerInterface */
+ protected $log;
+
+ /** @var EngelsystemMailer */
+ protected $mail;
+
+ /** @var Response */
+ protected $response;
+
+ /** @var SessionInterface */
+ protected $session;
+
+ /** @var array */
+ protected $permissions = [
+ 'reset' => 'login',
+ 'postReset' => 'login',
+ 'resetPassword' => 'login',
+ 'postResetPassword' => 'login',
+ ];
+
+ /**
+ * @param Response $response
+ * @param SessionInterface $session
+ * @param EngelsystemMailer $mail
+ * @param LoggerInterface $log
+ */
+ public function __construct(
+ Response $response,
+ SessionInterface $session,
+ EngelsystemMailer $mail,
+ LoggerInterface $log
+ ) {
+ $this->log = $log;
+ $this->mail = $mail;
+ $this->response = $response;
+ $this->session = $session;
+ }
+
+ /**
+ * @return Response
+ */
+ public function reset(): Response
+ {
+ return $this->showView('pages/password/reset');
+ }
+
+ /**
+ * @param Request $request
+ * @return Response
+ */
+ public function postReset(Request $request): Response
+ {
+ $data = $this->validate($request, [
+ 'email' => 'required|email',
+ ]);
+
+ /** @var User $user */
+ $user = User::whereEmail($data['email'])->first();
+ if ($user) {
+ $reset = PasswordReset::findOrNew($user->id);
+ $reset->user_id = $user->id;
+ $reset->token = md5(random_bytes(64));
+ $reset->save();
+
+ $this->log->info(
+ sprintf('Password recovery for %s (%u)', $user->name, $user->id),
+ ['user' => $user->toJson()]
+ );
+
+ $this->mail->sendViewTranslated(
+ $user,
+ 'Password recovery',
+ 'emails/password-reset',
+ ['username' => $user->name, 'reset' => $reset]
+ );
+ }
+
+ return $this->showView('pages/password/reset-success', ['type' => 'email']);
+ }
+
+ /**
+ * @param Request $request
+ * @return Response
+ */
+ public function resetPassword(Request $request): Response
+ {
+ $this->requireToken($request);
+
+ return $this->showView('pages/password/reset-form');
+ }
+
+ /**
+ * @param Request $request
+ * @return Response
+ */
+ public function postResetPassword(Request $request): Response
+ {
+ $reset = $this->requireToken($request);
+
+ $data = $this->validate($request, [
+ 'password' => 'required|min:' . config('min_password_length'),
+ 'password_confirmation' => 'required',
+ ]);
+
+ if ($data['password'] !== $data['password_confirmation']) {
+ $this->session->set('errors',
+ array_merge($this->session->get('errors', []), ['validation.password.confirmed']));
+
+ return $this->showView('pages/password/reset-form');
+ }
+
+ auth()->setPassword($reset->user, $data['password']);
+ $reset->delete();
+
+ return $this->showView('pages/password/reset-success', ['type' => 'reset']);
+ }
+
+ /**
+ * @param string $view
+ * @param array $data
+ * @return Response
+ */
+ protected function showView($view = 'pages/password/reset', $data = []): Response
+ {
+ $errors = Collection::make(Arr::flatten($this->session->get('errors', [])));
+ $this->session->remove('errors');
+
+ return $this->response->withView(
+ $view,
+ array_merge_recursive(['errors' => $errors], $data)
+ );
+ }
+
+ /**
+ * @param Request $request
+ * @return PasswordReset
+ */
+ protected function requireToken(Request $request): PasswordReset
+ {
+ $token = $request->getAttribute('token');
+ /** @var PasswordReset|null $reset */
+ $reset = PasswordReset::whereToken($token)->first();
+
+ if (!$reset) {
+ throw new HttpNotFound();
+ }
+
+ return $reset;
+ }
+}
diff --git a/src/Middleware/LegacyMiddleware.php b/src/Middleware/LegacyMiddleware.php
index 27a15faa..11508e1c 100644
--- a/src/Middleware/LegacyMiddleware.php
+++ b/src/Middleware/LegacyMiddleware.php
@@ -26,7 +26,6 @@ class LegacyMiddleware implements MiddlewareInterface
'shifts_json_export',
'users',
'user_driver_licenses',
- 'user_password_recovery',
'user_worklog',
];
@@ -112,11 +111,6 @@ class LegacyMiddleware implements MiddlewareInterface
case 'shifts_json_export':
require_once realpath(__DIR__ . '/../../includes/controller/shifts_controller.php');
shifts_json_export_controller();
- case 'user_password_recovery':
- require_once realpath(__DIR__ . '/../../includes/controller/users_controller.php');
- $title = user_password_recovery_title();
- $content = user_password_recovery_controller();
- return [$title, $content];
case 'public_dashboard':
return public_dashboard_controller();
case 'angeltypes':