From a56463e56ecb0e2c185be910a3a8898ba19869fc Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 17 Jun 2021 16:46:29 +0100 Subject: [PATCH 1/4] Fix Unique Keys not being update when changing a user's email address --- app/controllers/api/account.php | 13 ++++++++++-- src/Appwrite/Database/Adapter.php | 11 +++++++++- src/Appwrite/Database/Adapter/MySQL.php | 27 ++++++++++++++++++++++++- src/Appwrite/Database/Adapter/Redis.php | 16 +++++++++++++++ src/Appwrite/Database/Database.php | 12 +++++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 13639c912..8c29e14da 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, ['email' => $email]); + + $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..0bfac77e1 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..d179291ed 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,31 @@ 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 */ From 1cf66b59345f57ed12205825053a0b10bcb2d28a Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 21 Jun 2021 09:13:18 +0100 Subject: [PATCH 2/4] Update account.php --- app/controllers/api/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8c29e14da..63498c750 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1117,7 +1117,7 @@ App::patch('/v1/account/email') ] )); - $user = $projectDB->updateDocument($document, ['email' => $email]); + $user = $projectDB->updateDocument($document); $projectDB->addUniqueKey(\md5($document['$collection'].':'.'email'.'='.$email)); From 84f88628f57756db5bde97ee98661de8d5875cb3 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 23 Jun 2021 15:02:24 +0100 Subject: [PATCH 3/4] Implement Suggestions --- src/Appwrite/Database/Adapter.php | 4 ++-- src/Appwrite/Database/Adapter/MySQL.php | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Database/Adapter.php b/src/Appwrite/Database/Adapter.php index 0bfac77e1..bb650e844 100644 --- a/src/Appwrite/Database/Adapter.php +++ b/src/Appwrite/Database/Adapter.php @@ -91,7 +91,7 @@ abstract class Adapter /** * Delete Unique Key. * - * @param String $key + * @param string $key * * @return array */ @@ -100,7 +100,7 @@ abstract class Adapter /** * Add Unique Key. * - * @param String $key + * @param string $key * * @return array */ diff --git a/src/Appwrite/Database/Adapter/MySQL.php b/src/Appwrite/Database/Adapter/MySQL.php index d179291ed..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 String $key + * @param string $key * * @return array * @@ -380,13 +380,12 @@ class MySQL extends Adapter /** * Add Unique Key. * - * @param String $key + * @param string $key * * @return array * * @throws Exception */ - public function addUniqueKey($key) { $st = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.unique` From 0b1b21a5b00c0f9b6fc9c1558d7afc1ec22111aa Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 23 Jun 2021 16:06:52 +0100 Subject: [PATCH 4/4] Update Tests --- tests/e2e/Services/Account/AccountBase.php | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) 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;