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.