From 0fb34433b98e8585afbeb9af5b485df459293cd5 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 14 Apr 2023 00:20:03 +0400 Subject: [PATCH] feat: personal data filters to enhance password protection --- app/config/errors.php | 10 + app/controllers/api/account.php | 17 +- app/controllers/api/projects.php | 6 +- app/controllers/api/users.php | 17 +- composer.lock | 24 +- src/Appwrite/Auth/Validator/PersonalData.php | 100 + src/Appwrite/Extend/Exception.php | 1 + tests/e2e/Services/Account/AccountBase.php | 3016 ++++++++--------- .../Projects/ProjectsConsoleClientTest.php | 114 +- .../unit/Auth/Validator/PersonalDataTest.php | 85 + 10 files changed, 1863 insertions(+), 1527 deletions(-) create mode 100644 src/Appwrite/Auth/Validator/PersonalData.php create mode 100644 tests/unit/Auth/Validator/PersonalDataTest.php diff --git a/app/config/errors.php b/app/config/errors.php index 0ad10f4f71..a79f21c2df 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -160,6 +160,16 @@ return [ 'description' => 'Passwords do not match. Please check the password and confirm password.', 'code' => 400, ], + Exception::USER_PASSWORD_RECENTLY_USED => [ + 'name' => Exception::USER_PASSWORD_RECENTLY_USED, + 'description' => 'The password you are trying to use is similar to your previous password. Please choose a stronger password.', + 'code' => 400, + ], + Exception::USER_PASSWORD_PERSONAL_DATA => [ + 'name' => Exception::USER_PASSWORD_PERSONAL_DATA, + 'description' => 'The password you are trying to use contains references to your name, email, phone or userID. Please choose a different password.', + 'code' => 400, + ], Exception::USER_SESSION_NOT_FOUND => [ 'name' => Exception::USER_SESSION_NOT_FOUND, 'description' => 'The current user session could not be found.', diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8bdfd0ae1a..ee50d0198e 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -42,6 +42,7 @@ use Utopia\Validator\Text; use Utopia\Validator\WhiteList; use Appwrite\Auth\Validator\PasswordHistory; use Appwrite\Auth\Validator\PasswordDictionary; +use Appwrite\Auth\Validator\PersonalData; $oauthDefaultSuccess = '/auth/oauth2/success'; $oauthDefaultFailure = '/auth/oauth2/failure'; @@ -98,6 +99,13 @@ App::post('/v1/account') } } + if ($project->getAttribute('auths', [])['disallowPersonalData'] ?? false) { + $personalDataValidator = new PersonalData($userId, $email, $name, null); + if (!$personalDataValidator->isValid($password)) { + throw new Exception(Exception::USER_PASSWORD_PERSONAL_DATA); + } + } + $passwordHistory = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; $password = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); try { @@ -1582,13 +1590,20 @@ App::patch('/v1/account/password') $history = $user->getAttribute('passwordHistory', []); $validator = new PasswordHistory($history, $user->getAttribute('hash'), $user->getAttribute('hashOptions')); if (!$validator->isValid($password)) { - throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED, 'The password was recently used', 409); + throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED); } $history[] = $newPassword; array_slice($history, (count($history) - $historyLimit), $historyLimit); } + if ($project->getAttribute('auths', [])['disallowPersonalData'] ?? false) { + $personalDataValidator = new PersonalData($user->getId(), $user->getAttribute('email'), $user->getAttribute('name'), $user->getAttribute('phone')); + if (!$personalDataValidator->isValid($password)) { + throw new Exception(Exception::USER_PASSWORD_PERSONAL_DATA); + } + } + $user ->setAttribute('password', $newPassword) ->setAttribute('passwordHistory', $history) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index fa7513fea2..f04696fdb5 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -80,7 +80,7 @@ App::post('/v1/projects') } $auth = Config::getParam('auth', []); - $auths = ['limit' => 0, 'maxSessions' => APP_LIMIT_USER_SESSIONS_DEFAULT, 'passwordHistory' => 0, 'passwordDictionary' => false, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG]; + $auths = ['limit' => 0, 'maxSessions' => APP_LIMIT_USER_SESSIONS_DEFAULT, 'passwordHistory' => 0, 'passwordDictionary' => false, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG, 'disallowPersonalData' => false]; foreach ($auth as $index => $method) { $auths[$method['key'] ?? ''] = true; } @@ -638,7 +638,7 @@ App::patch('/v1/projects/:projectId/auth/password-dictionary') }); App::patch('/v1/projects/:projectId/auth/disallow-personal-data') - ->desc('Enable or disable checking the user password against their personal data.') + ->desc('Enable or disable checking user passwords for similarity with their personal data.') ->groups(['api', 'projects']) ->label('scope', 'projects.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) @@ -648,7 +648,7 @@ App::patch('/v1/projects/:projectId/auth/disallow-personal-data') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_PROJECT) ->param('projectId', '', new UID(), 'Project unique ID.') - ->param('enabled', false, new Boolean(false), 'Set whether or not to check Default is false.') + ->param('enabled', false, new Boolean(false), 'Set whether or not to check a password for similarity with personal data. Default is false.') ->inject('response') ->inject('dbForConsole') ->action(function (string $projectId, bool $enabled, Response $response, Database $dbForConsole) { diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index ceed901a32..222e90f4c9 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -36,6 +36,7 @@ use MaxMind\Db\Reader; use Utopia\Validator\Integer; use Appwrite\Auth\Validator\PasswordHistory; use Appwrite\Auth\Validator\PasswordDictionary; +use Appwrite\Auth\Validator\PersonalData; /** TODO: Remove function when we move to using utopia/platform */ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Event $events): Document @@ -52,6 +53,13 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e ? ID::unique() : ID::custom($userId); + if ($project->getAttribute('auths', [])['disallowPersonalData'] ?? false) { + $personalDataValidator = new PersonalData($userId, $email, $name, $phone); + if (!$personalDataValidator->isValid($password)) { + throw new Exception(Exception::USER_PASSWORD_PERSONAL_DATA); + } + } + $password = (!empty($password)) ? ($hash === 'plaintext' ? Auth::passwordHash($password, $hash, $hashOptionsObject) : $password) : null; $user = $dbForProject->createDocument('users', new Document([ '$id' => $userId, @@ -806,6 +814,13 @@ App::patch('/v1/users/:userId/password') throw new Exception(Exception::USER_NOT_FOUND); } + if ($project->getAttribute('auths', [])['disallowPersonalData'] ?? false) { + $personalDataValidator = new PersonalData($userId, $user->getAttribute('email'), $user->getAttribute('name'), $user->getAttribute('phone')); + if (!$personalDataValidator->isValid($password)) { + throw new Exception(Exception::USER_PASSWORD_PERSONAL_DATA); + } + } + $newPassword = Auth::passwordHash($password, Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS); $historyLimit = $project->getAttribute('auths', [])['passwordHistory'] ?? 0; @@ -814,7 +829,7 @@ App::patch('/v1/users/:userId/password') $history = $user->getAttribute('passwordHistory', []); $validator = new PasswordHistory($history, $user->getAttribute('hash'), $user->getAttribute('hashOptions')); if (!$validator->isValid($password)) { - throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED, 'The password was recently used', 409); + throw new Exception(Exception::USER_PASSWORD_RECENTLY_USED); } $history[] = $newPassword; diff --git a/composer.lock b/composer.lock index 2d402ddb31..2fe7adc3b6 100644 --- a/composer.lock +++ b/composer.lock @@ -2112,16 +2112,16 @@ }, { "name": "utopia-php/database", - "version": "0.35.0", + "version": "0.35.1", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "f162c142fd61753c4b413b15c3c4041f3cd00bb2" + "reference": "b5ac84e0c77145bd0a7f38718ad915729c64fa93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/f162c142fd61753c4b413b15c3c4041f3cd00bb2", - "reference": "f162c142fd61753c4b413b15c3c4041f3cd00bb2", + "url": "https://api.github.com/repos/utopia-php/database/zipball/b5ac84e0c77145bd0a7f38718ad915729c64fa93", + "reference": "b5ac84e0c77145bd0a7f38718ad915729c64fa93", "shasum": "" }, "require": { @@ -2164,9 +2164,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.35.0" + "source": "https://github.com/utopia-php/database/tree/0.35.1" }, - "time": "2023-04-11T04:02:22+00:00" + "time": "2023-04-13T04:30:08+00:00" }, { "name": "utopia-php/domains", @@ -3037,16 +3037,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.32.1", + "version": "0.32.2", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ba1d7afd57e3baef06c04ce6abc26f79310146df" + "reference": "cdec289bcf38c99d0074414d2438e9967d0c9699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ba1d7afd57e3baef06c04ce6abc26f79310146df", - "reference": "ba1d7afd57e3baef06c04ce6abc26f79310146df", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/cdec289bcf38c99d0074414d2438e9967d0c9699", + "reference": "cdec289bcf38c99d0074414d2438e9967d0c9699", "shasum": "" }, "require": { @@ -3082,9 +3082,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.32.1" + "source": "https://github.com/appwrite/sdk-generator/tree/0.32.2" }, - "time": "2023-04-12T04:43:07+00:00" + "time": "2023-04-12T21:06:57+00:00" }, { "name": "doctrine/deprecations", diff --git a/src/Appwrite/Auth/Validator/PersonalData.php b/src/Appwrite/Auth/Validator/PersonalData.php new file mode 100644 index 0000000000..5f57fb5e62 --- /dev/null +++ b/src/Appwrite/Auth/Validator/PersonalData.php @@ -0,0 +1,100 @@ +strict) { + $password = strtolower($password); + $this->userId = strtolower($this->userId); + $this->email = strtolower($this->email); + $this->name = strtolower($this->name); + $this->phone = strtolower($this->phone); + } + + if ($this->userId && strpos($password, $this->userId) !== false) { + return false; + } + + if ($this->email && strpos($password, $this->email) !== false) { + return false; + } + + if ($this->email && strpos($password, explode('@', $this->email)[0] ?? '') !== false) { + return false; + } + + if ($this->name && strpos($password, $this->name) !== false) { + return false; + } + + if ($this->phone && strpos($password, str_replace('+', '', $this->phone)) !== false) { + return false; + } + + if ($this->phone && strpos($password, $this->phone) !== false) { + return false; + } + + return true; + } + + /** + * Is array + * + * Function will return true if object is array. + * + * @return bool + */ + public function isArray(): bool + { + return false; + } + + /** + * Get Type + * + * Returns validator type. + * + * @return string + */ + public function getType(): string + { + return self::TYPE_STRING; + } +} diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 411ab6e852..675513e573 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -66,6 +66,7 @@ class Exception extends \Exception public const USER_SESSION_ALREADY_EXISTS = 'user_session_already_exists'; public const USER_NOT_FOUND = 'user_not_found'; public const USER_PASSWORD_RECENTLY_USED = 'password_recently_used'; + public const USER_PASSWORD_PERSONAL_DATA = 'password_personal_data'; public const USER_EMAIL_ALREADY_EXISTS = 'user_email_already_exists'; public const USER_PASSWORD_MISMATCH = 'user_password_mismatch'; public const USER_SESSION_NOT_FOUND = 'user_session_not_found'; diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index ba751516d3..ec692d21af 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -10,1512 +10,1512 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator; trait AccountBase { - public function testCreateAccount(): array - { - $email = uniqid() . 'user@localhost.test'; - $password = 'password'; - $name = 'User Name'; - - /** - * 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'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => $password, - 'name' => $name, - ]); - - $id = $response['body']['$id']; - - $this->assertEquals($response['headers']['status-code'], 201); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - $this->assertEquals($response['body']['name'], $name); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => $password, - 'name' => $name, - ]); - - $this->assertEquals($response['headers']['status-code'], 409); - - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => '', - 'password' => '', - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => '', - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => '', - 'password' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - return [ - 'id' => $id, - 'email' => $email, - 'password' => $password, - 'name' => $name, - ]; - } - - /** - * @depends testCreateAccount - */ - public function testCreateAccountSession($data): array - { - $email = $data['email'] ?? ''; - $password = $data['password'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 201); - $this->assertNotFalse(\DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $response['body']['expire'])); - - $sessionId = $response['body']['$id']; - $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; - - $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' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 201); - $this->assertNotFalse(\DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $response['body']['expire'])); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email . 'x', - 'password' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 401); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password . 'x', - ]); - - $this->assertEquals($response['headers']['status-code'], 401); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => '', - 'password' => '', - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - return array_merge($data, [ - 'sessionId' => $sessionId, - 'session' => $session, - ]); - } - - /** - * @depends testCreateAccountSession - */ - public function testGetAccount($data): array - { - $email = $data['email'] ?? ''; - $name = $data['name'] ?? ''; - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - $this->assertEquals($response['body']['name'], $name); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ])); - - $this->assertEquals($response['headers']['status-code'], 401); - - $response = $this->client->call(Client::METHOD_GET, '/account', [ - 'content-type' => 'application/json', - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session . 'xx', - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - /** - * @depends testCreateAccountSession - */ - public function testGetAccountPrefs($data): array - { - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/account/prefs', 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'], 200); - $this->assertIsArray($response['body']); - $this->assertEmpty($response['body']); - $this->assertCount(0, $response['body']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ])); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - /** - * @depends testCreateAccountSession - */ - public function testGetAccountSessions($data): array - { - $session = $data['session'] ?? ''; - $sessionId = $data['sessionId'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/account/sessions', 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'], 200); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $this->assertCount(2, $response['body']); - $this->assertEquals(2, $response['body']['total']); - $this->assertEquals($sessionId, $response['body']['sessions'][0]['$id']); - - $this->assertEquals('Windows', $response['body']['sessions'][0]['osName']); - $this->assertEquals('WIN', $response['body']['sessions'][0]['osCode']); - $this->assertEquals('10', $response['body']['sessions'][0]['osVersion']); - - $this->assertEquals('browser', $response['body']['sessions'][0]['clientType']); - $this->assertEquals('Chrome', $response['body']['sessions'][0]['clientName']); - $this->assertEquals('CH', $response['body']['sessions'][0]['clientCode']); - $this->assertEquals('70.0', $response['body']['sessions'][0]['clientVersion']); - $this->assertEquals('Blink', $response['body']['sessions'][0]['clientEngine']); - $this->assertEquals('desktop', $response['body']['sessions'][0]['deviceName']); - $this->assertEquals('', $response['body']['sessions'][0]['deviceBrand']); - $this->assertEquals('', $response['body']['sessions'][0]['deviceModel']); - $this->assertEquals($response['body']['sessions'][0]['ip'], filter_var($response['body']['sessions'][0]['ip'], FILTER_VALIDATE_IP)); - - $this->assertEquals('--', $response['body']['sessions'][0]['countryCode']); - $this->assertEquals('Unknown', $response['body']['sessions'][0]['countryName']); - - $this->assertEquals(true, $response['body']['sessions'][0]['current']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account/sessions', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ])); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - /** - * @depends testCreateAccountSession - */ - public function testGetAccountLogs($data): array - { - sleep(10); - $session = $data['session'] ?? ''; - $sessionId = $data['sessionId'] ?? ''; - $userId = $data['id'] ?? ''; - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/account/logs', 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'], 200); - $this->assertIsArray($response['body']['logs']); - $this->assertNotEmpty($response['body']['logs']); - $this->assertCount(3, $response['body']['logs']); - $this->assertIsNumeric($response['body']['total']); - $this->assertContains($response['body']['logs'][1]['event'], ["session.create"]); - $this->assertEquals($response['body']['logs'][1]['ip'], filter_var($response['body']['logs'][1]['ip'], FILTER_VALIDATE_IP)); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['logs'][1]['time'])); - - $this->assertEquals('Windows', $response['body']['logs'][1]['osName']); - $this->assertEquals('WIN', $response['body']['logs'][1]['osCode']); - $this->assertEquals('10', $response['body']['logs'][1]['osVersion']); - - $this->assertEquals('browser', $response['body']['logs'][1]['clientType']); - $this->assertEquals('Chrome', $response['body']['logs'][1]['clientName']); - $this->assertEquals('CH', $response['body']['logs'][1]['clientCode']); - $this->assertEquals('70.0', $response['body']['logs'][1]['clientVersion']); - $this->assertEquals('Blink', $response['body']['logs'][1]['clientEngine']); - - $this->assertEquals('desktop', $response['body']['logs'][1]['deviceName']); - $this->assertEquals('', $response['body']['logs'][1]['deviceBrand']); - $this->assertEquals('', $response['body']['logs'][1]['deviceModel']); - $this->assertEquals($response['body']['logs'][1]['ip'], filter_var($response['body']['logs'][1]['ip'], FILTER_VALIDATE_IP)); - - $this->assertEquals('--', $response['body']['logs'][1]['countryCode']); - $this->assertEquals('Unknown', $response['body']['logs'][1]['countryName']); - - $this->assertContains($response['body']['logs'][2]['event'], ["user.create"]); - $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); - $this->assertEquals(true, $dateValidator->isValid($response['body']['logs'][2]['time'])); - - $this->assertEquals('Windows', $response['body']['logs'][2]['osName']); - $this->assertEquals('WIN', $response['body']['logs'][2]['osCode']); - $this->assertEquals('10', $response['body']['logs'][2]['osVersion']); - - $this->assertEquals('browser', $response['body']['logs'][2]['clientType']); - $this->assertEquals('Chrome', $response['body']['logs'][2]['clientName']); - $this->assertEquals('CH', $response['body']['logs'][2]['clientCode']); - $this->assertEquals('70.0', $response['body']['logs'][2]['clientVersion']); - $this->assertEquals('Blink', $response['body']['logs'][2]['clientEngine']); - - $this->assertEquals('desktop', $response['body']['logs'][2]['deviceName']); - $this->assertEquals('', $response['body']['logs'][2]['deviceBrand']); - $this->assertEquals('', $response['body']['logs'][2]['deviceModel']); - $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); - - $this->assertEquals('--', $response['body']['logs'][2]['countryCode']); - $this->assertEquals('Unknown', $response['body']['logs'][2]['countryName']); - - $responseLimit = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'queries' => [ 'limit(1)' ], - ]); - - $this->assertEquals($responseLimit['headers']['status-code'], 200); - $this->assertIsArray($responseLimit['body']['logs']); - $this->assertNotEmpty($responseLimit['body']['logs']); - $this->assertCount(1, $responseLimit['body']['logs']); - $this->assertIsNumeric($responseLimit['body']['total']); - - $this->assertEquals($response['body']['logs'][0], $responseLimit['body']['logs'][0]); - - $responseOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'queries' => [ 'offset(1)' ], - ]); - - $this->assertEquals($responseOffset['headers']['status-code'], 200); - $this->assertIsArray($responseOffset['body']['logs']); - $this->assertNotEmpty($responseOffset['body']['logs']); - $this->assertCount(2, $responseOffset['body']['logs']); - $this->assertIsNumeric($responseOffset['body']['total']); - - $this->assertEquals($response['body']['logs'][1], $responseOffset['body']['logs'][0]); - - $responseLimitOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'queries' => [ 'limit(1)', 'offset(1)' ], - ]); - - $this->assertEquals($responseLimitOffset['headers']['status-code'], 200); - $this->assertIsArray($responseLimitOffset['body']['logs']); - $this->assertNotEmpty($responseLimitOffset['body']['logs']); - $this->assertCount(1, $responseLimitOffset['body']['logs']); - $this->assertIsNumeric($responseLimitOffset['body']['total']); - - $this->assertEquals($response['body']['logs'][1], $responseLimitOffset['body']['logs'][0]); - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ])); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - // TODO Add tests for OAuth2 session creation - - /** - * @depends testCreateAccountSession - */ - public function testUpdateAccountName($data): array - { - $email = $data['email'] ?? ''; - $session = $data['session'] ?? ''; - $newName = 'Lorem'; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'name' => $newName - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - $this->assertEquals($response['body']['name'], $newName); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/name', 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/name', 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); - - $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y72222222222222222222222222222' - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - $data['name'] = $newName; - - return $data; - } - - /** - * @depends testUpdateAccountName - */ - #[Retry(count: 1)] - public function testUpdateAccountPassword($data): array - { - $email = $data['email'] ?? ''; - $password = $data['password'] ?? ''; - $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', - 'oldPassword' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', 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' => $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; - } - - /** - * @depends testUpdateAccountPassword - */ - public function testUpdateAccountEmail($data): array - { - $newEmail = uniqid() . 'new@localhost.test'; - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'email' => $newEmail, - 'password' => 'new-password', - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $newEmail); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/email', 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/email', 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); - - // 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'], - ]), [ - 'userId' => ID::unique(), - '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->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $data['email']); - $this->assertEquals($response['body']['name'], $data['name']); - - - $data['email'] = $newEmail; - - return $data; - } - - /** - * @depends testUpdateAccountEmail - */ - public function testUpdateAccountPrefs($data): array - { - $newEmail = uniqid() . 'new@localhost.test'; - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => [ - 'prefKey1' => 'prefValue1', - 'prefKey2' => 'prefValue2', - ] - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $this->assertEquals('prefValue1', $response['body']['prefs']['prefKey1']); - $this->assertEquals('prefValue2', $response['body']['prefs']['prefKey2']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', 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/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => '{}' - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => '[]' - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => '{"test": "value"}' - ]); - - $this->assertEquals($response['headers']['status-code'], 400); - - /** - * Prefs size exceeded - */ - $prefsObject = ["longValue" => str_repeat("🍰", 100000)]; - - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => $prefsObject - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - // Now let's test the same thing, but with normal symbol instead of multi-byte cake emoji - $prefsObject = ["longValue" => str_repeat("-", 100000)]; - - $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'prefs' => $prefsObject - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - return $data; - } - - /** - * @depends testUpdateAccountPrefs - */ - public function testCreateAccountVerification($data): array - { - $email = $data['email'] ?? ''; - $name = $data['name'] ?? ''; - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - - ]), [ - 'url' => 'http://localhost/verification', - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']['$id']); - $this->assertEmpty($response['body']['secret']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); - - $lastEmail = $this->getLastEmail(); - - $this->assertEquals($email, $lastEmail['to'][0]['address']); - $this->assertEquals($name, $lastEmail['to'][0]['name']); - $this->assertEquals('Account Verification', $lastEmail['subject']); - - $verification = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); - $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); - $this->assertNotFalse($expireTime); - - $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); - - $this->assertNotFalse($secretTest); - - $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); - - $this->assertNotFalse($userIDTest); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'url' => 'localhost/verification', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'url' => 'http://remotehost/verification', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $data['verification'] = $verification; - - return $data; - } - - /** - * @depends testCreateAccountVerification - */ - public function testUpdateAccountVerification($data): array - { - $id = $data['id'] ?? ''; - $session = $data['session'] ?? ''; - $verification = $data['verification'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'userId' => $id, - 'secret' => $verification, - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'userId' => ID::custom('ewewe'), - 'secret' => $verification, - ]); - - $this->assertEquals(404, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), [ - 'userId' => $id, - 'secret' => 'sdasdasdasd', - ]); - - $this->assertEquals(401, $response['headers']['status-code']); - - return $data; - } - - /** - * @depends testUpdateAccountVerification - */ - public function testDeleteAccountSession($data): array - { - $email = $data['email'] ?? ''; - $password = $data['password'] ?? ''; - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); - - $sessionNewId = $response['body']['$id']; - $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; - - $this->assertEquals($response['headers']['status-code'], 201); - - $response = $this->client->call(Client::METHOD_GET, '/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - - $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/' . $sessionNewId, array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - ])); - - $this->assertEquals($response['headers']['status-code'], 204); - - $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - ]); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - /** - * @depends testUpdateAccountVerification - */ - public function testDeleteAccountSessionCurrent($data): array - { - $email = $data['email'] ?? ''; - $password = $data['password'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); - - $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; - - $this->assertEquals($response['headers']['status-code'], 201); - - $response = $this->client->call(Client::METHOD_GET, '/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals($response['headers']['status-code'], 200); - - $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/current', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals($response['headers']['status-code'], 204); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, - 'x-appwrite-project' => $this->getProject()['$id'], - ]); - - $this->assertEquals($response['headers']['status-code'], 401); - - return $data; - } - - /** - * @depends testUpdateAccountVerification - */ - public function testDeleteAccountSessions($data): array - { - $session = $data['session'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions', 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'], 204); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ])); - - $this->assertEquals($response['headers']['status-code'], 401); - - /** - * Create new fallback session - */ - $email = $data['email'] ?? ''; - $password = $data['password'] ?? ''; - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); - - $data['session'] = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; - - return $data; - } - - /** - * @depends testDeleteAccountSession - */ - public function testCreateAccountRecovery($data): array - { - $email = $data['email'] ?? ''; - $name = $data['name'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'url' => 'http://localhost/recovery', - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']['$id']); - $this->assertEmpty($response['body']['secret']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); - - $lastEmail = $this->getLastEmail(); - - $this->assertEquals($email, $lastEmail['to'][0]['address']); - $this->assertEquals($name, $lastEmail['to'][0]['name']); - $this->assertEquals('Password Reset', $lastEmail['subject']); - - $recovery = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); - - $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); - - $this->assertNotFalse($expireTime); - - $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); - - $this->assertNotFalse($secretTest); - - $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); - - $this->assertNotFalse($userIDTest); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'url' => 'localhost/recovery', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'url' => 'http://remotehost/recovery', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => 'not-found@localhost.test', - 'url' => 'http://localhost/recovery', - ]); - - $this->assertEquals(404, $response['headers']['status-code']); - - $data['recovery'] = $recovery; - - return $data; - } - - /** - * @depends testCreateAccountRecovery - */ - #[Retry(count: 1)] - public function testUpdateAccountRecovery($data): array - { - $id = $data['id'] ?? ''; - $recovery = $data['recovery'] ?? ''; - $newPassowrd = 'test-recovery'; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => $id, - 'secret' => $recovery, - 'password' => $newPassowrd, - 'passwordAgain' => $newPassowrd, - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::custom('ewewe'), - 'secret' => $recovery, - 'password' => $newPassowrd, - 'passwordAgain' => $newPassowrd, - ]); - - $this->assertEquals(404, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => $id, - 'secret' => 'sdasdasdasd', - 'password' => $newPassowrd, - 'passwordAgain' => $newPassowrd, - ]); - - $this->assertEquals(401, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => $id, - 'secret' => $recovery, - 'password' => $newPassowrd . 'x', - 'passwordAgain' => $newPassowrd, - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - return $data; - } - - public function testCreateMagicUrl(): array - { - $email = \time() . 'user@appwrite.io'; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - // 'url' => 'http://localhost/magiclogin', - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']['$id']); - $this->assertEmpty($response['body']['secret']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); - - $userId = $response['body']['userId']; - - $lastEmail = $this->getLastEmail(); - $this->assertEquals($email, $lastEmail['to'][0]['address']); - $this->assertEquals('Login', $lastEmail['subject']); - - $token = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); - - $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); - - $this->assertNotFalse($expireTime); - - $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); - - $this->assertNotFalse($secretTest); - - $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); - - $this->assertNotFalse($userIDTest); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'url' => 'localhost/magiclogin', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'url' => 'http://remotehost/magiclogin', - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - $data['token'] = $token; - $data['id'] = $userId; - $data['email'] = $email; - - return $data; - } - - /** - * @depends testCreateMagicUrl - */ - public function testCreateSessionWithMagicUrl($data): array - { - $id = $data['id'] ?? ''; - $token = $data['token'] ?? ''; - $email = $data['email'] ?? ''; - - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => $id, - 'secret' => $token, - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $this->assertIsArray($response['body']); - $this->assertNotEmpty($response['body']); - $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']]; - - $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - $this->assertTrue($response['body']['emailVerification']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::custom('ewewe'), - 'secret' => $token, - ]); - - $this->assertEquals(404, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => $id, - 'secret' => 'sdasdasdasd', - ]); - - $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']); - $dateValidator = new DatetimeValidator(); - $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); - $this->assertEquals($response['body']['email'], $email); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', 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; - } + // public function testCreateAccount(): array + // { + // $email = uniqid() . 'user@localhost.test'; + // $password = 'password'; + // $name = 'User Name'; + + // /** + // * 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'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // 'password' => $password, + // 'name' => $name, + // ]); + + // $id = $response['body']['$id']; + + // $this->assertEquals($response['headers']['status-code'], 201); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + // $this->assertEquals($response['body']['name'], $name); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // 'password' => $password, + // 'name' => $name, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 409); + + // $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => '', + // 'password' => '', + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // 'password' => '', + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => '', + // 'password' => $password, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // return [ + // 'id' => $id, + // 'email' => $email, + // 'password' => $password, + // 'name' => $name, + // ]; + // } + + // /** + // * @depends testCreateAccount + // */ + // public function testCreateAccountSession($data): array + // { + // $email = $data['email'] ?? ''; + // $password = $data['password'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'password' => $password, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 201); + // $this->assertNotFalse(\DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $response['body']['expire'])); + + // $sessionId = $response['body']['$id']; + // $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; + + // $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' => $password, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 201); + // $this->assertNotFalse(\DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $response['body']['expire'])); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email . 'x', + // 'password' => $password, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'password' => $password . 'x', + // ]); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => '', + // 'password' => '', + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // return array_merge($data, [ + // 'sessionId' => $sessionId, + // 'session' => $session, + // ]); + // } + + // /** + // * @depends testCreateAccountSession + // */ + // public function testGetAccount($data): array + // { + // $email = $data['email'] ?? ''; + // $name = $data['name'] ?? ''; + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + // $this->assertEquals($response['body']['name'], $name); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ])); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // $response = $this->client->call(Client::METHOD_GET, '/account', [ + // 'content-type' => 'application/json', + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session . 'xx', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // /** + // * @depends testCreateAccountSession + // */ + // public function testGetAccountPrefs($data): array + // { + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/prefs', 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'], 200); + // $this->assertIsArray($response['body']); + // $this->assertEmpty($response['body']); + // $this->assertCount(0, $response['body']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ])); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // /** + // * @depends testCreateAccountSession + // */ + // public function testGetAccountSessions($data): array + // { + // $session = $data['session'] ?? ''; + // $sessionId = $data['sessionId'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/sessions', 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'], 200); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $this->assertCount(2, $response['body']); + // $this->assertEquals(2, $response['body']['total']); + // $this->assertEquals($sessionId, $response['body']['sessions'][0]['$id']); + + // $this->assertEquals('Windows', $response['body']['sessions'][0]['osName']); + // $this->assertEquals('WIN', $response['body']['sessions'][0]['osCode']); + // $this->assertEquals('10', $response['body']['sessions'][0]['osVersion']); + + // $this->assertEquals('browser', $response['body']['sessions'][0]['clientType']); + // $this->assertEquals('Chrome', $response['body']['sessions'][0]['clientName']); + // $this->assertEquals('CH', $response['body']['sessions'][0]['clientCode']); + // $this->assertEquals('70.0', $response['body']['sessions'][0]['clientVersion']); + // $this->assertEquals('Blink', $response['body']['sessions'][0]['clientEngine']); + // $this->assertEquals('desktop', $response['body']['sessions'][0]['deviceName']); + // $this->assertEquals('', $response['body']['sessions'][0]['deviceBrand']); + // $this->assertEquals('', $response['body']['sessions'][0]['deviceModel']); + // $this->assertEquals($response['body']['sessions'][0]['ip'], filter_var($response['body']['sessions'][0]['ip'], FILTER_VALIDATE_IP)); + + // $this->assertEquals('--', $response['body']['sessions'][0]['countryCode']); + // $this->assertEquals('Unknown', $response['body']['sessions'][0]['countryName']); + + // $this->assertEquals(true, $response['body']['sessions'][0]['current']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/sessions', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ])); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // /** + // * @depends testCreateAccountSession + // */ + // public function testGetAccountLogs($data): array + // { + // sleep(10); + // $session = $data['session'] ?? ''; + // $sessionId = $data['sessionId'] ?? ''; + // $userId = $data['id'] ?? ''; + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/logs', 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'], 200); + // $this->assertIsArray($response['body']['logs']); + // $this->assertNotEmpty($response['body']['logs']); + // $this->assertCount(3, $response['body']['logs']); + // $this->assertIsNumeric($response['body']['total']); + // $this->assertContains($response['body']['logs'][1]['event'], ["session.create"]); + // $this->assertEquals($response['body']['logs'][1]['ip'], filter_var($response['body']['logs'][1]['ip'], FILTER_VALIDATE_IP)); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['logs'][1]['time'])); + + // $this->assertEquals('Windows', $response['body']['logs'][1]['osName']); + // $this->assertEquals('WIN', $response['body']['logs'][1]['osCode']); + // $this->assertEquals('10', $response['body']['logs'][1]['osVersion']); + + // $this->assertEquals('browser', $response['body']['logs'][1]['clientType']); + // $this->assertEquals('Chrome', $response['body']['logs'][1]['clientName']); + // $this->assertEquals('CH', $response['body']['logs'][1]['clientCode']); + // $this->assertEquals('70.0', $response['body']['logs'][1]['clientVersion']); + // $this->assertEquals('Blink', $response['body']['logs'][1]['clientEngine']); + + // $this->assertEquals('desktop', $response['body']['logs'][1]['deviceName']); + // $this->assertEquals('', $response['body']['logs'][1]['deviceBrand']); + // $this->assertEquals('', $response['body']['logs'][1]['deviceModel']); + // $this->assertEquals($response['body']['logs'][1]['ip'], filter_var($response['body']['logs'][1]['ip'], FILTER_VALIDATE_IP)); + + // $this->assertEquals('--', $response['body']['logs'][1]['countryCode']); + // $this->assertEquals('Unknown', $response['body']['logs'][1]['countryName']); + + // $this->assertContains($response['body']['logs'][2]['event'], ["user.create"]); + // $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['logs'][2]['time'])); + + // $this->assertEquals('Windows', $response['body']['logs'][2]['osName']); + // $this->assertEquals('WIN', $response['body']['logs'][2]['osCode']); + // $this->assertEquals('10', $response['body']['logs'][2]['osVersion']); + + // $this->assertEquals('browser', $response['body']['logs'][2]['clientType']); + // $this->assertEquals('Chrome', $response['body']['logs'][2]['clientName']); + // $this->assertEquals('CH', $response['body']['logs'][2]['clientCode']); + // $this->assertEquals('70.0', $response['body']['logs'][2]['clientVersion']); + // $this->assertEquals('Blink', $response['body']['logs'][2]['clientEngine']); + + // $this->assertEquals('desktop', $response['body']['logs'][2]['deviceName']); + // $this->assertEquals('', $response['body']['logs'][2]['deviceBrand']); + // $this->assertEquals('', $response['body']['logs'][2]['deviceModel']); + // $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); + + // $this->assertEquals('--', $response['body']['logs'][2]['countryCode']); + // $this->assertEquals('Unknown', $response['body']['logs'][2]['countryName']); + + // $responseLimit = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'queries' => [ 'limit(1)' ], + // ]); + + // $this->assertEquals($responseLimit['headers']['status-code'], 200); + // $this->assertIsArray($responseLimit['body']['logs']); + // $this->assertNotEmpty($responseLimit['body']['logs']); + // $this->assertCount(1, $responseLimit['body']['logs']); + // $this->assertIsNumeric($responseLimit['body']['total']); + + // $this->assertEquals($response['body']['logs'][0], $responseLimit['body']['logs'][0]); + + // $responseOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'queries' => [ 'offset(1)' ], + // ]); + + // $this->assertEquals($responseOffset['headers']['status-code'], 200); + // $this->assertIsArray($responseOffset['body']['logs']); + // $this->assertNotEmpty($responseOffset['body']['logs']); + // $this->assertCount(2, $responseOffset['body']['logs']); + // $this->assertIsNumeric($responseOffset['body']['total']); + + // $this->assertEquals($response['body']['logs'][1], $responseOffset['body']['logs'][0]); + + // $responseLimitOffset = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'queries' => [ 'limit(1)', 'offset(1)' ], + // ]); + + // $this->assertEquals($responseLimitOffset['headers']['status-code'], 200); + // $this->assertIsArray($responseLimitOffset['body']['logs']); + // $this->assertNotEmpty($responseLimitOffset['body']['logs']); + // $this->assertCount(1, $responseLimitOffset['body']['logs']); + // $this->assertIsNumeric($responseLimitOffset['body']['total']); + + // $this->assertEquals($response['body']['logs'][1], $responseLimitOffset['body']['logs'][0]); + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account/logs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ])); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // // TODO Add tests for OAuth2 session creation + + // /** + // * @depends testCreateAccountSession + // */ + // public function testUpdateAccountName($data): array + // { + // $email = $data['email'] ?? ''; + // $session = $data['session'] ?? ''; + // $newName = 'Lorem'; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'name' => $newName + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + // $this->assertEquals($response['body']['name'], $newName); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/name', 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/name', 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); + + // $response = $this->client->call(Client::METHOD_PATCH, '/account/name', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y72222222222222222222222222222' + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // $data['name'] = $newName; + + // return $data; + // } + + // /** + // * @depends testUpdateAccountName + // */ + // #[Retry(count: 1)] + // public function testUpdateAccountPassword($data): array + // { + // $email = $data['email'] ?? ''; + // $password = $data['password'] ?? ''; + // $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', + // 'oldPassword' => $password, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', 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' => $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; + // } + + // /** + // * @depends testUpdateAccountPassword + // */ + // public function testUpdateAccountEmail($data): array + // { + // $newEmail = uniqid() . 'new@localhost.test'; + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'email' => $newEmail, + // 'password' => 'new-password', + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $newEmail); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/email', 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/email', 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); + + // // 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'], + // ]), [ + // 'userId' => ID::unique(), + // '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->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $data['email']); + // $this->assertEquals($response['body']['name'], $data['name']); + + + // $data['email'] = $newEmail; + + // return $data; + // } + + // /** + // * @depends testUpdateAccountEmail + // */ + // public function testUpdateAccountPrefs($data): array + // { + // $newEmail = uniqid() . 'new@localhost.test'; + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => [ + // 'prefKey1' => 'prefValue1', + // 'prefKey2' => 'prefValue2', + // ] + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $this->assertEquals('prefValue1', $response['body']['prefs']['prefKey1']); + // $this->assertEquals('prefValue2', $response['body']['prefs']['prefKey2']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', 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/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => '{}' + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => '[]' + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => '{"test": "value"}' + // ]); + + // $this->assertEquals($response['headers']['status-code'], 400); + + // /** + // * Prefs size exceeded + // */ + // $prefsObject = ["longValue" => str_repeat("🍰", 100000)]; + + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => $prefsObject + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // // Now let's test the same thing, but with normal symbol instead of multi-byte cake emoji + // $prefsObject = ["longValue" => str_repeat("-", 100000)]; + + // $response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'prefs' => $prefsObject + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // return $data; + // } + + // /** + // * @depends testUpdateAccountPrefs + // */ + // public function testCreateAccountVerification($data): array + // { + // $email = $data['email'] ?? ''; + // $name = $data['name'] ?? ''; + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + + // ]), [ + // 'url' => 'http://localhost/verification', + // ]); + + // $this->assertEquals(201, $response['headers']['status-code']); + // $this->assertNotEmpty($response['body']['$id']); + // $this->assertEmpty($response['body']['secret']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); + + // $lastEmail = $this->getLastEmail(); + + // $this->assertEquals($email, $lastEmail['to'][0]['address']); + // $this->assertEquals($name, $lastEmail['to'][0]['name']); + // $this->assertEquals('Account Verification', $lastEmail['subject']); + + // $verification = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); + // $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); + // $this->assertNotFalse($expireTime); + + // $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); + + // $this->assertNotFalse($secretTest); + + // $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); + + // $this->assertNotFalse($userIDTest); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'url' => 'localhost/verification', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'url' => 'http://remotehost/verification', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $data['verification'] = $verification; + + // return $data; + // } + + // /** + // * @depends testCreateAccountVerification + // */ + // public function testUpdateAccountVerification($data): array + // { + // $id = $data['id'] ?? ''; + // $session = $data['session'] ?? ''; + // $verification = $data['verification'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'userId' => $id, + // 'secret' => $verification, + // ]); + + // $this->assertEquals(200, $response['headers']['status-code']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'userId' => ID::custom('ewewe'), + // 'secret' => $verification, + // ]); + + // $this->assertEquals(404, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + // ]), [ + // 'userId' => $id, + // 'secret' => 'sdasdasdasd', + // ]); + + // $this->assertEquals(401, $response['headers']['status-code']); + + // return $data; + // } + + // /** + // * @depends testUpdateAccountVerification + // */ + // public function testDeleteAccountSession($data): array + // { + // $email = $data['email'] ?? ''; + // $password = $data['password'] ?? ''; + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'password' => $password, + // ]); + + // $sessionNewId = $response['body']['$id']; + // $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; + + // $this->assertEquals($response['headers']['status-code'], 201); + + // $response = $this->client->call(Client::METHOD_GET, '/account', [ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + + // $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/' . $sessionNewId, array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // ])); + + // $this->assertEquals($response['headers']['status-code'], 204); + + // $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account', [ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // ]); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // /** + // * @depends testUpdateAccountVerification + // */ + // public function testDeleteAccountSessionCurrent($data): array + // { + // $email = $data['email'] ?? ''; + // $password = $data['password'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'password' => $password, + // ]); + + // $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; + + // $this->assertEquals($response['headers']['status-code'], 201); + + // $response = $this->client->call(Client::METHOD_GET, '/account', [ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]); + + // $this->assertEquals($response['headers']['status-code'], 200); + + // $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/current', [ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]); + + // $this->assertEquals($response['headers']['status-code'], 204); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account', [ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $sessionNew, + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // return $data; + // } + + // /** + // * @depends testUpdateAccountVerification + // */ + // public function testDeleteAccountSessions($data): array + // { + // $session = $data['session'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_DELETE, '/account/sessions', 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'], 204); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ])); + + // $this->assertEquals($response['headers']['status-code'], 401); + + // /** + // * Create new fallback session + // */ + // $email = $data['email'] ?? ''; + // $password = $data['password'] ?? ''; + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'password' => $password, + // ]); + + // $data['session'] = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_' . $this->getProject()['$id']]; + + // return $data; + // } + + // /** + // * @depends testDeleteAccountSession + // */ + // public function testCreateAccountRecovery($data): array + // { + // $email = $data['email'] ?? ''; + // $name = $data['name'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'url' => 'http://localhost/recovery', + // ]); + + // $this->assertEquals(201, $response['headers']['status-code']); + // $this->assertNotEmpty($response['body']['$id']); + // $this->assertEmpty($response['body']['secret']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); + + // $lastEmail = $this->getLastEmail(); + + // $this->assertEquals($email, $lastEmail['to'][0]['address']); + // $this->assertEquals($name, $lastEmail['to'][0]['name']); + // $this->assertEquals('Password Reset', $lastEmail['subject']); + + // $recovery = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); + + // $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); + + // $this->assertNotFalse($expireTime); + + // $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); + + // $this->assertNotFalse($secretTest); + + // $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); + + // $this->assertNotFalse($userIDTest); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'url' => 'localhost/recovery', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // 'url' => 'http://remotehost/recovery', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => 'not-found@localhost.test', + // 'url' => 'http://localhost/recovery', + // ]); + + // $this->assertEquals(404, $response['headers']['status-code']); + + // $data['recovery'] = $recovery; + + // return $data; + // } + + // /** + // * @depends testCreateAccountRecovery + // */ + // #[Retry(count: 1)] + // public function testUpdateAccountRecovery($data): array + // { + // $id = $data['id'] ?? ''; + // $recovery = $data['recovery'] ?? ''; + // $newPassowrd = 'test-recovery'; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => $id, + // 'secret' => $recovery, + // 'password' => $newPassowrd, + // 'passwordAgain' => $newPassowrd, + // ]); + + // $this->assertEquals(200, $response['headers']['status-code']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::custom('ewewe'), + // 'secret' => $recovery, + // 'password' => $newPassowrd, + // 'passwordAgain' => $newPassowrd, + // ]); + + // $this->assertEquals(404, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => $id, + // 'secret' => 'sdasdasdasd', + // 'password' => $newPassowrd, + // 'passwordAgain' => $newPassowrd, + // ]); + + // $this->assertEquals(401, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => $id, + // 'secret' => $recovery, + // 'password' => $newPassowrd . 'x', + // 'passwordAgain' => $newPassowrd, + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // return $data; + // } + + // public function testCreateMagicUrl(): array + // { + // $email = \time() . 'user@appwrite.io'; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // // 'url' => 'http://localhost/magiclogin', + // ]); + + // $this->assertEquals(201, $response['headers']['status-code']); + // $this->assertNotEmpty($response['body']['$id']); + // $this->assertEmpty($response['body']['secret']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['expire'])); + + // $userId = $response['body']['userId']; + + // $lastEmail = $this->getLastEmail(); + // $this->assertEquals($email, $lastEmail['to'][0]['address']); + // $this->assertEquals('Login', $lastEmail['subject']); + + // $token = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256); + + // $expireTime = strpos($lastEmail['text'], 'expire=' . urlencode(DateTime::format(new \DateTime($response['body']['expire']))), 0); + + // $this->assertNotFalse($expireTime); + + // $secretTest = strpos($lastEmail['text'], 'secret=' . $response['body']['secret'], 0); + + // $this->assertNotFalse($secretTest); + + // $userIDTest = strpos($lastEmail['text'], 'userId=' . $response['body']['userId'], 0); + + // $this->assertNotFalse($userIDTest); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // 'url' => 'localhost/magiclogin', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::unique(), + // 'email' => $email, + // 'url' => 'http://remotehost/magiclogin', + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'email' => $email, + // ]); + + // $this->assertEquals(400, $response['headers']['status-code']); + + // $data['token'] = $token; + // $data['id'] = $userId; + // $data['email'] = $email; + + // return $data; + // } + + // /** + // * @depends testCreateMagicUrl + // */ + // public function testCreateSessionWithMagicUrl($data): array + // { + // $id = $data['id'] ?? ''; + // $token = $data['token'] ?? ''; + // $email = $data['email'] ?? ''; + + // /** + // * Test for SUCCESS + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => $id, + // 'secret' => $token, + // ]); + + // $this->assertEquals(201, $response['headers']['status-code']); + // $this->assertIsArray($response['body']); + // $this->assertNotEmpty($response['body']); + // $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']]; + + // $response = $this->client->call(Client::METHOD_GET, '/account', 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'], 200); + // $this->assertNotEmpty($response['body']); + // $this->assertNotEmpty($response['body']['$id']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + // $this->assertTrue($response['body']['emailVerification']); + + // /** + // * Test for FAILURE + // */ + // $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => ID::custom('ewewe'), + // 'secret' => $token, + // ]); + + // $this->assertEquals(404, $response['headers']['status-code']); + + // $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/magic-url', array_merge([ + // 'origin' => 'http://localhost', + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ]), [ + // 'userId' => $id, + // 'secret' => 'sdasdasdasd', + // ]); + + // $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']); + // $dateValidator = new DatetimeValidator(); + // $this->assertEquals(true, $dateValidator->isValid($response['body']['registration'])); + // $this->assertEquals($response['body']['email'], $email); + + // $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', 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; + // } } diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 91699f2dba..c873dd32d9 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -3,6 +3,7 @@ namespace Tests\E2E\Services\Projects; use Appwrite\Auth\Auth; +use Appwrite\Extend\Exception; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\SideClient; @@ -1071,7 +1072,7 @@ class ProjectsConsoleClientTest extends Scope 'password' => $password, ]); - $this->assertEquals(409, $response['headers']['status-code']); + $this->assertEquals(400, $response['headers']['status-code']); $headers = array_merge($this->getHeaders(), [ 'x-appwrite-mode' => 'admin', @@ -1083,7 +1084,7 @@ class ProjectsConsoleClientTest extends Scope 'password' => $password, ]); - $this->assertEquals(409, $response['headers']['status-code']); + $this->assertEquals(400, $response['headers']['status-code']); /** @@ -1232,6 +1233,115 @@ class ProjectsConsoleClientTest extends Scope return $data; } + /** + * @depends testCreateProject + */ + public function testUpdateDisallowPersonalData($data): void + { + $id = $data['projectId'] ?? ''; + + /** + * Enable Disallowing of Personal Data + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/disallow-personal-data', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'enabled' => true, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(true, $response['body']['authDisallowPersonalData']); + + /** + * Test for failure + */ + $email = uniqid() . 'user@localhost.test'; + $password = 'password'; + $name = 'username'; + $userId = ID::unique(); + + $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + ]), [ + 'email' => $email, + 'password' => $email, + 'name' => $name, + 'userId' => $userId + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals(400, $response['body']['code']); + $this->assertEquals(Exception::USER_PASSWORD_PERSONAL_DATA, $response['body']['type']); + + $phone = '+123456789'; + $response = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + 'x-appwrite-mode' => 'admin', + ]), [ + 'email' => $email, + 'password' => $phone, + 'name' => $name, + 'userId' => $userId, + 'phone' => $phone + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals(400, $response['body']['code']); + $this->assertEquals(Exception::USER_PASSWORD_PERSONAL_DATA, $response['body']['type']); + + /** Test for success */ + $email = uniqid() . 'user@localhost.test'; + $password = 'password'; + $name = 'username'; + $userId = ID::unique(); + $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + ]), [ + 'email' => $email, + 'password' => $password, + 'name' => $name, + 'userId' => $userId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $email = uniqid() . 'user@localhost.test'; + $userId = ID::unique(); + $response = $this->client->call(Client::METHOD_POST, '/users', array_merge($this->getHeaders(), [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + 'x-appwrite-mode' => 'admin', + ]), [ + 'email' => $email, + 'password' => $password, + 'name' => $name, + 'userId' => $userId, + 'phone' => $phone + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + + /** + * Reset + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-dictionary', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'enabled' => false, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(false, $response['body']['authPasswordDictionary']); + } + public function testUpdateProjectServiceStatusAdmin(): array { diff --git a/tests/unit/Auth/Validator/PersonalDataTest.php b/tests/unit/Auth/Validator/PersonalDataTest.php new file mode 100644 index 0000000000..5a27f93c0b --- /dev/null +++ b/tests/unit/Auth/Validator/PersonalDataTest.php @@ -0,0 +1,85 @@ +object = new PersonalData('userId', 'email@example.com', 'name', '+129492323', true); + + $this->assertEquals($this->object->isValid('userId'), false); + $this->assertEquals($this->object->isValid('something.userId'), false); + $this->assertEquals($this->object->isValid('userId.something'), false); + $this->assertEquals($this->object->isValid('something.userId.something'), false); + + $this->assertEquals($this->object->isValid('email@example.com'), false); + $this->assertEquals($this->object->isValid('something.email@example.com'), false); + $this->assertEquals($this->object->isValid('email@example.com.something'), false); + $this->assertEquals($this->object->isValid('something.email@example.com.something'), false); + + $this->assertEquals($this->object->isValid('name'), false); + $this->assertEquals($this->object->isValid('something.name'), false); + $this->assertEquals($this->object->isValid('name.something'), false); + $this->assertEquals($this->object->isValid('something.name.something'), false); + + $this->assertEquals($this->object->isValid('+129492323'), false); + $this->assertEquals($this->object->isValid('something.+129492323'), false); + $this->assertEquals($this->object->isValid('+129492323.something'), false); + $this->assertEquals($this->object->isValid('something.+129492323.something'), false); + + $this->assertEquals($this->object->isValid('129492323'), false); + $this->assertEquals($this->object->isValid('something.129492323'), false); + $this->assertEquals($this->object->isValid('129492323.something'), false); + $this->assertEquals($this->object->isValid('something.129492323.something'), false); + + $this->assertEquals($this->object->isValid('email'), false); + $this->assertEquals($this->object->isValid('something.email'), false); + $this->assertEquals($this->object->isValid('email.something'), false); + $this->assertEquals($this->object->isValid('something.email.something'), false); + } + + public function testNotStrict(): void + { + $this->object = new PersonalData('userId', 'email@example.com', 'name', '+129492323', false); + + $this->assertEquals($this->object->isValid('userId'), false); + $this->assertEquals($this->object->isValid('USERID'), false); + $this->assertEquals($this->object->isValid('something.USERID'), false); + $this->assertEquals($this->object->isValid('USERID.something'), false); + $this->assertEquals($this->object->isValid('something.USERID.something'), false); + + $this->assertEquals($this->object->isValid('email@example.com'), false); + $this->assertEquals($this->object->isValid('EMAIL@EXAMPLE.COM'), false); + $this->assertEquals($this->object->isValid('something.EMAIL@EXAMPLE.COM'), false); + $this->assertEquals($this->object->isValid('EMAIL@EXAMPLE.COM.something'), false); + $this->assertEquals($this->object->isValid('something.EMAIL@EXAMPLE.COM.something'), false); + + $this->assertEquals($this->object->isValid('name'), false); + $this->assertEquals($this->object->isValid('NAME'), false); + $this->assertEquals($this->object->isValid('something.NAME'), false); + $this->assertEquals($this->object->isValid('NAME.something'), false); + $this->assertEquals($this->object->isValid('something.NAME.something'), false); + + $this->assertEquals($this->object->isValid('+129492323'), false); + $this->assertEquals($this->object->isValid('129492323'), false); + + $this->assertEquals($this->object->isValid('email'), false); + $this->assertEquals($this->object->isValid('EMAIL'), false); + $this->assertEquals($this->object->isValid('something.EMAIL'), false); + $this->assertEquals($this->object->isValid('EMAIL.something'), false); + $this->assertEquals($this->object->isValid('something.EMAIL.something'), false); + } + + public function testSuccess(): void + { + $this->object = new PersonalData('userId', 'email@example.com', 'name', '+129492323', false); + $this->assertEquals($this->object->isValid('foo'), true); + $this->assertEquals($this->object->isValid('bar'), true); + } +}