diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 13639c912..63498c750 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1103,14 +1103,23 @@ App::patch('/v1/account/email') // TODO after this user needs to confirm mail again - $user = $projectDB->updateDocument(\array_merge( + if (!$isAnonymousUser) { + // Remove previous unique ID. + $projectDB->deleteUniqueKey(\md5($user->getArrayCopy()['$collection'].':'.'email'.'='.$user->getAttribute('email'))); + } + + $document = (\array_merge( $user->getArrayCopy(), ($isAnonymousUser ? [ 'password' => Auth::passwordHash($password) ] : []), [ 'email' => $email, 'emailVerification' => false, ] - )); + )); + + $user = $projectDB->updateDocument($document); + + $projectDB->addUniqueKey(\md5($document['$collection'].':'.'email'.'='.$email)); if (false === $user) { throw new Exception('Failed saving user to DB', 500); diff --git a/src/Appwrite/Database/Adapter.php b/src/Appwrite/Database/Adapter.php index 6e14365f8..bb650e844 100644 --- a/src/Appwrite/Database/Adapter.php +++ b/src/Appwrite/Database/Adapter.php @@ -91,12 +91,21 @@ abstract class Adapter /** * Delete Unique Key. * - * @param int $key + * @param string $key * * @return array */ abstract public function deleteUniqueKey($key); + /** + * Add Unique Key. + * + * @param string $key + * + * @return array + */ + abstract public function addUniqueKey($key); + /** * Create Namespace. * diff --git a/src/Appwrite/Database/Adapter/MySQL.php b/src/Appwrite/Database/Adapter/MySQL.php index 37d07c3a2..6858e9342 100644 --- a/src/Appwrite/Database/Adapter/MySQL.php +++ b/src/Appwrite/Database/Adapter/MySQL.php @@ -360,7 +360,7 @@ class MySQL extends Adapter /** * Delete Unique Key. * - * @param int $key + * @param string $key * * @return array * @@ -377,6 +377,30 @@ class MySQL extends Adapter return []; } + /** + * Add Unique Key. + * + * @param string $key + * + * @return array + * + * @throws Exception + */ + public function addUniqueKey($key) + { + $st = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.unique` + SET `key` = :key; + '); + + $st->bindValue(':key', $key, PDO::PARAM_STR); + + if (!$st->execute()) { + throw new Duplicate('Duplicated Property: '.$key); + } + + return []; + } + /** * Create Relation. * diff --git a/src/Appwrite/Database/Adapter/Redis.php b/src/Appwrite/Database/Adapter/Redis.php index a1e440112..0a72f8b4b 100644 --- a/src/Appwrite/Database/Adapter/Redis.php +++ b/src/Appwrite/Database/Adapter/Redis.php @@ -169,6 +169,22 @@ class Redis extends Adapter return $data; } + /** + * Add Unique Key. + * + * @param $key + * + * @return array + * + * @throws Exception + */ + public function addUniqueKey($key) + { + $data = $this->adapter->addUniqueKey($key); + + return $data; + } + /** * Create Namespace. * diff --git a/src/Appwrite/Database/Database.php b/src/Appwrite/Database/Database.php index d0defdec0..bf1033eb8 100644 --- a/src/Appwrite/Database/Database.php +++ b/src/Appwrite/Database/Database.php @@ -370,6 +370,18 @@ class Database return new Document($this->adapter->deleteUniqueKey($key)); } + /** + * @param int $key + * + * @return Document|false + * + * @throws AuthorizationException + */ + public function addUniqueKey($key) + { + return new Document($this->adapter->addUniqueKey($key)); + } + /** * @return array */ diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 46b9f127d..18a6ee4d9 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -591,6 +591,29 @@ trait AccountBase $this->assertEquals($response['headers']['status-code'], 400); + // Test if we can create a new account with the old email + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'email' => $data['email'], + 'password' => $data['password'], + 'name' => $data['name'], + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertIsNumeric($response['body']['registration']); + $this->assertEquals($response['body']['email'], $data['email']); + $this->assertEquals($response['body']['name'], $data['name'],); + + $data['email'] = $newEmail; return $data;