@@ -133,55 +133,56 @@ protected function validatePassword(PasswordFormField $passwordFormField): void
133133 {
134134 $ usernameFormField = $ this ->form ->getNodeById ('username ' );
135135 \assert ($ usernameFormField instanceof TextFormField);
136- $ handleException = null ;
136+ $ validationError = null ;
137137
138138 try {
139139 $ this ->user = UserAuthenticationFactory::getInstance ()
140140 ->getUserAuthentication ()
141141 ->loginManually ($ usernameFormField ->getValue (), $ passwordFormField ->getValue ());
142142 } catch (UserInputException $ e ) {
143- if (
144- \get_class (UserAuthenticationFactory::getInstance ()->getUserAuthentication ()) === DefaultUserAuthentication::class
145- && $ e ->getField () == 'username '
146- ) {
143+ $ validationError = $ e ;
144+
145+ if ($ e ->getField () === 'username ' ) {
147146 try {
148- $ this ->user = EmailUserAuthentication::getInstance ()
149- ->loginManually ($ usernameFormField ->getValue (), $ passwordFormField ->getValue ());
150- } catch (UserInputException $ e2 ) {
151- if ($ e2 ->getField () == 'username ' ) {
152- $ handleException = $ e ;
153- } else {
154- $ handleException = $ e2 ;
147+ $ user = $ this ->tryAuthenticationByEmail ($ usernameFormField ->getValue (), $ passwordFormField ->getValue ());
148+ if ($ user !== null ) {
149+ $ this ->user = $ user ;
150+ $ validationError = null ;
151+ }
152+ } catch (UserInputException $ emailException ) {
153+ // The attempt to use the email address as login username is
154+ // only implicit, therefore we only use the inner exception
155+ // if the error is about an incorrect password.
156+ if ($ emailException ->getField () !== 'username ' ) {
157+ $ validationError = $ emailException ;
155158 }
156159 }
157- } else {
158- $ handleException = $ e ;
159160 }
160161 }
161162
162- if ($ handleException !== null ) {
163- if ($ handleException ->getField () == 'username ' ) {
163+ if ($ validationError !== null ) {
164+ if ($ validationError ->getField () == 'username ' ) {
164165 $ usernameFormField ->addValidationError (
165166 new FormFieldValidationError (
166- $ handleException ->getType (),
167- 'wcf.user.username.error. ' . $ handleException ->getType (),
167+ $ validationError ->getType (),
168+ 'wcf.user.username.error. ' . $ validationError ->getType (),
168169 [
169170 'username ' => $ usernameFormField ->getValue (),
170171 ]
171172 )
172173 );
173- } else if ($ handleException ->getField () == 'password ' ) {
174+ } else if ($ validationError ->getField () == 'password ' ) {
174175 $ passwordFormField ->addValidationError (
175176 new FormFieldValidationError (
176- $ handleException ->getType (),
177- 'wcf.user.password.error. ' . $ handleException ->getType ()
177+ $ validationError ->getType (),
178+ 'wcf.user.password.error. ' . $ validationError ->getType ()
178179 )
179180 );
180181 } else {
181182 throw new \LogicException ('unreachable ' );
182183 }
183184
184- $ this ->saveAuthenticationFailure ($ handleException ->getField (), $ usernameFormField ->getValue ());
185+ $ this ->saveAuthenticationFailure ($ validationError ->getField (), $ usernameFormField ->getValue ());
185186 }
186187
187188 if (RequestHandler::getInstance ()->isACPRequest () && $ this ->user !== null ) {
@@ -205,6 +206,20 @@ protected function validatePassword(PasswordFormField $passwordFormField): void
205206 }
206207 }
207208
209+ protected function tryAuthenticationByEmail (
210+ string $ username ,
211+ #[\SensitiveParameter] string $ password
212+ ): ?User {
213+ $ defaultAuthentication = UserAuthenticationFactory::getInstance ()->getUserAuthentication ();
214+ if (\get_class ($ defaultAuthentication ) !== DefaultUserAuthentication::class) {
215+ // The email fallback is only supported for the built-in
216+ // authentication method.
217+ return null ;
218+ }
219+
220+ return EmailUserAuthentication::getInstance ()->loginManually ($ username , $ password );
221+ }
222+
208223 protected function saveAuthenticationFailure (string $ errorField , string $ username ): void
209224 {
210225 if (!ENABLE_USER_AUTHENTICATION_FAILURE ) {
0 commit comments