]> BookStack Code Mirror - bookstack/blobdiff - app/Http/Controllers/Auth/ConfirmEmailController.php
Updated email confirmation flow so confirmation is done via POST
[bookstack] / app / Http / Controllers / Auth / ConfirmEmailController.php
index bffeb5f61b2f2f7528b87e6ad506f4b6dded53d2..b282d0601f31eaab351f971be08d0f0ad6540150 100644 (file)
@@ -3,32 +3,34 @@
 namespace BookStack\Http\Controllers\Auth;
 
 use BookStack\Auth\Access\EmailConfirmationService;
+use BookStack\Auth\Access\LoginService;
 use BookStack\Auth\UserRepo;
 use BookStack\Exceptions\ConfirmationEmailException;
 use BookStack\Exceptions\UserTokenExpiredException;
 use BookStack\Exceptions\UserTokenNotFoundException;
 use BookStack\Http\Controllers\Controller;
 use Exception;
-use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
-use Illuminate\Routing\Redirector;
-use Illuminate\View\View;
 
 class ConfirmEmailController extends Controller
 {
-    protected $emailConfirmationService;
-    protected $userRepo;
+    protected EmailConfirmationService $emailConfirmationService;
+    protected LoginService $loginService;
+    protected UserRepo $userRepo;
 
     /**
      * Create a new controller instance.
      */
-    public function __construct(EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
-    {
+    public function __construct(
+        EmailConfirmationService $emailConfirmationService,
+        LoginService $loginService,
+        UserRepo $userRepo
+    ) {
         $this->emailConfirmationService = $emailConfirmationService;
+        $this->loginService = $loginService;
         $this->userRepo = $userRepo;
     }
 
-
     /**
      * Show the page to tell the user to check their email
      * and confirm their address.
@@ -41,61 +43,67 @@ class ConfirmEmailController extends Controller
     /**
      * Shows a notice that a user's email address has not been confirmed,
      * Also has the option to re-send the confirmation email.
-     * @return View
      */
     public function showAwaiting()
     {
-        return view('auth.user-unconfirmed');
+        $user = $this->loginService->getLastLoginAttemptUser();
+
+        return view('auth.user-unconfirmed', ['user' => $user]);
+    }
+
+    /**
+     * Show the form for a user to provide their positive confirmation of their email.
+     */
+    public function showAcceptForm(string $token)
+    {
+        return view('auth.register-confirm-accept', ['token' => $token]);
     }
 
     /**
      * Confirms an email via a token and logs the user into the system.
-     * @param $token
-     * @return RedirectResponse|Redirector
+     *
      * @throws ConfirmationEmailException
      * @throws Exception
      */
-    public function confirm($token)
+    public function confirm(Request $request)
     {
+        $validated = $this->validate($request, [
+            'token' => ['required', 'string']
+        ]);
+
+        $token = $validated['token'];
+
         try {
             $userId = $this->emailConfirmationService->checkTokenAndGetUserId($token);
-        } catch (Exception $exception) {
-            if ($exception instanceof UserTokenNotFoundException) {
-                $this->showErrorNotification(trans('errors.email_confirmation_invalid'));
-                return redirect('/register');
-            }
-
-            if ($exception instanceof UserTokenExpiredException) {
-                $user = $this->userRepo->getById($exception->userId);
-                $this->emailConfirmationService->sendConfirmation($user);
-                $this->showErrorNotification(trans('errors.email_confirmation_expired'));
-                return redirect('/register/confirm');
-            }
-
-            throw $exception;
+        } catch (UserTokenNotFoundException $exception) {
+            $this->showErrorNotification(trans('errors.email_confirmation_invalid'));
+
+            return redirect('/register');
+        } catch (UserTokenExpiredException $exception) {
+            $user = $this->userRepo->getById($exception->userId);
+            $this->emailConfirmationService->sendConfirmation($user);
+            $this->showErrorNotification(trans('errors.email_confirmation_expired'));
+
+            return redirect('/register/confirm');
         }
 
         $user = $this->userRepo->getById($userId);
         $user->email_confirmed = true;
         $user->save();
 
-        auth()->login($user);
-        $this->showSuccessNotification(trans('auth.email_confirm_success'));
         $this->emailConfirmationService->deleteByUser($user);
+        $this->showSuccessNotification(trans('auth.email_confirm_success'));
 
-        return redirect('/');
+        return redirect('/login');
     }
 
-
     /**
-     * Resend the confirmation email
-     * @param Request $request
-     * @return View
+     * Resend the confirmation email.
      */
     public function resend(Request $request)
     {
         $this->validate($request, [
-            'email' => 'required|email|exists:users,email'
+            'email' => ['required', 'email', 'exists:users,email'],
         ]);
         $user = $this->userRepo->getByEmail($request->get('email'));
 
@@ -103,10 +111,12 @@ class ConfirmEmailController extends Controller
             $this->emailConfirmationService->sendConfirmation($user);
         } catch (Exception $e) {
             $this->showErrorNotification(trans('auth.email_confirm_send_error'));
+
             return redirect('/register/confirm');
         }
 
         $this->showSuccessNotification(trans('auth.email_confirm_resent'));
+
         return redirect('/register/confirm');
     }
 }