From 89dcc34453b6a1ba7bf76105c6cccb7f8fb8db22 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Sun, 11 Feb 2024 20:21:19 +0530 Subject: [PATCH 01/15] feat: initial commit --- app/controllers/api/account.php | 28 ++++++- app/controllers/api/projects.php | 32 ++++++++ src/Appwrite/Auth/Validator/MockNumber.php | 77 +++++++++++++++++++ src/Appwrite/Utopia/Response.php | 8 +- .../Utopia/Response/Model/MockOTP.php | 47 +++++++++++ .../Utopia/Response/Model/Project.php | 7 ++ 6 files changed, 194 insertions(+), 5 deletions(-) create mode 100644 src/Appwrite/Auth/Validator/MockNumber.php create mode 100644 src/Appwrite/Utopia/Response/Model/MockOTP.php diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 0a067cc8fd..d2da3d4ef6 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1288,7 +1288,16 @@ App::post('/v1/account/sessions/phone') Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); } - $secret = Auth::codeGenerator(); + $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; + $secret = null; + foreach ($mockNumbers as $mockNumber) { + if ($mockNumber['number'] === $phone) { + $secret = $mockNumber['otp']; + break; + } + } + + $secret ??= Auth::codeGenerator(); $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE)); $token = new Document([ @@ -2879,14 +2888,25 @@ App::post('/v1/account/verification/phone') throw new Exception(Exception::GENERAL_PHONE_DISABLED); } - if (empty($user->getAttribute('phone'))) { + $phone = $user->getAttribute('phone'); + if (!$phone) { throw new Exception(Exception::USER_PHONE_NOT_FOUND); } $roles = Authorization::getRoles(); $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); - $secret = Auth::codeGenerator(); + + $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; + $secret = null; + foreach ($mockNumbers as $mockNumber) { + if ($mockNumber['number'] === $phone) { + $secret = $mockNumber['otp']; + break; + } + } + + $secret ??= Auth::codeGenerator(); $expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM); $verification = new Document([ @@ -2922,7 +2942,7 @@ App::post('/v1/account/verification/phone') $message = $message->render(); $queueForMessaging - ->setRecipient($user->getAttribute('phone')) + ->setRecipient($phone) ->setMessage($message) ->trigger() ; diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index b8f8ac4727..6ad8ebbb1c 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -1,6 +1,7 @@ dynamic($project, Response::MODEL_PROJECT); }); +App::patch('/v1/projects/:projectId/auth/mock-numbers') + ->desc('Update the mock numbers for the project') + ->groups(['api', 'projects']) + ->label('scope', 'projects.write') + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) + ->label('sdk.namespace', 'projects') + ->label('sdk.method', 'updateMockOTP') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_PROJECT) + ->param('projectId', '', new UID(), 'Project unique ID.') + ->param('numbers', '', new ArrayList(new MockNumber(), 10), 'An array of mock numbers and their corresponding verification codes (OTPs). Each number should be a valid E.164 formatted phone number. Maximum of 10 numbers are allowed.') + ->inject('response') + ->inject('dbForConsole') + ->action(function (string $projectId, array $numbers, Response $response, Database $dbForConsole) { + + $project = $dbForConsole->getDocument('projects', $projectId); + + if ($project->isEmpty()) { + throw new Exception(Exception::PROJECT_NOT_FOUND); + } + + $auths = $project->getAttribute('auths', []); + + $auths['mockNumbers'] = $numbers; + + $project = $dbForConsole->updateDocument('projects', $project->getId(), $project->setAttribute('auths', $auths)); + + $response->dynamic($project, Response::MODEL_PROJECT); + }); + App::delete('/v1/projects/:projectId') ->desc('Delete project') ->groups(['api', 'projects']) diff --git a/src/Appwrite/Auth/Validator/MockNumber.php b/src/Appwrite/Auth/Validator/MockNumber.php new file mode 100644 index 0000000000..7d6752caae --- /dev/null +++ b/src/Appwrite/Auth/Validator/MockNumber.php @@ -0,0 +1,77 @@ +message; + } + + /** + * Is valid. + * + * @param mixed $value + * + * @return bool + */ + public function isValid($value): bool + { + $phone = new Phone(); + if (!$phone->isValid($value['phone'])) { + $this->message = $phone->getDescription(); + return false; + } + + $otp = new Text(6, 6); + if (!$otp->isValid($value['otp'])) { + $this->message = $otp->getDescription(); + 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/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 7e52536eed..06f3da31a5 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -98,6 +98,8 @@ use Appwrite\Utopia\Response\Model\MigrationFirebaseProject; use Appwrite\Utopia\Response\Model\MigrationReport; // Keep last use Appwrite\Utopia\Response\Model\Mock; +use Appwrite\Utopia\Response\Model\MockNumber; +use Appwrite\Utopia\Response\Model\MockOTP; /** * @method int getStatusCode() @@ -240,6 +242,8 @@ class Response extends SwooleResponse public const MODEL_KEY_LIST = 'keyList'; public const MODEL_PROVIDER = 'provider'; public const MODEL_PROVIDER_LIST = 'providerList'; + public const MODEL_MOCK_NUMBER = 'mockNumber'; + public const MODEL_MOCK_NUMBER_LIST = 'mockNumberList'; public const MODEL_PLATFORM = 'platform'; public const MODEL_PLATFORM_LIST = 'platformList'; public const MODEL_VARIABLE = 'variable'; @@ -316,7 +320,8 @@ class Response extends SwooleResponse ->setModel(new BaseList('Projects List', self::MODEL_PROJECT_LIST, 'projects', self::MODEL_PROJECT, true, false)) ->setModel(new BaseList('Webhooks List', self::MODEL_WEBHOOK_LIST, 'webhooks', self::MODEL_WEBHOOK, true, false)) ->setModel(new BaseList('API Keys List', self::MODEL_KEY_LIST, 'keys', self::MODEL_KEY, true, false)) - ->setModel(new BaseList('Providers List', self::MODEL_PROVIDER_LIST, 'platforms', self::MODEL_PROVIDER, true, false)) + ->setModel(new BaseList('Providers List', self::MODEL_PROVIDER_LIST, 'providers', self::MODEL_PROVIDER, true, false)) + ->setModel(new BaseList('Mock Numbers List', self::MODEL_MOCK_NUMBER_LIST, 'numbers', self::MODEL_MOCK_NUMBER, true, false)) ->setModel(new BaseList('Platforms List', self::MODEL_PLATFORM_LIST, 'platforms', self::MODEL_PLATFORM, true, false)) ->setModel(new BaseList('Countries List', self::MODEL_COUNTRY_LIST, 'countries', self::MODEL_COUNTRY)) ->setModel(new BaseList('Continents List', self::MODEL_CONTINENT_LIST, 'continents', self::MODEL_CONTINENT)) @@ -381,6 +386,7 @@ class Response extends SwooleResponse ->setModel(new Webhook()) ->setModel(new Key()) ->setModel(new Provider()) + ->setModel(new MockNumber()) ->setModel(new Platform()) ->setModel(new Variable()) ->setModel(new Country()) diff --git a/src/Appwrite/Utopia/Response/Model/MockOTP.php b/src/Appwrite/Utopia/Response/Model/MockOTP.php new file mode 100644 index 0000000000..57bf19b0df --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/MockOTP.php @@ -0,0 +1,47 @@ +addRule('number', [ + 'type' => self::TYPE_STRING, + 'description' => 'Mock phone number for testing.', + 'default' => '', + 'example' => '+1612842323', + ]) + ->addRule('otp', [ + 'type' => self::TYPE_STRING, + 'description' => 'Mock OTP for the number. ', + 'default' => '', + 'example' => '123456', + ]) + ; + } + + /** + * Get Name + * + * @return string + */ + public function getName(): string + { + return 'Mock Number'; + } + + /** + * Get Type + * + * @return string + */ + public function getType(): string + { + return Response::MODEL_MOCK_NUMBER; + } +} diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index 20703ffbeb..673f9860e0 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -138,6 +138,12 @@ class Project extends Model 'default' => false, 'example' => true, ]) + ->addRule('authMockNumbers', [ + 'type' => Response::MODEL_MOCK_NUMBER_LIST, + 'description' => 'Whether or not to check the user password for similarity with their personal data.', + 'default' => false, + 'example' => true, + ]) ->addRule('providers', [ 'type' => Response::MODEL_PROVIDER, 'description' => 'List of Providers.', @@ -321,6 +327,7 @@ class Project extends Model $document->setAttribute('authPasswordHistory', $authValues['passwordHistory'] ?? 0); $document->setAttribute('authPasswordDictionary', $authValues['passwordDictionary'] ?? false); $document->setAttribute('authPersonalDataCheck', $authValues['personalDataCheck'] ?? false); + $document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? false); foreach ($auth as $index => $method) { $key = $method['key']; From be92aa92e5c04b59ab027bfd6c206f7e562dfa1c Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Sun, 11 Feb 2024 20:28:05 +0530 Subject: [PATCH 02/15] chore: rename files --- app/controllers/api/account.php | 4 ++-- app/controllers/api/projects.php | 2 +- src/Appwrite/Auth/Validator/MockNumber.php | 3 +-- src/Appwrite/Utopia/Response.php | 1 - .../Utopia/Response/Model/{MockOTP.php => MockNumber.php} | 0 5 files changed, 4 insertions(+), 6 deletions(-) rename src/Appwrite/Utopia/Response/Model/{MockOTP.php => MockNumber.php} (100%) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index d2da3d4ef6..be06145434 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1296,7 +1296,7 @@ App::post('/v1/account/sessions/phone') break; } } - + $secret ??= Auth::codeGenerator(); $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE)); @@ -2905,7 +2905,7 @@ App::post('/v1/account/verification/phone') break; } } - + $secret ??= Auth::codeGenerator(); $expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 6ad8ebbb1c..139317c239 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -858,7 +858,7 @@ App::patch('/v1/projects/:projectId/auth/mock-numbers') ->label('scope', 'projects.write') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'projects') - ->label('sdk.method', 'updateMockOTP') + ->label('sdk.method', 'updateMockNumbers') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_PROJECT) diff --git a/src/Appwrite/Auth/Validator/MockNumber.php b/src/Appwrite/Auth/Validator/MockNumber.php index 7d6752caae..bd21c48785 100644 --- a/src/Appwrite/Auth/Validator/MockNumber.php +++ b/src/Appwrite/Auth/Validator/MockNumber.php @@ -8,11 +8,10 @@ use Utopia\Validator\Text; /** * MockNumber. * - * Validates if a given object represents a valid phone and OTP pair + * Validates if a given object represents a valid phone and OTP pair */ class MockNumber extends Validator { - private $message = ''; /** diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 06f3da31a5..077e424856 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -99,7 +99,6 @@ use Appwrite\Utopia\Response\Model\MigrationReport; // Keep last use Appwrite\Utopia\Response\Model\Mock; use Appwrite\Utopia\Response\Model\MockNumber; -use Appwrite\Utopia\Response\Model\MockOTP; /** * @method int getStatusCode() diff --git a/src/Appwrite/Utopia/Response/Model/MockOTP.php b/src/Appwrite/Utopia/Response/Model/MockNumber.php similarity index 100% rename from src/Appwrite/Utopia/Response/Model/MockOTP.php rename to src/Appwrite/Utopia/Response/Model/MockNumber.php From 28a16173ab686e7a6806ef3c902a36c57afbb12c Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 14 Feb 2024 12:10:19 +0530 Subject: [PATCH 03/15] feat: add tests --- app/controllers/api/account.php | 68 +++---- src/Appwrite/Auth/Validator/MockNumber.php | 7 +- .../Projects/ProjectsConsoleClientTest.php | 167 +++++++++++++++++- 3 files changed, 209 insertions(+), 33 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index be06145434..1e78c49d1a 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1288,11 +1288,13 @@ App::post('/v1/account/sessions/phone') Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); } - $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; $secret = null; + $triggerSMS = true; + $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; foreach ($mockNumbers as $mockNumber) { - if ($mockNumber['number'] === $phone) { + if ($mockNumber['phone'] === $phone) { $secret = $mockNumber['otp']; + $triggerSMS = false; break; } } @@ -1322,21 +1324,23 @@ App::post('/v1/account/sessions/phone') $dbForProject->deleteCachedDocument('users', $user->getId()); - $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); + if ($triggerSMS) { + $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); - $customTemplate = $project->getAttribute('templates', [])['sms.login-' . $locale->default] ?? []; - if (!empty($customTemplate)) { - $message = $customTemplate['message'] ?? $message; + $customTemplate = $project->getAttribute('templates', [])['sms.login-' . $locale->default] ?? []; + if (!empty($customTemplate)) { + $message = $customTemplate['message'] ?? $message; + } + + $message = $message->setParam('{{token}}', $secret); + $message = $message->render(); + + $queueForMessaging + ->setRecipient($phone) + ->setMessage($message) + ->trigger(); } - $message = $message->setParam('{{token}}', $secret); - $message = $message->render(); - - $queueForMessaging - ->setRecipient($phone) - ->setMessage($message) - ->trigger(); - $queueForEvents->setPayload( $response->output( $token->setAttribute('secret', $secret), @@ -1428,7 +1432,7 @@ App::put('/v1/account/sessions/phone') /** * We act like we're updating and validating - * the recovery token but actually we don't need it anymore. + * the recovery token but actually we don't need it anymore. */ $dbForProject->deleteDocument('tokens', $token); $dbForProject->deleteCachedDocument('users', $user->getId()); @@ -2897,11 +2901,13 @@ App::post('/v1/account/verification/phone') $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); - $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; $secret = null; + $triggerSMS = true; + $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; foreach ($mockNumbers as $mockNumber) { - if ($mockNumber['number'] === $phone) { + if ($mockNumber['phone'] === $phone) { $secret = $mockNumber['otp']; + $triggerSMS = false; break; } } @@ -2931,22 +2937,24 @@ App::post('/v1/account/verification/phone') $dbForProject->deleteCachedDocument('users', $user->getId()); - $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); + if ($triggerSMS) { + $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); - $customTemplate = $project->getAttribute('templates', [])['sms.verification-' . $locale->default] ?? []; - if (!empty($customTemplate)) { - $message = $customTemplate['message'] ?? $message; + $customTemplate = $project->getAttribute('templates', [])['sms.verification-' . $locale->default] ?? []; + if (!empty($customTemplate)) { + $message = $customTemplate['message'] ?? $message; + } + + $message = $message->setParam('{{token}}', $secret); + $message = $message->render(); + + $queueForMessaging + ->setRecipient($phone) + ->setMessage($message) + ->trigger() + ; } - $message = $message->setParam('{{token}}', $secret); - $message = $message->render(); - - $queueForMessaging - ->setRecipient($phone) - ->setMessage($message) - ->trigger() - ; - $queueForEvents ->setParam('userId', $user->getId()) ->setParam('tokenId', $verification->getId()) diff --git a/src/Appwrite/Auth/Validator/MockNumber.php b/src/Appwrite/Auth/Validator/MockNumber.php index bd21c48785..41bda13723 100644 --- a/src/Appwrite/Auth/Validator/MockNumber.php +++ b/src/Appwrite/Auth/Validator/MockNumber.php @@ -35,6 +35,11 @@ class MockNumber extends Validator */ public function isValid($value): bool { + if (!\is_array($value) || !isset($value['phone']) || !isset($value['otp'])) { + $this->message = 'Invalid payload structure. Please check the "phone" and "otp" fields'; + return false; + } + $phone = new Phone(); if (!$phone->isValid($value['phone'])) { $this->message = $phone->getDescription(); @@ -43,7 +48,7 @@ class MockNumber extends Validator $otp = new Text(6, 6); if (!$otp->isValid($value['otp'])) { - $this->message = $otp->getDescription(); + $this->message = 'OTP must be a valid string and exactly 6 characters.'; return false; } diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index f90a04f290..6780ec91f1 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -18,8 +18,8 @@ class ProjectsConsoleClientTest extends Scope use SideClient; /** - * @group smtpAndTemplates - * @group projectsCRUD */ + * @group testing + * */ public function testCreateProject(): array { /** @@ -1355,6 +1355,169 @@ class ProjectsConsoleClientTest extends Scope return $data; } + /** + * @group testing + * @depends testCreateProject + */ + public function testUpdateMockNumbers($data) + { + $id = $data['projectId'] ?? ''; + + /** + * Test for Failure + */ + + /** Trying to pass an empty body to the endpoint */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Param "numbers" is not optional.', $response['body']['message']); + + /** Trying to pass body with incorrect structure */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + 'phone'=> '+1655513432', + 'otp' => '123456' + ] + ]); + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array and Invalid payload structure. Please check the "phone" and "otp" fields', $response['body']['message']); + + /** Trying to pass an OTP longer than 6 characters*/ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + [ + 'phone'=> '+1655513432', + 'otp' => '12345678' + ] + ] + ]); + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); + + /** Trying to pass an OTP shorter than 6 characters*/ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + [ + 'phone'=> '+1655513432', + 'otp' => '123' + ] + ] + ]); + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); + + /** Trying to pass an invalid phone number */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + [ + 'phone'=> '1655234', + 'otp' => '123456' + ] + ] + ]); + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); + + /** Trying to pass a number longer than 15 digits */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + [ + 'phone'=> '+1234567890987654', + 'otp' => '123456' + ] + ] + ]); + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); + + $numbers = []; + for ($i = 0; $i < 11; $i++) { + $numbers[] = [ + 'phone'=> '+1655513432', + 'otp' => '123456' + ]; + } + + var_dump($numbers); + + /** Trying to pass more than 10 values */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => $numbers + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + var_dump($response['body']['message']); + + /** + * Test for success + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [] + ]); + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'numbers' => [ + [ + 'phone'=> '+1655513432', + 'otp' => '123456' + ] + ] + ]); + $this->assertEquals(200, $response['headers']['status-code']); + + // Create phone session for this project and check if the mock number is used + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/phone', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + ]), [ + 'userId' => 'unique()', + 'phone' => '+1655513432', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $userId = $response['body']['userId']; + + $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/phone', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + ]), [ + 'userId' => $userId, + 'secret' => '123456', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + } + /** * @depends testUpdateProjectAuthLimit */ From abad778a1e7ed2c300ee0e129c505f43cfe7c452 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 14 Feb 2024 17:22:43 +0000 Subject: [PATCH 04/15] chore: linter --- src/Appwrite/Auth/Validator/MockNumber.php | 2 +- .../Projects/ProjectsConsoleClientTest.php | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Auth/Validator/MockNumber.php b/src/Appwrite/Auth/Validator/MockNumber.php index 41bda13723..d94eb83f23 100644 --- a/src/Appwrite/Auth/Validator/MockNumber.php +++ b/src/Appwrite/Auth/Validator/MockNumber.php @@ -39,7 +39,7 @@ class MockNumber extends Validator $this->message = 'Invalid payload structure. Please check the "phone" and "otp" fields'; return false; } - + $phone = new Phone(); if (!$phone->isValid($value['phone'])) { $this->message = $phone->getDescription(); diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 0f1e75e73a..3ab0929827 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -19,7 +19,7 @@ class ProjectsConsoleClientTest extends Scope use SideClient; /** - * @group testing + * @group testing * */ public function testCreateProject(): array { @@ -1387,7 +1387,7 @@ class ProjectsConsoleClientTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'numbers' => [ - 'phone'=> '+1655513432', + 'phone' => '+1655513432', 'otp' => '123456' ] ]); @@ -1401,7 +1401,7 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'numbers' => [ [ - 'phone'=> '+1655513432', + 'phone' => '+1655513432', 'otp' => '12345678' ] ] @@ -1416,7 +1416,7 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'numbers' => [ [ - 'phone'=> '+1655513432', + 'phone' => '+1655513432', 'otp' => '123' ] ] @@ -1431,7 +1431,7 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'numbers' => [ [ - 'phone'=> '1655234', + 'phone' => '1655234', 'otp' => '123456' ] ] @@ -1446,7 +1446,7 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'numbers' => [ [ - 'phone'=> '+1234567890987654', + 'phone' => '+1234567890987654', 'otp' => '123456' ] ] @@ -1457,11 +1457,11 @@ class ProjectsConsoleClientTest extends Scope $numbers = []; for ($i = 0; $i < 11; $i++) { $numbers[] = [ - 'phone'=> '+1655513432', + 'phone' => '+1655513432', 'otp' => '123456' ]; } - + var_dump($numbers); /** Trying to pass more than 10 values */ @@ -1492,7 +1492,7 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders()), [ 'numbers' => [ [ - 'phone'=> '+1655513432', + 'phone' => '+1655513432', 'otp' => '123456' ] ] From a912bbe37475bfaef58ab123da8f8de4ddc8569e Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Sun, 16 Jun 2024 07:19:10 +0000 Subject: [PATCH 05/15] chore: update variable name --- app/controllers/api/account.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 9f8770e94c..b8c8e30489 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1302,12 +1302,12 @@ App::post('/v1/account/sessions/phone') } $secret = null; - $triggerSMS = true; + $sendSMS = true; $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; foreach ($mockNumbers as $mockNumber) { if ($mockNumber['phone'] === $phone) { $secret = $mockNumber['otp']; - $triggerSMS = false; + $sendSMS = false; break; } } @@ -1337,7 +1337,7 @@ App::post('/v1/account/sessions/phone') $dbForProject->deleteCachedDocument('users', $user->getId()); - if ($triggerSMS) { + if ($sendSMS) { $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); $customTemplate = $project->getAttribute('templates', [])['sms.login-' . $locale->default] ?? []; @@ -2917,12 +2917,12 @@ App::post('/v1/account/verification/phone') $isAppUser = Auth::isAppUser($roles); $secret = null; - $triggerSMS = true; + $sendSMS = true; $mockNumbers = $project->getAttribute('auths', [])['mockNumbers'] ?? []; foreach ($mockNumbers as $mockNumber) { if ($mockNumber['phone'] === $phone) { $secret = $mockNumber['otp']; - $triggerSMS = false; + $sendSMS = false; break; } } @@ -2952,7 +2952,7 @@ App::post('/v1/account/verification/phone') $dbForProject->deleteCachedDocument('users', $user->getId()); - if ($triggerSMS) { + if ($sendSMS) { $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); $customTemplate = $project->getAttribute('templates', [])['sms.verification-' . $locale->default] ?? []; From fa070c5e1e0ecb83f9e7d800812c1eea1129bbea Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Sun, 16 Jun 2024 22:41:13 +0000 Subject: [PATCH 06/15] chore: sync & updates --- .env | 2 +- src/Appwrite/Utopia/Response.php | 3 --- src/Appwrite/Utopia/Response/Model/MockNumber.php | 2 +- src/Appwrite/Utopia/Response/Model/Project.php | 4 ++-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.env b/.env index b889ebb513..8830fe4365 100644 --- a/.env +++ b/.env @@ -6,7 +6,7 @@ _APP_CONSOLE_WHITELIST_ROOT=disabled _APP_CONSOLE_WHITELIST_EMAILS= _APP_CONSOLE_WHITELIST_IPS= _APP_CONSOLE_COUNTRIES_DENYLIST=AQ -_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io +_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io,*.gitpod.io _APP_SYSTEM_EMAIL_NAME=Appwrite _APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 2e21b32229..c5aef714a1 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -101,7 +101,6 @@ use Appwrite\Utopia\Response\Model\UsageUsers; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; use Appwrite\Utopia\Response\Model\Webhook; -use Appwrite\Utopia\Response\Model\Mock; use Appwrite\Utopia\Response\Model\MockNumber; use Exception; use Swoole\Http\Response as SwooleHTTPResponse; @@ -268,8 +267,6 @@ class Response extends SwooleResponse public const MODEL_WEBHOOK_LIST = 'webhookList'; public const MODEL_KEY = 'key'; public const MODEL_KEY_LIST = 'keyList'; - public const MODEL_PROVIDER = 'provider'; - public const MODEL_PROVIDER_LIST = 'providerList'; public const MODEL_MOCK_NUMBER = 'mockNumber'; public const MODEL_MOCK_NUMBER_LIST = 'mockNumberList'; public const MODEL_AUTH_PROVIDER = 'authProvider'; diff --git a/src/Appwrite/Utopia/Response/Model/MockNumber.php b/src/Appwrite/Utopia/Response/Model/MockNumber.php index 57bf19b0df..952849d2b5 100644 --- a/src/Appwrite/Utopia/Response/Model/MockNumber.php +++ b/src/Appwrite/Utopia/Response/Model/MockNumber.php @@ -27,7 +27,7 @@ class MockNumber extends Model /** * Get Name - * + *oj * @return string */ public function getName(): string diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index 3e0a95131d..bf0e6ffeec 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -141,7 +141,7 @@ class Project extends Model ->addRule('authMockNumbers', [ 'type' => Response::MODEL_MOCK_NUMBER_LIST, 'description' => 'Whether or not to check the user password for similarity with their personal data.', - 'default' => false, + 'default' => [], 'example' => true, ]) ->addRule('oAuthProviders', [ @@ -327,7 +327,7 @@ class Project extends Model $document->setAttribute('authPasswordHistory', $authValues['passwordHistory'] ?? 0); $document->setAttribute('authPasswordDictionary', $authValues['passwordDictionary'] ?? false); $document->setAttribute('authPersonalDataCheck', $authValues['personalDataCheck'] ?? false); - $document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? false); + $document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? []); foreach ($auth as $index => $method) { $key = $method['key']; From e32e7063bb502d1e5df7db3a3181953c81bce56d Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:01:33 +0530 Subject: [PATCH 07/15] chore: linter --- .env | 2 +- composer.lock | 95 ++++++++++--------- src/Appwrite/Utopia/Response.php | 2 +- .../Projects/ProjectsConsoleClientTest.php | 8 +- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/.env b/.env index 8830fe4365..b889ebb513 100644 --- a/.env +++ b/.env @@ -6,7 +6,7 @@ _APP_CONSOLE_WHITELIST_ROOT=disabled _APP_CONSOLE_WHITELIST_EMAILS= _APP_CONSOLE_WHITELIST_IPS= _APP_CONSOLE_COUNTRIES_DENYLIST=AQ -_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io,*.gitpod.io +_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io _APP_SYSTEM_EMAIL_NAME=Appwrite _APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io diff --git a/composer.lock b/composer.lock index 8acbbed541..5464005e37 100644 --- a/composer.lock +++ b/composer.lock @@ -1427,16 +1427,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "0.37.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", "shasum": "" }, "require": { @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/0.37.1" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-06-05T18:03:59+00:00" }, { "name": "utopia-php/analytics", @@ -1522,16 +1522,16 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "0.39.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", "shasum": "" }, "require": { @@ -1563,9 +1563,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/0.39.1" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-06-05T19:28:22+00:00" }, { "name": "utopia-php/cache", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "0.49.11", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec" + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/216209121bc97a2010f67a39c561fafe1e936bec", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec", + "url": "https://api.github.com/repos/utopia-php/database/zipball/4f4b35d99ecdee971c3042279bb1ac8264825030", + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.10" + "source": "https://github.com/utopia-php/database/tree/0.49.11" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-05-30T12:40:27+00:00" }, { "name": "utopia-php/domains", @@ -2987,16 +2987,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.6", + "version": "0.38.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699" + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "shasum": "" }, "require": { @@ -3032,9 +3032,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.38.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, - "time": "2024-05-20T18:00:16+00:00" + "time": "2024-06-10T00:23:02+00:00" }, { "name": "doctrine/deprecations", @@ -3155,16 +3155,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.0", + "version": "v1.16.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98" + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", + "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", "shasum": "" }, "require": { @@ -3175,13 +3175,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.57.1", - "illuminate/view": "^10.48.10", - "larastan/larastan": "^2.9.6", + "friendsofphp/php-cs-fixer": "^3.59.3", + "illuminate/view": "^10.48.12", + "larastan/larastan": "^2.9.7", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.7" + "pestphp/pest": "^2.34.8" }, "bin": [ "builds/pint" @@ -3217,7 +3217,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-05-21T18:08:25+00:00" + "time": "2024-06-18T16:50:05+00:00" }, { "name": "matthiasmullie/minify", @@ -3345,16 +3345,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3362,11 +3362,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -3392,7 +3393,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3400,7 +3401,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -3824,16 +3825,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -3865,9 +3866,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-05-06T12:04:23+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5613,5 +5614,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index c5aef714a1..f83ad58756 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -72,6 +72,7 @@ use Appwrite\Utopia\Response\Model\Migration; use Appwrite\Utopia\Response\Model\MigrationFirebaseProject; use Appwrite\Utopia\Response\Model\MigrationReport; use Appwrite\Utopia\Response\Model\Mock; +use Appwrite\Utopia\Response\Model\MockNumber; use Appwrite\Utopia\Response\Model\None; use Appwrite\Utopia\Response\Model\Phone; use Appwrite\Utopia\Response\Model\Platform; @@ -101,7 +102,6 @@ use Appwrite\Utopia\Response\Model\UsageUsers; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; use Appwrite\Utopia\Response\Model\Webhook; -use Appwrite\Utopia\Response\Model\MockNumber; use Exception; use Swoole\Http\Response as SwooleHTTPResponse; // Keep last diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 8c3636cc6a..cd6887a492 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -1689,8 +1689,8 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $id, ]), [ - 'userId' => 'unique()', - 'phone' => '+1655513432', + 'userId' => 'unique()', + 'phone' => '+1655513432', ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -1700,8 +1700,8 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $id, ]), [ - 'userId' => $userId, - 'secret' => '123456', + 'userId' => $userId, + 'secret' => '123456', ]); $this->assertEquals(201, $response['headers']['status-code']); From e436ad721fb0c764ca66711b94a7ba9946ca6b88 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:02:36 +0530 Subject: [PATCH 08/15] chore: linter --- src/Appwrite/Utopia/Response/Model/MockNumber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response/Model/MockNumber.php b/src/Appwrite/Utopia/Response/Model/MockNumber.php index 952849d2b5..b09d0e5453 100644 --- a/src/Appwrite/Utopia/Response/Model/MockNumber.php +++ b/src/Appwrite/Utopia/Response/Model/MockNumber.php @@ -12,7 +12,7 @@ class MockNumber extends Model $this ->addRule('number', [ 'type' => self::TYPE_STRING, - 'description' => 'Mock phone number for testing.', + 'description' => 'Mock phone number for testing phone authentication. Useful for testing phone authentication without sending an SMS.', 'default' => '', 'example' => '+1612842323', ]) From 392aaca681392ec155cf7b9e0e5344391e987ae0 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:19:56 +0530 Subject: [PATCH 09/15] chore: fix tests --- app/controllers/api/account.php | 2 +- .../Projects/ProjectsConsoleClientTest.php | 31 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 0d5a1a59aa..5ce8682399 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2284,7 +2284,7 @@ App::post('/v1/account/tokens/phone') } $secret ??= Auth::codeGenerator(); - $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE)); + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_OTP)); $token = new Document([ '$id' => ID::unique(), diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index cd6887a492..14bb11046f 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -611,7 +611,7 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'emails' => [ 'testuser@appwrite.io', 'testusertwo@appwrite.io' ], + 'emails' => ['testuser@appwrite.io', 'testusertwo@appwrite.io'], 'senderEmail' => 'custommailer@appwrite.io', 'senderName' => 'Custom Mailer', 'replyTo' => 'reply@appwrite.io', @@ -648,7 +648,7 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'emails' => [ 'u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io' ], + 'emails' => ['u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io'], 'senderEmail' => 'custommailer@appwrite.io', 'senderName' => 'Custom Mailer', 'replyTo' => 'reply@appwrite.io', @@ -664,7 +664,7 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'emails' => [ 'u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io', 'u11@appwrite.io' ], + 'emails' => ['u1@appwrite.io', 'u2@appwrite.io', 'u3@appwrite.io', 'u4@appwrite.io', 'u5@appwrite.io', 'u6@appwrite.io', 'u7@appwrite.io', 'u8@appwrite.io', 'u9@appwrite.io', 'u10@appwrite.io', 'u11@appwrite.io'], 'senderEmail' => 'custommailer@appwrite.io', 'senderName' => 'Custom Mailer', 'replyTo' => 'reply@appwrite.io', @@ -1530,8 +1530,8 @@ class ProjectsConsoleClientTest extends Scope /** - * Reset - */ + * Reset + */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1560,8 +1560,7 @@ class ProjectsConsoleClientTest extends Scope $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - ]); + ], $this->getHeaders()), []); $this->assertEquals(400, $response['headers']['status-code']); $this->assertEquals('Param "numbers" is not optional.', $response['body']['message']); @@ -1577,7 +1576,7 @@ class ProjectsConsoleClientTest extends Scope ] ]); $this->assertEquals(400, $response['headers']['status-code']); - $this->assertEquals('Invalid `numbers` param: Value must a valid array and Invalid payload structure. Please check the "phone" and "otp" fields', $response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Invalid payload structure. Please check the "phone" and "otp" fields', $response['body']['message']); /** Trying to pass an OTP longer than 6 characters*/ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ @@ -1592,7 +1591,7 @@ class ProjectsConsoleClientTest extends Scope ] ]); $this->assertEquals(400, $response['headers']['status-code']); - $this->assertEquals('Invalid `numbers` param: Value must a valid array and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); /** Trying to pass an OTP shorter than 6 characters*/ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ @@ -1607,7 +1606,7 @@ class ProjectsConsoleClientTest extends Scope ] ]); $this->assertEquals(400, $response['headers']['status-code']); - $this->assertEquals('Invalid `numbers` param: Value must a valid array and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and OTP must be a valid string and exactly 6 characters.', $response['body']['message']); /** Trying to pass an invalid phone number */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ @@ -1622,7 +1621,7 @@ class ProjectsConsoleClientTest extends Scope ] ]); $this->assertEquals(400, $response['headers']['status-code']); - $this->assertEquals('Invalid `numbers` param: Value must a valid array and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); /** Trying to pass a number longer than 15 digits */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ @@ -1637,7 +1636,7 @@ class ProjectsConsoleClientTest extends Scope ] ]); $this->assertEquals(400, $response['headers']['status-code']); - $this->assertEquals('Invalid `numbers` param: Value must a valid array and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); $numbers = []; for ($i = 0; $i < 11; $i++) { @@ -1647,8 +1646,6 @@ class ProjectsConsoleClientTest extends Scope ]; } - var_dump($numbers); - /** Trying to pass more than 10 values */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/mock-numbers', array_merge([ 'content-type' => 'application/json', @@ -1658,7 +1655,7 @@ class ProjectsConsoleClientTest extends Scope ]); $this->assertEquals(400, $response['headers']['status-code']); - var_dump($response['body']['message']); + $this->assertEquals('Invalid `numbers` param: Value must a valid array no longer than 10 items and Phone number must start with a \'+\' can have a maximum of fifteen digits.', $response['body']['message']); /** * Test for success @@ -1810,8 +1807,8 @@ class ProjectsConsoleClientTest extends Scope /** - * Reset - */ + * Reset + */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], From 1b1cfc38c8d7348272eedb9b22ac9b68adf7f057 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:31:20 +0530 Subject: [PATCH 10/15] fix: undefined variable --- app/controllers/api/account.php | 89 ++++++++----------- .../Projects/ProjectsConsoleClientTest.php | 16 +++- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 5ce8682399..d005a6594c 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2316,37 +2316,29 @@ App::post('/v1/account/tokens/phone') $message = $customTemplate['message'] ?? $message; } - $message = $message->setParam('{{token}}', $secret); + $messageContent = Template::fromString($locale->getText("sms.verification.body")); + $messageContent + ->setParam('{{project}}', $project->getAttribute('name')) + ->setParam('{{secret}}', $secret); + $messageContent = \strip_tags($messageContent->render()); + $message = $message->setParam('{{token}}', $messageContent); + $message = $message->render(); + $messageDoc = new Document([ + '$id' => $token->getId(), + 'data' => [ + 'content' => $message, + ], + ]); + $queueForMessaging - ->setRecipient($phone) - ->setMessage($message) - ->trigger(); + ->setType(MESSAGE_SEND_TYPE_INTERNAL) + ->setMessage($messageDoc) + ->setRecipients([$phone]) + ->setProviderType(MESSAGE_TYPE_SMS); } - $messageContent = Template::fromString($locale->getText("sms.verification.body")); - $messageContent - ->setParam('{{project}}', $project->getAttribute('name')) - ->setParam('{{secret}}', $secret); - $messageContent = \strip_tags($messageContent->render()); - $message = $message->setParam('{{token}}', $messageContent); - - $message = $message->render(); - - $messageDoc = new Document([ - '$id' => $token->getId(), - 'data' => [ - 'content' => $message, - ], - ]); - - $queueForMessaging - ->setType(MESSAGE_SEND_TYPE_INTERNAL) - ->setMessage($messageDoc) - ->setRecipients([$phone]) - ->setProviderType(MESSAGE_TYPE_SMS); - // Set to unhashed secret for events and server responses $token->setAttribute('secret', $secret); @@ -3420,38 +3412,29 @@ App::post('/v1/account/verification/phone') $message = $customTemplate['message'] ?? $message; } - $message = $message->setParam('{{token}}', $secret); + $messageContent = Template::fromString($locale->getText("sms.verification.body")); + $messageContent + ->setParam('{{project}}', $project->getAttribute('name')) + ->setParam('{{secret}}', $secret); + $messageContent = \strip_tags($messageContent->render()); + $message = $message->setParam('{{token}}', $messageContent); + $message = $message->render(); + $messageDoc = new Document([ + '$id' => $verification->getId(), + 'data' => [ + 'content' => $message, + ], + ]); + $queueForMessaging - ->setRecipient($phone) - ->setMessage($message) - ->trigger() - ; + ->setType(MESSAGE_SEND_TYPE_INTERNAL) + ->setMessage($messageDoc) + ->setRecipients([$user->getAttribute('phone')]) + ->setProviderType(MESSAGE_TYPE_SMS); } - $messageContent = Template::fromString($locale->getText("sms.verification.body")); - $messageContent - ->setParam('{{project}}', $project->getAttribute('name')) - ->setParam('{{secret}}', $secret); - $messageContent = \strip_tags($messageContent->render()); - $message = $message->setParam('{{token}}', $messageContent); - - $message = $message->render(); - - $messageDoc = new Document([ - '$id' => $verification->getId(), - 'data' => [ - 'content' => $message, - ], - ]); - - $queueForMessaging - ->setType(MESSAGE_SEND_TYPE_INTERNAL) - ->setMessage($messageDoc) - ->setRecipients([$user->getAttribute('phone')]) - ->setProviderType(MESSAGE_TYPE_SMS); - // Set to unhashed secret for events and server responses $verification->setAttribute('secret', $secret); diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 14bb11046f..047d855acf 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -1545,9 +1545,9 @@ class ProjectsConsoleClientTest extends Scope } /** - * @group testing - * @depends testCreateProject - */ + * @group smtpAndTemplates + * @group projectsCRUD + * */ public function testUpdateMockNumbers($data) { $id = $data['projectId'] ?? ''; @@ -1693,6 +1693,16 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $userId = $response['body']['userId']; + $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/phone', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + ]), [ + 'userId' => $userId, + 'secret' => '654321', // Try a random code + ]); + + $this->assertEquals(401, $response['headers']['status-code']); + $response = $this->client->call(Client::METHOD_PUT, '/account/sessions/phone', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $id, From 8d5b79c13dea827e04c5f996daffa5d44ab27ce1 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:31:54 +0530 Subject: [PATCH 11/15] fix: undefined variable --- src/Appwrite/Utopia/Response/Model/MockNumber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response/Model/MockNumber.php b/src/Appwrite/Utopia/Response/Model/MockNumber.php index b09d0e5453..fec8331ec5 100644 --- a/src/Appwrite/Utopia/Response/Model/MockNumber.php +++ b/src/Appwrite/Utopia/Response/Model/MockNumber.php @@ -27,7 +27,7 @@ class MockNumber extends Model /** * Get Name - *oj + * * @return string */ public function getName(): string From 3b791f0b6f4172367b9111b9c77ac0a30e75d9f6 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 20 Jun 2024 20:44:02 +0530 Subject: [PATCH 12/15] chore: linter --- tests/e2e/Services/Projects/ProjectsConsoleClientTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 047d855acf..5e4e1348a6 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -1546,7 +1546,9 @@ class ProjectsConsoleClientTest extends Scope /** * @group smtpAndTemplates - * @group projectsCRUD + * @group projectsCRUD + * + * @depends testCreateProject * */ public function testUpdateMockNumbers($data) { From fa93d9d1cc4b4d3a2ee9db3df84d76c57c5177a7 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Tue, 25 Jun 2024 15:31:02 +0000 Subject: [PATCH 13/15] chore: linter --- composer.lock | 156 -------------------------------------------------- 1 file changed, 156 deletions(-) diff --git a/composer.lock b/composer.lock index 22f6066aa9..5e48445d23 100644 --- a/composer.lock +++ b/composer.lock @@ -1879,10 +1879,6 @@ "source": "https://github.com/utopia-php/dsn/tree/0.2.1" }, "time": "2024-05-07T02:01:25+00:00" -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "utopia-php/fetch", @@ -1922,11 +1918,6 @@ "source": "https://github.com/utopia-php/fetch/tree/0.2.1" }, "time": "2024-03-18T11:50:59+00:00" -<<<<<<< HEAD -======= ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "utopia-php/framework", @@ -2336,10 +2327,6 @@ }, { "name": "utopia-php/platform", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "version": "0.7.0", "source": { "type": "git", @@ -2350,21 +2337,6 @@ "type": "zip", "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", -<<<<<<< HEAD -======= - "version": "0.5.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/platform.git", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3", ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "shasum": "" }, "require": { @@ -2372,17 +2344,8 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", -<<<<<<< HEAD -<<<<<<< HEAD "utopia-php/framework": "0.33.*", "utopia-php/queue": "0.7.*" -======= - "utopia-php/framework": "0.33.*" ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "utopia-php/framework": "0.33.*", - "utopia-php/queue": "0.7.*" ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, "require-dev": { "laravel/pint": "1.2.*", @@ -2408,21 +2371,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", -<<<<<<< HEAD -<<<<<<< HEAD "source": "https://github.com/utopia-php/platform/tree/0.7.0" }, "time": "2024-05-08T17:00:55+00:00" -======= - "source": "https://github.com/utopia-php/platform/tree/0.5.2" - }, - "time": "2024-05-22T12:50:35+00:00" ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "source": "https://github.com/utopia-php/platform/tree/0.7.0" - }, - "time": "2024-05-08T17:00:55+00:00" ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "utopia-php/pools", @@ -3037,8 +2988,6 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", -<<<<<<< HEAD -<<<<<<< HEAD "version": "0.38.7", "source": { "type": "git", @@ -3049,26 +2998,6 @@ "type": "zip", "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", -======= - "version": "0.38.6", -======= - "version": "0.38.7", ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" - }, - "dist": { - "type": "zip", -<<<<<<< HEAD - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", - "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "shasum": "" }, "require": { @@ -3104,21 +3033,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", -<<<<<<< HEAD -<<<<<<< HEAD "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, "time": "2024-06-10T00:23:02+00:00" -======= - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.6" - }, - "time": "2024-05-20T18:00:16+00:00" ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" - }, - "time": "2024-06-10T00:23:02+00:00" ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "doctrine/deprecations", @@ -3239,8 +3156,6 @@ }, { "name": "laravel/pint", -<<<<<<< HEAD -<<<<<<< HEAD "version": "v1.16.1", "source": { "type": "git", @@ -3251,26 +3166,6 @@ "type": "zip", "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", -======= - "version": "v1.16.0", -======= - "version": "v1.16.1", ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "9266a47f1b9231b83e0cfd849009547329d871b1" - }, - "dist": { - "type": "zip", -<<<<<<< HEAD - "url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", - "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "shasum": "" }, "require": { @@ -3281,21 +3176,9 @@ "php": "^8.1.0" }, "require-dev": { -<<<<<<< HEAD -<<<<<<< HEAD "friendsofphp/php-cs-fixer": "^3.59.3", "illuminate/view": "^10.48.12", "larastan/larastan": "^2.9.7", -======= - "friendsofphp/php-cs-fixer": "^3.57.1", - "illuminate/view": "^10.48.10", - "larastan/larastan": "^2.9.6", ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "friendsofphp/php-cs-fixer": "^3.59.3", - "illuminate/view": "^10.48.12", - "larastan/larastan": "^2.9.7", ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", @@ -3335,15 +3218,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, -<<<<<<< HEAD -<<<<<<< HEAD "time": "2024-06-18T16:50:05+00:00" -======= - "time": "2024-05-21T18:08:25+00:00" ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "time": "2024-06-18T16:50:05+00:00" ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "matthiasmullie/minify", @@ -3951,10 +3826,6 @@ }, { "name": "phpstan/phpdoc-parser", -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "version": "1.29.1", "source": { "type": "git", @@ -3965,21 +3836,6 @@ "type": "zip", "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", -<<<<<<< HEAD -======= - "version": "1.29.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 "shasum": "" }, "require": { @@ -4011,21 +3867,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", -<<<<<<< HEAD -<<<<<<< HEAD "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, "time": "2024-05-31T08:52:43+00:00" -======= - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" - }, - "time": "2024-05-06T12:04:23+00:00" ->>>>>>> 83d60612f2b93055e757913af49deab12d60c60f -======= - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" - }, - "time": "2024-05-31T08:52:43+00:00" ->>>>>>> 91fe8b7a8bccd9def26e7858dc15c049ade953a5 }, { "name": "phpunit/php-code-coverage", From 3a570b1f73cf2c81cb5f27adeb224e6f807527d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 3 Jul 2024 08:27:54 +0000 Subject: [PATCH 14/15] PR review changes --- app/console | 2 +- app/controllers/api/projects.php | 3 ++- app/init.php | 1 + src/Appwrite/Utopia/Response.php | 2 -- src/Appwrite/Utopia/Response/Model/MockNumber.php | 2 +- src/Appwrite/Utopia/Response/Model/Project.php | 2 +- tests/e2e/Services/Projects/ProjectsConsoleClientTest.php | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/console b/app/console index 5169fe16d6..f483d9631d 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 5169fe16d63066f64ab5013c78953aea04e24b53 +Subproject commit f483d9631d6f21e94aedb20b5c37c56fea06c23e diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index b7f1526b56..066a959efc 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -105,7 +105,8 @@ App::post('/v1/projects') 'passwordHistory' => 0, 'passwordDictionary' => false, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG, - 'personalDataCheck' => false + 'personalDataCheck' => false, + 'mockNumbers' => [] ]; foreach ($auth as $method) { $auths[$method['key'] ?? ''] = true; diff --git a/app/init.php b/app/init.php index 9b406916c5..eae9b21b44 100644 --- a/app/init.php +++ b/app/init.php @@ -1321,6 +1321,7 @@ App::setResource('console', function () { 'legalAddress' => '', 'legalTaxId' => '', 'auths' => [ + 'mockNumbers' => [], 'invites' => System::getEnv('_APP_CONSOLE_INVITES', 'enabled') === 'enabled', 'limit' => (System::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG, // 1 Year in seconds diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 254b23582c..1e1d5f87ae 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -351,7 +351,6 @@ class Response extends SwooleResponse ->setModel(new BaseList('Projects List', self::MODEL_PROJECT_LIST, 'projects', self::MODEL_PROJECT, true, false)) ->setModel(new BaseList('Webhooks List', self::MODEL_WEBHOOK_LIST, 'webhooks', self::MODEL_WEBHOOK, true, false)) ->setModel(new BaseList('API Keys List', self::MODEL_KEY_LIST, 'keys', self::MODEL_KEY, true, false)) - ->setModel(new BaseList('Providers List', self::MODEL_PROVIDER_LIST, 'providers', self::MODEL_PROVIDER, true, false)) ->setModel(new BaseList('Mock Numbers List', self::MODEL_MOCK_NUMBER_LIST, 'numbers', self::MODEL_MOCK_NUMBER, true, false)) ->setModel(new BaseList('Auth Providers List', self::MODEL_AUTH_PROVIDER_LIST, 'platforms', self::MODEL_AUTH_PROVIDER, true, false)) ->setModel(new BaseList('Platforms List', self::MODEL_PLATFORM_LIST, 'platforms', self::MODEL_PLATFORM, true, false)) @@ -424,7 +423,6 @@ class Response extends SwooleResponse ->setModel(new Project()) ->setModel(new Webhook()) ->setModel(new Key()) - ->setModel(new Provider()) ->setModel(new MockNumber()) ->setModel(new AuthProvider()) ->setModel(new Platform()) diff --git a/src/Appwrite/Utopia/Response/Model/MockNumber.php b/src/Appwrite/Utopia/Response/Model/MockNumber.php index fec8331ec5..14ce747da6 100644 --- a/src/Appwrite/Utopia/Response/Model/MockNumber.php +++ b/src/Appwrite/Utopia/Response/Model/MockNumber.php @@ -10,7 +10,7 @@ class MockNumber extends Model public function __construct() { $this - ->addRule('number', [ + ->addRule('phone', [ 'type' => self::TYPE_STRING, 'description' => 'Mock phone number for testing phone authentication. Useful for testing phone authentication without sending an SMS.', 'default' => '', diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index bf0e6ffeec..638e9e4549 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -140,7 +140,7 @@ class Project extends Model ]) ->addRule('authMockNumbers', [ 'type' => Response::MODEL_MOCK_NUMBER_LIST, - 'description' => 'Whether or not to check the user password for similarity with their personal data.', + 'description' => 'An array of mock numbers and their corresponding verification codes (OTPs).', 'default' => [], 'example' => true, ]) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 2c1d873cc9..753322f168 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -21,8 +21,8 @@ class ProjectsConsoleClientTest extends Scope use SideClient; /** - * @group testing - * */ + * @group smtpAndTemplates + * @group projectsCRUD */ public function testCreateProject(): array { /** From b5fc9d5789e0a5d65b4dbef0a2d58f53556ceb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 3 Jul 2024 09:35:56 +0000 Subject: [PATCH 15/15] PR review changes --- app/controllers/api/account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 6f15e8fb1d..b6e6337a00 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -3453,7 +3453,7 @@ App::post('/v1/account/verification/phone') } $phone = $user->getAttribute('phone'); - if (!$phone) { + if (empty($phone)) { throw new Exception(Exception::USER_PHONE_NOT_FOUND); }