File tree Expand file tree Collapse file tree 9 files changed +124
-0
lines changed Expand file tree Collapse file tree 9 files changed +124
-0
lines changed Original file line number Diff line number Diff line change 1313 'home ' => '/home ' ,
1414 'prefix ' => '' ,
1515 'domain ' => null ,
16+ 'lowercase_usernames ' => false ,
1617 'limiters ' => [
1718 'login ' => null ,
1819 ],
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace Laravel \Fortify \Actions ;
4+
5+ use Illuminate \Support \Str ;
6+ use Laravel \Fortify \Fortify ;
7+
8+ class CanonicalizeUsername
9+ {
10+ /**
11+ * Handle the incoming request.
12+ *
13+ * @param \Illuminate\Http\Request $request
14+ * @param callable $next
15+ * @return mixed
16+ */
17+ public function handle ($ request , $ next )
18+ {
19+ $ request ->merge ([
20+ Fortify::username () => Str::lower ($ request ->{Fortify::username ()}),
21+ ]);
22+
23+ return $ next ($ request );
24+ }
25+ }
Original file line number Diff line number Diff line change 77use Illuminate \Routing \Controller ;
88use Illuminate \Routing \Pipeline ;
99use Laravel \Fortify \Actions \AttemptToAuthenticate ;
10+ use Laravel \Fortify \Actions \CanonicalizeUsername ;
1011use Laravel \Fortify \Actions \EnsureLoginIsNotThrottled ;
1112use Laravel \Fortify \Actions \PrepareAuthenticatedSession ;
1213use Laravel \Fortify \Actions \RedirectIfTwoFactorAuthenticatable ;
@@ -83,6 +84,7 @@ protected function loginPipeline(LoginRequest $request)
8384
8485 return (new Pipeline (app ()))->send ($ request )->through (array_filter ([
8586 config ('fortify.limiters.login ' ) ? null : EnsureLoginIsNotThrottled::class,
87+ config ('fortify.lowercase_usernames ' ) ? CanonicalizeUsername::class : null ,
8688 Features::enabled (Features::twoFactorAuthentication ()) ? RedirectIfTwoFactorAuthenticatable::class : null ,
8789 AttemptToAuthenticate::class,
8890 PrepareAuthenticatedSession::class,
Original file line number Diff line number Diff line change 44
55use Illuminate \Http \Request ;
66use Illuminate \Routing \Controller ;
7+ use Illuminate \Support \Str ;
78use Laravel \Fortify \Contracts \ProfileInformationUpdatedResponse ;
89use Laravel \Fortify \Contracts \UpdatesUserProfileInformation ;
10+ use Laravel \Fortify \Fortify ;
911
1012class ProfileInformationController extends Controller
1113{
@@ -19,6 +21,12 @@ class ProfileInformationController extends Controller
1921 public function update (Request $ request ,
2022 UpdatesUserProfileInformation $ updater )
2123 {
24+ if (config ('fortify.lowercase_usernames ' )) {
25+ $ request ->merge ([
26+ Fortify::username () => Str::lower ($ request ->{Fortify::username ()}),
27+ ]);
28+ }
29+
2230 $ updater ->update ($ request ->user (), $ request ->all ());
2331
2432 return app (ProfileInformationUpdatedResponse::class);
Original file line number Diff line number Diff line change 66use Illuminate \Contracts \Auth \StatefulGuard ;
77use Illuminate \Http \Request ;
88use Illuminate \Routing \Controller ;
9+ use Illuminate \Support \Str ;
910use Laravel \Fortify \Contracts \CreatesNewUsers ;
1011use Laravel \Fortify \Contracts \RegisterResponse ;
1112use Laravel \Fortify \Contracts \RegisterViewResponse ;
13+ use Laravel \Fortify \Fortify ;
1214
1315class RegisteredUserController extends Controller
1416{
@@ -51,6 +53,12 @@ public function create(Request $request): RegisterViewResponse
5153 public function store (Request $ request ,
5254 CreatesNewUsers $ creator ): RegisterResponse
5355 {
56+ if (config ('fortify.lowercase_usernames ' )) {
57+ $ request ->merge ([
58+ Fortify::username () => Str::lower ($ request ->{Fortify::username ()}),
59+ ]);
60+ }
61+
5462 event (new Registered ($ user = $ creator ->create ($ request ->all ())));
5563
5664 $ this ->guard ->login ($ user );
Original file line number Diff line number Diff line change 5050
5151 'email ' => 'email ' ,
5252
53+ /*
54+ |--------------------------------------------------------------------------
55+ | Lowercase Usernames
56+ |--------------------------------------------------------------------------
57+ |
58+ | This value defines whether usernames should be lowercased before saving
59+ | them in the database, as some database system string fields are case
60+ | sensitive. You may disable this for your application if necessary.
61+ |
62+ */
63+
64+ 'lowercase_usernames ' => true ,
65+
5366 /*
5467 |--------------------------------------------------------------------------
5568 | Home Path
Original file line number Diff line number Diff line change @@ -428,6 +428,26 @@ public function test_two_factor_challenge_requires_a_challenged_user()
428428 $ this ->assertNull (Auth::getUser ());
429429 }
430430
431+ public function test_case_insensitive_usernames_can_be_used ()
432+ {
433+ app ('config ' )->set ('fortify.lowercase_usernames ' , true );
434+
435+ $ this ->loadLaravelMigrations (['--database ' => 'testbench ' ]);
436+
437+ TestAuthenticationSessionUser::forceCreate ([
438+ 'name ' => 'Taylor Otwell ' ,
439+ 'email ' => 'taylor@laravel.com ' ,
440+ 'password ' => bcrypt ('secret ' ),
441+ ]);
442+
443+ $ response = $ this ->withoutExceptionHandling ()->post ('/login ' , [
444+ 'email ' => 'TAYLOR@LARAVEL.COM ' ,
445+ 'password ' => 'secret ' ,
446+ ]);
447+
448+ $ response ->assertRedirect ('/home ' );
449+ }
450+
431451 protected function getPackageProviders ($ app )
432452 {
433453 return [FortifyServiceProvider::class];
Original file line number Diff line number Diff line change @@ -23,4 +23,26 @@ public function test_contact_information_can_be_updated()
2323
2424 $ response ->assertStatus (200 );
2525 }
26+
27+ public function test_email_address_will_be_updated_case_insensitive ()
28+ {
29+ app ('config ' )->set ('fortify.lowercase_usernames ' , true );
30+
31+ $ user = Mockery::mock (Authenticatable::class);
32+
33+ $ this ->mock (UpdatesUserProfileInformation::class)
34+ ->shouldReceive ('update ' )
35+ ->with ($ user , [
36+ 'name ' => 'Taylor Otwell ' ,
37+ 'email ' => 'taylor@laravel.com ' ,
38+ ])
39+ ->once ();
40+
41+ $ response = $ this ->withoutExceptionHandling ()->actingAs ($ user )->putJson ('/user/profile-information ' , [
42+ 'name ' => 'Taylor Otwell ' ,
43+ 'email ' => 'TAYLOR@LARAVEL.COM ' ,
44+ ]);
45+
46+ $ response ->assertStatus (200 );
47+ }
2648}
Original file line number Diff line number Diff line change @@ -52,4 +52,29 @@ public function test_users_can_be_created_and_redirected_to_intended_url()
5252
5353 $ response ->assertRedirect ('http://foo.com/bar ' );
5454 }
55+
56+ public function test_usernames_will_be_stored_case_insensitive ()
57+ {
58+ app ('config ' )->set ('fortify.lowercase_usernames ' , true );
59+
60+ $ this ->mock (CreatesNewUsers::class)
61+ ->shouldReceive ('create ' )
62+ ->with ([
63+ 'email ' => 'taylor@laravel.com ' ,
64+ 'password ' => 'password ' ,
65+ ])
66+ ->once ()
67+ ->andReturn (Mockery::mock (Authenticatable::class));
68+
69+ $ this ->mock (StatefulGuard::class)
70+ ->shouldReceive ('login ' )
71+ ->once ();
72+
73+ $ response = $ this ->post ('/register ' , [
74+ 'email ' => 'TAYLOR@LARAVEL.COM ' ,
75+ 'password ' => 'password ' ,
76+ ]);
77+
78+ $ response ->assertRedirect ('/home ' );
79+ }
5580}
You can’t perform that action at this time.
0 commit comments