summaryrefslogtreecommitdiff
path: root/src/Controllers
diff options
context:
space:
mode:
authormsquare <msquare@notrademark.de>2019-10-13 13:43:08 +0200
committermsquare <msquare@notrademark.de>2019-10-13 13:43:08 +0200
commitc0e97bfe753013b115345b00cbfd9858799a6ac9 (patch)
tree7e98447e4c7d874ec27e26801771086843f3efc3 /src/Controllers
parent285f5509dd948c2359c861eec364a677e8ce4910 (diff)
parent7a2427e70296ef652f76fe2e2edc47d2e0f70f5a (diff)
Password recovery rebuild, correctly translated Mails and some minor fixes #658
Diffstat (limited to 'src/Controllers')
-rw-r--r--src/Controllers/AuthController.php2
-rw-r--r--src/Controllers/PasswordResetController.php167
2 files changed, 168 insertions, 1 deletions
diff --git a/src/Controllers/AuthController.php b/src/Controllers/AuthController.php
index c69c2377..7892064b 100644
--- a/src/Controllers/AuthController.php
+++ b/src/Controllers/AuthController.php
@@ -88,7 +88,7 @@ class AuthController extends BaseController
$user = $this->auth->authenticate($data['login'], $data['password']);
if (!$user instanceof User) {
- $this->session->set('errors', $this->session->get('errors', []) + ['auth.not-found']);
+ $this->session->set('errors', array_merge($this->session->get('errors', []), ['auth.not-found']));
return $this->showLogin();
}
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;
+ }
+}