From e5155a5dcb3553da589ac2955989c32315ddf79a Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Sun, 18 Aug 2019 10:47:59 +0100 Subject: [PATCH] Refactored confirm actions to their own controller --- app/Auth/Access/EmailConfirmationService.php | 10 ++ .../Auth/ConfirmEmailController.php | 118 ++++++++++++++++++ .../Controllers/Auth/RegisterController.php | 89 +------------ routes/web.php | 8 +- 4 files changed, 134 insertions(+), 91 deletions(-) create mode 100644 app/Http/Controllers/Auth/ConfirmEmailController.php diff --git a/app/Auth/Access/EmailConfirmationService.php b/app/Auth/Access/EmailConfirmationService.php index a9aecaf22..a94c54d19 100644 --- a/app/Auth/Access/EmailConfirmationService.php +++ b/app/Auth/Access/EmailConfirmationService.php @@ -27,4 +27,14 @@ class EmailConfirmationService extends UserTokenService $user->notify(new ConfirmEmail($token)); } + /** + * Check if confirmation is required in this instance. + * @return bool + */ + public function confirmationRequired() : bool + { + return setting('registration-confirmation') + || setting('registration-restrict'); + } + } diff --git a/app/Http/Controllers/Auth/ConfirmEmailController.php b/app/Http/Controllers/Auth/ConfirmEmailController.php new file mode 100644 index 000000000..3e240b94e --- /dev/null +++ b/app/Http/Controllers/Auth/ConfirmEmailController.php @@ -0,0 +1,118 @@ +<?php + +namespace BookStack\Http\Controllers\Auth; + +use BookStack\Auth\Access\EmailConfirmationService; +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; + + /** + * Create a new controller instance. + * + * @param EmailConfirmationService $emailConfirmationService + * @param UserRepo $userRepo + */ + public function __construct(EmailConfirmationService $emailConfirmationService, UserRepo $userRepo) + { + $this->emailConfirmationService = $emailConfirmationService; + $this->userRepo = $userRepo; + parent::__construct(); + } + + + /** + * Show the page to tell the user to check their email + * and confirm their address. + */ + public function show() + { + return view('auth.register-confirm'); + } + + /** + * 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'); + } + + /** + * 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) + { + try { + $userId = $this->emailConfirmationService->checkTokenAndGetUserId($token); + } catch (Exception $exception) { + + if ($exception instanceof UserTokenNotFoundException) { + session()->flash('error', trans('errors.email_confirmation_invalid')); + return redirect('/register'); + } + + if ($exception instanceof UserTokenExpiredException) { + $user = $this->userRepo->getById($exception->userId); + $this->emailConfirmationService->sendConfirmation($user); + session()->flash('error', trans('errors.email_confirmation_expired')); + return redirect('/register/confirm'); + } + + throw $exception; + } + + $user = $this->userRepo->getById($userId); + $user->email_confirmed = true; + $user->save(); + + auth()->login($user); + session()->flash('success', trans('auth.email_confirm_success')); + $this->emailConfirmationService->deleteByUser($user); + + return redirect('/'); + } + + + /** + * Resend the confirmation email + * @param Request $request + * @return View + */ + public function resend(Request $request) + { + $this->validate($request, [ + 'email' => 'required|email|exists:users,email' + ]); + $user = $this->userRepo->getByEmail($request->get('email')); + + try { + $this->emailConfirmationService->sendConfirmation($user); + } catch (Exception $e) { + session()->flash('error', trans('auth.email_confirm_send_error')); + return redirect('/register/confirm'); + } + + session()->flash('success', trans('auth.email_confirm_resent')); + return redirect('/register/confirm'); + } + +} diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 47541784b..c411f2363 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -7,13 +7,10 @@ use BookStack\Auth\Access\SocialAuthService; use BookStack\Auth\SocialAccount; use BookStack\Auth\User; use BookStack\Auth\UserRepo; -use BookStack\Exceptions\ConfirmationEmailException; use BookStack\Exceptions\SocialDriverNotConfigured; use BookStack\Exceptions\SocialSignInAccountNotUsed; use BookStack\Exceptions\SocialSignInException; use BookStack\Exceptions\UserRegistrationException; -use BookStack\Exceptions\UserTokenExpiredException; -use BookStack\Exceptions\UserTokenNotFoundException; use BookStack\Http\Controllers\Controller; use Exception; use Illuminate\Foundation\Auth\RegistersUsers; @@ -21,7 +18,6 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Routing\Redirector; -use Illuminate\View\View; use Laravel\Socialite\Contracts\User as SocialUser; use Validator; @@ -56,7 +52,7 @@ class RegisterController extends Controller * Create a new controller instance. * * @param SocialAuthService $socialAuthService - * @param \BookStack\Auth\EmailConfirmationService $emailConfirmationService + * @param EmailConfirmationService $emailConfirmationService * @param UserRepo $userRepo */ public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo) @@ -162,7 +158,7 @@ class RegisterController extends Controller $newUser->socialAccounts()->save($socialAccount); } - if ((setting('registration-confirmation') || $registrationRestrict) && !$emailVerified) { + if ($this->emailConfirmationService->confirmationRequired() && !$emailVerified) { $newUser->save(); try { @@ -179,87 +175,6 @@ class RegisterController extends Controller return redirect($this->redirectPath()); } - /** - * Show the page to tell the user to check their email - * and confirm their address. - */ - public function getRegisterConfirmation() - { - return view('auth.register-confirm'); - } - - /** - * Confirms an email via a token and logs the user into the system. - * @param $token - * @return RedirectResponse|Redirector - * @throws ConfirmationEmailException - * @throws Exception - */ - public function confirmEmail($token) - { - try { - $userId = $this->emailConfirmationService->checkTokenAndGetUserId($token); - } catch (Exception $exception) { - - if ($exception instanceof UserTokenNotFoundException) { - session()->flash('error', trans('errors.email_confirmation_invalid')); - return redirect('/register'); - } - - if ($exception instanceof UserTokenExpiredException) { - $user = $this->userRepo->getById($exception->userId); - $this->emailConfirmationService->sendConfirmation($user); - session()->flash('error', trans('errors.email_confirmation_expired')); - return redirect('/register/confirm'); - } - - throw $exception; - } - - $user = $this->userRepo->getById($userId); - $user->email_confirmed = true; - $user->save(); - - auth()->login($user); - session()->flash('success', trans('auth.email_confirm_success')); - $this->emailConfirmationService->deleteByUser($user); - - return redirect($this->redirectPath); - } - - /** - * 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 showAwaitingConfirmation() - { - return view('auth.user-unconfirmed'); - } - - /** - * Resend the confirmation email - * @param Request $request - * @return View - */ - public function resendConfirmation(Request $request) - { - $this->validate($request, [ - 'email' => 'required|email|exists:users,email' - ]); - $user = $this->userRepo->getByEmail($request->get('email')); - - try { - $this->emailConfirmationService->sendConfirmation($user); - } catch (Exception $e) { - session()->flash('error', trans('auth.email_confirm_send_error')); - return redirect('/register/confirm'); - } - - session()->flash('success', trans('auth.email_confirm_resent')); - return redirect('/register/confirm'); - } - /** * Redirect to the social site for authentication intended to register. * @param $socialDriver diff --git a/routes/web.php b/routes/web.php index 11ca5d1af..2530a3cb6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -211,10 +211,10 @@ Route::get('/login', 'Auth\LoginController@getLogin'); Route::post('/login', 'Auth\LoginController@login'); Route::get('/logout', 'Auth\LoginController@logout'); Route::get('/register', 'Auth\RegisterController@getRegister'); -Route::get('/register/confirm', 'Auth\RegisterController@getRegisterConfirmation'); -Route::get('/register/confirm/awaiting', 'Auth\RegisterController@showAwaitingConfirmation'); -Route::post('/register/confirm/resend', 'Auth\RegisterController@resendConfirmation'); -Route::get('/register/confirm/{token}', 'Auth\RegisterController@confirmEmail'); +Route::get('/register/confirm', 'Auth\ConfirmEmailController@show'); +Route::get('/register/confirm/awaiting', 'Auth\ConfirmEmailController@showAwaiting'); +Route::post('/register/confirm/resend', 'Auth\ConfirmEmailController@resend'); +Route::get('/register/confirm/{token}', 'Auth\ConfirmEmailController@confirm'); Route::post('/register', 'Auth\RegisterController@postRegister'); // Password reset link request routes...