Add more events for authentication

This commit is contained in:
Pig Fang 2019-12-24 17:09:30 +08:00
parent 0195b0fbd0
commit 2b827cf651
3 changed files with 273 additions and 93 deletions

View File

@ -11,6 +11,7 @@ use App\Rules;
use Auth; use Auth;
use Cache; use Cache;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite; use Laravel\Socialite\Facades\Socialite;
use Mail; use Mail;
@ -31,25 +32,29 @@ class AuthController extends Controller
]); ]);
} }
public function handleLogin(Request $request, Rules\Captcha $captcha) public function handleLogin(
{ Request $request,
Rules\Captcha $captcha,
Dispatcher $dispatcher
) {
$this->validate($request, [ $this->validate($request, [
'identification' => 'required', 'identification' => 'required',
'password' => 'required|min:6|max:32', 'password' => 'required|min:6|max:32',
]); ]);
$identification = $request->input('identification'); $identification = $request->input('identification');
$password = $request->input('password');
// Guess type of identification // Guess type of identification
$authType = filter_var($identification, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; $authType = filter_var($identification, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
$dispatcher->dispatch('auth.login.attempt', [$identification, $password, $authType]);
event(new Events\UserTryToLogin($identification, $authType)); event(new Events\UserTryToLogin($identification, $authType));
if ($authType == 'email') { if ($authType == 'email') {
$user = User::where('email', $identification)->first(); $user = User::where('email', $identification)->first();
} else { } else {
$player = Player::where('name', $identification)->first(); $player = Player::where('name', $identification)->first();
$user = $player ? $player->user : null; $user = optional($player)->user;
} }
// Require CAPTCHA if user fails to login more than 3 times // Require CAPTCHA if user fails to login more than 3 times
@ -62,39 +67,42 @@ class AuthController extends Controller
if (!$user) { if (!$user) {
return json(trans('auth.validation.user'), 2); return json(trans('auth.validation.user'), 2);
}
$dispatcher->dispatch('auth.login.ready', [$user]);
if ($user->verifyPassword($request->input('password'))) {
Session::forget('login_fails');
Cache::forget($loginFailsCacheKey);
Auth::login($user, $request->input('keep'));
$dispatcher->dispatch('auth.login.succeeded', [$user]);
event(new Events\UserLoggedIn($user));
return json(trans('auth.login.success'), 0, [
'redirectTo' => $request->session()->pull('last_requested_path', url('/user')),
]);
} else { } else {
if ($user->verifyPassword($request->input('password'))) { $loginFails++;
Session::forget('login_fails'); Cache::put($loginFailsCacheKey, $loginFails, 3600);
$dispatcher->dispatch('auth.login.failed', [$user, $loginFails]);
Auth::login($user, $request->input('keep')); return json(trans('auth.validation.password'), 1, [
'login_fails' => $loginFails,
event(new Events\UserLoggedIn($user)); ]);
Cache::forget($loginFailsCacheKey);
return json(trans('auth.login.success'), 0, [
'redirectTo' => $request->session()->pull('last_requested_path', url('/user')),
]);
} else {
// Increase the counter
Cache::put($loginFailsCacheKey, ++$loginFails, 3600);
return json(trans('auth.validation.password'), 1, [
'login_fails' => $loginFails,
]);
}
} }
} }
public function logout() public function logout(Dispatcher $dispatcher)
{ {
if (Auth::check()) { $user = Auth::user();
Auth::logout();
return json(trans('auth.logout.success'), 0); $dispatcher->dispatch('auth.logout.before', [$user]);
} else { Auth::logout();
return json(trans('auth.logout.fail'), 1); $dispatcher->dispatch('auth.logout.after', [$user]);
}
return json(trans('auth.logout.success'), 0);
} }
public function register() public function register()
@ -113,8 +121,11 @@ class AuthController extends Controller
} }
} }
public function handleRegister(Request $request, Rules\Captcha $captcha) public function handleRegister(
{ Request $request,
Rules\Captcha $captcha,
Dispatcher $dispatcher
) {
if (!option('user_can_register')) { if (!option('user_can_register')) {
return json(trans('auth.register.close'), 7); return json(trans('auth.register.close'), 7);
} }
@ -133,6 +144,8 @@ class AuthController extends Controller
'captcha' => ['required', $captcha], 'captcha' => ['required', $captcha],
], $rule)); ], $rule));
$dispatcher->dispatch('auth.registration.attempt', [$data]);
if (option('register_with_player_name')) { if (option('register_with_player_name')) {
event(new Events\CheckPlayerExists($request->get('player_name'))); event(new Events\CheckPlayerExists($request->get('player_name')));
@ -147,6 +160,8 @@ class AuthController extends Controller
return json(trans('auth.register.max', ['regs' => option('regs_per_ip')]), 7); return json(trans('auth.register.max', ['regs' => option('regs_per_ip')]), 7);
} }
$dispatcher->dispatch('auth.registration.ready', [$data]);
$user = new User(); $user = new User();
$user->email = $data['email']; $user->email = $data['email'];
$user->nickname = $data[option('register_with_player_name') ? 'player_name' : 'nickname']; $user->nickname = $data[option('register_with_player_name') ? 'player_name' : 'nickname'];
@ -161,6 +176,7 @@ class AuthController extends Controller
$user->save(); $user->save();
$dispatcher->dispatch('auth.registration.completed', [$user]);
event(new Events\UserRegistered($user)); event(new Events\UserRegistered($user));
if (option('register_with_player_name')) { if (option('register_with_player_name')) {
@ -173,7 +189,9 @@ class AuthController extends Controller
event(new Events\PlayerWasAdded($player)); event(new Events\PlayerWasAdded($player));
} }
$dispatcher->dispatch('auth.login.ready', [$user]);
Auth::login($user); Auth::login($user);
$dispatcher->dispatch('auth.login.succeeded', [$user]);
return json(trans('auth.register.success'), 0); return json(trans('auth.register.success'), 0);
} }
@ -192,9 +210,13 @@ class AuthController extends Controller
} }
} }
public function handleForgot(Request $request, Rules\Captcha $captcha) public function handleForgot(
{ Request $request,
$this->validate($request, [ Rules\Captcha $captcha,
Dispatcher $dispatcher
) {
$data = $this->validate($request, [
'email' => 'required|email',
'captcha' => ['required', $captcha], 'captcha' => ['required', $captcha],
]); ]);
@ -202,31 +224,35 @@ class AuthController extends Controller
return json(trans('auth.forgot.disabled'), 1); return json(trans('auth.forgot.disabled'), 1);
} }
$email = $data['email'];
$dispatcher->dispatch('auth.forgot.attempt', [$email]);
$rateLimit = 180; $rateLimit = 180;
$lastMailCacheKey = sha1('last_mail_'.get_client_ip()); $lastMailCacheKey = sha1('last_mail_'.get_client_ip());
$remain = $rateLimit + Cache::get($lastMailCacheKey, 0) - time(); $remain = $rateLimit + Cache::get($lastMailCacheKey, 0) - time();
// Rate limit
if ($remain > 0) { if ($remain > 0) {
return json(trans('auth.forgot.frequent-mail'), 2); return json(trans('auth.forgot.frequent-mail'), 2);
} }
$user = User::where('email', $request->email)->first(); $user = User::where('email', $email)->first();
if (!$user) { if (!$user) {
return json(trans('auth.forgot.unregistered'), 1); return json(trans('auth.forgot.unregistered'), 1);
} }
$url = URL::temporarySignedRoute('auth.reset', now()->addHour(), ['uid' => $user->uid]); $dispatcher->dispatch('auth.forgot.ready', [$user]);
$url = URL::temporarySignedRoute('auth.reset', now()->addHour(), ['uid' => $user->uid]);
try { try {
Mail::to($request->input('email'))->send(new ForgotPassword($url)); Mail::to($email)->send(new ForgotPassword($url));
} catch (\Exception $e) { } catch (\Exception $e) {
report($e); report($e);
$dispatcher->dispatch('auth.forgot.failed', [$user, $url]);
return json(trans('auth.forgot.failed', ['msg' => $e->getMessage()]), 2); return json(trans('auth.forgot.failed', ['msg' => $e->getMessage()]), 2);
} }
$dispatcher->dispatch('auth.forgot.sent', [$user, $url]);
Cache::put($lastMailCacheKey, time(), 3600); Cache::put($lastMailCacheKey, time(), 3600);
return json(trans('auth.forgot.success'), 0); return json(trans('auth.forgot.success'), 0);
@ -237,13 +263,16 @@ class AuthController extends Controller
return view('auth.reset')->with('user', User::find($uid)); return view('auth.reset')->with('user', User::find($uid));
} }
public function handleReset(Request $request, $uid) public function handleReset(Dispatcher $dispatcher, Request $request, $uid)
{ {
$validated = $this->validate($request, [ ['password' => $password] = $this->validate($request, [
'password' => 'required|min:8|max:32', 'password' => 'required|min:8|max:32',
]); ]);
$user = User::find($uid);
User::find($uid)->changePassword($validated['password']); $dispatcher->dispatch('auth.reset.before', [$user, $password]);
$user->changePassword($password);
$dispatcher->dispatch('auth.reset.after', [$user, $password]);
return json(trans('auth.reset.success'), 0); return json(trans('auth.reset.success'), 0);
} }
@ -314,7 +343,7 @@ class AuthController extends Controller
return Socialite::driver($driver)->redirect(); return Socialite::driver($driver)->redirect();
} }
public function oauthCallback($driver) public function oauthCallback(Dispatcher $dispatcher, $driver)
{ {
$remoteUser = Socialite::driver($driver)->user(); $remoteUser = Socialite::driver($driver)->user();
@ -324,11 +353,7 @@ class AuthController extends Controller
} }
$user = User::where('email', $email)->first(); $user = User::where('email', $email)->first();
if ($user) { if (!$user) {
event(new Events\UserLoggedIn($user));
Auth::login($user);
} else {
$user = new User(); $user = new User();
$user->email = $email; $user->email = $email;
$user->nickname = $remoteUser->nickname ?? $remoteUser->name ?? $email; $user->nickname = $remoteUser->nickname ?? $remoteUser->name ?? $email;
@ -342,11 +367,13 @@ class AuthController extends Controller
$user->verified = true; $user->verified = true;
$user->save(); $user->save();
event(new Events\UserRegistered($user)); $dispatcher->dispatch('auth.registration.completed', [$user]);
Auth::login($user);
} }
$dispatcher->dispatch('auth.login.ready', [$user]);
Auth::login($user);
$dispatcher->dispatch('auth.login.succeeded', [$user]);
return redirect('/user'); return redirect('/user');
} }
} }

