Problem/Motivation

After 5 fail login attempts, the website got a fatal PHP error said 'TypeError: Argument 4 passed to Drupal\tfa\TfaContext::__construct() must implement interface Drupal\user\UserInterface, null given'

Steps to reproduce

1. Enable and set up the TFA for user login.
2. Try login with any wrong password for 6 times (Default flood threshold is 5)
3. A white screen show up said' The website encountered an unexpected error. Please try again later.'

Proposed resolution

The logic behind Drupal user login form is changed since Drupal 9.
See the difference from the source code in D9:
https://git.drupalcode.org/project/drupal/-/blob/9.2.x/core/modules/user...

In D8:
https://git.drupalcode.org/project/drupal/-/blob/8.9.x/core/modules/user...

Therefore, we need to add following codes into /src/Form/TfaLoginForm.php

// The user ID must not be NULL.
    if (empty($uid = $form_state->get('uid'))) {
      return;
    }

Remaining tasks

Since the logic is different between D8 and D9, we need to rewrite the TFA user login form to reflect all changes since Drupal 9.

User interface changes

N/A

API changes

N/A

Data model changes

N/A

CommentFileSizeAuthor
#2 tfa-3205297-2.patch629 bytesMingsong

Issue fork tfa-3205297

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Mingsong created an issue. See original summary.

Mingsong’s picture

FileSize
629 bytes

Patch to fix this issue.

Mingsong’s picture

Title: Fatal error after exceeding login attempts in Drupal 9 » Fatal error after exceeding login attempts with Drupal 9

  • jcnventura committed 5b3d59d on 8.x-1.x authored by Mingsong
    Issue #3205297: Fatal error after exceeding login attempts in Drupal 9
    
jcnventura’s picture

Status: Active » Fixed

Thanks for the code. Even when whoever did it in core decided to make it clever and horrible to read by doing an if (var = value) {}.

All the programming best practice standards I've read recommend against that, but I understand why you decided to 'do as core does'.

Mingsong’s picture

Agree, It is very confusing to write code in this way.

Mingsong’s picture

Issue summary: View changes

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Anonymous’s picture

When Applying patches from the issue :User login page broken this modules gets broken as the parent constructor needs BareHtmlPageRendererInterface. Solution is to update the constructor as follows

* @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_renderer
   *   The renderer.
   */
  public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, UserAuthInterface $user_auth, RendererInterface $renderer, TfaValidationPluginManager $tfa_validation_manager, TfaLoginPluginManager $tfa_plugin_manager, UserDataInterface $user_data, RedirectDestinationInterface $destination, Request $request, BareHtmlPageRendererInterface $bare_html_renderer) {
    parent::__construct($flood, $user_storage, $user_auth, $renderer, $bare_html_renderer);

Also add $container->get('bare_html_page_renderer') at the end of the create function.