From 12e4f49cba3fc81bd626676f005c9e152205281d Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 15 May 2024 20:25:29 +0300 Subject: [PATCH 01/21] adding requests count on error --- app/controllers/shared/api.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 7b218e050a..810254ae6d 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -15,13 +15,11 @@ use Appwrite\Extend\Exception as AppwriteException; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; -use Appwrite\Utopia\View; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\App; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; -use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; From dae9cb995c17fc5667f176e9ed0aa00a5b9fa4f1 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 16 May 2024 21:21:21 +0300 Subject: [PATCH 02/21] adding requests count on error --- app/controllers/shared/api.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 810254ae6d..d1073ee8e7 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -26,10 +26,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; -use Utopia\DSN\DSN; -use Utopia\Logger\Log; use Utopia\Logger\Log\User; -use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -750,7 +747,7 @@ App::error() ->inject('response') ->inject('project') ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { + ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { if ($error instanceof AppwriteException) { $publish = $error->isPublishable(); @@ -777,4 +774,4 @@ App::error() ->trigger(); } - }); \ No newline at end of file + }); From e1ac0d622ee92b9f61edc1cc94c93ca0f19db8c5 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 19 May 2024 10:55:14 +0300 Subject: [PATCH 03/21] adding requests count on error --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8865a32d91..e247799645 100644 --- a/composer.json +++ b/composer.json @@ -57,7 +57,7 @@ "utopia-php/fetch": "0.2.*", "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", - "utopia-php/logger": "0.3.*", + "utopia-php/logger": "0.5.*", "utopia-php/messaging": "0.10.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", From 8aabb92fdaccec0bd7964e9e7d3b95d13a82ac8e Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 19 May 2024 13:50:25 +0300 Subject: [PATCH 04/21] adding requests count on error --- app/controllers/shared/api.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index d1073ee8e7..91e7f87113 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -27,6 +27,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log\User; +use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -755,6 +756,10 @@ App::error() $publish = $error->getCode() === 0 || $error->getCode() >= 500; } + if ($error->getCode() >= 400 && $error->getCode() < 500) { + $publish = true; + } + if ($publish && $project->getId() !== 'console') { if (!Auth::isPrivilegedUser(Authorization::getRoles())) { $fileSize = 0; From 87cf7776df0cc6402a29179e8b769b511679f88c Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 10:59:19 +0300 Subject: [PATCH 05/21] lint --- app/controllers/shared/api.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 91e7f87113..172ded7f31 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -27,7 +27,6 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log\User; -use Utopia\Logger\Logger; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -757,8 +756,8 @@ App::error() } if ($error->getCode() >= 400 && $error->getCode() < 500) { - $publish = true; - } + $publish = true; + } if ($publish && $project->getId() !== 'console') { if (!Auth::isPrivilegedUser(Authorization::getRoles())) { From a22d98296c81e92e5c629b9a0f93ffc3f6873804 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:33:40 +0300 Subject: [PATCH 06/21] lint --- app/controllers/shared/api.php | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index d44efce45d..72708d9b88 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -746,7 +746,7 @@ App::error() ->inject('response') ->inject('project') ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Audit $queueForAudits, Usage $queueForUsage) { + ->action(function (Throwable $error, Request $request, Response $response, Document $project, Usage $queueForUsage) { if ($error instanceof AppwriteException) { $publish = $error->isPublishable(); diff --git a/composer.lock b/composer.lock index bfe8fc0730..8acbbed541 100644 --- a/composer.lock +++ b/composer.lock @@ -5613,5 +5613,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" } From c996dbcdc911b08525ece4f9de28419e8eb0caf7 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:39:23 +0300 Subject: [PATCH 07/21] lint --- app/controllers/general.php | 24 +++++++++++++++++++- app/controllers/shared/api.php | 41 +--------------------------------- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index f1be7bd614..ca57b27ec6 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -2,6 +2,7 @@ require_once __DIR__ . '/../init.php'; +use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; use Appwrite\Event\Event; use Appwrite\Event\Usage; @@ -646,7 +647,8 @@ App::error() ->inject('project') ->inject('logger') ->inject('log') - ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log) { + ->inject('queueForUsage') + ->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage) { $version = System::getEnv('_APP_VERSION', 'UNKNOWN'); $route = $utopia->getRoute(); $class = \get_class($error); @@ -735,6 +737,26 @@ App::error() } } + if ($publish && $project->getId() !== 'console') { + if (!Auth::isPrivilegedUser(Authorization::getRoles())) { + $fileSize = 0; + $file = $request->getFiles('file'); + if (!empty($file)) { + $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; + } + + $queueForUsage + ->addMetric(METRIC_NETWORK_REQUESTS, 1) + ->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize) + ->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize()); + } + + $queueForUsage + ->setProject($project) + ->trigger(); + } + + if ($logger && $publish) { try { /** @var Utopia\Database\Document $user */ diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 72708d9b88..54f9da27c1 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -738,43 +738,4 @@ App::init() if (System::getEnv('_APP_USAGE_STATS', 'enabled') !== 'enabled') { throw new Exception(Exception::GENERAL_USAGE_DISABLED); } - }); - -App::error() - ->inject('error') - ->inject('request') - ->inject('response') - ->inject('project') - ->inject('queueForUsage') - ->action(function (Throwable $error, Request $request, Response $response, Document $project, Usage $queueForUsage) { - - if ($error instanceof AppwriteException) { - $publish = $error->isPublishable(); - } else { - $publish = $error->getCode() === 0 || $error->getCode() >= 500; - } - - if ($error->getCode() >= 400 && $error->getCode() < 500) { - $publish = true; - } - - if ($publish && $project->getId() !== 'console') { - if (!Auth::isPrivilegedUser(Authorization::getRoles())) { - $fileSize = 0; - $file = $request->getFiles('file'); - if (!empty($file)) { - $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; - } - - $queueForUsage - ->addMetric(METRIC_NETWORK_REQUESTS, 1) - ->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize) - ->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize()); - } - - $queueForUsage - ->setProject($project) - ->trigger(); - } - - }); + }); \ No newline at end of file From a2ef77f0f593b403bab295e820de11f489026610 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 23 May 2024 16:47:37 +0300 Subject: [PATCH 08/21] lint --- app/controllers/shared/api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 54f9da27c1..1afd6b652e 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -738,4 +738,4 @@ App::init() if (System::getEnv('_APP_USAGE_STATS', 'enabled') !== 'enabled') { throw new Exception(Exception::GENERAL_USAGE_DISABLED); } - }); \ No newline at end of file + }); From a895ce4270099e9184d201a6c4c9d2951d09b7fb Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 16:51:29 +1200 Subject: [PATCH 09/21] Remove redundant backup checks --- app/controllers/api/projects.php | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 5464014b48..c07c708bd4 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -111,35 +111,8 @@ App::post('/v1/projects') $projectId = ($projectId == 'unique()') ? ID::unique() : $projectId; - $backups['database_db_fra1_v14x_02'] = ['from' => '03:00', 'to' => '05:00']; - $backups['database_db_fra1_v14x_03'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_04'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_05'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_06'] = ['from' => '00:00', 'to' => '02:00']; - $backups['database_db_fra1_v14x_07'] = ['from' => '00:00', 'to' => '02:00']; - $databases = Config::getParam('pools-database', []); - /** - * Remove databases from the list that are currently undergoing an backup - */ - if (count($databases) > 1) { - $now = new \DateTime(); - - foreach ($databases as $index => $database) { - if (empty($backups[$database])) { - continue; - } - $backup = $backups[$database]; - $from = \DateTime::createFromFormat('H:i', $backup['from']); - $to = \DateTime::createFromFormat('H:i', $backup['to']); - if ($now >= $from && $now <= $to) { - unset($databases[$index]); - break; - } - } - } - $databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE'); $index = \array_search($databaseOverride, $databases); if ($index !== false) { From 4ed125f7c880c6e8ec7dec92e543fd5d91f1d3e0 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 16:53:09 +1200 Subject: [PATCH 10/21] Remove random shared tables assignment in preparation of setting as override instead --- app/controllers/api/projects.php | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index c07c708bd4..f90dda6cab 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -125,33 +125,8 @@ App::post('/v1/projects') throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project."); } - // TODO: 1 in 5 projects use shared tables. Temporary until all projects are using shared tables. - if ( - ( - !\mt_rand(0, 4) - && System::getEnv('_APP_DATABASE_SHARED_TABLES', 'enabled') === 'enabled' - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - ) || - ( - $dsn === DATABASE_SHARED_TABLES - ) - ) { - $schema = 'appwrite'; - $database = 'appwrite'; - $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; - - if (!empty($namespace)) { - $dsn .= '&namespace=' . $namespace; - } - } - - // TODO: Allow overriding in development mode. Temporary until all projects are using shared tables. - if ( - App::isDevelopment() - && System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted' - && $request->getHeader('x-appwrited-share-tables', false) - ) { + // TODO: Temporary until all projects are using shared tables. + if ($dsn === DATABASE_SHARED_TABLES || (App::isDevelopment() && $request->getHeader('x-appwrite-shared-tables', false))) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); From e19b465ce2bd48019dd362f24e3fdaf711d5040e Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:10:47 +1200 Subject: [PATCH 11/21] Move shared tables db to env var from const --- app/cli.php | 4 ++-- app/controllers/api/projects.php | 6 +++--- app/init.php | 7 ++----- app/realtime.php | 2 +- app/worker.php | 6 +++--- src/Appwrite/Platform/Workers/Deletes.php | 6 +++--- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/app/cli.php b/app/cli.php index da7d23c18d..69d4c1c5a8 100644 --- a/app/cli.php +++ b/app/cli.php @@ -109,7 +109,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -133,7 +133,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index f90dda6cab..26a6431f11 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -126,11 +126,11 @@ App::post('/v1/projects') } // TODO: Temporary until all projects are using shared tables. - if ($dsn === DATABASE_SHARED_TABLES || (App::isDevelopment() && $request->getHeader('x-appwrite-shared-tables', false))) { + if ($dsn === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $schema = 'appwrite'; $database = 'appwrite'; $namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''); - $dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database; + $dsn = $schema . '://' . System::getEnv('_APP_DATABASE_SHARED_TABLES', '') . '?database=' . $database; if (!empty($namespace)) { $dsn .= '&namespace=' . $namespace; @@ -184,7 +184,7 @@ App::post('/v1/projects') $adapter = $pools->get($dsn->getHost())->pop()->getResource(); $dbForProject = new Database($adapter, $cache); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/init.php b/app/init.php index 57ad5fab87..c6c9c401a7 100644 --- a/app/init.php +++ b/app/init.php @@ -143,9 +143,6 @@ const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; -// Databases -const DATABASE_SHARED_TABLES = 'database_db_fra1_self_hosted_16_0'; - // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; const DATABASE_RECONNECT_MAX_ATTEMPTS = 10; @@ -1338,7 +1335,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -1391,7 +1388,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, ->setMetadata('project', $project->getId()) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/realtime.php b/app/realtime.php index 2904b1db9c..cde4327417 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -92,7 +92,7 @@ if (!function_exists("getProjectDB")) { $database = new Database($adapter, getCache()); - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/app/worker.php b/app/worker.php index 763ab1d914..5d72d52635 100644 --- a/app/worker.php +++ b/app/worker.php @@ -94,7 +94,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -127,7 +127,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso if (isset($databases[$dsn->getHost()])) { $database = $databases[$dsn->getHost()]; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) @@ -151,7 +151,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso $databases[$dsn->getHost()] = $database; - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $database ->setSharedTables(true) ->setTenant($project->getInternalId()) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 49b41da495..d54f3f5079 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -498,14 +498,14 @@ class Deletes extends Action $collections = $dbForProject->listCollections($limit); foreach ($collections as $collection) { - if ($dsn->getHost() !== DATABASE_SHARED_TABLES || !\in_array($collection->getId(), $projectCollectionIds)) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) { $dbForProject->deleteCollection($collection->getId()); } else { $this->deleteByGroup($collection->getId(), [], database: $dbForProject); } } - if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections); if (empty(\array_diff($collectionsIds, $projectCollectionIds))) { @@ -554,7 +554,7 @@ class Deletes extends Action ], $dbForConsole); // Delete metadata table - if ($dsn->getHost() !== DATABASE_SHARED_TABLES) { + if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) { $dbForProject->deleteCollection('_metadata'); } else { $this->deleteByGroup('_metadata', [], $dbForProject); From 00c047d804aa3d25565552cd9fce941abab2ca76 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:29:06 +1200 Subject: [PATCH 12/21] Run full tests on shared tables --- .github/workflows/tests.yml | 3 + docker-compose.yml | 40 +- .../Projects/ProjectsConsoleClientTest.php | 501 ------------------ 3 files changed, 21 insertions(+), 523 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cc4c700f7..7bc39392ef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -145,3 +145,6 @@ jobs: - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug + + - name: Run ${{matrix.service}} Shared Tables Tests + run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug diff --git a/docker-compose.yml b/docker-compose.yml index c104102a76..168b5271f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -189,6 +189,7 @@ services: - _APP_CONSOLE_COUNTRIES_DENYLIST - _APP_EXPERIMENT_LOGGING_PROVIDER - _APP_EXPERIMENT_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-realtime: entrypoint: realtime @@ -238,6 +239,7 @@ services: - _APP_USAGE_STATS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-audits: entrypoint: worker-audits @@ -267,6 +269,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -299,6 +302,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_WEBHOOK_MAX_FAILED_ATTEMPTS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-deletes: entrypoint: worker-deletes @@ -356,6 +360,7 @@ services: - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST + - _APP_DATABASE_SHARED_TABLES appwrite-worker-databases: entrypoint: worker-databases @@ -387,6 +392,7 @@ services: - _APP_LOGGING_CONFIG - _APP_WORKERS_NUM - _APP_QUEUE_NAME + - _APP_DATABASE_SHARED_TABLES appwrite-worker-builds: entrypoint: worker-builds @@ -452,6 +458,7 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET + - _APP_DATABASE_SHARED_TABLES appwrite-worker-certificates: entrypoint: worker-certificates @@ -487,6 +494,7 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_DATABASE_SHARED_TABLES appwrite-worker-functions: entrypoint: worker-functions @@ -526,6 +534,7 @@ services: - _APP_DOCKER_HUB_PASSWORD - _APP_LOGGING_CONFIG - _APP_LOGGING_PROVIDER + - _APP_DATABASE_SHARED_TABLES appwrite-worker-mails: entrypoint: worker-mails @@ -560,6 +569,7 @@ services: - _APP_LOGGING_CONFIG - _APP_DOMAIN - _APP_OPTIONS_FORCE_HTTPS + - _APP_DATABASE_SHARED_TABLES appwrite-worker-messaging: entrypoint: worker-messaging @@ -592,6 +602,7 @@ services: - _APP_SMS_FROM - _APP_SMS_PROVIDER - _APP_SMS_PROJECTS_DENY_LIST + - _APP_DATABASE_SHARED_TABLES appwrite-worker-migrations: entrypoint: worker-migrations @@ -627,6 +638,7 @@ services: - _APP_LOGGING_CONFIG - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET + - _APP_DATABASE_SHARED_TABLES appwrite-task-maintenance: entrypoint: maintenance @@ -664,6 +676,7 @@ services: - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage: entrypoint: worker-usage @@ -695,6 +708,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-worker-usage-dump: entrypoint: worker-usage-dump @@ -726,6 +740,7 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-functions: entrypoint: schedule-functions @@ -753,6 +768,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-task-scheduler-messages: entrypoint: schedule-messages @@ -780,6 +796,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DATABASE_SHARED_TABLES appwrite-assistant: container_name: appwrite-assistant @@ -878,20 +895,7 @@ services: - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - MARIADB_AUTO_UPGRADE=1 - command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests - # command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu - - # smtp: - # image: appwrite/smtp:1.2.0 - # container_name: appwrite-smtp - # restart: unless-stopped - # networks: - # - appwrite - # environment: - # - LOCAL_DOMAINS=@ - # - RELAY_FROM_HOSTS=192.168.0.0/16 ; *.yourdomain.com - # - SMARTHOST_HOST=smtp - # - SMARTHOST_PORT=587 + command: "mysqld --innodb-flush-method=fsync" redis: image: redis:7.2.4-alpine @@ -909,14 +913,6 @@ services: volumes: - appwrite-redis:/data:rw - # clamav: - # image: appwrite/clamav:1.2.0 - # container_name: appwrite-clamav - # networks: - # - appwrite - # volumes: - # - appwrite-uploads:/storage/uploads - # Dev Tools Start ------------------------------------------------------------------------------------------ # # The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 62f5cfe435..5e0a48642b 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -9,7 +9,6 @@ use Tests\E2E\General\UsageTest; use Tests\E2E\Scopes\ProjectConsole; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -3494,504 +3493,4 @@ class ProjectsConsoleClientTest extends Scope return $data; } - - public function testTenantIsolation(): void - { - // Create a team and a project - $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'teamId' => ID::unique(), - 'name' => 'Amazing Team', - ]); - - $teamId = $team['body']['$id']; - - // Project-level isolation - $project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Project-level isolation - $project3 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => false - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Application level isolation (shared tables) - $project4 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-shared-tables' => true - ], $this->getHeaders()), [ - 'projectId' => ID::unique(), - 'name' => 'Amazing Project', - 'teamId' => $teamId, - 'region' => 'default' - ]); - - // Create and API key in each project - $key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key3 = $this->client->call(Client::METHOD_POST, '/projects/' . $project3['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - $key4 = $this->client->call(Client::METHOD_POST, '/projects/' . $project4['body']['$id'] . '/keys', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'name' => 'Key Test', - 'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'], - ]); - - // Create a database in each project - $database1 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database2 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database3 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - $database4 = $this->client->call(Client::METHOD_POST, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => ID::unique(), - 'name' => 'Amazing Database', - ]); - - // Create a collection in each project - $collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - $collection4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => ID::unique(), - 'name' => 'Amazing Collection', - ]); - - // Create an attribute in each project - $attribute1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - $attribute4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes/string', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'size' => 255, - 'required' => true - ]); - - // Wait for attributes - \sleep(2); - - // Create an index in each project - $index1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ], [ - 'databaseId' => $database1['body']['$id'], - 'collectionId' => $collection1['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute1['body']['key']], - ]); - - $index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection2['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute2['body']['key']], - ]); - - $index3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ], [ - 'databaseId' => $database3['body']['$id'], - 'collectionId' => $collection3['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute3['body']['key']], - ]); - - $index4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'databaseId' => $database4['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'key' => ID::unique(), - 'type' => Database::INDEX_KEY, - 'attributes' => [$attribute4['body']['key']], - ]); - - // Wait for indexes - \sleep(2); - - // Assert that each project has only 1 database, 1 collection, 1 attribute and 1 index - $databasesProject1 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject1['body']['total']); - $this->assertEquals(1, \count($databasesProject1['body']['databases'])); - - $databasesProject2 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject2['body']['total']); - $this->assertEquals(1, \count($databasesProject2['body']['databases'])); - - $databasesProject3 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject3['body']['total']); - $this->assertEquals(1, \count($databasesProject3['body']['databases'])); - - $databasesProject4 = $this->client->call(Client::METHOD_GET, '/databases', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $databasesProject4['body']['total']); - $this->assertEquals(1, \count($databasesProject4['body']['databases'])); - - $collectionsProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject1['body']['total']); - $this->assertEquals(1, \count($collectionsProject1['body']['collections'])); - - $collectionsProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject2['body']['total']); - $this->assertEquals(1, \count($collectionsProject2['body']['collections'])); - - $collectionsProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject3['body']['total']); - $this->assertEquals(1, \count($collectionsProject3['body']['collections'])); - - $collectionsProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $collectionsProject4['body']['total']); - $this->assertEquals(1, \count($collectionsProject4['body']['collections'])); - - $attributesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject1['body']['total']); - $this->assertEquals(1, \count($attributesProject1['body']['attributes'])); - $this->assertEquals('available', $attributesProject1['body']['attributes'][0]['status']); - - $attributesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject2['body']['total']); - $this->assertEquals(1, \count($attributesProject2['body']['attributes'])); - $this->assertEquals('available', $attributesProject2['body']['attributes'][0]['status']); - - $attributesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject3['body']['total']); - $this->assertEquals(1, \count($attributesProject3['body']['attributes'])); - $this->assertEquals('available', $attributesProject3['body']['attributes'][0]['status']); - - $attributesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $attributesProject4['body']['total']); - $this->assertEquals(1, \count($attributesProject4['body']['attributes'])); - $this->assertEquals('available', $attributesProject4['body']['attributes'][0]['status']); - - $indexesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject1['body']['total']); - $this->assertEquals(1, \count($indexesProject1['body']['indexes'])); - - $indexesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject2['body']['total']); - $this->assertEquals(1, \count($indexesProject2['body']['indexes'])); - - $indexesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject3['body']['total']); - $this->assertEquals(1, \count($indexesProject3['body']['indexes'])); - - $indexesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ]); - - $this->assertEquals(1, $indexesProject4['body']['total']); - $this->assertEquals(1, \count($indexesProject4['body']['indexes'])); - - // Attempt to read cross-type resources - $collectionProject2WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject2WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject2Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject2Key['headers']['status-code']); - - // Attempt to read cross-tenant resources - $collectionProject3WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project1['body']['$id'], - 'x-appwrite-key' => $key1['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject3WithProject1Key['headers']['status-code']); - - $collectionProject1WithProject3Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project3['body']['$id'], - 'x-appwrite-key' => $key3['body']['secret'] - ]); - - $this->assertEquals(404, $collectionProject1WithProject3Key['headers']['status-code']); - - // Assert that shared project resources can have the same ID as they're unique on tenant + ID not just ID - $collection5 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'databaseId' => $database2['body']['$id'], - 'collectionId' => $collection4['body']['$id'], - 'name' => 'Amazing Collection', - ]); - - $this->assertEquals(201, $collection5['headers']['status-code']); - - // Assert that users across projects on shared tables can have the same email as they're unique on tenant + email not just email - $user1 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2['body']['$id'], - 'x-appwrite-key' => $key2['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user1['headers']['status-code']); - - $user2 = $this->client->call(Client::METHOD_POST, '/users', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project4['body']['$id'], - 'x-appwrite-key' => $key4['body']['secret'] - ], [ - 'userId' => 'user', - 'email' => 'test@appwrite.io', - 'password' => 'password', - 'name' => 'Test User', - ]); - - $this->assertEquals(201, $user2['headers']['status-code']); - } } From bbb4b0bc12d6e0a0441c2417604cd83ba4b16302 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 24 May 2024 20:29:25 +1200 Subject: [PATCH 13/21] Remove shared table headers --- app/controllers/general.php | 4 ++-- tests/e2e/General/HTTPTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index f1be7bd614..3e243a90d3 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -580,7 +580,7 @@ App::init() ->addHeader('Server', 'Appwrite') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $refDomain) ->addHeader('Access-Control-Allow-Credentials', 'true'); @@ -631,7 +631,7 @@ App::options() $response ->addHeader('Server', 'Appwrite') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent') ->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') diff --git a/tests/e2e/General/HTTPTest.php b/tests/e2e/General/HTTPTest.php index 0bb5ca4650..92bc52561c 100644 --- a/tests/e2e/General/HTTPTest.php +++ b/tests/e2e/General/HTTPTest.php @@ -31,7 +31,7 @@ class HTTPTest extends Scope $this->assertEquals(204, $response['headers']['status-code']); $this->assertEquals('Appwrite', $response['headers']['server']); $this->assertEquals('GET, POST, PUT, PATCH, DELETE', $response['headers']['access-control-allow-methods']); - $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); + $this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']); $this->assertEquals('X-Appwrite-Session, X-Fallback-Cookies', $response['headers']['access-control-expose-headers']); $this->assertEquals('http://localhost', $response['headers']['access-control-allow-origin']); $this->assertEquals('true', $response['headers']['access-control-allow-credentials']); From d4db55ab7755375d4363b2cef69058527c94781c Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 29 May 2024 18:11:58 +0900 Subject: [PATCH 14/21] Fix failed queue param in failed jobs --- app/controllers/api/health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 4b4ce8f307..f4581df8e4 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -852,7 +852,7 @@ App::get('/v1/health/queue/failed/:name') Event::FUNCTIONS_QUEUE_NAME, Event::USAGE_QUEUE_NAME, Event::USAGE_DUMP_QUEUE_NAME, - Event::WEBHOOK_CLASS_NAME, + Event::WEBHOOK_QUEUE_NAME, Event::CERTIFICATES_QUEUE_NAME, Event::BUILDS_QUEUE_NAME, Event::MESSAGING_QUEUE_NAME, From 065b5f4858201e93854cd73550d17c9467056abf Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 30 May 2024 16:07:11 +0300 Subject: [PATCH 15/21] test --- composer.json | 2 +- composer.lock | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 205fe308f0..1e60d87bc6 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "dev-main as 0.49.10", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 8acbbed541..0c9e96e2e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "53996479cd4ba0c73dbc72d46b240be0", + "content-hash": "b37a830efbb0467d058a640b289a0a91", "packages": [ { "name": "adhocore/jwt", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "dev-main", "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": { @@ -1749,6 +1749,7 @@ "swoole/ide-helper": "4.8.0", "utopia-php/cli": "^0.14.0" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -1769,9 +1770,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/main" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-05-30T12:40:27+00:00" }, { "name": "utopia-php/domains", @@ -5587,9 +5588,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-main", + "alias": "0.49.10", + "alias_normalized": "0.49.10.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -5613,5 +5623,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From c6a520909e0b41d39c6e5f7afc99a65324324065 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:23:15 +0100 Subject: [PATCH 16/21] feat: support twilio messaging service sid --- composer.json | 2 +- composer.lock | 14 +++++++------- src/Appwrite/Platform/Workers/Messaging.php | 18 +++++++++++++----- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index 1e60d87bc6..3c34ddbfbb 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.5.*", - "utopia-php/messaging": "0.11.*", + "utopia-php/messaging": "0.12.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.5.*", diff --git a/composer.lock b/composer.lock index 0c9e96e2e1..a05931eb63 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b37a830efbb0467d058a640b289a0a91", + "content-hash": "20844ba2607c2746ee92e3b9474086ab", "packages": [ { "name": "adhocore/jwt", @@ -2120,16 +2120,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.11.0", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154" + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/b499c3ad11af711c28252c62d83f24e6106a2154", - "reference": "b499c3ad11af711c28252c62d83f24e6106a2154", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/6e466d3511981291843c6ebf9ce3f44fc75e37b0", + "reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0", "shasum": "" }, "require": { @@ -2165,9 +2165,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.11.0" + "source": "https://github.com/utopia-php/messaging/tree/0.12.0" }, - "time": "2024-05-08T17:10:02+00:00" + "time": "2024-05-30T14:58:25+00:00" }, { "name": "utopia-php/migration", diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 19d2c5a0fe..6f642fabb7 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -399,7 +399,10 @@ class Messaging extends Action 'credentials' => match ($host) { 'twilio' => [ 'accountSid' => $user, - 'authToken' => $password + 'authToken' => $password, + // Twilio Messaging Service SIDs always start with MG + // https://www.twilio.com/docs/messaging/services + 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null ], 'textmagic' => [ 'username' => $user, @@ -420,9 +423,14 @@ class Messaging extends Action ], default => null }, - 'options' => [ - 'from' => $from - ] + 'options' => match ($host) { + 'twilio' => [ + 'from' => \str_starts_with($from, 'MG') ? null : $from + ], + default => [ + 'from' => $from + ] + } ]); $adapter = $this->getSmsAdapter($provider); @@ -465,7 +473,7 @@ class Messaging extends Action return match ($provider->getAttribute('provider')) { 'mock' => new Mock('username', 'password'), - 'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken']), + 'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken'], null, isset($credentials['messagingServiceSid']) ? $credentials['messagingServiceSid'] : null), 'textmagic' => new TextMagic($credentials['username'], $credentials['apiKey']), 'telesign' => new Telesign($credentials['customerId'], $credentials['apiKey']), 'msg91' => new Msg91($credentials['senderId'], $credentials['authKey'], $credentials['templateId']), From 72cca45d6d6d714398b75aaf2832faf7fa82dad1 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:34:43 +0100 Subject: [PATCH 17/21] feat: use param instead --- src/Appwrite/Platform/Workers/Messaging.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 6f642fabb7..a58f2e12ba 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -400,9 +400,7 @@ class Messaging extends Action 'twilio' => [ 'accountSid' => $user, 'authToken' => $password, - // Twilio Messaging Service SIDs always start with MG - // https://www.twilio.com/docs/messaging/services - 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null + 'messagingServiceSid' => $smsDSN->getParam('messagingServiceSid') ?? null ], 'textmagic' => [ 'username' => $user, @@ -425,7 +423,7 @@ class Messaging extends Action }, 'options' => match ($host) { 'twilio' => [ - 'from' => \str_starts_with($from, 'MG') ? null : $from + 'from' => $smsDSN->getParam('messagingServiceSid') ? null : $from ], default => [ 'from' => $from From ab4401992c460489d8f1e645d26592cd4caae404 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:36:05 +0100 Subject: [PATCH 18/21] Revert "feat: use param instead" This reverts commit 72cca45d6d6d714398b75aaf2832faf7fa82dad1. --- src/Appwrite/Platform/Workers/Messaging.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index a58f2e12ba..6f642fabb7 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -400,7 +400,9 @@ class Messaging extends Action 'twilio' => [ 'accountSid' => $user, 'authToken' => $password, - 'messagingServiceSid' => $smsDSN->getParam('messagingServiceSid') ?? null + // Twilio Messaging Service SIDs always start with MG + // https://www.twilio.com/docs/messaging/services + 'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null ], 'textmagic' => [ 'username' => $user, @@ -423,7 +425,7 @@ class Messaging extends Action }, 'options' => match ($host) { 'twilio' => [ - 'from' => $smsDSN->getParam('messagingServiceSid') ? null : $from + 'from' => \str_starts_with($from, 'MG') ? null : $from ], default => [ 'from' => $from From e91a532e743bc195ebd40d6fe40c48049df1d3bb Mon Sep 17 00:00:00 2001 From: fogelito Date: Thu, 30 May 2024 18:46:21 +0300 Subject: [PATCH 19/21] Database tag --- composer.json | 2 +- composer.lock | 20 +++++--------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index 1e60d87bc6..205fe308f0 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ "utopia-php/cache": "0.9.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-main as 0.49.10", + "utopia-php/database": "0.49.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index 0c9e96e2e1..8119cf4343 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b37a830efbb0467d058a640b289a0a91", + "content-hash": "53996479cd4ba0c73dbc72d46b240be0", "packages": [ { "name": "adhocore/jwt", @@ -1719,7 +1719,7 @@ }, { "name": "utopia-php/database", - "version": "dev-main", + "version": "0.49.11", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", @@ -1749,7 +1749,6 @@ "swoole/ide-helper": "4.8.0", "utopia-php/cli": "^0.14.0" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -1770,7 +1769,7 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/main" + "source": "https://github.com/utopia-php/database/tree/0.49.11" }, "time": "2024-05-30T12:40:27+00:00" }, @@ -5588,18 +5587,9 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [ - { - "package": "utopia-php/database", - "version": "dev-main", - "alias": "0.49.10", - "alias_normalized": "0.49.10.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/database": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 61336be50db635bdccf9dfd003101e71b70ac5a2 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Thu, 30 May 2024 16:51:48 +0100 Subject: [PATCH 20/21] doc: update _APP_SMS_FROM --- app/config/variables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/variables.php b/app/config/variables.php index b61a267785..77e8a36763 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -450,7 +450,7 @@ return [ ], [ 'name' => '_APP_SMS_FROM', - 'description' => 'Phone number used for sending out messages. Must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789).', + 'description' => 'Phone number used for sending out messages. If using Twilio, this may be a Messaging Service SID, starting with MG. Otherwise, the number must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789). ', 'introduction' => '0.15.0', 'default' => '', 'required' => false, From 5b3a3d5bf965d9e76947c9191a909fa1010fbd7b Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 4 Jun 2024 20:10:45 +1200 Subject: [PATCH 21/21] Add flaky test retry --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 119c1a2223..966f948ce6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Functions; +use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -42,6 +43,7 @@ class FunctionsCustomClientTest extends Scope return []; } + #[Retry(count: 2)] public function testCreateExecution(): array { /**