From 51c9165bacf7276736f10e8c112c14d635842a17 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 13 Apr 2022 10:11:31 +0000 Subject: [PATCH 1/4] Fix 'magic URL' accounts from not being able to create a new account. --- app/controllers/api/account.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index f0c10dd5ea..8df1244c63 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -675,7 +675,7 @@ App::post('/v1/account/sessions/magic-url') 'emailVerification' => false, 'status' => true, 'password' => null, - 'passwordUpdate' => \time(), + 'passwordUpdate' => 0, 'registration' => \time(), 'reset' => false, 'prefs' => new \stdClass(), @@ -946,7 +946,7 @@ App::post('/v1/account/sessions/anonymous') 'emailVerification' => false, 'status' => true, 'password' => null, - 'passwordUpdate' => \time(), + 'passwordUpdate' => 0, 'registration' => \time(), 'reset' => false, 'name' => null, @@ -1376,6 +1376,7 @@ App::patch('/v1/account/password') /** @var Appwrite\Stats\Stats $usage */ // Check old password only if its an existing user. + if ($user->getAttribute('passwordUpdate') !== 0 && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS); } From 37d0de8291f5e97e307f70344608652dad96e012 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 13 Apr 2022 10:27:58 +0000 Subject: [PATCH 2/4] Add tests --- tests/e2e/Services/Account/AccountBase.php | 100 +++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 1bb489c0a1..cca6c8ff72 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -1327,6 +1327,7 @@ trait AccountBase $data['token'] = $token; $data['id'] = $userId; + $data['email'] = $email; return $data; } @@ -1357,6 +1358,9 @@ trait AccountBase $this->assertNotEmpty($response['body']['$id']); $this->assertNotEmpty($response['body']['userId']); + $sessionId = $response['body']['$id']; + $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; + /** * Test for FAILURE */ @@ -1382,6 +1386,102 @@ trait AccountBase $this->assertEquals(401, $response['headers']['status-code']); + + $data['sessionId'] = $sessionId; + $data['session'] = $session; + return $data; } + + /** + * @depends testCreateSessionWithMagicUrl + */ + public function testUpdateAccountPasswordWithMagicUrl($data):array + { + $email = $data['email'] ?? ''; + $session = $data['session'] ?? ''; + + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'password' => 'new-password' + ]); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertIsArray($response['body']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertIsNumeric($response['body']['registration']); + $this->assertEquals($response['body']['email'], $email); + + $response = $this->client->call(Client::METHOD_POST, '/account/sessions', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'email' => $email, + 'password' => 'new-password', + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + + /** + * Test for FAILURE + */ + $response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ])); + + $this->assertEquals($response['headers']['status-code'], 401); + + $response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + ]); + + $this->assertEquals($response['headers']['status-code'], 400); + + /** + * Existing user tries to update password by passing wrong old password -> SHOULD FAIL + */ + $response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'password' => 'new-password', + 'oldPassword' => 'wrong-password', + ]); + $this->assertEquals($response['headers']['status-code'], 401); + + /** + * Existing user tries to update password without passing old password -> SHOULD FAIL + */ + $response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session, + ]), [ + 'password' => 'new-password' + ]); + $this->assertEquals($response['headers']['status-code'], 401); + + $data['password'] = 'new-password'; + + return $data; + } + } \ No newline at end of file From 812249ebcb677bbc46be071e9f22e25a1e221732 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 13 Apr 2022 10:45:17 +0000 Subject: [PATCH 3/4] update account.php --- app/controllers/api/account.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8df1244c63..007e53193b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1376,7 +1376,6 @@ App::patch('/v1/account/password') /** @var Appwrite\Stats\Stats $usage */ // Check old password only if its an existing user. - if ($user->getAttribute('passwordUpdate') !== 0 && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password throw new Exception('Invalid credentials', 401, Exception::USER_INVALID_CREDENTIALS); } From 8ebe3ae7ca69bf02792568975409d0035237f903 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 13 Apr 2022 13:00:43 +0100 Subject: [PATCH 4/4] Update Docs for update password --- docs/references/account/update-password.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/account/update-password.md b/docs/references/account/update-password.md index c682030a10..d912c9d439 100644 --- a/docs/references/account/update-password.md +++ b/docs/references/account/update-password.md @@ -1 +1 @@ -Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional. \ No newline at end of file +Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth, Team Invites and Magic URL, oldPassword is optional. \ No newline at end of file