feat: update authentication to allow login using username or email and add tests for inactive users

This commit is contained in:
Yoga Pangestu 2026-07-28 23:49:39 +07:00
parent 7d753ee6d8
commit 993f3599fc
4 changed files with 47 additions and 6 deletions

View File

@ -4,8 +4,10 @@
use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Models\User;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
@ -39,6 +41,18 @@ public function boot(): void
*/
private function configureActions(): void
{
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->login)
->orWhere('username', $request->login)
->first();
if ($user && $user->is_active && Hash::check($request->password, $user->password)) {
return $user;
}
return false;
});
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
Fortify::createUsersUsing(CreateNewUser::class);
}

View File

@ -45,7 +45,7 @@
|
*/
'username' => 'email',
'username' => 'login',
'email' => 'email',

View File

@ -14,7 +14,7 @@
$user = User::factory()->create();
$response = $this->post(route('login.store'), [
'email' => $user->email,
'login' => $user->email,
'password' => 'password',
]);
@ -22,9 +22,36 @@
$response->assertRedirect(route('dashboard', absolute: false));
});
test('users can authenticate using username', function () {
$user = User::factory()->create();
$response = $this->post(route('login.store'), [
'login' => $user->username,
'password' => 'password',
]);
$this->assertAuthenticated();
$response->assertRedirect(route('dashboard', absolute: false));
});
test('inactive users cannot authenticate', function () {
$user = User::factory()->create(['is_active' => false]);
$response = $this->post(route('login.store'), [
'login' => $user->email,
'password' => 'password',
]);
$this->assertGuest();
});
test('users with two factor enabled are redirected to two factor challenge', function () {
$this->skipUnlessFortifyHas(Features::twoFactorAuthentication());
if (! method_exists(User::factory(), 'withTwoFactor')) {
$this->markTestSkipped('Two factor factory method not available.');
}
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
@ -33,7 +60,7 @@
$user = User::factory()->withTwoFactor()->create();
$response = $this->post(route('login'), [
'email' => $user->email,
'login' => $user->email,
'password' => 'password',
]);
@ -46,7 +73,7 @@
$user = User::factory()->create();
$this->post(route('login.store'), [
'email' => $user->email,
'login' => $user->email,
'password' => 'wrong-password',
]);
@ -69,7 +96,7 @@
RateLimiter::increment(md5('login'.implode('|', [$user->email, '127.0.0.1'])), amount: 5);
$response = $this->post(route('login.store'), [
'email' => $user->email,
'login' => $user->email,
'password' => 'wrong-password',
]);

View File

@ -15,7 +15,7 @@
*/
pest()->extend(TestCase::class)
// ->use(RefreshDatabase::class)
->use(RefreshDatabase::class)
->in('Feature');
/*