View File

@ -32,7 +32,7 @@ Route::group(['prefix' => 'auth'], function () {
Route::get('/login/{driver}/callback', 'AuthController@oauthCallback'); Route::get('/login/{driver}/callback', 'AuthController@oauthCallback');
}); });
Route::any('/logout', 'AuthController@logout'); Route::post('/logout', 'AuthController@logout')->middleware('authorize');
Route::any('/captcha', 'AuthController@captcha'); Route::any('/captcha', 'AuthController@captcha');
Route::post('/login', 'AuthController@handleLogin'); Route::post('/login', 'AuthController@handleLogin');

View File

@ -75,6 +75,28 @@ class AuthControllerTest extends TestCase
$this->flushSession(); $this->flushSession();
// Should return a warning if user isn't existed
$this->postJson(
'/auth/login', [
'identification' => 'nope@nope.net',
'password' => '12345678',
])->assertJson([
'code' => 2,
'message' => trans('auth.validation.user'),
]);
Event::assertDispatched('auth.login.attempt', function ($event, $payload) use ($user) {
$this->assertEquals('nope@nope.net', $payload[0]);
$this->assertEquals('12345678', $payload[1]);
$this->assertEquals('email', $payload[2]);
return true;
});
Event::assertNotDispatched('auth.login.ready');
Event::assertNotDispatched('auth.login.succeeded');
Event::assertNotDispatched('auth.login.failed');
$this->flushSession();
Event::fake();
$loginFailsCacheKey = sha1('login_fails_'.get_client_ip()); $loginFailsCacheKey = sha1('login_fails_'.get_client_ip());
// Logging in should be failed if password is wrong // Logging in should be failed if password is wrong
@ -90,6 +112,24 @@ class AuthControllerTest extends TestCase
] ]
); );
$this->assertTrue(Cache::has($loginFailsCacheKey)); $this->assertTrue(Cache::has($loginFailsCacheKey));
Event::assertDispatched('auth.login.attempt', function ($event, $payload) use ($user) {
$this->assertEquals($user->email, $payload[0]);
$this->assertEquals('wrong-password', $payload[1]);
$this->assertEquals('email', $payload[2]);
return true;
});
Event::assertDispatched('auth.login.ready', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
return true;
});
Event::assertDispatched('auth.login.failed', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
$this->assertEquals(1, $payload[1]);
return true;
});
$this->flushSession(); $this->flushSession();
@ -104,18 +144,6 @@ class AuthControllerTest extends TestCase
Cache::flush(); Cache::flush();
$this->flushSession(); $this->flushSession();
// Should return a warning if user isn't existed
$this->postJson(
'/auth/login', [
'identification' => 'nope@nope.net',
'password' => '12345678',
])->assertJson([
'code' => 2,
'message' => trans('auth.validation.user'),
]);
$this->flushSession();
// Should clean the `login_fails` session if logged in successfully // Should clean the `login_fails` session if logged in successfully
Cache::put($loginFailsCacheKey, 1); Cache::put($loginFailsCacheKey, 1);
$this->postJson('/auth/login', [ $this->postJson('/auth/login', [
@ -128,6 +156,16 @@ class AuthControllerTest extends TestCase
] ]
); );
$this->assertFalse(Cache::has($loginFailsCacheKey)); $this->assertFalse(Cache::has($loginFailsCacheKey));
Event::assertDispatched('auth.login.ready', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
return true;
});
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
return true;
});
Event::assertDispatched(Events\UserTryToLogin::class); Event::assertDispatched(Events\UserTryToLogin::class);
Event::assertDispatched(Events\UserLoggedIn::class); Event::assertDispatched(Events\UserLoggedIn::class);
@ -152,11 +190,7 @@ class AuthControllerTest extends TestCase
public function testLogout() public function testLogout()
{ {
$this->postJson('/auth/logout') Event::fake();
->assertJson([
'code' => 1,
'message' => trans('auth.logout.fail'),
]);
$user = factory(User::class)->create(); $user = factory(User::class)->create();
$this->actingAs($user)->postJson('/auth/logout')->assertJson( $this->actingAs($user)->postJson('/auth/logout')->assertJson(
@ -166,6 +200,16 @@ class AuthControllerTest extends TestCase
] ]
); );
$this->assertGuest(); $this->assertGuest();
Event::assertDispatched('auth.logout.before', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
return true;
});
Event::assertDispatched('auth.logout.after', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
return true;
});
} }
public function testRegister() public function testRegister()
@ -269,6 +313,15 @@ class AuthControllerTest extends TestCase
'message' => trans('user.player.add.repeated'), 'message' => trans('user.player.add.repeated'),
]); ]);
$this->assertNull(User::where('email', 'a@b.c')->first()); $this->assertNull(User::where('email', 'a@b.c')->first());
Event::assertDispatched('auth.registration.attempt', function ($event, $payload) {
[$data] = $payload;
$this->assertEquals('a@b.c', $data['email']);
$this->assertEquals('12345678', $data['password']);
return true;
});
Event::assertNotDispatched('auth.registration.ready');
Event::assertNotDispatched('auth.registration.completed');
option(['register_with_player_name' => false]); option(['register_with_player_name' => false]);
@ -318,11 +371,7 @@ class AuthControllerTest extends TestCase
'message' => trans('auth.register.close'), 'message' => trans('auth.register.close'),
]); ]);
// Reopen for test option(['user_can_register' => true, 'regs_per_ip' => -1]);
Option::set('user_can_register', true);
// Should be forbidden if registering's count current IP is over
Option::set('regs_per_ip', -1);
$this->postJson( $this->postJson(
'/auth/register', '/auth/register',
[ [
@ -362,7 +411,40 @@ class AuthControllerTest extends TestCase
'permission' => User::NORMAL, 'permission' => User::NORMAL,
]); ]);
$this->assertAuthenticated(); $this->assertAuthenticated();
Event::assertDispatched('auth.registration.attempt', function ($event, $payload) {
[$data] = $payload;
$this->assertEquals('a@b.c', $data['email']);
$this->assertEquals('12345678', $data['password']);
return true;
});
Event::assertDispatched('auth.registration.ready', function ($event, $payload) {
[$data] = $payload;
$this->assertEquals('a@b.c', $data['email']);
$this->assertEquals('12345678', $data['password']);
return true;
});
Event::assertDispatched('auth.registration.completed', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
$this->assertGreaterThan(0, $user->uid);
return true;
});
Event::assertDispatched(Events\UserRegistered::class); Event::assertDispatched(Events\UserRegistered::class);
Event::assertDispatched('auth.login.ready', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
// Require player name // Require player name
option(['register_with_player_name' => true]); option(['register_with_player_name' => true]);
@ -388,11 +470,13 @@ class AuthControllerTest extends TestCase
public function testHandleForgot() public function testHandleForgot()
{ {
Event::fake();
Mail::fake(); Mail::fake();
// Should be forbidden if "forgot password" is closed // Should be forbidden if "forgot password" is closed
config(['mail.driver' => '']); config(['mail.driver' => '']);
$this->postJson('/auth/forgot', [ $this->postJson('/auth/forgot', [
'email' => 'nope@nope.net',
'captcha' => 'a', 'captcha' => 'a',
])->assertJson([ ])->assertJson([
'code' => 1, 'code' => 1,
@ -405,11 +489,20 @@ class AuthControllerTest extends TestCase
// Should be forbidden if sending email frequently // Should be forbidden if sending email frequently
Cache::put($lastMailCacheKey, time()); Cache::put($lastMailCacheKey, time());
$this->postJson('/auth/forgot', [ $this->postJson('/auth/forgot', [
'email' => 'nope@nope.net',
'captcha' => 'a', 'captcha' => 'a',
])->assertJson([ ])->assertJson([
'code' => 2, 'code' => 2,
'message' => trans('auth.forgot.frequent-mail'), 'message' => trans('auth.forgot.frequent-mail'),
]); ]);
Event::assertDispatched('auth.forgot.attempt', function ($event, $payload) {
$this->assertEquals('nope@nope.net', $payload[0]);
return true;
});
Event::assertNotDispatched('auth.forgot.ready');
Event::assertNotDispatched('auth.forgot.sent');
Event::assertNotDispatched('auth.forgot.sent');
Cache::flush(); Cache::flush();
$this->flushSession(); $this->flushSession();
@ -423,6 +516,7 @@ class AuthControllerTest extends TestCase
'message' => trans('auth.forgot.unregistered'), 'message' => trans('auth.forgot.unregistered'),
]); ]);
Event::fake();
$this->postJson('/auth/forgot', [ $this->postJson('/auth/forgot', [
'email' => $user->email, 'email' => $user->email,
'captcha' => 'a', 'captcha' => 'a',
@ -432,11 +526,28 @@ class AuthControllerTest extends TestCase
]); ]);
$this->assertTrue(Cache::has($lastMailCacheKey)); $this->assertTrue(Cache::has($lastMailCacheKey));
Cache::flush(); Cache::flush();
Event::assertDispatched('auth.forgot.attempt', function ($event, $payload) use ($user) {
$this->assertEquals($user->email, $payload[0]);
return true;
});
Event::assertDispatched('auth.forgot.ready', function ($event, $payload) use ($user) {
$this->assertEquals($user->email, $payload[0]->email);
return true;
});
Mail::assertSent(ForgotPassword::class, function ($mail) use ($user) { Mail::assertSent(ForgotPassword::class, function ($mail) use ($user) {
return $mail->hasTo($user->email); return $mail->hasTo($user->email);
}); });
Event::assertDispatched('auth.forgot.sent', function ($event, $payload) use ($user) {
$this->assertEquals($user->email, $payload[0]->email);
$this->assertStringContainsString('auth/reset/'.$user->uid, $payload[1]);
return true;
});
// Should handle exception when sending email // Should handle exception when sending email
Event::fake();
Mail::shouldReceive('to') Mail::shouldReceive('to')
->once() ->once()
->andThrow(new \Mockery\Exception('A fake exception.')); ->andThrow(new \Mockery\Exception('A fake exception.'));
@ -449,6 +560,13 @@ class AuthControllerTest extends TestCase
'code' => 2, 'code' => 2,
'message' => trans('auth.forgot.failed', ['msg' => 'A fake exception.']), 'message' => trans('auth.forgot.failed', ['msg' => 'A fake exception.']),
]); ]);
Event::assertNotDispatched('auth.forgot.sent');
Event::assertDispatched('auth.forgot.failed', function ($event, $payload) use ($user) {
$this->assertEquals($user->email, $payload[0]->email);
$this->assertStringContainsString('auth/reset/'.$user->uid, $payload[1]);
return true;
});
// Addition: Mailable test // Addition: Mailable test
$site_name = option_localized('site_name'); $site_name = option_localized('site_name');
@ -470,6 +588,8 @@ class AuthControllerTest extends TestCase
public function testHandleReset() public function testHandleReset()
{ {
Event::fake();
$user = factory(User::class)->create(); $user = factory(User::class)->create();
$url = URL::temporarySignedRoute('auth.reset', now()->addHour(), ['uid' => $user->uid]); $url = URL::temporarySignedRoute('auth.reset', now()->addHour(), ['uid' => $user->uid]);
@ -477,30 +597,32 @@ class AuthControllerTest extends TestCase
$this->postJson($url)->assertJsonValidationErrors('password'); $this->postJson($url)->assertJsonValidationErrors('password');
// Should return a warning if `password` is too short // Should return a warning if `password` is too short
$this->postJson( $this->postJson($url, ['password' => '123'])
$url, [ ->assertJsonValidationErrors('password');
'password' => '123',
])->assertJsonValidationErrors('password');
// Should return a warning if `password` is too long // Should return a warning if `password` is too long
$this->postJson( $this->postJson($url, ['password' => Str::random(33)])
$url, [ ->assertJsonValidationErrors('password');
'password' => Str::random(33),
])->assertJsonValidationErrors('password');
// Success // Success
$this->postJson( $this->postJson($url, ['password' => '12345678'])->assertJson([
$url, [
'password' => '12345678',
])->assertJson([
'code' => 0, 'code' => 0,
'message' => trans('auth.reset.success'), 'message' => trans('auth.reset.success'),
]); ]);
// We must re-query the user model, $user->refresh();
// because the old instance hasn't been changed
// after resetting password.
$user = User::find($user->uid);
$this->assertTrue($user->verifyPassword('12345678')); $this->assertTrue($user->verifyPassword('12345678'));
Event::assertDispatched('auth.reset.before', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
$this->assertEquals('12345678', $payload[1]);
return true;
});
Event::assertDispatched('auth.reset.after', function ($event, $payload) use ($user) {
$this->assertEquals($user->uid, $payload[0]->uid);
$this->assertEquals('12345678', $payload[1]);
return true;
});
} }
public function testCaptcha() public function testCaptcha()
@ -664,14 +786,45 @@ class AuthControllerTest extends TestCase
'permission' => User::NORMAL, 'permission' => User::NORMAL,
'verified' => true, 'verified' => true,
]); ]);
Event::assertDispatched(Events\UserRegistered::class);
$this->assertAuthenticated(); $this->assertAuthenticated();
Event::assertDispatched('auth.registration.completed', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
$this->assertEquals(1, $user->uid);
return true;
});
Event::assertDispatched('auth.login.ready', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
auth()->logout(); auth()->logout();
$this->assertGuest(); $this->assertGuest();
Event::fake();
$this->get('/auth/login/github/callback')->assertRedirect('/user'); $this->get('/auth/login/github/callback')->assertRedirect('/user');
Event::assertDispatched(Events\UserLoggedIn::class);
$this->assertAuthenticated(); $this->assertAuthenticated();
Event::assertNotDispatched('auth.registration.completed');
Event::assertDispatched('auth.login.ready', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
Event::assertDispatched('auth.login.succeeded', function ($event, $payload) {
[$user] = $payload;
$this->assertEquals('a@b.c', $user->email);
return true;
});
} }
} }