Merge pull request #10889 from appwrite/fix-error-setting-user-password

Fix: error setting user password
This commit is contained in:
Jake Barnby 2025-12-02 01:23:48 +00:00 committed by GitHub
commit 088359c257
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 3 deletions

View file

@ -117,14 +117,19 @@ function createUser(Hash $hash, string $userId, ?string $email, ?string $passwor
$hashedPassword = null;
$isHashed = !$hash instanceof Plaintext;
$defaultHash = new ProofsPassword();
if (!empty($password)) {
if (!$isHashed) { // Password was never hashed, hash it with the default hash
$defaultHash = new ProofsPassword();
$hashedPassword = $defaultHash->hash($password);
$hash = $defaultHash->getHash();
} else {
$hashedPassword = $password;
}
} else {
// when password is not provided, plaintext was set as the default hash causing the issue
$hash = $defaultHash->getHash();
$isHashed = !$hash instanceof Plaintext;
}
$user = new Document([
@ -160,7 +165,7 @@ function createUser(Hash $hash, string $userId, ?string $email, ?string $passwor
'emailIsFree' => $emailCanonical?->isFree(),
]);
if (!$isHashed) {
if (!$isHashed && !empty($password)) {
$hooks->trigger('passwordValidator', [$dbForProject, $project, $plaintextPassword, &$user, true]);
}
@ -2627,7 +2632,8 @@ App::post('/v1/users/:userId/jwts')
$session = \count($sessions) > 0 ? $sessions[\count($sessions) - 1] : new Document();
} else {
// Find by ID
foreach ($sessions as $loopSession) { /** @var Utopia\Database\Document $loopSession */
foreach ($sessions as $loopSession) {
/** @var Utopia\Database\Document $loopSession */
if ($loopSession->getId() == $sessionId) {
$session = $loopSession;
break;

View file

@ -6,6 +6,7 @@ use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideConsole;
use Utopia\Database\Helpers\ID;
class UsersConsoleClientTest extends Scope
{
@ -45,4 +46,39 @@ class UsersConsoleClientTest extends Scope
$this->assertIsArray($response['body']['users']);
$this->assertIsArray($response['body']['sessions']);
}
public function testCreateUserWithoutPasswordThenSetPassword()
{
// Create a user with email but without password
$userId = ID::unique();
$email = $userId . '@example.com';
$response = $this->client->call(Client::METHOD_POST, '/users', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()), [
'userId' => $userId,
'email' => $email,
// no password provided
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals($userId, $response['body']['$id']);
$this->assertEquals($email, $response['body']['email']);
$this->assertEmpty($response['body']['password']);
// Now set the password for that user (console-side)
$newPassword = 'NewPass123!';
$set = $this->client->call(Client::METHOD_PATCH, '/users/' . $userId . '/password', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()), [
'password' => $newPassword,
]);
$this->assertEquals(200, $set['headers']['status-code']);
$this->assertEquals($userId, $set['body']['$id']);
$this->assertNotEmpty($set['body']['password']);
}
}