Skip to content

Allow login and registration with capitalized emails #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion resources/views/livewire/auth/forgot-password.blade.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Livewire\Attributes\Layout;
use Livewire\Volt\Component;

Expand All @@ -15,7 +16,7 @@ public function sendPasswordResetLink(): void
$this->validate([
'email' => ['required', 'string', 'email'],
]);

$this->email = Str::lower($this->email);
Password::sendResetLink($this->only('email'));

session()->flash('status', __('A reset link will be sent if the account exists.'));
Expand Down
2 changes: 1 addition & 1 deletion resources/views/livewire/auth/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function login(): void

$this->ensureIsNotRateLimited();

if (! Auth::attempt(['email' => $this->email, 'password' => $this->password], $this->remember)) {
if (! Auth::attempt(['email' => Str::lower($this->email), 'password' => $this->password], $this->remember)) {
RateLimiter::hit($this->throttleKey());

throw ValidationException::withMessages([
Expand Down
4 changes: 3 additions & 1 deletion resources/views/livewire/auth/register.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Livewire\Attributes\Layout;
use Livewire\Volt\Component;
Expand All @@ -21,10 +22,11 @@ public function register(): void
{
$validated = $this->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:' . User::class],
'email' => ['required', 'string', 'email', 'max:255', 'unique:' . User::class],
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
]);

$validated['email'] = Str::lower($validated['email']);
$validated['password'] = Hash::make($validated['password']);

event(new Registered(($user = User::create($validated))));
Expand Down
3 changes: 2 additions & 1 deletion resources/views/livewire/auth/reset-password.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function mount(string $token): void
{
$this->token = $token;

$this->email = request()->string('email');
$this->email = Str::lower(request()->string('email'));
}

/**
Expand All @@ -37,6 +37,7 @@ public function resetPassword(): void
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
]);
$this->email = Str::lower($this->email);

// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
Expand Down
21 changes: 21 additions & 0 deletions tests/Feature/Auth/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Livewire\Volt\Volt as LivewireVolt;
use Tests\TestCase;

Expand Down Expand Up @@ -48,6 +49,26 @@ public function test_users_can_not_authenticate_with_invalid_password(): void
$this->assertGuest();
}

public function test_user_can_authenticate_with_uppercase_email(): void
{
$user = User::factory()->create([
'email' => '[email protected]',
'password' => bcrypt('password'),
]);

$response = LivewireVolt::test('auth.login')
->set('email', Str::upper($user->email)) // [email protected]
->set('password', 'password')
->call('login');

$response
->assertHasNoErrors()
->assertRedirect(route('dashboard', absolute: false));

$this->assertAuthenticatedAs($user);
}


public function test_users_can_logout(): void
{
$user = User::factory()->create();
Expand Down
35 changes: 35 additions & 0 deletions tests/Feature/Auth/PasswordResetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Str;
use Livewire\Volt\Volt;
use Tests\TestCase;

Expand Down Expand Up @@ -52,6 +53,40 @@ public function test_reset_password_screen_can_be_rendered(): void
});
}

public function test_password_can_be_reset_with_uppercase_email(): void
{
Notification::fake();

$user = User::factory()->create([
'email' => '[email protected]',
]);

$uppercaseEmail = Str::upper($user->email); // => [email protected]

Volt::test('auth.forgot-password')
->set('email', $uppercaseEmail)
->call('sendPasswordResetLink');

Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user, $uppercaseEmail) {
$response = Volt::test('auth.reset-password', ['token' => $notification->token])
->set('email', $uppercaseEmail)
->set('password', 'password')
->set('password_confirmation', 'password')
->call('resetPassword');

$response
->assertHasNoErrors()
->assertRedirect(route('login', absolute: false));

$this->assertTrue(auth()->attempt([
'email' => $user->email, // => [email protected]
'password' => 'password',
]));

return true;
});
}

public function test_password_can_be_reset_with_valid_token(): void
{
Notification::fake();
Expand Down
24 changes: 24 additions & 0 deletions tests/Feature/Auth/RegistrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Tests\Feature\Auth;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Str;
use Livewire\Volt\Volt;
use Tests\TestCase;

Expand Down Expand Up @@ -32,4 +33,27 @@ public function test_new_users_can_register(): void

$this->assertAuthenticated();
}

public function test_new_user_email_is_stored_as_lowercase_even_if_input_is_uppercase(): void
{
$uppercaseEmail = '[email protected]';

$response = Volt::test('auth.register')
->set('name', 'Test User')
->set('email', $uppercaseEmail)
->set('password', 'password')
->set('password_confirmation', 'password')
->call('register');

$response
->assertHasNoErrors()
->assertRedirect(route('dashboard', absolute: false));

$this->assertAuthenticated();

$this->assertDatabaseHas('users', [
'email' => Str::lower($uppercaseEmail),
]);
}

}