<p>When setting the password for the new User model, you should use the <a href="https://docs.craftcms.com/api/v3/craft-elements-user.html#newpassword" rel="nofollow noreferrer"><code>newPassword</code></a> property instead of <code>password</code>, i.e.</p>
<pre class="lang-php prettyprint-override"><code>$user-&gt;newPassword = $userData['password'];
</code></pre>
<p>This is due to the User model actually hashing and saving the provided password only <em>after</em> the user has initially been saved, and only if that password is provided via the <code>newPassword</code> model attribute. Relevant logic in the Craft source code is <a href="https://github.com/craftcms/cms/blob/75d999d9a5d5351186d02a6a8286f89ae4c035b3/src/elements/User.php#L1732" rel="nofollow noreferrer">here</a>.</p>
<p>The above is tested and working as expected on Craft 3.7.56. I'm not aware if or when something changed in regards to setting <code>$user-&gt;password</code> when saving users programmatically via <code>Craft::$app-&gt;getElementes()</code> – I could be wrong, but chances are that it has never actually worked?</p>

CC BY-SA 4.0
2022-10-25T16:58:56.080Z
Thank you, that did it! While it seems highly unlikely that it never worked, I guess it is possible. I would have started with Craft's own code from their front-end registration help doc (which now has the "newPassword" variable, but may not have in the past). No matter, it works now. Thank you again for your help!
Kirk Roberts
CC BY-SA 4.0
2022-10-24T22:19:06.093Z
2022-10-24T22:33:02.210Z
2022-10-24T22:33:02.210Z
Mats Mikkel Rummelhoff
<p>We have a front-end registration form that was working as expected for months, and now mysteriously when someone registers they can't log in because their password is empty. Using a front-end password reset works and then they can log in normally.</p>
<p>Clearly a bug was introduced into the code somehow but I can't find it and we don't know when exactly this happened. We are currently using Craft CMS 3.7.56.</p>
<p>We have a custom module controller handling the registration, and I can output the new user's chosen password to a custom log file all the way up to just before we call the redirect for the next page. Then on that page if I try to output the user's password it is empty. I have boiled this down so there is not — I think — anything happening in my code between those two events, the redirect <code>return $this-&gt;redirectToPostedUrl();</code> and then the calling of <code>currentUser.password</code>. Still there is no output of the password, whereas with an established user account the password is visible. (This is all in a test environment.)</p>
<p>I am at a loss as to what else to try to figure this out. Any tips will be greatly appreciated!</p>
<p><strong>Update</strong></p>
<p>Typical &quot;give up, post for help, then facepalm&quot; moment. I think I see where the issue is now, but am still unclear as to how I am going wrong.</p>
<p>Here is part of <code>actionRegisterUser()</code> in my module's Controller:</p>
<pre><code>$userData = array(
        'firstName' =&gt; $post['firstName'],
        'lastName' =&gt; $post['lastName'],
        'email' =&gt; $post['email'],
        'phone' =&gt; $post['phone'],
        'emailNotificationsSales' =&gt; @$post['emailNotificationsSales'],
        'password' =&gt; $post['password'],
        'eventIds' =&gt; array($event-&gt;id),
      );
      $user = StpModule::$instance-&gt;stpModuleService-&gt;saveAndGetUser($userData);
</code></pre>
<p>The <code>saveAndGetUser()</code> Service's relevant code is:</p>
<pre><code>$user = Craft::$app-&gt;users-&gt;getUserByUsernameOrEmail($userData['email']);
if (empty($user)) {
          // if not, create a new one
          $user = new User();
          $user-&gt;firstName = trim($userData['firstName']);
          $user-&gt;lastName = trim($userData['lastName']);
          $user-&gt;email = $userData['email'];
          $user-&gt;username = $userData['email'];
          $user-&gt;setFieldValues([
              'phone' =&gt; $userData['phone'],
              'emailNotificationsSales' =&gt; @$userData['emailNotificationsSales'] ?? 1,
              'wasPreregistered' =&gt; @$userData['wasPreregistered'] ?? 0,
          ]);
          if (!empty($userData['password'])) {
              $user-&gt;password = $userData['password'];
          }
          $user-&gt;validate(null, false);
        }
Craft::$app-&gt;getElements()-&gt;saveElement($user, false);
return $user;
</code></pre>
<p>This is the point where things are wacky. If I test for <code>$user-&gt;password</code> I get the entered value. If I do a fresh query to get that User like this:</p>
<pre><code>$userTest = Craft::$app-&gt;users-&gt;getUserByUsernameOrEmail($user-&gt;email);
</code></pre>
<p>Then <code>$userTest-&gt;password</code> is empty. So it seems like the password is not saved even though it is passed to the Service.</p>

