diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index c63cfc84..028caa81 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -344,7 +344,7 @@ class AuthController extends Controller return redirect('/user'); } - public function verify(Request $request, $uid) + public function verify(Request $request) { if (!option('require_verification')) { throw new PrettyPageException(trans('user.verification.disabled'), 1); @@ -352,15 +352,23 @@ class AuthController extends Controller abort_unless($request->hasValidSignature(false), 403, trans('auth.verify.invalid')); - $user = User::find($uid); - if (!$user || $user->verified) { - throw new PrettyPageException(trans('auth.verify.invalid'), 1); + return view('auth.verify'); + } + + public function handleVerify(Request $request, User $user) + { + abort_unless($request->hasValidSignature(false), 403, trans('auth.verify.invalid')); + + ['email' => $email] = $request->validate(['email' => 'required|email']); + + if ($user->email !== $email) { + return back()->with('errorMessage', trans('auth.verify.not-matched')); } $user->verified = true; $user->save(); - return view('auth.verify', ['site_name' => option_localized('site_name')]); + return redirect()->route('user.home'); } public function jwtLogin(Request $request) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 74aa154f..0a48fe46 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -157,7 +157,7 @@ class UserController extends Controller return json(trans('user.verification.verified'), 1); } - $url = URL::signedRoute('auth.verify', ['uid' => $user->uid], null, false); + $url = URL::signedRoute('auth.verify', ['user' => $user], null, false); try { Mail::to($user->email)->send(new EmailVerification(url($url))); diff --git a/app/Listeners/SendEmailVerification.php b/app/Listeners/SendEmailVerification.php index 577c2700..097fd169 100644 --- a/app/Listeners/SendEmailVerification.php +++ b/app/Listeners/SendEmailVerification.php @@ -12,7 +12,7 @@ class SendEmailVerification public function handle(User $user) { if (option('require_verification')) { - $url = URL::signedRoute('auth.verify', ['uid' => $user->uid], null, false); + $url = URL::signedRoute('auth.verify', ['user' => $user->uid], null, false); try { Mail::to($user->email)->send(new EmailVerification(url($url))); diff --git a/resources/lang/en/auth.yml b/resources/lang/en/auth.yml index ce7d8383..71260b4e 100644 --- a/resources/lang/en/auth.yml +++ b/resources/lang/en/auth.yml @@ -49,10 +49,8 @@ bind: verify: title: Email Verification - success: Your account was now verified. - message: Welcome to :sitename! - button: Homepage invalid: Invalid link. + not-matched: Email doesn't match. validation: user: No such user. diff --git a/resources/views/auth/verify.twig b/resources/views/auth/verify.twig index 7c41d9ff..c7af493f 100644 --- a/resources/views/auth/verify.twig +++ b/resources/views/auth/verify.twig @@ -4,12 +4,31 @@ {% block content %}

- {{ trans('auth.verify.message', {sitename: site_name}) }} + {{ trans('auth.bind.message') }}

-
- {{ trans('auth.verify.success') }} -
- - {{ trans('auth.verify.button') }} - +
+ {{ csrf_field() }} +
+ +
+
+ +
+
+
+ {% if errors.any %} +
+ + {{ errors.first }} +
+ {% elseif session_has('errorMessage') %} +
+ + {{ session_pull('errorMessage') }} +
+ {% endif %} + +
{% endblock %} diff --git a/routes/web.php b/routes/web.php index 4d4be08d..58d4e791 100644 --- a/routes/web.php +++ b/routes/web.php @@ -39,7 +39,8 @@ Route::prefix('auth')->name('auth.')->group(function () { Route::post('bind', 'AuthController@fillEmail'); }); - Route::get('verify/{uid}', 'AuthController@verify')->name('verify'); + Route::get('verify/{user}', 'AuthController@verify')->name('verify'); + Route::post('verify/{user}', 'AuthController@handleVerify'); }); Route::prefix('user') diff --git a/tests/HttpTest/ControllersTest/AuthControllerTest.php b/tests/HttpTest/ControllersTest/AuthControllerTest.php index 614f9896..d6b18a86 100644 --- a/tests/HttpTest/ControllersTest/AuthControllerTest.php +++ b/tests/HttpTest/ControllersTest/AuthControllerTest.php @@ -724,27 +724,39 @@ class AuthControllerTest extends TestCase public function testVerify() { - $url = URL::signedRoute('auth.verify', ['uid' => 1], null, false); + $url = URL::signedRoute('auth.verify', ['user' => 1], null, false); - // Should be forbidden if account verification is disabled + // should be forbidden if account verification is disabled option(['require_verification' => false]); $this->get($url)->assertSee(trans('user.verification.disabled')); option(['require_verification' => true]); - // Invalid link - $this->get(route('auth.verify', ['uid' => 1]))->assertForbidden(); - - // Non-existed user - $this->get($url)->assertSee(trans('auth.verify.invalid')); - - $user = factory(User::class)->create(); - $url = URL::signedRoute('auth.verify', ['uid' => $user->uid], null, false); - $this->get($url)->assertSee(trans('auth.verify.invalid')); + // invalid link + $this->get(route('auth.verify', ['user' => 1]))->assertForbidden(); $user = factory(User::class)->create(['verified' => false]); - $url = URL::signedRoute('auth.verify', ['uid' => $user->uid], null, false); + $url = URL::signedRoute('auth.verify', ['user' => $user], null, false); $this->get($url)->assertViewIs('auth.verify'); - $this->assertEquals(1, User::find($user->uid)->verified); + } + + public function testHandleVerify() + { + $user = factory(User::class)->create(['verified' => false]); + $url = URL::signedRoute('auth.verify', ['user' => $user], null, false); + + // empty email + $this->post($url, [], ['Referer' => $url])->assertRedirect($url); + + // not an email + $this->post($url, ['email' => 't'], ['Referer' => $url])->assertRedirect($url); + + // invalid email + $this->post($url, ['email' => 'a@b.c'], ['Referer' => $url]) + ->assertRedirect($url); + + // success + $this->post($url, ['email' => $user->email], ['Referer' => $url]) + ->assertRedirect(route('user.home')); } public function testApiLogin()