Problem/Motivation

After updating to Drupal 9.3.6 and Password Policy 3.x-dev#966f272d364c35a9c535f768f6b80dddd04ea36b (latest commit as of March 11th), we have started seeing issues when trying to update user passwords. The website whitescreens and we get this error:

Drupal\Core\Entity\EntityStorageException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'field_last_password_reset_value' at row 1: INSERT INTO "user__field_last_password_reset" ("entity_id", "revision_id", "bundle", "delta", "langcode", "field_last_password_reset_value") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5); Array ( [:db_insert_placeholder_0] => 1040411 [:db_insert_placeholder_1] => 1040411 [:db_insert_placeholder_2] => user [:db_insert_placeholder_3] => 0 [:db_insert_placeholder_4] => en [:db_insert_placeholder_5] => 2022-03-11 10:26:34 Europe/London ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 811 of /var/www/html/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

Doing some digging I spotted that the timestamp it's trying to save is 2022-03-11 10:26:34 Europe/London including the whole timezone - rather than something like 2022-03-11T10:26:34 which is how all the rest of the values appear in the database.

Caveat: we have overridden some of the Password Policy validation functions, but I have made sure these are all up-to-date with the latest versions in dev; the only modifications are to add extra user form IDs to if statements.

We have a number of password reset dates in the database already (approx. 93k of them!) and it's only since I updated to the latest version. We are using a specific dev version to fix another bug (we went from 3.0-beta1 to 3.1, and still needed the text updates from #2894929: Instructions unclear for constraint of Uppercase and Lowercase Characters).

Proposed resolution

It looks like this stems from the code setting the password reset value in _password_policy_user_profile_form_update_fields:

// Line 305
  if ($uid && ($current_pass || $form_state->get('user_pass_reset')) && $new_pass) {
    $form_state->setValue(
      'field_last_password_reset',
      [['value' => new DrupalDateTime()]]
    );
    $form_state->setValue('field_password_expiration', ['value' => '0']);
    $form_state->setValue('field_pending_expire_sent', ['value' => '0']);
  }

Checking the value of the `new DrupalDateTime` I can see:

$datetime->__toString(): string (33) "2022-03-11 10:41:04 Europe/London"

In other places the code now uses the Drupal date formatter. I've updated the code on mine to be consistent with that:

    $date = \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, DateTimeItemInterface::STORAGE_TIMEZONE);
    $form_state->setValue(
      'field_last_password_reset',
      [['value' => $date]]
    );

Which in turn gives:

$date: string (19) "2022-03-11T10:41:04"

And this is stored correctly in the database, in the same format as the other entries.

I'll have a go at creating a fork and patching this shortly. Marking as major, because this is preventing us from using the module and parts of the site.

Testing Note

- Make sure to manually or apply the patch to remove the duplicate entries from the 'password_policy_history' table. Before testing this issue.

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:

Comments

Sophie.SK created an issue. See original summary.

sophie.sk’s picture

Status: Active » Needs review

Merge request raised.

Jing Qian’s picture

Tested and working with Drupal 9.3.8

the_g_bomb’s picture

Status: Needs review » Reviewed & tested by the community

Patch applies cleanly and fixed the issue as expected.

lamp5’s picture

Status: Reviewed & tested by the community » Needs work

I can confirm that patch fix this issue but last password change date is unchanged so after each cron run, you have to change your password.
I think that this #3095980: Password history policy inserts password twice in password_policy_history table cause the issue.

the_g_bomb’s picture

@lamp5
I have done a quick test to see if I can verify your issue.

I am using a clean install of drupal with password_policy dev-3.x. I have added 2 patches:

            "drupal/password_policy": {
                "2867320 - Password Policy History module wrong behaviour.": "https://git.drupalcode.org/project/password_policy/-/merge_requests/28.patch",
                "3269065 - Data too long for column": "https://git.drupalcode.org/project/password_policy/-/merge_requests/31.patch"
            }

I then created a password policy that expired the password every day, just to have a policy active.

To test this I changed the password and looked in the database to see what has happened and can see in the table "user__field_last_password_reset" that the "field_last_password_reset_value" is set to the current time.
1st Password reset database entry
I then changed the password and looked again
2nd Password reset database entry
As you can see I am seeing the field being updated.
The value displayed in the User edit page corresponds showing an updated date.
UI Display of the last password reset

@lamp5 Could you confirm if you have removed the duplicate entries created prior to these patches merged and that the password_policy module is up to date?

the_g_bomb’s picture

Status: Needs work » Needs review
joshua1234511’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Tested the MR.
The issue has been resolved.
Tested with and without the patch from https://www.drupal.org/project/password_policy/issues/3266140#comment-14...

Test 1: Old duplicate entries not removed
- This new entires the value works correctly
- Old entires the date updates is incorrect.(inconsitent)
- Fails

Test 2: Removed duplicate entire (Patch applied from 3266140)
- The field "field_last_password_reset_value" has the correct value.
- Pass

Based the test marking this as RTBC

paulocs made their first commit to this issue’s fork.

  • paulocs committed 10be725 on 8.x-3.x authored by Sophie.SK
    Issue #3269065 by Sophie.SK, the_g_bomb: Data too long for column '...
paulocs’s picture

Status: Reviewed & tested by the community » Fixed

Thank you.

Status: Fixed » Closed (fixed)

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