CC BY-SA 4.0
2022-10-21T22:38:11.273Z
Can you share the relevant parts of the custom controller action that sets the password, saves the user and redirects?
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2022-10-24T11:16:08.390Z
Thanks for the response Mats. I'll see about posting code later today when I have a chance to look at this again.
Kirk Roberts
CC BY-SA 4.0
2022-10-24T13:23:43.377Z
@MatsMikkelRummelhoff Digging deeper it looks like my issue is that I am trying to save the User, then log them in so they will be the "owner" of some Entries that are being created as part of registration, then update the User with relations to those Entries. I will add some code to my initial post.
Kirk Roberts
CC BY-SA 4.0
2022-10-24T13:54:47.043Z
@MatsMikkelRummelhoff Added some code. Please be gentle! :D
Kirk Roberts
<controller><registration><password><frontend-form>
How can I troubleshoot why a user's initial password is being deleted after a front-end registration? [answer: it was not set in the first place]
# How can I troubleshoot why a user's initial password is being deleted after a front-end registration? [answer: it was not set in the first place]

(Asked by: username_0 on 2022-10-20)

We have a front-end registration form that was working as expected for months, and now mysteriously when someone registers they can't log in because their password is empty. Using a front-end password reset works and then they can log in normally.
Clearly a bug was introduced into the code somehow but I can't find it and we don't know when exactly this happened. We are currently using Craft CMS 3.7.56.
We have a custom module controller handling the registration, and I can output the new user's chosen password to a custom log file all the way up to just before we call the redirect for the next page. Then on that page if I try to output the user's password it is empty. I have boiled this down so there is not — I think — anything happening in my code between those two events, the redirect return $this->redirectToPostedUrl(); and then the calling of currentUser.password. Still there is no output of the password, whereas with an established user account the password is visible. (This is all in a test environment.)
I am at a loss as to what else to try to figure this out. Any tips will be greatly appreciated!
Update
Typical "give up, post for help, then facepalm" moment. I think I see where the issue is now, but am still unclear as to how I am going wrong.
Here is part of actionRegisterUser() in my module's Controller:
$userData = array(
        'firstName' => $post['firstName'],
        'lastName' => $post['lastName'],
        'email' => $post['email'],
        'phone' => $post['phone'],
        'emailNotificationsSales' => @$post['emailNotificationsSales'],
        'password' => $post['password'],
        'eventIds' => array($event->id),
      );
      $user = StpModule::$instance->stpModuleService->saveAndGetUser($userData);

The saveAndGetUser() Service's relevant code is:
$user = Craft::$app->users->getUserByUsernameOrEmail($userData['email']);
if (empty($user)) {
          // if not, create a new one
          $user = new User();
          $user->firstName = trim($userData['firstName']);
          $user->lastName = trim($userData['lastName']);
          $user->email = $userData['email'];
          $user->username = $userData['email'];
          $user->setFieldValues([
              'phone' => $userData['phone'],
              'emailNotificationsSales' => @$userData['emailNotificationsSales'] ?? 1,
              'wasPreregistered' => @$userData['wasPreregistered'] ?? 0,
          ]);
          if (!empty($userData['password'])) {
              $user->password = $userData['password'];
          }
          $user->validate(null, false);
        }
Craft::$app->getElements()->saveElement($user, false);
return $user;

This is the point where things are wacky. If I test for $user->password I get the entered value. If I do a fresh query to get that User like this:
$userTest = Craft::$app->users->getUserByUsernameOrEmail($user->email);

Then $userTest->password is empty. So it seems like the password is not saved even though it is passed to the Service.

**Tags:** controller, registration, password, frontend-form

> **Comments:**
> **username_1**: Can you share the relevant parts of the custom controller action that sets the password, saves the user and redirects?  
> **username_0**: Thanks for the response Mats. I'll see about posting code later today when I have a chance to look at this again.  
> **username_0**: @MatsMikkelRummelhoff Digging deeper it looks like my issue is that I am trying to save the User, then log them in so they will be the "owner" of some Entries that are being created as part of registration, then update the User with relations to those Entries. I will add some code to my initial post.  
> **username_0**: @MatsMikkelRummelhoff Added some code. Please be gentle! :D  

---

## 1 answers

### Answer by username_1 on 2022-10-24. Score: 1 | Accepted answer

When setting the password for the new User model, you should use the newPassword property instead of password, i.e.
$user->newPassword = $userData['password'];

This is due to the User model actually hashing and saving the provided password only after the user has initially been saved, and only if that password is provided via the newPassword model attribute. Relevant logic in the Craft source code is here.
The above is tested and working as expected on Craft 3.7.56. I'm not aware if or when something changed in regards to setting $user->password when saving users programmatically via Craft::$app->getElementes() – I could be wrong, but chances are that it has never actually worked?

> **Comments:**
> **username_0**: Thank you, that did it! While it seems highly unlikely that it never worked, I guess it is possible. I would have started with Craft's own code from their front-end registration help doc (which now has the "newPassword" variable, but may not have in the past). No matter, it works now. Thank you again for your help!  

---

