From bc2703ea08f554e7cbd359002be0cc3423ebab2b Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Wed, 22 Dec 2021 20:51:49 -0500 Subject: [PATCH 01/24] Set default database for collections --- app/http.php | 6 +++--- app/init.php | 9 ++++++--- app/realtime.php | 9 +++++---- composer.json | 2 +- composer.lock | 27 ++++++++++++++++++--------- docker-compose.yml | 4 ++-- src/Appwrite/Resque/Worker.php | 11 ++++++----- 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/app/http.php b/app/http.php index fa92c5d397..d76f722f34 100644 --- a/app/http.php +++ b/app/http.php @@ -78,14 +78,14 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { $dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */ - if(!$dbForConsole->exists()) { + // if(!$dbForConsole->exists('appwrite')) { Console::success('[Setup] - Server database init started...'); $collections = Config::getParam('collections', []); /** @var array $collections */ $redis->flushAll(); - $dbForConsole->create(); + $dbForConsole->create('appwrite'); $audit = new Audit($dbForConsole); $audit->setup(); @@ -125,7 +125,7 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { } Console::success('[Setup] - Server database init completed...'); - } + // } }); Console::success('Server started successfully (max payload is '.number_format($payloadSize).' bytes)'); diff --git a/app/init.php b/app/init.php index f6b186d53e..2c64b858f3 100644 --- a/app/init.php +++ b/app/init.php @@ -785,7 +785,8 @@ App::setResource('dbForInternal', function($db, $cache, $project) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_'.$project->getId().'_internal'); + $database->setDefaultDatabase('appwrite'); + $database->setNamespace('_project_'.$project->getId()); return $database; }, ['db', 'cache', 'project']); @@ -794,7 +795,8 @@ App::setResource('dbForExternal', function($db, $cache, $project) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_'.$project->getId().'_external'); + $database->setDefaultDatabase('appwrite'); + $database->setNamespace('project_'.$project->getId()); return $database; }, ['db', 'cache', 'project']); @@ -803,7 +805,8 @@ App::setResource('dbForConsole', function($db, $cache) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_console_internal'); + $database->setDefaultDatabase('appwrite'); + $database->setNamespace('_console'); return $database; }, ['db', 'cache']); diff --git a/app/realtime.php b/app/realtime.php index 5215cd2477..e9ce8353b2 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -58,6 +58,7 @@ function getDatabase(Registry &$register, string $namespace) $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); + $database->setDefaultDatabase('appwrite'); $database->setNamespace($namespace); return [ @@ -77,7 +78,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume */ go(function () use ($register, $containerId, &$statsDocument) { try { - [$database, $returnDatabase] = getDatabase($register, 'project_console_internal'); + [$database, $returnDatabase] = getDatabase($register, '_console'); $document = new Document([ '$id' => $database->getId(), '$collection' => 'realtime', @@ -133,7 +134,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume } try { - [$database, $returnDatabase] = getDatabase($register, 'project_console_internal'); + [$database, $returnDatabase] = getDatabase($register, '_console'); $statsDocument ->setAttribute('timestamp', time()) @@ -163,7 +164,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, */ if ($realtime->hasSubscriber('console', 'role:member', 'project')) { - [$database, $returnDatabase] = getDatabase($register, 'project_console_internal'); + [$database, $returnDatabase] = getDatabase($register, '_console'); $payload = []; @@ -267,7 +268,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, return; } - [$database, $returnDatabase] = getDatabase($register, 'project_' . $projectId . '_internal'); + [$database, $returnDatabase] = getDatabase($register, 'project_' . $projectId); $user = $database->getDocument('users', $userId); diff --git a/composer.json b/composer.json index 525c49e702..e03fb76571 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.12.*", + "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0", "utopia-php/locale": "0.4.*", "utopia-php/orchestration": "0.2.*", "utopia-php/registry": "0.5.*", diff --git a/composer.lock b/composer.lock index 6316ff1ba4..2125a78a76 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": "c755b0ae991777da3e44b0442690fa46", + "content-hash": "f546dc6dcc6af7ccdb62435aed4fc0ca", "packages": [ { "name": "adhocore/jwt", @@ -2138,16 +2138,16 @@ }, { "name": "utopia-php/database", - "version": "0.12.1", + "version": "dev-feat-database-and-namespace", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "af512b7a00cc7c6e30fa03efbc5fd7e77a93e2df" + "reference": "dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/af512b7a00cc7c6e30fa03efbc5fd7e77a93e2df", - "reference": "af512b7a00cc7c6e30fa03efbc5fd7e77a93e2df", + "url": "https://api.github.com/repos/utopia-php/database/zipball/dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1", + "reference": "dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1", "shasum": "" }, "require": { @@ -2195,9 +2195,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.12.1" + "source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace" }, - "time": "2021-12-13T14:57:32+00:00" + "time": "2021-12-22T20:55:21+00:00" }, { "name": "utopia-php/domains", @@ -6496,9 +6496,18 @@ "time": "2015-12-17T08:42:14+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/database", + "version": "dev-feat-database-and-namespace", + "alias": "0.13.0", + "alias_normalized": "0.13.0.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/database": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/docker-compose.yml b/docker-compose.yml index 3e50c9640e..8ea8f6f9c3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,7 +71,7 @@ services: - ./psalm.xml:/usr/src/code/psalm.xml - ./tests:/usr/src/code/tests - ./app:/usr/src/code/app - # - ./vendor:/usr/src/code/vendor + - ./vendor:/usr/src/code/vendor - ./docs:/usr/src/code/docs - ./src:/usr/src/code/src # - ./debug:/tmp @@ -441,7 +441,7 @@ services: - _APP_REDIS_PASS mariadb: - image: appwrite/mariadb:1.2.0 # fix issues when upgrading using: mysql_upgrade -u root -p + image: mariadb:10.7 # fix issues when upgrading using: mysql_upgrade -u root -p container_name: appwrite-mariadb networks: - appwrite diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index dd7b25a876..b357b1cfc9 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -86,16 +86,16 @@ abstract class Worker if (!$projectId) { throw new \Exception('ProjectID not provided - cannot get database'); } - $namespace = "project_{$projectId}_internal"; + $namespace = "project_{$projectId}"; break; case self::DATABASE_EXTERNAL: if (!$projectId) { throw new \Exception('ProjectID not provided - cannot get database'); } - $namespace = "project_{$projectId}_external"; + $namespace = "project_{$projectId}"; break; case self::DATABASE_CONSOLE: - $namespace = "project_console_internal"; + $namespace = "_console"; $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created break; default: @@ -110,9 +110,10 @@ abstract class Worker $attempts++; $cache = new Cache(new RedisCache($register->get('cache'))); $database = new Database(new MariaDB($register->get('db')), $cache); + $database->setDefaultDatabase('appwrite'); $database->setNamespace($namespace); // Main DB - if (!$database->exists()) { - throw new \Exception("Table does not exist: {$database->getNamespace()}"); + if (!empty($projectId) && !$database->getDocument('projects', $projectId)->isEmpty()) { + throw new \Exception("Project does not exist: {$projectId}"); } break; // leave loop if successful } catch(\Exception $e) { From 647db81169659afca4558dedbdb519f62975feef Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Thu, 23 Dec 2021 16:25:33 -0500 Subject: [PATCH 02/24] Test changes in audit and abuse libraries --- composer.json | 4 ++-- composer.lock | 56 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index e03fb76571..689d4f219e 100644 --- a/composer.json +++ b/composer.json @@ -39,9 +39,9 @@ "appwrite/php-runtimes": "0.6.*", "utopia-php/framework": "0.19.*", - "utopia-php/abuse": "0.6.*", + "utopia-php/abuse": "dev-feat-use-namespace-as-table-prefix as 0.7.0", "utopia-php/analytics": "0.2.*", - "utopia-php/audit": "0.7.*", + "utopia-php/audit": "dev-feat-use-namespace-as-table-prefix as 0.8.0", "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", diff --git a/composer.lock b/composer.lock index 2125a78a76..2a7c9c996c 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": "f546dc6dcc6af7ccdb62435aed4fc0ca", + "content-hash": "3410f6496e9bb8fd1dd0d996abf4a94f", "packages": [ { "name": "adhocore/jwt", @@ -1820,22 +1820,22 @@ }, { "name": "utopia-php/abuse", - "version": "0.6.3", + "version": "dev-feat-use-namespace-as-table-prefix", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e" + "reference": "340774ba29828d0570ab9d91eadcd31e7a52d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/d63e928c2c50b367495a499a85ba9806ee274c5e", - "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/340774ba29828d0570ab9d91eadcd31e7a52d5d4", + "reference": "340774ba29828d0570ab9d91eadcd31e7a52d5d4", "shasum": "" }, "require": { "ext-pdo": "*", - "php": ">=7.4", - "utopia-php/database": ">=0.6 <1.0" + "php": ">=8.0", + "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -1867,9 +1867,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.6.3" + "source": "https://github.com/utopia-php/abuse/tree/feat-use-namespace-as-table-prefix" }, - "time": "2021-08-16T18:38:31+00:00" + "time": "2021-12-23T21:21:10+00:00" }, { "name": "utopia-php/analytics", @@ -1928,22 +1928,22 @@ }, { "name": "utopia-php/audit", - "version": "0.7.0", + "version": "dev-feat-use-namespace-as-table-prefix", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "485cdd2354db7eb8f7aa74bbe39c39b583e99c04" + "reference": "02681f6b0bd048348c758c06ebfcc5e05f7c19e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/485cdd2354db7eb8f7aa74bbe39c39b583e99c04", - "reference": "485cdd2354db7eb8f7aa74bbe39c39b583e99c04", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/02681f6b0bd048348c758c06ebfcc5e05f7c19e1", + "reference": "02681f6b0bd048348c758c06ebfcc5e05f7c19e1", "shasum": "" }, "require": { "ext-pdo": "*", - "php": ">=7.4", - "utopia-php/database": ">=0.11 <1.0" + "php": ">=8.0", + "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1975,9 +1975,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.7.0" + "source": "https://github.com/utopia-php/audit/tree/feat-use-namespace-as-table-prefix" }, - "time": "2021-11-17T17:23:42+00:00" + "time": "2021-12-23T21:11:58+00:00" }, { "name": "utopia-php/cache", @@ -2142,12 +2142,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1" + "reference": "f4e02988c2dc4385c08dbb318c81462d5188ed8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1", - "reference": "dce7c47b51cd5b4ccbdf87e192be13b22c8a25e1", + "url": "https://api.github.com/repos/utopia-php/database/zipball/f4e02988c2dc4385c08dbb318c81462d5188ed8e", + "reference": "f4e02988c2dc4385c08dbb318c81462d5188ed8e", "shasum": "" }, "require": { @@ -2197,7 +2197,7 @@ "issues": "https://github.com/utopia-php/database/issues", "source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace" }, - "time": "2021-12-22T20:55:21+00:00" + "time": "2021-12-23T20:51:18+00:00" }, { "name": "utopia-php/domains", @@ -6497,6 +6497,18 @@ } ], "aliases": [ + { + "package": "utopia-php/abuse", + "version": "dev-feat-use-namespace-as-table-prefix", + "alias": "0.7.0", + "alias_normalized": "0.7.0.0" + }, + { + "package": "utopia-php/audit", + "version": "dev-feat-use-namespace-as-table-prefix", + "alias": "0.8.0", + "alias_normalized": "0.8.0.0" + }, { "package": "utopia-php/database", "version": "dev-feat-database-and-namespace", @@ -6506,6 +6518,8 @@ ], "minimum-stability": "stable", "stability-flags": { + "utopia-php/abuse": 20, + "utopia-php/audit": 20, "utopia-php/database": 20 }, "prefer-stable": false, From 05a061127fe9f123fbbcf8acdbb98c9685d2889f Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Thu, 23 Dec 2021 17:51:10 -0500 Subject: [PATCH 03/24] Use the same namespace --- app/init.php | 4 ++-- app/realtime.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/init.php b/app/init.php index 2c64b858f3..3a316b315f 100644 --- a/app/init.php +++ b/app/init.php @@ -796,7 +796,7 @@ App::setResource('dbForExternal', function($db, $cache, $project) { $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase('appwrite'); - $database->setNamespace('project_'.$project->getId()); + $database->setNamespace('_project_'.$project->getId()); return $database; }, ['db', 'cache', 'project']); @@ -806,7 +806,7 @@ App::setResource('dbForConsole', function($db, $cache) { $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase('appwrite'); - $database->setNamespace('_console'); + $database->setNamespace('_project_console'); return $database; }, ['db', 'cache']); diff --git a/app/realtime.php b/app/realtime.php index e9ce8353b2..4ef84f5900 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -78,7 +78,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume */ go(function () use ($register, $containerId, &$statsDocument) { try { - [$database, $returnDatabase] = getDatabase($register, '_console'); + [$database, $returnDatabase] = getDatabase($register, '_project_console'); $document = new Document([ '$id' => $database->getId(), '$collection' => 'realtime', @@ -134,7 +134,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume } try { - [$database, $returnDatabase] = getDatabase($register, '_console'); + [$database, $returnDatabase] = getDatabase($register, '_project_console'); $statsDocument ->setAttribute('timestamp', time()) @@ -164,7 +164,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, */ if ($realtime->hasSubscriber('console', 'role:member', 'project')) { - [$database, $returnDatabase] = getDatabase($register, '_console'); + [$database, $returnDatabase] = getDatabase($register, '_project_console'); $payload = []; From 1bb6ab969140933dc205a6c5284fcde3623f4d7b Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Thu, 23 Dec 2021 17:51:21 -0500 Subject: [PATCH 04/24] Only create the projectDB once --- app/controllers/api/projects.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 53c07ef27d..479a7f4a4a 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -106,10 +106,9 @@ App::post('/v1/projects') $collections = Config::getParam('collections', []); /** @var array $collections */ - $dbForInternal->setNamespace('project_' . $project->getId() . '_internal'); - $dbForInternal->create(); - $dbForExternal->setNamespace('project_' . $project->getId() . '_external'); - $dbForExternal->create(); + $dbForInternal->setNamespace('_project_' . $project->getId()); + $dbForExternal->setNamespace('_project_' . $project->getId()); + $dbForExternal->create('appwrite'); $audit = new Audit($dbForInternal); $audit->setup(); From 3f43b426faedb1f1300521a4611bde27a71d23e1 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Thu, 23 Dec 2021 17:51:38 -0500 Subject: [PATCH 05/24] Prepend "collection_" to collections --- app/controllers/api/database.php | 44 ++++++++++++++++---------------- app/workers/database.php | 8 +++--- composer.lock | 8 +++--- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 292324419f..84f8cbd552 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -166,7 +166,7 @@ App::post('/v1/database/collections') $collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId; try { - $dbForExternal->createCollection($collectionId); + $dbForExternal->createCollection('collection_' . $collectionId); $collection = $dbForInternal->createDocument('collections', new Document([ '$id' => $collectionId, @@ -402,7 +402,7 @@ App::get('/v1/database/:collectionId/usage') /** @var Utopia\Database\Database $dbForInternal */ /** @var Utopia\Registry\Registry $register */ - $collection = $dbForExternal->getCollection($collectionId); + $collection = $dbForExternal->getCollection('collection_' . $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -515,7 +515,7 @@ App::get('/v1/database/collections/:collectionId/logs') /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - $collection = $dbForExternal->getCollection($collectionId); + $collection = $dbForExternal->getCollection('collection_' . $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -680,7 +680,7 @@ App::delete('/v1/database/collections/:collectionId') throw new Exception('Failed to remove collection from DB', 500); } - $dbForExternal->deleteCachedCollection($collection->getId()); + $dbForExternal->deleteCachedCollection('collection_' . $collection->getId()); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) @@ -1662,9 +1662,9 @@ App::post('/v1/database/collections/:collectionId/documents') try { if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->createDocument($collectionId, new Document($data))); + $document = Authorization::skip(fn() => $dbForExternal->createDocument('collection_' . $collectionId, new Document($data))); } else { - $document = $dbForExternal->createDocument($collectionId, new Document($data)); + $document = $dbForExternal->createDocument('collection_' . $collectionId, new Document($data)); } } catch (StructureException $exception) { @@ -1758,7 +1758,7 @@ App::get('/v1/database/collections/:collectionId/documents') $cursorDocument = null; if (!empty($cursor)) { - $cursorDocument = $dbForExternal->getDocument($collectionId, $cursor); + $cursorDocument = $dbForExternal->getDocument('collection_' . $collectionId, $cursor); if ($cursorDocument->isEmpty()) { throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400); @@ -1767,11 +1767,11 @@ App::get('/v1/database/collections/:collectionId/documents') if ($collection->getAttribute('permission') === 'collection') { /** @var Document[] $documents */ - $documents = Authorization::skip(fn() => $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection)); - $sum = Authorization::skip(fn() => $dbForExternal->count($collectionId, $queries, APP_LIMIT_COUNT)); + $documents = Authorization::skip(fn() => $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection)); + $sum = Authorization::skip(fn() => $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT)); } else { - $documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection); - $sum = $dbForExternal->count($collectionId, $queries, APP_LIMIT_COUNT); + $documents = $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection); + $sum = $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT); } $usage @@ -1830,9 +1830,9 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->getDocument($collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument($collectionId, $documentId); + $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); } if ($document->isEmpty()) { @@ -1881,7 +1881,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId/logs') throw new Exception('Collection not found', 404); } - $document = $dbForExternal->getDocument($collectionId, $documentId); + $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); if ($document->isEmpty()) { throw new Exception('No document found', 404); @@ -1992,9 +1992,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') throw new Exception('Unauthorized permissions', 401); } - $document = Authorization::skip(fn() => $dbForExternal->getDocument($collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument($collectionId, $documentId); + $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); } @@ -2038,9 +2038,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') try { if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->updateDocument($collection->getId(), $document->getId(), new Document($data))); + $document = Authorization::skip(fn() => $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data))); } else { - $document = $dbForExternal->updateDocument($collection->getId(), $document->getId(), new Document($data)); + $document = $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)); } } catch (AuthorizationException $exception) { @@ -2118,9 +2118,9 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->getDocument($collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument($collectionId, $documentId); + $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); } if ($document->isEmpty()) { @@ -2128,12 +2128,12 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') } if ($collection->getAttribute('permission') === 'collection') { - Authorization::skip(fn() => $dbForExternal->deleteDocument($collectionId, $documentId)); + Authorization::skip(fn() => $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId)); } else { $dbForExternal->deleteDocument($collectionId, $documentId); } - $dbForExternal->deleteCachedDocument($collectionId, $documentId); + $dbForExternal->deleteCachedDocument('collection_' . $collectionId, $documentId); $usage ->setParam('database.documents.delete', 1) diff --git a/app/workers/database.php b/app/workers/database.php index f58502704a..cf4ea10f5e 100644 --- a/app/workers/database.php +++ b/app/workers/database.php @@ -87,7 +87,7 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if(!$dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) { + if(!$dbForExternal->createAttribute('collection_' . $collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) { throw new Exception('Failed to create Attribute'); } $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available')); @@ -137,7 +137,7 @@ class DatabaseV1 extends Worker // - failed: attribute was never created // - stuck: attribute was available but cannot be removed try { - if($status !== 'failed' && !$dbForExternal->deleteAttribute($collectionId, $key)) { + if($status !== 'failed' && !$dbForExternal->deleteAttribute('collection_' . $collectionId, $key)) { throw new Exception('Failed to delete Attribute'); } $dbForInternal->deleteDocument('attributes', $attribute->getId()); @@ -235,7 +235,7 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if(!$dbForExternal->createIndex($collectionId, $key, $type, $attributes, $lengths, $orders)) { + if(!$dbForExternal->createIndex('collection_' . $collectionId, $key, $type, $attributes, $lengths, $orders)) { throw new Exception('Failed to create Index'); } $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available')); @@ -279,7 +279,7 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if($status !== 'failed' && !$dbForExternal->deleteIndex($collectionId, $key)) { + if($status !== 'failed' && !$dbForExternal->deleteIndex('collection_' . $collectionId, $key)) { throw new Exception('Failed to delete index'); } $dbForInternal->deleteDocument('indexes', $index->getId()); diff --git a/composer.lock b/composer.lock index 2a7c9c996c..05a20f94be 100644 --- a/composer.lock +++ b/composer.lock @@ -2142,12 +2142,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "f4e02988c2dc4385c08dbb318c81462d5188ed8e" + "reference": "414178de818ce50832d26b4f4826f10fef64c740" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/f4e02988c2dc4385c08dbb318c81462d5188ed8e", - "reference": "f4e02988c2dc4385c08dbb318c81462d5188ed8e", + "url": "https://api.github.com/repos/utopia-php/database/zipball/414178de818ce50832d26b4f4826f10fef64c740", + "reference": "414178de818ce50832d26b4f4826f10fef64c740", "shasum": "" }, "require": { @@ -2197,7 +2197,7 @@ "issues": "https://github.com/utopia-php/database/issues", "source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace" }, - "time": "2021-12-23T20:51:18+00:00" + "time": "2021-12-23T22:38:30+00:00" }, { "name": "utopia-php/domains", From c3bbce1b049cbc283ab65a746c5376370d9a3ab2 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Thu, 23 Dec 2021 19:27:55 -0500 Subject: [PATCH 06/24] Use correct namespace --- app/controllers/api/database.php | 2 +- src/Appwrite/Resque/Worker.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 84f8cbd552..e3f8b151c3 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -2130,7 +2130,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') if ($collection->getAttribute('permission') === 'collection') { Authorization::skip(fn() => $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId)); } else { - $dbForExternal->deleteDocument($collectionId, $documentId); + $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId); } $dbForExternal->deleteCachedDocument('collection_' . $collectionId, $documentId); diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index b357b1cfc9..864c0e2c43 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -86,16 +86,16 @@ abstract class Worker if (!$projectId) { throw new \Exception('ProjectID not provided - cannot get database'); } - $namespace = "project_{$projectId}"; + $namespace = "_project_{$projectId}"; break; case self::DATABASE_EXTERNAL: if (!$projectId) { throw new \Exception('ProjectID not provided - cannot get database'); } - $namespace = "project_{$projectId}"; + $namespace = "_project_{$projectId}"; break; case self::DATABASE_CONSOLE: - $namespace = "_console"; + $namespace = "_project_console"; $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created break; default: From 6aeb12f3a0b1b692effd39719662e8ed4b12c8c0 Mon Sep 17 00:00:00 2001 From: kodumbeats Date: Fri, 24 Dec 2021 16:20:56 -0500 Subject: [PATCH 07/24] Use correct namespace for realtime --- app/realtime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/realtime.php b/app/realtime.php index 4ef84f5900..dbef9ee697 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -268,7 +268,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, return; } - [$database, $returnDatabase] = getDatabase($register, 'project_' . $projectId); + [$database, $returnDatabase] = getDatabase($register, '_project_' . $projectId); $user = $database->getDocument('users', $userId); From ffae301d5fb267a05c2b4028e5cec5c49f99ff75 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 11:45:24 +0100 Subject: [PATCH 08/24] fix: database service --- app/controllers/api/database.php | 22 ++++++++++++++ tests/e2e/Services/Database/DatabaseBase.php | 31 ++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index e3f8b151c3..1629441258 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -1621,6 +1621,8 @@ App::post('/v1/database/collections/:collectionId/documents') /** * Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions. + * + * @var Document $collection */ $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); @@ -1666,6 +1668,7 @@ App::post('/v1/database/collections/:collectionId/documents') } else { $document = $dbForExternal->createDocument('collection_' . $collectionId, new Document($data)); } + $document->setAttribute('$collection', $collectionId); } catch (StructureException $exception) { throw new Exception($exception->getMessage(), 400); @@ -1774,6 +1777,11 @@ App::get('/v1/database/collections/:collectionId/documents') $sum = $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT); } + /** + * Reset $collection attribute to remove prefix. + */ + $documents = array_map(fn(Document $document) => $document->setAttribute('$collection', $collectionId), $documents); + $usage ->setParam('database.documents.read', 1) ->setParam('collectionId', $collectionId) @@ -1835,6 +1843,11 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); } + /** + * Reset $collection attribute to remove prefix. + */ + $document->setAttribute('$collection', $collectionId); + if ($document->isEmpty()) { throw new Exception('No document found', 404); } @@ -2042,6 +2055,10 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') } else { $document = $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)); } + /** + * Reset $collection attribute to remove prefix. + */ + $document->setAttribute('$collection', $collectionId); } catch (AuthorizationException $exception) { throw new Exception('Unauthorized permissions', 401); @@ -2135,6 +2152,11 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') $dbForExternal->deleteCachedDocument('collection_' . $collectionId, $documentId); + /** + * Reset $collection attribute to remove prefix. + */ + $document->setAttribute('$collection', $collectionId); + $usage ->setParam('database.documents.delete', 1) ->setParam('collectionId', $collectionId) diff --git a/tests/e2e/Services/Database/DatabaseBase.php b/tests/e2e/Services/Database/DatabaseBase.php index 97d70e2521..28369de58e 100644 --- a/tests/e2e/Services/Database/DatabaseBase.php +++ b/tests/e2e/Services/Database/DatabaseBase.php @@ -827,6 +827,10 @@ trait DatabaseBase $this->assertEquals(2019, $documents['body']['documents'][2]['releaseYear']); $this->assertCount(3, $documents['body']['documents']); + foreach ($documents['body']['documents'] as $document) { + $this->assertEquals($data['moviesId'], $document['$collection']); + } + $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -841,7 +845,28 @@ trait DatabaseBase $this->assertEquals(2019, $documents['body']['documents'][0]['releaseYear']); $this->assertCount(3, $documents['body']['documents']); - return []; + return $documents['body']['documents']; + } + + /** + * @depends testListDocuments + */ + public function testGetDocument(array $documents): void + { + foreach ($documents as $document) { + $response = $this->client->call(Client::METHOD_GET, '/database/collections/' . $document['$collection'] . '/documents/' . $document['$id'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals($response['headers']['status-code'], 200); + $this->assertEquals($response['body']['$id'], $document['$id']); + $this->assertEquals($response['body']['$collection'], $document['$collection']); + $this->assertEquals($response['body']['title'], $document['title']); + $this->assertEquals($response['body']['releaseYear'], $document['releaseYear']); + $this->assertEquals($response['body']['$read'], $document['$read']); + $this->assertEquals($response['body']['$write'], $document['$write']); + } } /** @@ -1218,6 +1243,8 @@ trait DatabaseBase ]); $this->assertEquals($document['headers']['status-code'], 200); + $this->assertEquals($document['body']['$id'], $id); + $this->assertEquals($document['body']['$collection'], $data['moviesId']); $this->assertEquals($document['body']['title'], 'Thor: Ragnarok'); $this->assertEquals($document['body']['releaseYear'], 2017); $this->assertEquals('role:member', $document['body']['$read'][0]); @@ -1280,7 +1307,7 @@ trait DatabaseBase ], $this->getHeaders())); $this->assertEquals($document['headers']['status-code'], 404); - + return $data; } From 67e90fe27d07c3ad83c34564c188ca6d5df49651 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 11:45:31 +0100 Subject: [PATCH 09/24] fix: realtime api --- app/realtime.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index dbef9ee697..84e90557a7 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -341,7 +341,8 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_' . $project->getId() . '_internal'); + $database->setDefaultDatabase('appwrite'); + $database->setNamespace('_project_' . $project->getId()); /* * Project Check @@ -445,7 +446,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); - $database->setNamespace('project_' . $realtime->connections[$connection]['projectId'] . '_internal'); + $database->setDefaultDatabase('appwrite'); + $database->setNamespace('_project_' . $realtime->connections[$connection]['projectId']); /* * Abuse Check From 693b8c718548f152dca32b140c8423187c59aa4a Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 13:45:23 +0100 Subject: [PATCH 10/24] fix: replace internal and external database with project database --- .env | 2 +- app/controllers/api/account.php | 224 +++++++++--------- app/controllers/api/database.php | 378 +++++++++++++----------------- app/controllers/api/functions.php | 164 +++++++------ app/controllers/api/locale.php | 8 +- app/controllers/api/projects.php | 35 ++- app/controllers/api/storage.php | 94 ++++---- app/controllers/api/teams.php | 168 ++++++------- app/controllers/api/users.php | 164 ++++++------- app/controllers/shared/api.php | 8 +- app/http.php | 88 ++++--- app/init.php | 61 ++--- app/tasks/usage.php | 23 +- app/workers/audits.php | 4 +- app/workers/database.php | 48 ++-- app/workers/deletes.php | 48 ++-- app/workers/functions.php | 2 +- composer.lock | 8 +- src/Appwrite/Resque/Worker.php | 25 +- 19 files changed, 743 insertions(+), 809 deletions(-) diff --git a/.env b/.env index 87834e19eb..9f6050fe50 100644 --- a/.env +++ b/.env @@ -18,7 +18,7 @@ _APP_REDIS_PORT=6379 _APP_DB_HOST=mariadb _APP_DB_PORT=3306 _APP_DB_SCHEMA=appwrite -_APP_DB_USER=root +_APP_DB_USER=user _APP_DB_PASS=password _APP_STORAGE_ANTIVIRUS=disabled _APP_STORAGE_ANTIVIRUS_HOST=clamav diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 7756041528..e3d951e861 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -51,14 +51,14 @@ App::post('/v1/account') ->inject('request') ->inject('response') ->inject('project') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForInternal, $audits, $usage) { + ->action(function ($userId, $email, $password, $name, $request, $response, $project, $dbForProject, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -79,7 +79,7 @@ App::post('/v1/account') $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [ + $sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]), ], APP_LIMIT_USERS); @@ -89,8 +89,8 @@ App::post('/v1/account') } try { - $userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId; - $user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([ + $userId = $userId == 'unique()' ? $dbForProject->getId() : $userId; + $user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['role:all'], '$write' => ['user:' . $userId], @@ -149,15 +149,15 @@ App::post('/v1/account/sessions') ->param('password', '', new Password(), 'User password. Must be at least 8 chars.') ->inject('request') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('geodb') ->inject('audits') ->inject('usage') - ->action(function ($email, $password, $request, $response, $dbForInternal, $locale, $geodb, $audits, $usage) { + ->action(function ($email, $password, $request, $response, $dbForProject, $locale, $geodb, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ @@ -166,7 +166,7 @@ App::post('/v1/account/sessions') $email = \strtolower($email); $protocol = $request->getProtocol(); - $profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $profile = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) { $audits @@ -188,7 +188,7 @@ App::post('/v1/account/sessions') $secret = Auth::tokenGenerator(); $session = new Document(array_merge( [ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $profile->getId(), 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => $email, @@ -202,13 +202,13 @@ App::post('/v1/account/sessions') Authorization::setRole('user:' . $profile->getId()); - $session = $dbForInternal->createDocument('sessions', $session + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:' . $profile->getId()]) ->setAttribute('$write', ['user:' . $profile->getId()]) ); $profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND); - $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile); + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile); $audits ->setParam('userId', $profile->getId()) @@ -376,17 +376,17 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') ->inject('response') ->inject('project') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('geodb') ->inject('audits') ->inject('events') ->inject('usage') - ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForInternal, $geodb, $audits, $events, $usage) use ($oauthDefaultSuccess) { + ->action(function ($provider, $code, $state, $request, $response, $project, $user, $dbForProject, $geodb, $audits, $events, $usage) use ($oauthDefaultSuccess) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -458,13 +458,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') if ($current === $session['$id']) { unset($sessions[$key]); - $dbForInternal->deleteDocument('sessions', $session->getId()); - $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); + $dbForProject->deleteDocument('sessions', $session->getId()); + $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); } } } - $user = ($user->isEmpty()) ? $dbForInternal->findOne('sessions', [ // Get user by provider id + $user = ($user->isEmpty()) ? $dbForProject->findOne('sessions', [ // Get user by provider id new Query('provider', QUERY::TYPE_EQUAL, [$provider]), new Query('providerUid', QUERY::TYPE_EQUAL, [$oauth2ID]), ]) : $user; @@ -473,13 +473,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $name = $oauth2->getUserName($accessToken); $email = $oauth2->getUserEmail($accessToken); - $user = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $user = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT); + $sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT); if ($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); @@ -487,8 +487,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') } try { - $userId = $dbForInternal->getId(); - $user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([ + $userId = $dbForProject->getId(); + $user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['role:all'], '$write' => ['user:' . $userId], @@ -524,7 +524,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $secret = Auth::tokenGenerator(); $expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG; $session = new Document(array_merge([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'provider' => $provider, 'providerUid' => $oauth2ID, @@ -552,12 +552,12 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Authorization::setRole('user:' . $user->getId()); - $session = $dbForInternal->createDocument('sessions', $session + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:' . $user->getId()]) ->setAttribute('$write', ['user:' . $user->getId()]) ); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); $audits ->setParam('userId', $user->getId()) @@ -621,16 +621,16 @@ App::post('/v1/account/sessions/magic-url') ->inject('request') ->inject('response') ->inject('project') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('audits') ->inject('events') ->inject('mails') - ->action(function ($userId, $email, $url, $request, $response, $project, $dbForInternal, $locale, $audits, $events, $mails) { + ->action(function ($userId, $email, $url, $request, $response, $project, $dbForProject, $locale, $audits, $events, $mails) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ @@ -644,13 +644,13 @@ App::post('/v1/account/sessions/magic-url') $isPrivilegedUser = Auth::isPrivilegedUser($roles); $isAppUser = Auth::isAppUser($roles); - $user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); + $user = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); if (!$user) { $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [ + $sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]), ], APP_LIMIT_COUNT); @@ -659,9 +659,9 @@ App::post('/v1/account/sessions/magic-url') } } - $userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId; + $userId = $userId == 'unique()' ? $dbForProject->getId() : $userId; - $user = Authorization::skip(fn () => $dbForInternal->createDocument('users', new Document([ + $user = Authorization::skip(fn () => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['role:all'], '$write' => ['user:' . $userId], @@ -689,7 +689,7 @@ App::post('/v1/account/sessions/magic-url') $expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM; $token = new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'type' => Auth::TOKEN_TYPE_MAGIC_URL, 'secret' => Auth::hash($loginSecret), // One way hash encryption to protect DB leak @@ -702,7 +702,7 @@ App::post('/v1/account/sessions/magic-url') $user->setAttribute('tokens', $token, Document::SET_TYPE_APPEND); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); if (false === $user) { throw new Exception('Failed to save user to DB', 500); @@ -766,21 +766,21 @@ App::put('/v1/account/sessions/magic-url') ->param('secret', '', new Text(256), 'Valid verification token.') ->inject('request') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('geodb') ->inject('audits') - ->action(function ($userId, $secret, $request, $response, $dbForInternal, $locale, $geodb, $audits) { + ->action(function ($userId, $secret, $request, $response, $dbForProject, $locale, $geodb, $audits) { /** @var string $userId */ /** @var string $secret */ /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -798,7 +798,7 @@ App::put('/v1/account/sessions/magic-url') $expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG; $session = new Document(array_merge( [ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'provider' => Auth::SESSION_PROVIDER_MAGIC_URL, 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak @@ -814,7 +814,7 @@ App::put('/v1/account/sessions/magic-url') Authorization::setRole('user:' . $user->getId()); - $session = $dbForInternal->createDocument('sessions', $session + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:' . $user->getId()]) ->setAttribute('$write', ['user:' . $user->getId()]) ); @@ -836,7 +836,7 @@ App::put('/v1/account/sessions/magic-url') ->setAttribute('tokens', $tokens); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); if (false === $user) { throw new Exception('Failed saving user to DB', 500); @@ -894,17 +894,17 @@ App::post('/v1/account/sessions/anonymous') ->inject('locale') ->inject('user') ->inject('project') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('geodb') ->inject('audits') ->inject('usage') - ->action(function ($request, $response, $locale, $user, $project, $dbForInternal, $geodb, $audits, $usage) { + ->action(function ($request, $response, $locale, $user, $project, $dbForProject, $geodb, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Locale\Locale $locale */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -922,7 +922,7 @@ App::post('/v1/account/sessions/anonymous') $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0) { - $sum = $dbForInternal->count('users', [ + $sum = $dbForProject->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]), ], APP_LIMIT_COUNT); @@ -931,8 +931,8 @@ App::post('/v1/account/sessions/anonymous') } } - $userId = $dbForInternal->getId(); - $user = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([ + $userId = $dbForProject->getId(); + $user = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['role:all'], '$write' => ['user:' . $userId], @@ -960,7 +960,7 @@ App::post('/v1/account/sessions/anonymous') $expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG; $session = new Document(array_merge( [ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'provider' => Auth::SESSION_PROVIDER_ANONYMOUS, 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak @@ -976,12 +976,12 @@ App::post('/v1/account/sessions/anonymous') Authorization::setRole('user:' . $user->getId()); - $session = $dbForInternal->createDocument('sessions', $session + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:' . $user->getId()]) ->setAttribute('$write', ['user:' . $user->getId()]) ); - $user = $dbForInternal->updateDocument('users', $user->getId(), + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)); $audits @@ -1178,18 +1178,18 @@ App::get('/v1/account/logs') ->inject('user') ->inject('locale') ->inject('geodb') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForInternal, $usage) { + ->action(function ($limit, $offset, $response, $user, $locale, $geodb, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $audit = new Audit($dbForInternal); + $audit = new Audit($dbForProject); $auditEvents = [ 'account.create', 'account.delete', @@ -1262,13 +1262,13 @@ App::get('/v1/account/sessions/:sessionId') ->inject('response') ->inject('user') ->inject('locale') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($sessionId, $response, $user, $locale, $dbForInternal, $usage) { + ->action(function ($sessionId, $response, $user, $locale, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ $sessions = $user->getAttribute('sessions', []); @@ -1314,17 +1314,17 @@ App::patch('/v1/account/name') ->param('name', '', new Text(128), 'User name. Max length: 128 chars.') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($name, $response, $user, $dbForInternal, $audits, $usage) { + ->action(function ($name, $response, $user, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->updateDocument('users', $user->getId(), $user + $user = $dbForProject->updateDocument('users', $user->getId(), $user ->setAttribute('name', $name) ->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email')])) ); @@ -1358,13 +1358,13 @@ App::patch('/v1/account/password') ->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true) ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($password, $oldPassword, $response, $user, $dbForInternal, $audits, $usage) { + ->action(function ($password, $oldPassword, $response, $user, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1373,7 +1373,7 @@ App::patch('/v1/account/password') throw new Exception('Invalid credentials', 401); } - $user = $dbForInternal->updateDocument('users', $user->getId(), $user + $user = $dbForProject->updateDocument('users', $user->getId(), $user ->setAttribute('password', Auth::passwordHash($password)) ->setAttribute('passwordUpdate', \time()) ); @@ -1406,13 +1406,13 @@ App::patch('/v1/account/email') ->param('password', '', new Password(), 'User password. Must be at least 8 chars.') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($email, $password, $response, $user, $dbForInternal, $audits, $usage) { + ->action(function ($email, $password, $response, $user, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1426,14 +1426,14 @@ App::patch('/v1/account/email') } $email = \strtolower($email); - $profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $profile = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if ($profile) { throw new Exception('User already registered', 409); } try { - $user = $dbForInternal->updateDocument('users', $user->getId(), $user + $user = $dbForProject->updateDocument('users', $user->getId(), $user ->setAttribute('password', $isAnonymousUser ? Auth::passwordHash($password) : $user->getAttribute('password', '')) ->setAttribute('email', $email) ->setAttribute('emailVerification', false) // After this user needs to confirm mail again @@ -1470,17 +1470,17 @@ App::patch('/v1/account/prefs') ->param('prefs', [], new Assoc(), 'Prefs key-value JSON object.') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($prefs, $response, $user, $dbForInternal, $audits, $usage) { + ->action(function ($prefs, $response, $user, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); $audits ->setParam('event', 'account.update.prefs') @@ -1507,21 +1507,21 @@ App::delete('/v1/account') ->inject('request') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('events') ->inject('usage') - ->action(function ($request, $response, $user, $dbForInternal, $audits, $events, $usage) { + ->action(function ($request, $response, $user, $dbForProject, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Stats\Stats $usage */ $protocol = $request->getProtocol(); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', false)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', false)); // TODO Seems to be related to users.php/App::delete('/v1/users/:userId'). Can we share code between these two? Do todos below apply to users.php? @@ -1576,16 +1576,16 @@ App::delete('/v1/account/sessions/:sessionId') ->inject('request') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('audits') ->inject('events') ->inject('usage') - ->action(function ($sessionId, $request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) { + ->action(function ($sessionId, $request, $response, $user, $dbForProject, $locale, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ @@ -1602,7 +1602,7 @@ App::delete('/v1/account/sessions/:sessionId') if ($sessionId == $session->getId()) { unset($sessions[$key]); - $dbForInternal->deleteDocument('sessions', $session->getId()); + $dbForProject->deleteDocument('sessions', $session->getId()); $audits ->setParam('userId', $user->getId()) @@ -1630,7 +1630,7 @@ App::delete('/v1/account/sessions/:sessionId') ; } - $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); + $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions)); $events ->setParam('eventData', $response->output($session, Response::MODEL_SESSION)) @@ -1662,16 +1662,16 @@ App::delete('/v1/account/sessions') ->inject('request') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('audits') ->inject('events') ->inject('usage') - ->action(function ($request, $response, $user, $dbForInternal, $locale, $audits, $events, $usage) { + ->action(function ($request, $response, $user, $dbForProject, $locale, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ @@ -1681,7 +1681,7 @@ App::delete('/v1/account/sessions') $sessions = $user->getAttribute('sessions', []); foreach ($sessions as $session) {/** @var Document $session */ - $dbForInternal->deleteDocument('sessions', $session->getId()); + $dbForProject->deleteDocument('sessions', $session->getId()); $audits ->setParam('userId', $user->getId()) @@ -1709,7 +1709,7 @@ App::delete('/v1/account/sessions') } } - $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); + $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); $numOfSessions = count($sessions); @@ -1745,17 +1745,17 @@ App::post('/v1/account/recovery') ->param('url', '', function ($clients) {return new Host($clients);}, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients']) ->inject('request') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('project') ->inject('locale') ->inject('mails') ->inject('audits') ->inject('events') ->inject('usage') - ->action(function ($email, $url, $request, $response, $dbForInternal, $project, $locale, $mails, $audits, $events, $usage) { + ->action(function ($email, $url, $request, $response, $dbForProject, $project, $locale, $mails, $audits, $events, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $mails */ @@ -1772,7 +1772,7 @@ App::post('/v1/account/recovery') $isAppUser = Auth::isAppUser($roles); $email = \strtolower($email); - $profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $profile = $dbForProject->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if (!$profile) { throw new Exception('User not found', 404); @@ -1786,7 +1786,7 @@ App::post('/v1/account/recovery') $secret = Auth::tokenGenerator(); $recovery = new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $profile->getId(), 'type' => Auth::TOKEN_TYPE_RECOVERY, 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak @@ -1799,7 +1799,7 @@ App::post('/v1/account/recovery') $profile->setAttribute('tokens', $recovery, Document::SET_TYPE_APPEND); - $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile); + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile); $url = Template::parseURL($url); $url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret, 'expire' => $expire]); @@ -1860,12 +1860,12 @@ App::put('/v1/account/recovery') ->param('password', '', new Password(), 'New user password. Must be at least 8 chars.') ->param('passwordAgain', '', new Password(), 'Repeat new user password. Must be at least 8 chars.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForInternal, $audits, $usage) { + ->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1873,7 +1873,7 @@ App::put('/v1/account/recovery') throw new Exception('Passwords must match', 400); } - $profile = $dbForInternal->getDocument('users', $userId); + $profile = $dbForProject->getDocument('users', $userId); if ($profile->isEmpty() || $profile->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -1888,7 +1888,7 @@ App::put('/v1/account/recovery') Authorization::setRole('user:' . $profile->getId()); - $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile ->setAttribute('password', Auth::passwordHash($password)) ->setAttribute('passwordUpdate', \time()) ->setAttribute('emailVerification', true) @@ -1905,7 +1905,7 @@ App::put('/v1/account/recovery') } } - $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens)); + $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens)); $audits ->setParam('userId', $profile->getId()) @@ -1938,18 +1938,18 @@ App::post('/v1/account/verification') ->inject('response') ->inject('project') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('audits') ->inject('events') ->inject('mails') ->inject('usage') - ->action(function ($url, $request, $response, $project, $user, $dbForInternal, $locale, $audits, $events, $mails, $usage) { + ->action(function ($url, $request, $response, $project, $user, $dbForProject, $locale, $audits, $events, $mails, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ @@ -1969,7 +1969,7 @@ App::post('/v1/account/verification') $expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM; $verification = new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'type' => Auth::TOKEN_TYPE_VERIFICATION, 'secret' => Auth::hash($verificationSecret), // One way hash encryption to protect DB leak @@ -1982,7 +1982,7 @@ App::post('/v1/account/verification') $user->setAttribute('tokens', $verification, Document::SET_TYPE_APPEND); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); $url = Template::parseURL($url); $url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret, 'expire' => $expire]); @@ -2042,17 +2042,17 @@ App::put('/v1/account/verification') ->param('secret', '', new Text(256), 'Valid verification token.') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($userId, $secret, $response, $user, $dbForInternal, $audits, $usage) { + ->action(function ($userId, $secret, $response, $user, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $profile = $dbForInternal->getDocument('users', $userId); + $profile = $dbForProject->getDocument('users', $userId); if ($profile->isEmpty()) { throw new Exception('User not found', 404); @@ -2067,7 +2067,7 @@ App::put('/v1/account/verification') Authorization::setRole('user:' . $profile->getId()); - $profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true)); + $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true)); /** * We act like we're updating and validating @@ -2080,7 +2080,7 @@ App::put('/v1/account/verification') } } - $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens)); + $dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens)); $audits ->setParam('userId', $profile->getId()) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 1629441258..3716f5a956 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -33,6 +33,8 @@ use Appwrite\Network\Validator\IP; use Appwrite\Network\Validator\URL; use Appwrite\Utopia\Response; use Appwrite\Detector\Detector; +use Appwrite\Event\Event; +use Appwrite\Stats\Stats; /** * Create attribute of varying type @@ -40,15 +42,14 @@ use Appwrite\Detector\Detector; * @param string $collectionId * @param Utopia\Database\Document $attribute * @param Appwrite\Utopia\Response $response - * @param Utopia\Database\Database $dbForInternal - * @param Utopia\Database\Database $dbForExternal + * @param Utopia\Database\Database $dbForProject * @param Appwrite\Event\Event $database * @param Appwrite\Event\Event $audits * @param Appwrite\Stats\Stats $usage * * @return Document Newly created attribute document */ -function createAttribute($collectionId, $attribute, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage): Document +function createAttribute(string $collectionId, Document $attribute, Response $response, Database $dbForProject, Event $database, Event $audits, Stats $usage): Document { $key = $attribute->getAttribute('key'); $type = $attribute->getAttribute('type', ''); @@ -61,7 +62,7 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $ $filters = $attribute->getAttribute('filters', []); // filters are hidden from the endpoint $default = $attribute->getAttribute('default'); - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -73,7 +74,7 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $ } } - // Must throw here since dbForExternal->createAttribute is performed by db worker + // Must throw here since dbForProject->createAttribute is performed by db worker if ($required && $default) { throw new Exception('Cannot set default value for required attribute', 400); } @@ -99,8 +100,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $ 'filters' => $filters, ]); - $dbForInternal->checkAttribute($collection, $attribute); - $attribute = $dbForInternal->createDocument('attributes', $attribute); + $dbForProject->checkAttribute($collection, $attribute); + $attribute = $dbForProject->createDocument('attributes', $attribute); } catch (DuplicateException $exception) { throw new Exception('Attribute already exists', 409); @@ -109,8 +110,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $ throw new Exception('Attribute limit exceeded', 400); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); - $dbForExternal->deleteCachedCollection($collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedCollection($collectionId); // Pass clone of $attribute object to workers // so we can later modify Document to fit response model @@ -153,22 +154,21 @@ App::post('/v1/database/collections') ->param('read', null, new Permissions(), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.') ->param('write', null, new Permissions(), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage) { + ->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId; + $collectionId = $collectionId == 'unique()' ? $dbForProject->getId() : $collectionId; try { - $dbForExternal->createCollection('collection_' . $collectionId); + $dbForProject->createCollection('collection_' . $collectionId); - $collection = $dbForInternal->createDocument('collections', new Document([ + $collection = $dbForProject->createDocument('collections', new Document([ '$id' => $collectionId, '$read' => $read ?? [], // Collection permissions for collection documents (based on permission model) '$write' => $write ?? [], // Collection permissions for collection documents (based on permission model) @@ -213,14 +213,14 @@ App::get('/v1/database/collections') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) { + ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ if (!empty($cursor)) { - $cursorCollection = $dbForInternal->getDocument('collections', $cursor); + $cursorCollection = $dbForProject->getDocument('collections', $cursor); if ($cursorCollection->isEmpty()) { throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400); @@ -236,8 +236,8 @@ App::get('/v1/database/collections') $usage->setParam('database.collections.read', 1); $response->dynamic(new Document([ - 'collections' => $dbForInternal->find('collections', $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection), - 'sum' => $dbForInternal->count('collections', $queries, APP_LIMIT_COUNT), + 'collections' => $dbForProject->find('collections', $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection), + 'sum' => $dbForProject->count('collections', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_COLLECTION_LIST); }); @@ -254,13 +254,13 @@ App::get('/v1/database/collections/:collectionId') ->label('sdk.response.model', Response::MODEL_COLLECTION) ->param('collectionId', '', new UID(), 'Collection ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($collectionId, $response, $dbForInternal, $usage) { + ->action(function ($collectionId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -283,11 +283,11 @@ App::get('/v1/database/usage') ->label('sdk.response.model', Response::MODEL_USAGE_DATABASE) ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($range, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($range, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForConsole */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Registry\Registry $register */ $usage = []; @@ -326,12 +326,12 @@ App::get('/v1/database/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); @@ -394,15 +394,13 @@ App::get('/v1/database/:collectionId/usage') ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->param('collectionId', '', new UID(), 'Collection ID.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') - ->action(function ($range, $collectionId, $response, $dbForInternal, $dbForExternal) { + ->inject('dbForProject') + ->action(function ($range, $collectionId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForConsole */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Registry\Registry $register */ - $collection = $dbForExternal->getCollection('collection_' . $collectionId); + $collection = $dbForProject->getCollection('collection_' . $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -439,12 +437,12 @@ App::get('/v1/database/:collectionId/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); @@ -503,25 +501,23 @@ App::get('/v1/database/collections/:collectionId/logs') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function ($collectionId, $limit, $offset, $response, $dbForInternal, $dbForExternal, $locale, $geodb) { + ->action(function ($collectionId, $limit, $offset, $response, $dbForProject, $locale, $geodb) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - $collection = $dbForExternal->getCollection('collection_' . $collectionId); + $collection = $dbForProject->getCollection('collection_' . $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $audit = new Audit($dbForInternal); + $audit = new Audit($dbForProject); $resource = 'collection/'.$collection->getId(); $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -595,16 +591,16 @@ App::put('/v1/database/collections/:collectionId') ->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->param('enabled', true, new Boolean(), 'Is collection enabled?', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForInternal, $audits, $usage) { + ->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForProject, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -615,7 +611,7 @@ App::put('/v1/database/collections/:collectionId') $enabled ??= $collection->getAttribute('enabled', true); try { - $collection = $dbForInternal->updateDocument('collections', $collection->getId(), $collection + $collection = $dbForProject->updateDocument('collections', $collection->getId(), $collection ->setAttribute('$write', $write) ->setAttribute('$read', $read) ->setAttribute('name', $name) @@ -656,31 +652,29 @@ App::delete('/v1/database/collections/:collectionId') ->label('sdk.response.model', Response::MODEL_NONE) ->param('collectionId', '', new UID(), 'Collection ID.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('events') ->inject('audits') ->inject('deletes') ->inject('usage') - ->action(function ($collectionId, $response, $dbForInternal, $dbForExternal, $events, $audits, $deletes, $usage) { + ->action(function ($collectionId, $response, $dbForProject, $events, $audits, $deletes, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $audits */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - if (!$dbForInternal->deleteDocument('collections', $collectionId)) { + if (!$dbForProject->deleteDocument('collections', $collectionId)) { throw new Exception('Failed to remove collection from DB', 500); } - $dbForExternal->deleteCachedCollection('collection_' . $collection->getId()); + $dbForProject->deleteCachedCollection('collection_' . $collection->getId()); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) @@ -721,15 +715,13 @@ App::post('/v1/database/collections/:collectionId/attributes/string') ->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -747,7 +739,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string') 'required' => $required, 'default' => $default, 'array' => $array, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING); }); @@ -770,15 +762,13 @@ App::post('/v1/database/collections/:collectionId/attributes/email') ->param('default', null, new Email(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -791,7 +781,7 @@ App::post('/v1/database/collections/:collectionId/attributes/email') 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_EMAIL, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_EMAIL); }); @@ -815,15 +805,13 @@ App::post('/v1/database/collections/:collectionId/attributes/enum') ->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -852,7 +840,7 @@ App::post('/v1/database/collections/:collectionId/attributes/enum') 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_ENUM, 'formatOptions' => ['elements' => $elements], - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_ENUM); }); @@ -875,15 +863,13 @@ App::post('/v1/database/collections/:collectionId/attributes/ip') ->param('default', null, new IP(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -896,7 +882,7 @@ App::post('/v1/database/collections/:collectionId/attributes/ip') 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_IP, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_IP); }); @@ -919,14 +905,12 @@ App::post('/v1/database/collections/:collectionId/attributes/url') ->param('default', null, new URL(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -939,7 +923,7 @@ App::post('/v1/database/collections/:collectionId/attributes/url') 'default' => $default, 'array' => $array, 'format' => APP_DATABASE_ATTRIBUTE_URL, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_URL); }); @@ -964,15 +948,13 @@ App::post('/v1/database/collections/:collectionId/attributes/integer') ->param('default', null, new Integer(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1003,7 +985,7 @@ App::post('/v1/database/collections/:collectionId/attributes/integer') 'min' => $min, 'max' => $max, ], - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $formatOptions = $attribute->getAttribute('formatOptions', []); @@ -1035,15 +1017,13 @@ App::post('/v1/database/collections/:collectionId/attributes/float') ->param('default', null, new FloatValidator(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1079,7 +1059,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float') 'min' => $min, 'max' => $max, ], - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $formatOptions = $attribute->getAttribute('formatOptions', []); @@ -1109,14 +1089,13 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean') ->param('default', null, new Boolean(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ + /** @var Utopia\Database\Database $dbForProject*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1128,7 +1107,7 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean') 'required' => $required, 'default' => $default, 'array' => $array, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits, $usage); + ]), $response, $dbForProject, $database, $audits, $usage); $response->dynamic($attribute, Response::MODEL_ATTRIBUTE_BOOLEAN); }); @@ -1146,13 +1125,13 @@ App::get('/v1/database/collections/:collectionId/attributes') ->label('sdk.response.model', Response::MODEL_ATTRIBUTE_LIST) ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($collectionId, $response, $dbForInternal, $usage) { + ->action(function ($collectionId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -1190,13 +1169,13 @@ App::get('/v1/database/collections/:collectionId/attributes/:key') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('key', '', new Key(), 'Attribute Key.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($collectionId, $key, $response, $dbForInternal, $usage) { + ->action(function ($collectionId, $key, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if (empty($collection)) { throw new Exception('Collection not found', 404); @@ -1245,28 +1224,26 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('key', '', new Key(), 'Attribute Key.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('database') ->inject('events') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $response, $dbForInternal, $dbForExternal, $database, $events, $audits, $usage) { + ->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $attribute = $dbForInternal->getDocument('attributes', $collectionId.'_'.$key); + $attribute = $dbForProject->getDocument('attributes', $collectionId.'_'.$key); if (empty($attribute->getId())) { throw new Exception('Attribute not found', 404); @@ -1274,11 +1251,11 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key') // Only update status if removing available attribute if ($attribute->getAttribute('status' === 'available')) { - $attribute = $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting')); + $attribute = $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting')); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); - $dbForExternal->deleteCachedCollection($collection->getId()); + $dbForProject->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedCollection($collection->getId()); $database ->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE) @@ -1337,24 +1314,24 @@ App::post('/v1/database/collections/:collectionId/indexes') ->param('attributes', null, new ArrayList(new Key()), 'Array of attributes to index.') ->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING)), 'Array of index orders.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('database') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForInternal, $database, $audits, $usage) { + ->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForProject, $database, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $audits */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $count = $dbForInternal->count('indexes', [ + $count = $dbForProject->count('indexes', [ new Query('collectionId', Query::TYPE_EQUAL, [$collectionId]) ], 61); @@ -1365,9 +1342,7 @@ App::post('/v1/database/collections/:collectionId/indexes') } // Convert Document[] to array of attribute metadata - $oldAttributes = \array_map(function ($a) { - return $a->getArrayCopy(); - }, $collection->getAttribute('attributes')); + $oldAttributes = \array_map(fn ($a) => $a->getArrayCopy(), $collection->getAttribute('attributes')); // lengths hidden by default $lengths = []; @@ -1394,7 +1369,7 @@ App::post('/v1/database/collections/:collectionId/indexes') } try { - $index = $dbForInternal->createDocument('indexes', new Document([ + $index = $dbForProject->createDocument('indexes', new Document([ '$id' => $collectionId.'_'.$key, 'key' => $key, 'status' => 'processing', // processing, available, failed, deleting, stuck @@ -1408,7 +1383,7 @@ App::post('/v1/database/collections/:collectionId/indexes') throw new Exception('Index already exists', 409); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); $database ->setParam('type', DATABASE_TYPE_CREATE_INDEX) @@ -1441,13 +1416,13 @@ App::get('/v1/database/collections/:collectionId/indexes') ->label('sdk.response.model', Response::MODEL_INDEX_LIST) ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($collectionId, $response, $dbForInternal, $usage) { + ->action(function ($collectionId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -1477,13 +1452,13 @@ App::get('/v1/database/collections/:collectionId/indexes/:key') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('key', null, new Key(), 'Index Key.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($collectionId, $key, $response, $dbForInternal, $usage) { + ->action(function ($collectionId, $key, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); @@ -1521,26 +1496,26 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key') ->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('key', '', new Key(), 'Index Key.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('database') ->inject('events') ->inject('audits') ->inject('usage') - ->action(function ($collectionId, $key, $response, $dbForInternal, $database, $events, $audits, $usage) { + ->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $index = $dbForInternal->getDocument('indexes', $collectionId.'_'.$key); + $index = $dbForProject->getDocument('indexes', $collectionId.'_'.$key); if (empty($index->getId())) { throw new Exception('Index not found', 404); @@ -1548,10 +1523,10 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key') // Only update status if removing available index if ($index->getAttribute('status') === 'available') { - $index = $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting')); + $index = $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting')); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); $database ->setParam('type', DATABASE_TYPE_DELETE_INDEX) @@ -1592,17 +1567,15 @@ App::post('/v1/database/collections/:collectionId/documents') ->param('read', null, new Permissions(), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->param('write', null, new Permissions(), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('user') ->inject('audits') ->inject('usage') ->inject('events') ->inject('mode') - ->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $user, $audits, $usage, $events, $mode) { + ->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForProject, $user, $audits, $usage, $events, $mode) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $user */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -1624,7 +1597,7 @@ App::post('/v1/database/collections/:collectionId/documents') * * @var Document $collection */ - $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); + $collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId)); if ($collection->isEmpty() || !$collection->getAttribute('enabled')) { if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) { @@ -1641,7 +1614,7 @@ App::post('/v1/database/collections/:collectionId/documents') } $data['$collection'] = $collection->getId(); // Adding this param to make API easier for developers - $data['$id'] = $documentId == 'unique()' ? $dbForExternal->getId() : $documentId; + $data['$id'] = $documentId == 'unique()' ? $dbForProject->getId() : $documentId; $data['$read'] = (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? []; // By default set read permissions for user $data['$write'] = (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? []; // By default set write permissions for user @@ -1664,9 +1637,9 @@ App::post('/v1/database/collections/:collectionId/documents') try { if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->createDocument('collection_' . $collectionId, new Document($data))); + $document = Authorization::skip(fn() => $dbForProject->createDocument('collection_' . $collectionId, new Document($data))); } else { - $document = $dbForExternal->createDocument('collection_' . $collectionId, new Document($data)); + $document = $dbForProject->createDocument('collection_' . $collectionId, new Document($data)); } $document->setAttribute('$collection', $collectionId); } @@ -1714,17 +1687,13 @@ App::get('/v1/database/collections/:collectionId/documents') ->param('orderAttributes', [], new ArrayList(new Text(128)), 'Array of attributes used to sort results.', true) ->param('orderTypes', [], new ArrayList(new WhiteList(['DESC', 'ASC'], true)), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') - ->inject('user') + ->inject('dbForProject') ->inject('usage') ->inject('mode') - ->action(function ($collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes, $response, $dbForInternal, $dbForExternal, $user, $usage, $mode) { + ->action(function ($collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes, $response, $dbForProject, $usage, $mode) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - /** @var Utopia\Database\Document $user */ /** @var string $mode */ /** @@ -1732,7 +1701,7 @@ App::get('/v1/database/collections/:collectionId/documents') * * @var Utopia\Database\Document $collection */ - $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); + $collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId)); if ($collection->isEmpty() || !$collection->getAttribute('enabled')) { if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) { @@ -1748,9 +1717,7 @@ App::get('/v1/database/collections/:collectionId/documents') } } - $queries = \array_map(function ($query) { - return Query::parse($query); - }, $queries); + $queries = \array_map(fn ($query) => Query::parse($query), $queries); if (!empty($queries)) { $validator = new QueriesValidator(new QueryValidator($collection->getAttribute('attributes', [])), $collection->getAttribute('indexes', []), true); @@ -1761,7 +1728,7 @@ App::get('/v1/database/collections/:collectionId/documents') $cursorDocument = null; if (!empty($cursor)) { - $cursorDocument = $dbForExternal->getDocument('collection_' . $collectionId, $cursor); + $cursorDocument = $dbForProject->getDocument('collection_' . $collectionId, $cursor); if ($cursorDocument->isEmpty()) { throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400); @@ -1770,11 +1737,11 @@ App::get('/v1/database/collections/:collectionId/documents') if ($collection->getAttribute('permission') === 'collection') { /** @var Document[] $documents */ - $documents = Authorization::skip(fn() => $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection)); - $sum = Authorization::skip(fn() => $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT)); + $documents = Authorization::skip(fn() => $dbForProject->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection)); + $sum = Authorization::skip(fn() => $dbForProject->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT)); } else { - $documents = $dbForExternal->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection); - $sum = $dbForExternal->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT); + $documents = $dbForProject->find('collection_' . $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection); + $sum = $dbForProject->count('collection_' . $collectionId, $queries, APP_LIMIT_COUNT); } /** @@ -1807,20 +1774,18 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') ->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('documentId', null, new UID(), 'Document ID.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('usage') ->inject('mode') - ->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $usage, $mode) { + ->action(function ($collectionId, $documentId, $response, $dbForProject, $usage, $mode) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $$dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var string $mode */ /** * Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions. */ - $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); + $collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId)); if ($collection->isEmpty() || !$collection->getAttribute('enabled')) { if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) { @@ -1838,9 +1803,9 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); + $document = $dbForProject->getDocument('collection_' . $collectionId, $documentId); } /** @@ -1876,31 +1841,29 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId/logs') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('locale') ->inject('geodb') - ->action(function ($collectionId, $documentId, $limit, $offset, $response, $dbForInternal, $dbForExternal, $locale, $geodb) { + ->action(function ($collectionId, $documentId, $limit, $offset, $response, $dbForProject, $locale, $geodb) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - $collection = $dbForInternal->getDocument('collections', $collectionId); + $collection = $dbForProject->getDocument('collections', $collectionId); if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); + $document = $dbForProject->getDocument('collection_' . $collectionId, $documentId); if ($document->isEmpty()) { throw new Exception('No document found', 404); } - $audit = new Audit($dbForInternal); + $audit = new Audit($dbForProject); $resource = 'document/'.$document->getId(); $logs = $audit->getLogsByResource($resource, $limit, $offset); @@ -1972,16 +1935,14 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') ->param('read', null, new Permissions(), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('audits') ->inject('usage') ->inject('events') ->inject('mode') - ->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage, $events, $mode) { + ->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForProject, $audits, $usage, $events, $mode) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ /** @var Appwrite\Event\Event $events */ @@ -1990,7 +1951,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') /** * Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions. */ - $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); + $collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId)); if ($collection->isEmpty() || !$collection->getAttribute('enabled')) { if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) { @@ -2005,9 +1966,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') throw new Exception('Unauthorized permissions', 401); } - $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); + $document = $dbForProject->getDocument('collection_' . $collectionId, $documentId); } @@ -2051,9 +2012,9 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId') try { if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data))); + $document = Authorization::skip(fn() => $dbForProject->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data))); } else { - $document = $dbForExternal->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)); + $document = $dbForProject->updateDocument('collection_' . $collection->getId(), $document->getId(), new Document($data)); } /** * Reset $collection attribute to remove prefix. @@ -2100,15 +2061,14 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') ->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).') ->param('documentId', null, new UID(), 'Document ID.') ->inject('response') - ->inject('dbForInternal') - ->inject('dbForExternal') + ->inject('dbForProject') ->inject('events') ->inject('audits') ->inject('usage') ->inject('mode') - ->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $events, $audits, $usage, $mode) { + ->action(function ($collectionId, $documentId, $response, $dbForProject, $events, $audits, $usage, $mode) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -2117,7 +2077,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') /** * Skip Authorization to get the collection. Needed in case of empty permissions for document level permissions. */ - $collection = Authorization::skip(fn() => $dbForInternal->getDocument('collections', $collectionId)); + $collection = Authorization::skip(fn() => $dbForProject->getDocument('collections', $collectionId)); if ($collection->isEmpty() || !$collection->getAttribute('enabled')) { if (!($mode === APP_MODE_ADMIN && Auth::isPrivilegedUser(Authorization::getRoles()))) { @@ -2135,9 +2095,9 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') if ($collection->getAttribute('permission') === 'collection') { /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForExternal->getDocument('collection_' . $collectionId, $documentId)); + $document = Authorization::skip(fn() => $dbForProject->getDocument('collection_' . $collectionId, $documentId)); } else { - $document = $dbForExternal->getDocument('collection_' . $collectionId, $documentId); + $document = $dbForProject->getDocument('collection_' . $collectionId, $documentId); } if ($document->isEmpty()) { @@ -2145,12 +2105,12 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId') } if ($collection->getAttribute('permission') === 'collection') { - Authorization::skip(fn() => $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId)); + Authorization::skip(fn() => $dbForProject->deleteDocument('collection_' . $collectionId, $documentId)); } else { - $dbForExternal->deleteDocument('collection_' . $collectionId, $documentId); + $dbForProject->deleteDocument('collection_' . $collectionId, $documentId); } - $dbForExternal->deleteCachedDocument('collection_' . $collectionId, $documentId); + $dbForProject->deleteCachedDocument('collection_' . $collectionId, $documentId); /** * Reset $collection attribute to remove prefix. diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index cfa999e467..673d84ba40 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -48,13 +48,13 @@ App::post('/v1/functions') ->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true) ->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $functionId = ($functionId == 'unique()') ? $dbForInternal->getId() : $functionId; - $function = $dbForInternal->createDocument('functions', new Document([ + $functionId = ($functionId == 'unique()') ? $dbForProject->getId() : $functionId; + $function = $dbForProject->createDocument('functions', new Document([ '$id' => $functionId, 'execute' => $execute, 'dateCreated' => time(), @@ -94,13 +94,13 @@ App::get('/v1/functions') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ if (!empty($cursor)) { - $cursorFunction = $dbForInternal->getDocument('functions', $cursor); + $cursorFunction = $dbForProject->getDocument('functions', $cursor); if ($cursorFunction->isEmpty()) { throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400); @@ -114,8 +114,8 @@ App::get('/v1/functions') } $response->dynamic(new Document([ - 'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection), - 'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT), + 'functions' => $dbForProject->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection), + 'sum' => $dbForProject->count('functions', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_FUNCTION_LIST); }); @@ -160,12 +160,12 @@ App::get('/v1/functions/:functionId') ->label('sdk.response.model', Response::MODEL_FUNCTION) ->param('functionId', '', new UID(), 'Function ID.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); @@ -187,16 +187,14 @@ App::get('/v1/functions/:functionId/usage') ->param('functionId', '', new UID(), 'Function ID.') ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d']), 'Date range.', true) ->inject('response') - ->inject('project') - ->inject('dbForInternal') - ->inject('register') - ->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) { + ->inject('dbForProject') + ->action(function ($functionId, $range, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Registry\Registry $register */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); @@ -231,12 +229,12 @@ App::get('/v1/functions/:functionId/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); @@ -298,14 +296,14 @@ App::put('/v1/functions/:functionId') ->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true) ->param('timeout', 15, new Range(1, 900), 'Maximum execution time in seconds.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('project') - ->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) { + ->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForProject, $project) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $project */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); @@ -315,7 +313,7 @@ App::put('/v1/functions/:functionId') $cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? new CronExpression($schedule) : null; $next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0; - $function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ + $function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ 'execute' => $execute, 'dateUpdated' => time(), 'name' => $name, @@ -355,15 +353,15 @@ App::patch('/v1/functions/:functionId/tag') ->param('functionId', '', new UID(), 'Function ID.') ->param('tag', '', new UID(), 'Tag ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('project') - ->action(function ($functionId, $tag, $response, $dbForInternal, $project) { + ->action(function ($functionId, $tag, $response, $dbForProject, $project) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $project */ - $function = $dbForInternal->getDocument('functions', $functionId); - $tag = $dbForInternal->getDocument('tags', $tag); + $function = $dbForProject->getDocument('functions', $functionId); + $tag = $dbForProject->getDocument('tags', $tag); if ($function->isEmpty()) { throw new Exception('Function not found', 404); @@ -377,7 +375,7 @@ App::patch('/v1/functions/:functionId/tag') $cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null; $next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0; - $function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ + $function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ 'tag' => $tag->getId(), 'scheduleNext' => (int)$next, ]))); @@ -408,20 +406,20 @@ App::delete('/v1/functions/:functionId') ->label('sdk.response.model', Response::MODEL_NONE) ->param('functionId', '', new UID(), 'Function ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('deletes') - ->action(function ($functionId, $response, $dbForInternal, $deletes) { + ->action(function ($functionId, $response, $dbForProject, $deletes) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $deletes */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } - if (!$dbForInternal->deleteDocument('functions', $function->getId())) { + if (!$dbForProject->deleteDocument('functions', $function->getId())) { throw new Exception('Failed to remove function from DB', 500); } @@ -452,15 +450,15 @@ App::post('/v1/functions/:functionId/tags') ->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false) ->inject('request') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($functionId, $command, $file, $request, $response, $dbForInternal, $usage) { + ->action(function ($functionId, $command, $file, $request, $response, $dbForProject, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $usage */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); @@ -501,8 +499,8 @@ App::post('/v1/functions/:functionId/tags') throw new Exception('Failed moving file', 500); } - $tagId = $dbForInternal->getId(); - $tag = $dbForInternal->createDocument('tags', new Document([ + $tagId = $dbForProject->getId(); + $tag = $dbForProject->createDocument('tags', new Document([ '$id' => $tagId, '$read' => [], '$write' => [], @@ -541,19 +539,19 @@ App::get('/v1/functions/:functionId/tags') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } if (!empty($cursor)) { - $cursorTag = $dbForInternal->getDocument('tags', $cursor); + $cursorTag = $dbForProject->getDocument('tags', $cursor); if ($cursorTag->isEmpty()) { throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400); @@ -568,8 +566,8 @@ App::get('/v1/functions/:functionId/tags') $queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]); - $results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection); - $sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT); + $results = $dbForProject->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection); + $sum = $dbForProject->count('tags', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ 'tags' => $results, @@ -591,18 +589,18 @@ App::get('/v1/functions/:functionId/tags/:tagId') ->param('functionId', '', new UID(), 'Function ID.') ->param('tagId', '', new UID(), 'Tag ID.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $tagId, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $tagId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } - $tag = $dbForInternal->getDocument('tags', $tagId); + $tag = $dbForProject->getDocument('tags', $tagId); if ($tag->getAttribute('functionId') !== $function->getId()) { throw new Exception('Tag not found', 404); @@ -629,20 +627,20 @@ App::delete('/v1/functions/:functionId/tags/:tagId') ->param('functionId', '', new UID(), 'Function ID.') ->param('tagId', '', new UID(), 'Tag ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($functionId, $tagId, $response, $dbForInternal, $usage) { + ->action(function ($functionId, $tagId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $usage */ - $function = $dbForInternal->getDocument('functions', $functionId); + $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } - $tag = $dbForInternal->getDocument('tags', $tagId); + $tag = $dbForProject->getDocument('tags', $tagId); if ($tag->getAttribute('functionId') !== $function->getId()) { throw new Exception('Tag not found', 404); @@ -655,13 +653,13 @@ App::delete('/v1/functions/:functionId/tags/:tagId') $device = Storage::getDevice('functions'); if ($device->delete($tag->getAttribute('path', ''))) { - if (!$dbForInternal->deleteDocument('tags', $tag->getId())) { + if (!$dbForProject->deleteDocument('tags', $tag->getId())) { throw new Exception('Failed to remove tag from DB', 500); } } if($function->getAttribute('tag') === $tag->getId()) { // Reset function tag - $function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ + $function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ 'tag' => '', ]))); } @@ -692,21 +690,21 @@ App::post('/v1/functions/:functionId/executions') // ->param('async', 1, new Range(0, 1), 'Execute code asynchronously. Pass 1 for true, 0 for false. Default value is 1.', true) ->inject('response') ->inject('project') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('user') - ->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForInternal, $user) { + ->action(function ($functionId, $data, /*$async,*/ $response, $project, $dbForProject, $user) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $user */ - $function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId)); + $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } - $tag = Authorization::skip(fn() => $dbForInternal->getDocument('tags', $function->getAttribute('tag'))); + $tag = Authorization::skip(fn() => $dbForProject->getDocument('tags', $function->getAttribute('tag'))); if ($tag->getAttribute('functionId') !== $function->getId()) { throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404); @@ -722,9 +720,9 @@ App::post('/v1/functions/:functionId/executions') throw new Exception($validator->getDescription(), 401); } - $executionId = $dbForInternal->getId(); + $executionId = $dbForProject->getId(); - $execution = Authorization::skip(fn() => $dbForInternal->createDocument('executions', new Document([ + $execution = Authorization::skip(fn() => $dbForProject->createDocument('executions', new Document([ '$id' => $executionId, '$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [], '$write' => [], @@ -794,19 +792,19 @@ App::get('/v1/functions/:functionId/executions') ->param('cursor', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true) ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId)); + $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } if (!empty($cursor)) { - $cursorExecution = $dbForInternal->getDocument('executions', $cursor); + $cursorExecution = $dbForProject->getDocument('executions', $cursor); if ($cursorExecution->isEmpty()) { throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400); @@ -821,8 +819,8 @@ App::get('/v1/functions/:functionId/executions') $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); } - $results = $dbForInternal->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection); - $sum = $dbForInternal->count('executions', $queries, APP_LIMIT_COUNT); + $results = $dbForProject->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection); + $sum = $dbForProject->count('executions', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ 'executions' => $results, @@ -844,18 +842,18 @@ App::get('/v1/functions/:functionId/executions/:executionId') ->param('functionId', '', new UID(), 'Function ID.') ->param('executionId', '', new UID(), 'Execution ID.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($functionId, $executionId, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($functionId, $executionId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $function = Authorization::skip(fn() => $dbForInternal->getDocument('functions', $functionId)); + $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { throw new Exception('Function not found', 404); } - $execution = $dbForInternal->getDocument('executions', $executionId); + $execution = $dbForProject->getDocument('executions', $executionId); if ($execution->getAttribute('functionId') !== $function->getId()) { throw new Exception('Execution not found', 404); diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php index 7e529693f8..d5e2feb170 100644 --- a/app/controllers/api/locale.php +++ b/app/controllers/api/locale.php @@ -224,9 +224,7 @@ App::get('/v1/locale/currencies') $list = Config::getParam('locale-currencies'); - $list = array_map(function($node) { - return new Document($node); - }, $list); + $list = array_map(fn($node) => new Document($node), $list); $response->dynamic(new Document(['currencies' => $list, 'sum' => \count($list)]), Response::MODEL_CURRENCY_LIST); }); @@ -249,9 +247,7 @@ App::get('/v1/locale/languages') $list = Config::getParam('locale-languages'); - $list = array_map(function($node) { - return new Document($node); - }, $list); + $list = array_map(fn ($node) => new Document($node), $list); $response->dynamic(new Document(['languages' => $list, 'sum' => \count($list)]), Response::MODEL_LANGUAGE_LIST); }); \ No newline at end of file diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 479a7f4a4a..9c4f9bc9bf 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -57,13 +57,11 @@ App::post('/v1/projects') ->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true) ->inject('response') ->inject('dbForConsole') - ->inject('dbForInternal') - ->inject('dbForExternal') - ->action(function ($projectId, $name, $teamId, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId, $response, $dbForConsole, $dbForInternal, $dbForExternal) { + ->inject('dbForProject') + ->action(function ($projectId, $name, $teamId, $description, $logo, $url, $legalName, $legalCountry, $legalState, $legalCity, $legalAddress, $legalTaxId, $response, $dbForConsole, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForConsole */ - /** @var Utopia\Database\Database $dbForInternal */ - /** @var Utopia\Database\Database $dbForExternal */ + /** @var Utopia\Database\Database $dbForProject */ $team = $dbForConsole->getDocument('teams', $teamId); @@ -106,14 +104,13 @@ App::post('/v1/projects') $collections = Config::getParam('collections', []); /** @var array $collections */ - $dbForInternal->setNamespace('_project_' . $project->getId()); - $dbForExternal->setNamespace('_project_' . $project->getId()); - $dbForExternal->create('appwrite'); + $dbForProject->setNamespace('_project_' . $project->getId()); + $dbForProject->create('appwrite'); - $audit = new Audit($dbForInternal); + $audit = new Audit($dbForProject); $audit->setup(); - $adapter = new TimeLimit('', 0, 1, $dbForInternal); + $adapter = new TimeLimit('', 0, 1, $dbForProject); $adapter->setup(); foreach ($collections as $key => $collection) { @@ -142,7 +139,7 @@ App::post('/v1/projects') ]); } - $dbForInternal->createCollection($key, $attributes, $indexes); + $dbForProject->createCollection($key, $attributes, $indexes); } $response->setStatusCode(Response::STATUS_CODE_CREATED); @@ -234,12 +231,12 @@ App::get('/v1/projects/:projectId/usage') ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->inject('response') ->inject('dbForConsole') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('register') - ->action(function ($projectId, $range, $response, $dbForConsole, $dbForInternal, $register) { + ->action(function ($projectId, $range, $response, $dbForConsole, $dbForProject, $register) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForConsole */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Registry\Registry $register */ $project = $dbForConsole->getDocument('projects', $projectId); @@ -269,11 +266,11 @@ App::get('/v1/projects/:projectId/usage') ], ]; - $dbForInternal->setNamespace('project_' . $projectId . '_internal'); + $dbForProject->setNamespace('_project_' . $projectId); $metrics = [ - 'requests', - 'network', + 'requests', + 'network', 'executions', 'users.count', 'database.documents.count', @@ -283,12 +280,12 @@ App::get('/v1/projects/:projectId/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 1b58cda273..39d18e3d36 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -47,14 +47,14 @@ App::post('/v1/storage/files') ->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true) ->inject('request') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('user') ->inject('audits') ->inject('usage') - ->action(function ($fileId, $file, $read, $write, $request, $response, $dbForInternal, $user, $audits, $usage) { + ->action(function ($fileId, $file, $read, $write, $request, $response, $dbForProject, $user, $audits, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $user */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ @@ -146,8 +146,8 @@ App::post('/v1/storage/files') $sizeActual = $device->getFileSize($path); - $fileId = ($fileId == 'unique()') ? $dbForInternal->getId() : $fileId; - $file = $dbForInternal->createDocument('files', new Document([ + $fileId = ($fileId == 'unique()') ? $dbForProject->getId() : $fileId; + $file = $dbForProject->createDocument('files', new Document([ '$id' => $fileId, '$read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user '$write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user @@ -202,15 +202,15 @@ App::get('/v1/storage/files') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) { + ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ if (!empty($cursor)) { - $cursorFile = $dbForInternal->getDocument('files', $cursor); + $cursorFile = $dbForProject->getDocument('files', $cursor); if ($cursorFile->isEmpty()) { throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400); @@ -229,8 +229,8 @@ App::get('/v1/storage/files') ; $response->dynamic(new Document([ - 'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection), - 'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT), + 'files' => $dbForProject->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection), + 'sum' => $dbForProject->count('files', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_FILE_LIST); }); @@ -247,14 +247,14 @@ App::get('/v1/storage/files/:fileId') ->label('sdk.response.model', Response::MODEL_FILE) ->param('fileId', '', new UID(), 'File ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($fileId, $response, $dbForInternal, $usage) { + ->action(function ($fileId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); if (empty($file->getId())) { throw new Exception('File not found', 404); @@ -292,13 +292,13 @@ App::get('/v1/storage/files/:fileId/preview') ->inject('request') ->inject('response') ->inject('project') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $dbForInternal, $usage) { + ->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $dbForProject, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $stats */ $storage = 'files'; @@ -322,7 +322,7 @@ App::get('/v1/storage/files/:fileId/preview') $date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache $key = \md5($fileId.$width.$height.$gravity.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output); - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); if (empty($file->getId())) { throw new Exception('File not found', 404); @@ -440,14 +440,14 @@ App::get('/v1/storage/files/:fileId/download') ->label('sdk.methodType', 'location') ->param('fileId', '', new UID(), 'File ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($fileId, $response, $dbForInternal, $usage) { + ->action(function ($fileId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); if (empty($file->getId())) { throw new Exception('File not found', 404); @@ -505,14 +505,14 @@ App::get('/v1/storage/files/:fileId/view') ->label('sdk.methodType', 'location') ->param('fileId', '', new UID(), 'File ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($fileId, $response, $dbForInternal, $usage) { + ->action(function ($fileId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); $mimes = Config::getParam('storage-mimes'); if (empty($file->getId())) { @@ -583,13 +583,13 @@ App::put('/v1/storage/files/:fileId') ->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.') ->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('user') ->inject('audits') ->inject('usage') - ->action(function ($fileId, $read, $write, $response, $dbForInternal, $user, $audits, $usage) { + ->action(function ($fileId, $read, $write, $response, $dbForProject, $user, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Document $user */ /** @var Appwrite\Event\Event $audits */ @@ -612,13 +612,13 @@ App::put('/v1/storage/files/:fileId') } } - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); if (empty($file->getId())) { throw new Exception('File not found', 404); } - $file = $dbForInternal->updateDocument('files', $fileId, new Document(\array_merge($file->getArrayCopy(), [ + $file = $dbForProject->updateDocument('files', $fileId, new Document(\array_merge($file->getArrayCopy(), [ '$read' => $read, '$write' => $write, 'bucketId' => '', @@ -650,18 +650,18 @@ App::delete('/v1/storage/files/:fileId') ->label('sdk.response.model', Response::MODEL_NONE) ->param('fileId', '', new UID(), 'File ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') ->inject('audits') ->inject('usage') - ->action(function ($fileId, $response, $dbForInternal, $events, $audits, $usage) { + ->action(function ($fileId, $response, $dbForProject, $events, $audits, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Stats\Stats $usage */ - $file = $dbForInternal->getDocument('files', $fileId); + $file = $dbForProject->getDocument('files', $fileId); if (empty($file->getId())) { throw new Exception('File not found', 404); @@ -670,7 +670,7 @@ App::delete('/v1/storage/files/:fileId') $device = Storage::getDevice('files'); if ($device->delete($file->getAttribute('path', ''))) { - if (!$dbForInternal->deleteDocument('files', $fileId)) { + if (!$dbForProject->deleteDocument('files', $fileId)) { throw new Exception('Failed to remove file from DB', 500); } } @@ -705,10 +705,10 @@ App::get('/v1/storage/usage') ->label('sdk.response.model', Response::MODEL_USAGE_STORAGE) ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($range, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($range, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ $usage = []; if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { @@ -738,12 +738,12 @@ App::get('/v1/storage/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); @@ -797,10 +797,10 @@ App::get('/v1/storage/:bucketId/usage') ->param('bucketId', '', new UID(), 'Bucket ID.') ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($bucketId, $range, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($bucketId, $range, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ // TODO: Check if the storage bucket exists else throw 404 @@ -835,12 +835,12 @@ App::get('/v1/storage/:bucketId/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 90eb6afe66..20bed66f53 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -39,19 +39,19 @@ App::post('/v1/teams') ->param('roles', ['owner'], new ArrayList(new Key()), 'Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', true) ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') - ->action(function ($teamId, $name, $roles, $response, $user, $dbForInternal, $events) { + ->action(function ($teamId, $name, $roles, $response, $user, $dbForProject, $events) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); $isAppUser = Auth::isAppUser(Authorization::getRoles()); - $teamId = $teamId == 'unique()' ? $dbForInternal->getId() : $teamId; - $team = Authorization::skip(fn() => $dbForInternal->createDocument('teams', new Document([ + $teamId = $teamId == 'unique()' ? $dbForProject->getId() : $teamId; + $team = Authorization::skip(fn() => $dbForProject->createDocument('teams', new Document([ '$id' => $teamId , '$read' => ['team:'.$teamId], '$write' => ['team:'.$teamId .'/owner'], @@ -74,11 +74,11 @@ App::post('/v1/teams') 'secret' => '', ]); - $membership = $dbForInternal->createDocument('memberships', $membership); + $membership = $dbForProject->createDocument('memberships', $membership); // Attach user to team $user->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); } if (!empty($user->getId())) { @@ -107,13 +107,13 @@ App::get('/v1/teams') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ if (!empty($cursor)) { - $cursorTeam = $dbForInternal->getDocument('teams', $cursor); + $cursorTeam = $dbForProject->getDocument('teams', $cursor); if ($cursorTeam->isEmpty()) { throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400); @@ -126,8 +126,8 @@ App::get('/v1/teams') $queries[] = new Query('search', Query::TYPE_SEARCH, [$search]); } - $results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection); - $sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT); + $results = $dbForProject->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection); + $sum = $dbForProject->count('teams', $queries, APP_LIMIT_COUNT); $response->dynamic(new Document([ 'teams' => $results, @@ -148,12 +148,12 @@ App::get('/v1/teams/:teamId') ->label('sdk.response.model', Response::MODEL_TEAM) ->param('teamId', '', new UID(), 'Team ID.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($teamId, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($teamId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); @@ -177,18 +177,18 @@ App::put('/v1/teams/:teamId') ->param('teamId', '', new UID(), 'Team ID.') ->param('name', null, new Text(128), 'New team name. Max length: 128 chars.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($teamId, $name, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($teamId, $name, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - $team = $dbForInternal->updateDocument('teams', $team->getId(),$team + $team = $dbForProject->updateDocument('teams', $team->getId(),$team ->setAttribute('name', $name) ->setAttribute('search', implode(' ', [$teamId, $name])) ); @@ -209,33 +209,33 @@ App::delete('/v1/teams/:teamId') ->label('sdk.response.model', Response::MODEL_NONE) ->param('teamId', '', new UID(), 'Team ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') ->inject('deletes') - ->action(function ($teamId, $response, $dbForInternal, $events, $deletes) { + ->action(function ($teamId, $response, $dbForProject, $events, $deletes) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $deletes */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - $memberships = $dbForInternal->find('memberships', [ + $memberships = $dbForProject->find('memberships', [ new Query('teamId', Query::TYPE_EQUAL, [$teamId]), ], 2000, 0); // TODO fix members limit // TODO delete all members individually from the user object foreach ($memberships as $membership) { - if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) { + if (!$dbForProject->deleteDocument('memberships', $membership->getId())) { throw new Exception('Failed to remove membership for team from DB', 500); } } - if (!$dbForInternal->deleteDocument('teams', $teamId)) { + if (!$dbForProject->deleteDocument('teams', $teamId)) { throw new Exception('Failed to remove team from DB', 500); } @@ -273,15 +273,15 @@ App::post('/v1/teams/:teamId/memberships') ->inject('response') ->inject('project') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('audits') ->inject('mails') - ->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) { + ->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForProject, $locale, $audits, $mails) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $mails */ @@ -294,20 +294,20 @@ App::post('/v1/teams/:teamId/memberships') $email = \strtolower($email); $name = (empty($name)) ? $email : $name; - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - $invitee = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address + $invitee = $dbForProject->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address if (empty($invitee)) { // Create new user if no user with same email found $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed. - $sum = $dbForInternal->count('users', [], APP_LIMIT_USERS); + $sum = $dbForProject->count('users', [], APP_LIMIT_USERS); if($sum >= $limit) { throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501); @@ -315,8 +315,8 @@ App::post('/v1/teams/:teamId/memberships') } try { - $userId = $dbForInternal->getId(); - $invitee = Authorization::skip(fn() => $dbForInternal->createDocument('users', new Document([ + $userId = $dbForProject->getId(); + $invitee = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['user:'.$userId, 'role:all'], '$write' => ['user:'.$userId], @@ -353,7 +353,7 @@ App::post('/v1/teams/:teamId/memberships') $secret = Auth::tokenGenerator(); $membership = new Document([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), '$read' => ['role:all'], '$write' => ['user:'.$invitee->getId(), 'team:'.$team->getId().'/owner'], 'userId' => $invitee->getId(), @@ -367,20 +367,20 @@ App::post('/v1/teams/:teamId/memberships') if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership try { - $membership = Authorization::skip(fn() => $dbForInternal->createDocument('memberships', $membership)); + $membership = Authorization::skip(fn() => $dbForProject->createDocument('memberships', $membership)); } catch (Duplicate $th) { throw new Exception('User has already been invited or is already a member of this team', 409); } $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1); - $team = Authorization::skip(fn() => $dbForInternal->updateDocument('teams', $team->getId(), $team)); + $team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team)); // Attach user to team $invitee->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND); - $invitee = Authorization::skip(fn() => $dbForInternal->updateDocument('users', $invitee->getId(), $invitee)); + $invitee = Authorization::skip(fn() => $dbForProject->updateDocument('users', $invitee->getId(), $invitee)); } else { try { - $membership = $dbForInternal->createDocument('memberships', $membership); + $membership = $dbForProject->createDocument('memberships', $membership); } catch (Duplicate $th) { throw new Exception('User has already been invited or is already a member of this team', 409); } @@ -438,32 +438,32 @@ App::get('/v1/teams/:teamId/memberships') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') - ->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } if (!empty($cursor)) { - $cursorMembership = $dbForInternal->getDocument('memberships', $cursor); + $cursorMembership = $dbForProject->getDocument('memberships', $cursor); if ($cursorMembership->isEmpty()) { throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400); } } - $memberships = $dbForInternal->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection); - $sum = $dbForInternal->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT); + $memberships = $dbForProject->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection); + $sum = $dbForProject->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT); $memberships = array_filter($memberships, fn(Document $membership) => !empty($membership->getAttribute('userId'))); - $memberships = array_map(function($membership) use ($dbForInternal) { - $user = $dbForInternal->getDocument('users', $membership->getAttribute('userId')); + $memberships = array_map(function($membership) use ($dbForProject) { + $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); $membership ->setAttribute('name', $user->getAttribute('name')) @@ -493,24 +493,24 @@ App::get('/v1/teams/:teamId/memberships/:membershipId') ->param('teamId', '', new UID(), 'Team ID.') ->param('membershipId', '', new UID(), 'Membership ID.') ->inject('response') - ->inject('dbForInternal') - ->action(function ($teamId, $membershipId, $response, $dbForInternal) { + ->inject('dbForProject') + ->action(function ($teamId, $membershipId, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - $membership = $dbForInternal->getDocument('memberships', $membershipId); + $membership = $dbForProject->getDocument('memberships', $membershipId); if($membership->isEmpty() || empty($membership->getAttribute('userId'))) { throw new Exception('Membership not found', 404); } - $user = $dbForInternal->getDocument('users', $membership->getAttribute('userId')); + $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); $membership ->setAttribute('name', $user->getAttribute('name')) @@ -538,26 +538,26 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') ->inject('request') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') - ->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) { + ->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForProject, $audits) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - $membership = $dbForInternal->getDocument('memberships', $membershipId); + $membership = $dbForProject->getDocument('memberships', $membershipId); if ($membership->isEmpty()) { throw new Exception('Membership not found', 404); } - $profile = $dbForInternal->getDocument('users', $membership->getAttribute('userId')); + $profile = $dbForProject->getDocument('users', $membership->getAttribute('userId')); if ($profile->isEmpty()) { throw new Exception('User not found', 404); } @@ -572,7 +572,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId') // Update the roles $membership->setAttribute('roles', $roles); - $membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership); + $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); // TODO sync updated membership in the user $profile object using TYPE_REPLACE @@ -604,20 +604,20 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->inject('request') ->inject('response') ->inject('user') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('geodb') ->inject('audits') - ->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) { + ->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForProject, $geodb, $audits) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $user */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Event\Event $audits */ $protocol = $request->getProtocol(); - $membership = $dbForInternal->getDocument('memberships', $membershipId); + $membership = $dbForProject->getDocument('memberships', $membershipId); if ($membership->isEmpty()) { throw new Exception('Membership not found', 404); @@ -627,7 +627,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') throw new Exception('Team IDs don\'t match', 404); } - $team = Authorization::skip(fn() => $dbForInternal->getDocument('teams', $teamId)); + $team = Authorization::skip(fn() => $dbForProject->getDocument('teams', $teamId)); if ($team->isEmpty()) { throw new Exception('Team not found', 404); @@ -642,7 +642,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') } if ($user->isEmpty()) { - $user = $dbForInternal->getDocument('users', $userId); // Get user + $user = $dbForProject->getDocument('users', $userId); // Get user } if ($membership->getAttribute('userId') !== $user->getId()) { @@ -668,7 +668,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') $expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG; $secret = Auth::tokenGenerator(); $session = new Document(array_merge([ - '$id' => $dbForInternal->getId(), + '$id' => $dbForProject->getId(), 'userId' => $user->getId(), 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => $user->getAttribute('email'), @@ -679,7 +679,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', ], $detector->getOS(), $detector->getClient(), $detector->getDevice())); - $session = $dbForInternal->createDocument('sessions', $session + $session = $dbForProject->createDocument('sessions', $session ->setAttribute('$read', ['user:'.$user->getId()]) ->setAttribute('$write', ['user:'.$user->getId()]) ); @@ -688,10 +688,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') Authorization::setRole('user:'.$userId); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); - $membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); + $membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership); - $team = Authorization::skip(fn() => $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1))); + $team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1))); $audits ->setParam('userId', $user->getId()) @@ -730,16 +730,16 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') ->param('teamId', '', new UID(), 'Team ID.') ->param('membershipId', '', new UID(), 'Membership ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') ->inject('events') - ->action(function ($teamId, $membershipId, $response, $dbForInternal, $audits, $events) { + ->action(function ($teamId, $membershipId, $response, $dbForProject, $audits, $events) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ /** @var Appwrite\Event\Event $events */ - $membership = $dbForInternal->getDocument('memberships', $membershipId); + $membership = $dbForProject->getDocument('memberships', $membershipId); if ($membership->isEmpty()) { throw new Exception('Invite not found', 404); @@ -749,19 +749,19 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') throw new Exception('Team IDs don\'t match', 404); } - $user = $dbForInternal->getDocument('users', $membership->getAttribute('userId')); + $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); if ($user->isEmpty()) { throw new Exception('User not found', 404); } - $team = $dbForInternal->getDocument('teams', $teamId); + $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { throw new Exception('Team not found', 404); } - if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) { + if (!$dbForProject->deleteDocument('memberships', $membership->getId())) { throw new Exception('Failed to remove membership from DB', 500); } @@ -778,11 +778,11 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') $user->setAttribute('memberships', $memberships); - Authorization::skip(fn() => $dbForInternal->updateDocument('users', $user->getId(), $user)); + Authorization::skip(fn() => $dbForProject->updateDocument('users', $user->getId(), $user)); if ($membership->getAttribute('confirm')) { // Count only confirmed members $team->setAttribute('sum', \max($team->getAttribute('sum', 0) - 1, 0)); - $team = $dbForInternal->updateDocument('teams', $team->getId(), $team); + $team = $dbForProject->updateDocument('teams', $team->getId(), $team); } $audits diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 5cef36f6ca..a55a585384 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -39,18 +39,18 @@ App::post('/v1/users') ->param('password', '', new Password(), 'User password. Must be at least 8 chars.') ->param('name', '', new Text(128), 'User name. Max length: 128 chars.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $email, $password, $name, $response, $dbForInternal, $usage) { + ->action(function ($userId, $email, $password, $name, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ $email = \strtolower($email); try { - $userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId; - $user = $dbForInternal->createDocument('users', new Document([ + $userId = $userId == 'unique()' ? $dbForProject->getId() : $userId; + $user = $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$read' => ['role:all'], '$write' => ['user:'.$userId], @@ -99,15 +99,15 @@ App::get('/v1/users') ->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true) ->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) { + ->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ if (!empty($cursor)) { - $cursorUser = $dbForInternal->getDocument('users', $cursor); + $cursorUser = $dbForProject->getDocument('users', $cursor); if ($cursorUser->isEmpty()) { throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400); @@ -127,8 +127,8 @@ App::get('/v1/users') ; $response->dynamic(new Document([ - 'users' => $dbForInternal->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection), - 'sum' => $dbForInternal->count('users', $queries, APP_LIMIT_COUNT), + 'users' => $dbForProject->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection), + 'sum' => $dbForProject->count('users', $queries, APP_LIMIT_COUNT), ]), Response::MODEL_USER_LIST); }); @@ -145,14 +145,14 @@ App::get('/v1/users/:userId') ->label('sdk.response.model', Response::MODEL_USER) ->param('userId', '', new UID(), 'User ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $usage) { + ->action(function ($userId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -177,14 +177,14 @@ App::get('/v1/users/:userId/prefs') ->label('sdk.response.model', Response::MODEL_PREFERENCES) ->param('userId', '', new UID(), 'User ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $usage) { + ->action(function ($userId, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -211,16 +211,16 @@ App::get('/v1/users/:userId/sessions') ->label('sdk.response.model', Response::MODEL_SESSION_LIST) ->param('userId', '', new UID(), 'User ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $locale, $usage) { + ->action(function ($userId, $response, $dbForProject, $locale, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -245,7 +245,7 @@ App::get('/v1/users/:userId/sessions') 'sessions' => $sessions, 'sum' => count($sessions), ]), Response::MODEL_SESSION_LIST); - }, ['response', 'dbForInternal', 'locale']); + }); App::get('/v1/users/:userId/logs') ->desc('Get User Logs') @@ -262,25 +262,25 @@ App::get('/v1/users/:userId/logs') ->param('limit', 25, new Range(0, 100), 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('locale') ->inject('geodb') ->inject('usage') - ->action(function ($userId, $limit, $offset, $response, $dbForInternal, $locale, $geodb, $usage) { + ->action(function ($userId, $limit, $offset, $response, $dbForProject, $locale, $geodb, $usage) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - $audit = new Audit($dbForInternal); + $audit = new Audit($dbForProject); $auditEvents = [ 'account.create', 'account.delete', @@ -367,20 +367,20 @@ App::patch('/v1/users/:userId/status') ->param('userId', '', new UID(), 'User ID.') ->param('status', null, new Boolean(true), 'User Status. To activate the user pass `true` and to block the user pass `false`.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $status, $response, $dbForInternal, $usage) { + ->action(function ($userId, $status, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', (bool) $status)); $usage ->setParam('users.update', 1) @@ -403,20 +403,20 @@ App::patch('/v1/users/:userId/verification') ->param('userId', '', new UID(), 'User ID.') ->param('emailVerification', false, new Boolean(), 'User email verification status.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $emailVerification, $response, $dbForInternal, $usage) { + ->action(function ($userId, $emailVerification, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', $emailVerification)); $usage ->setParam('users.update', 1) @@ -439,20 +439,20 @@ App::patch('/v1/users/:userId/name') ->param('userId', '', new UID(), 'User ID.') ->param('name', '', new Text(128), 'User name. Max length: 128 chars.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') - ->action(function ($userId, $name, $response, $dbForInternal, $audits) { + ->action(function ($userId, $name, $response, $dbForProject, $audits) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('name', $name)); $audits ->setParam('userId', $user->getId()) @@ -478,14 +478,14 @@ App::patch('/v1/users/:userId/password') ->param('userId', '', new UID(), 'User ID.') ->param('password', '', new Password(), 'New user password. Must be at least 8 chars.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') - ->action(function ($userId, $password, $response, $dbForInternal, $audits) { + ->action(function ($userId, $password, $response, $dbForProject, $audits) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -495,7 +495,7 @@ App::patch('/v1/users/:userId/password') ->setAttribute('password', Auth::passwordHash($password)) ->setAttribute('passwordUpdate', \time()); - $user = $dbForInternal->updateDocument('users', $user->getId(), $user); + $user = $dbForProject->updateDocument('users', $user->getId(), $user); $audits ->setParam('userId', $user->getId()) @@ -521,14 +521,14 @@ App::patch('/v1/users/:userId/email') ->param('userId', '', new UID(), 'User ID.') ->param('email', '', new Email(), 'User email.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('audits') - ->action(function ($userId, $email, $response, $dbForInternal, $audits) { + ->action(function ($userId, $email, $response, $dbForProject, $audits) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $audits */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -542,7 +542,7 @@ App::patch('/v1/users/:userId/email') $email = \strtolower($email); try { - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('email', $email)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('email', $email)); } catch(Duplicate $th) { throw new Exception('Email already exists', 409); } @@ -571,20 +571,20 @@ App::patch('/v1/users/:userId/prefs') ->param('userId', '', new UID(), 'User ID.') ->param('prefs', '', new Assoc(), 'Prefs key-value JSON object.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('usage') - ->action(function ($userId, $prefs, $response, $dbForInternal, $usage) { + ->action(function ($userId, $prefs, $response, $dbForProject, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); } - $user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); + $user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs)); $usage ->setParam('users.update', 1) @@ -606,16 +606,16 @@ App::delete('/v1/users/:userId/sessions/:sessionId') ->param('userId', '', new UID(), 'User ID.') ->param('sessionId', null, new UID(), 'Session ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') ->inject('usage') - ->action(function ($userId, $sessionId, $response, $dbForInternal, $events, $usage) { + ->action(function ($userId, $sessionId, $response, $dbForProject, $events, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -628,7 +628,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId') if ($sessionId == $session->getId()) { unset($sessions[$key]); - $dbForInternal->deleteDocument('sessions', $session->getId()); + $dbForProject->deleteDocument('sessions', $session->getId()); $user->setAttribute('sessions', $sessions); @@ -636,7 +636,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId') ->setParam('eventData', $response->output($user, Response::MODEL_USER)) ; - $dbForInternal->updateDocument('users', $user->getId(), $user); + $dbForProject->updateDocument('users', $user->getId(), $user); } } @@ -661,16 +661,16 @@ App::delete('/v1/users/:userId/sessions') ->label('sdk.response.model', Response::MODEL_NONE) ->param('userId', '', new UID(), 'User ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $events, $usage) { + ->action(function ($userId, $response, $dbForProject, $events, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -679,10 +679,10 @@ App::delete('/v1/users/:userId/sessions') $sessions = $user->getAttribute('sessions', []); foreach ($sessions as $key => $session) { /** @var Document $session */ - $dbForInternal->deleteDocument('sessions', $session->getId()); + $dbForProject->deleteDocument('sessions', $session->getId()); } - $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); + $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', [])); $events ->setParam('eventData', $response->output($user, Response::MODEL_USER)) @@ -708,18 +708,18 @@ App::delete('/v1/users/:userId') ->label('sdk.response.model', Response::MODEL_NONE) ->param('userId', '', function () {return new UID();}, 'User ID.') ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('events') ->inject('deletes') ->inject('usage') - ->action(function ($userId, $response, $dbForInternal, $events, $deletes, $usage) { + ->action(function ($userId, $response, $dbForProject, $events, $deletes, $usage) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Appwrite\Event\Event $events */ /** @var Appwrite\Event\Event $deletes */ /** @var Appwrite\Stats\Stats $usage */ - $user = $dbForInternal->getDocument('users', $userId); + $user = $dbForProject->getDocument('users', $userId); if ($user->isEmpty() || $user->getAttribute('deleted')) { throw new Exception('User not found', 404); @@ -735,7 +735,7 @@ App::delete('/v1/users/:userId') ->setAttribute("deleted", true) ; - $dbForInternal->updateDocument('users', $userId, $user); + $dbForProject->updateDocument('users', $userId, $user); $deletes ->setParam('type', DELETE_TYPE_DOCUMENT) @@ -764,13 +764,13 @@ App::get('/v1/users/usage') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_USAGE_USERS) ->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true) - ->param('provider', '', new WhiteList(\array_merge(['email', 'anonymous'], \array_map(function($value) { return "oauth-".$value; }, \array_keys(Config::getParam('providers', [])))), true), 'Provider Name.', true) + ->param('provider', '', new WhiteList(\array_merge(['email', 'anonymous'], \array_map(fn($value) => "oauth-".$value, \array_keys(Config::getParam('providers', [])))), true), 'Provider Name.', true) ->inject('response') - ->inject('dbForInternal') + ->inject('dbForProject') ->inject('register') - ->action(function ($range, $provider, $response, $dbForInternal) { + ->action(function ($range, $provider, $response, $dbForProject) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ $usage = []; if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { @@ -806,12 +806,12 @@ App::get('/v1/users/usage') $stats = []; - Authorization::skip(function() use ($dbForInternal, $periods, $range, $metrics, &$stats) { + Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) { foreach ($metrics as $metric) { $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForInternal->find('stats', [ + $requestDocs = $dbForProject->find('stats', [ new Query('period', Query::TYPE_EQUAL, [$period]), new Query('metric', Query::TYPE_EQUAL, [$metric]), ], $limit, 0, ['time'], [Database::ORDER_DESC]); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index ef1e15a4d9..bdd5d618ed 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -11,7 +11,7 @@ use Utopia\Database\Document; use Utopia\Storage\Device\Local; use Utopia\Storage\Storage; -App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $usage, $deletes, $database, $dbForInternal, $mode) { +App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $usage, $deletes, $database, $dbForProject, $mode) { /** @var Utopia\App $utopia */ /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ @@ -24,7 +24,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud /** @var Appwrite\Event\Event $deletes */ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $functions */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId())); Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId())); @@ -38,7 +38,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud /* * Abuse Check */ - $timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForInternal); + $timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject); $timeLimit ->setParam('{userId}', $user->getId()) ->setParam('{userAgent}', $request->getUserAgent('')) @@ -120,7 +120,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud $database ->setParam('projectId', $project->getId()) ; -}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'usage', 'deletes', 'database', 'dbForInternal', 'mode'], 'api'); +}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'usage', 'deletes', 'database', 'dbForProject', 'mode'], 'api'); App::init(function ($utopia, $request, $project) { /** @var Utopia\App $utopia */ diff --git a/app/http.php b/app/http.php index d76f722f34..abb2fd6f8c 100644 --- a/app/http.php +++ b/app/http.php @@ -78,54 +78,70 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { $dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */ - // if(!$dbForConsole->exists('appwrite')) { - Console::success('[Setup] - Server database init started...'); - - $collections = Config::getParam('collections', []); /** @var array $collections */ + Console::success('[Setup] - Server database init started...'); + $collections = Config::getParam('collections', []); /** @var array $collections */ + if(!$dbForConsole->exists('appwrite')) { $redis->flushAll(); - $dbForConsole->create('appwrite'); + Console::success('[Setup] - Creating database: appwrite...'); + $dbForConsole->create('appwrite'); + } + + try { + Console::success('[Setup] - Creating metadata table: appwrite...'); + $dbForConsole->createMetadata(); + } catch (\Throwable $th) { + Console::success('[Setup] - Skip: metadata table already exists'); + } + + if($dbForConsole->getCollection(Audit::COLLECTION)->isEmpty()) { $audit = new Audit($dbForConsole); $audit->setup(); + } + if ($dbForConsole->getCollection(TimeLimit::COLLECTION)->isEmpty()) { $adapter = new TimeLimit("", 0, 1, $dbForConsole); $adapter->setup(); + } - foreach ($collections as $key => $collection) { - Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...'); - - $attributes = []; - $indexes = []; - - foreach ($collection['attributes'] as $attribute) { - $attributes[] = new Document([ - '$id' => $attribute['$id'], - 'type' => $attribute['type'], - 'size' => $attribute['size'], - 'required' => $attribute['required'], - 'signed' => $attribute['signed'], - 'array' => $attribute['array'], - 'filters' => $attribute['filters'], - ]); - } - - foreach ($collection['indexes'] as $index) { - $indexes[] = new Document([ - '$id' => $index['$id'], - 'type' => $index['type'], - 'attributes' => $index['attributes'], - 'lengths' => $index['lengths'], - 'orders' => $index['orders'], - ]); - } - - $dbForConsole->createCollection($key, $attributes, $indexes); + foreach ($collections as $key => $collection) { + if(!$dbForConsole->getCollection($key)->isEmpty()) { + continue; } - Console::success('[Setup] - Server database init completed...'); - // } + Console::success('[Setup] - Creating collection: ' . $collection['$id'] . '...'); + + $attributes = []; + $indexes = []; + + foreach ($collection['attributes'] as $attribute) { + $attributes[] = new Document([ + '$id' => $attribute['$id'], + 'type' => $attribute['type'], + 'size' => $attribute['size'], + 'required' => $attribute['required'], + 'signed' => $attribute['signed'], + 'array' => $attribute['array'], + 'filters' => $attribute['filters'], + ]); + } + + foreach ($collection['indexes'] as $index) { + $indexes[] = new Document([ + '$id' => $index['$id'], + 'type' => $index['type'], + 'attributes' => $index['attributes'], + 'lengths' => $index['lengths'], + 'orders' => $index['orders'], + ]); + } + + $dbForConsole->createCollection($key, $attributes, $indexes); + + } + Console::success('[Setup] - Server database init completed...'); }); Console::success('Server started successfully (max payload is '.number_format($payloadSize).' bytes)'); diff --git a/app/init.php b/app/init.php index 3a316b315f..5f593e702a 100644 --- a/app/init.php +++ b/app/init.php @@ -602,7 +602,7 @@ App::setResource('usage', function($register) { return new Stats($register->get('statsd')); }, ['register']); -App::setResource('clients', function($request, $console, $project) { +App::setResource('clients', function ($request, $console, $project) { $console->setAttribute('platforms', [ // Always allow current host '$collection' => 'platforms', 'name' => 'Current Host', @@ -614,34 +614,35 @@ App::setResource('clients', function($request, $console, $project) { * Get All verified client URLs for both console and current projects * + Filter for duplicated entries */ - $clientsConsole = \array_map(function ($node) { - return $node['hostname']; - }, \array_filter($console->getAttribute('platforms', []), function ($node) { - if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) { - return true; - } + $clientsConsole = \array_map( + fn ($node) => $node['hostname'], + \array_filter( + $console->getAttribute('platforms', []), + fn ($node) => (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) + ) + ); - return false; - })); - - $clients = \array_unique(\array_merge($clientsConsole, \array_map(function ($node) { - return $node['hostname']; - }, \array_filter($project->getAttribute('platforms', []), function ($node) { - if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) { - return true; - } - - return false; - })))); + $clients = \array_unique( + \array_merge( + $clientsConsole, + \array_map( + fn ($node) => $node['hostname'], + \array_filter( + $project->getAttribute('platforms', []), + fn ($node) => (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) + ) + ) + ) + ); return $clients; }, ['request', 'console', 'project']); -App::setResource('user', function($mode, $project, $console, $request, $response, $dbForInternal, $dbForConsole) { +App::setResource('user', function($mode, $project, $console, $request, $response, $dbForProject, $dbForConsole) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Document $project */ - /** @var Utopia\Database\Database $dbForInternal */ + /** @var Utopia\Database\Database $dbForProject */ /** @var Utopia\Database\Database $dbForConsole */ /** @var string $mode */ @@ -675,7 +676,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response $user = new Document(['$id' => '', '$collection' => 'users']); } else { - $user = $dbForInternal->getDocument('users', Auth::$unique); + $user = $dbForProject->getDocument('users', Auth::$unique); } } else { @@ -710,7 +711,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response $jwtSessionId = $payload['sessionId'] ?? ''; if($jwtUserId && $jwtSessionId) { - $user = $dbForInternal->getDocument('users', $jwtUserId); + $user = $dbForProject->getDocument('users', $jwtUserId); } if (empty($user->find('$id', $jwtSessionId, 'sessions'))) { // Match JWT to active token @@ -719,7 +720,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response } return $user; -}, ['mode', 'project', 'console', 'request', 'response', 'dbForInternal', 'dbForConsole']); +}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForConsole']); App::setResource('project', function($dbForConsole, $request, $console) { /** @var Utopia\Swoole\Request $request */ @@ -781,17 +782,7 @@ App::setResource('console', function() { ]); }, []); -App::setResource('dbForInternal', function($db, $cache, $project) { - $cache = new Cache(new RedisCache($cache)); - - $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); - $database->setNamespace('_project_'.$project->getId()); - - return $database; -}, ['db', 'cache', 'project']); - -App::setResource('dbForExternal', function($db, $cache, $project) { +App::setResource('dbForProject', function($db, $cache, $project) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); diff --git a/app/tasks/usage.php b/app/tasks/usage.php index 5110193a31..24f5e86cfe 100644 --- a/app/tasks/usage.php +++ b/app/tasks/usage.php @@ -223,7 +223,9 @@ $cli $cacheAdapter = new Cache(new Redis($redis)); $dbForProject = new Database(new MariaDB($db), $cacheAdapter); $dbForConsole = new Database(new MariaDB($db), $cacheAdapter); - $dbForConsole->setNamespace('project_console_internal'); + $dbForProject->setDefaultDatabase('appwrite'); + $dbForConsole->setDefaultDatabase('appwrite'); + $dbForConsole->setNamespace('_project_console'); $latestTime = []; @@ -276,9 +278,7 @@ $cli $filters = $options['filters'] ?? []; // Some metrics might have additional filters, like function's status if (!empty($filters)) { - $filters = ' AND ' . implode(' AND ', array_map(function ($filter, $value) { - return "\"{$filter}\"='{$value}'"; - }, array_keys($filters), array_values($filters))); + $filters = ' AND ' . implode(' AND ', array_map(fn ($filter, $value) => "\"{$filter}\"='{$value}'", array_keys($filters), array_values($filters))); } else { $filters = ''; } @@ -291,7 +291,7 @@ $cli $projectId = $point['projectId']; if (!empty($projectId) && $projectId !== 'console') { - $dbForProject->setNamespace('project_' . $projectId . '_internal'); + $dbForProject->setNamespace('_project_' . $projectId); $metricUpdated = $metric; if (!empty($groupBy)) { @@ -371,7 +371,7 @@ $cli $projectId = $project->getId(); // Get total storage - $dbForProject->setNamespace('project_' . $projectId . '_internal'); + $dbForProject->setNamespace('_project_' . $projectId); $storageTotal = $dbForProject->sum('files', 'sizeOriginal') + $dbForProject->sum('tags', 'size'); $time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes @@ -435,9 +435,8 @@ $cli foreach ($collections as $collection => $options) { try { - $dbForProject->setNamespace("project_{$projectId}_{$options['namespace']}"); + $dbForProject->setNamespace("_project_{$projectId}"); $count = $dbForProject->count($collection); - $dbForProject->setNamespace("project_{$projectId}_internal"); $metricPrefix = $options['metricPrefix'] ?? ''; $metric = empty($metricPrefix) ? "{$collection}.count" : "{$metricPrefix}.{$collection}.count"; @@ -491,7 +490,7 @@ $cli $subCollectionCounts = []; //total project level count of sub collections do { // Loop over all the parent collection document for each sub collection - $dbForProject->setNamespace("project_{$projectId}_{$options['namespace']}"); + $dbForProject->setNamespace("_project_{$projectId}"); $parents = $dbForProject->find($collection, [], 100, cursor: $latestParent); // Get all the parents for the sub collections for example for documents, this will get all the collections if (empty($parents)) { @@ -502,12 +501,12 @@ $cli foreach ($parents as $parent) { foreach ($subCollections as $subCollection => $subOptions) { // Sub collection counts, like database.collections.collectionId.documents.count - $dbForProject->setNamespace("project_{$projectId}_{$subOptions['namespace']}"); + $dbForProject->setNamespace("_project_{$projectId}"); $count = $dbForProject->count($parent->getId()); $subCollectionCounts[$subCollection] = ($subCollectionCounts[$subCollection] ?? 0) + $count; // Project level counts for sub collections like database.documents.count - $dbForProject->setNamespace("project_{$projectId}_internal"); + $dbForProject->setNamespace("_project_{$projectId}"); $metric = empty($metricPrefix) ? "{$collection}.{$parent->getId()}.{$subCollection}.count" : "{$metricPrefix}.{$collection}.{$parent->getId()}.{$subCollection}.count"; $time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes @@ -557,7 +556,7 @@ $cli * Inserting project level counts for sub collections like database.documents.count */ foreach ($subCollectionCounts as $subCollection => $count) { - $dbForProject->setNamespace("project_{$projectId}_internal"); + $dbForProject->setNamespace("_project_{$projectId}"); $metric = empty($metricPrefix) ? "{$subCollection}.count" : "{$metricPrefix}.{$subCollection}.count"; diff --git a/app/workers/audits.php b/app/workers/audits.php index cd6c34819a..10952d483b 100644 --- a/app/workers/audits.php +++ b/app/workers/audits.php @@ -28,8 +28,8 @@ class AuditsV1 extends Worker $ip = $this->args['ip']; $data = $this->args['data']; - $dbForInternal = $this->getInternalDB($projectId); - $audit = new Audit($dbForInternal); + $dbForProject = $this->getProjectDB($projectId); + $audit = new Audit($dbForProject); $audit->log($userId, $event, $resource, $userAgent, $ip, '', [ 'userName' => $userName, diff --git a/app/workers/database.php b/app/workers/database.php index cf4ea10f5e..6f634e1b31 100644 --- a/app/workers/database.php +++ b/app/workers/database.php @@ -69,8 +69,7 @@ class DatabaseV1 extends Worker protected function createAttribute(Document $collection, Document $attribute, string $projectId): void { $dbForConsole = $this->getConsoleDB(); - $dbForInternal = $this->getInternalDB($projectId); - $dbForExternal = $this->getExternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); $event = 'database.attributes.update'; $collectionId = $collection->getId(); @@ -87,13 +86,13 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if(!$dbForExternal->createAttribute('collection_' . $collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) { + if(!$dbForProject->createAttribute('collection_' . $collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) { throw new Exception('Failed to create Attribute'); } - $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available')); + $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available')); } catch (\Throwable $th) { Console::error($th->getMessage()); - $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed')); + $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed')); } finally { $target = Realtime::fromPayload($event, $attribute, $project); @@ -110,7 +109,7 @@ class DatabaseV1 extends Worker ); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); } /** @@ -121,8 +120,7 @@ class DatabaseV1 extends Worker protected function deleteAttribute(Document $collection, Document $attribute, string $projectId): void { $dbForConsole = $this->getConsoleDB(); - $dbForInternal = $this->getInternalDB($projectId); - $dbForExternal = $this->getExternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); $event = 'database.attributes.delete'; $collectionId = $collection->getId(); @@ -137,13 +135,13 @@ class DatabaseV1 extends Worker // - failed: attribute was never created // - stuck: attribute was available but cannot be removed try { - if($status !== 'failed' && !$dbForExternal->deleteAttribute('collection_' . $collectionId, $key)) { + if($status !== 'failed' && !$dbForProject->deleteAttribute('collection_' . $collectionId, $key)) { throw new Exception('Failed to delete Attribute'); } - $dbForInternal->deleteDocument('attributes', $attribute->getId()); + $dbForProject->deleteDocument('attributes', $attribute->getId()); } catch (\Throwable $th) { Console::error($th->getMessage()); - $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'stuck')); + $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'stuck')); } finally { $target = Realtime::fromPayload($event, $attribute, $project); @@ -182,7 +180,7 @@ class DatabaseV1 extends Worker $orders = \array_values(\array_diff($orders, [$orders[$found]])); if (empty($attributes)) { - $dbForInternal->deleteDocument('indexes', $index->getId()); + $dbForProject->deleteDocument('indexes', $index->getId()); } else { $index ->setAttribute('attributes', $attributes, Document::SET_TYPE_ASSIGN) @@ -205,13 +203,13 @@ class DatabaseV1 extends Worker if ($exists) { // Delete the duplicate if created, else update in db $this->deleteIndex($collection, $index, $projectId); } else { - $dbForInternal->updateDocument('indexes', $index->getId(), $index); + $dbForProject->updateDocument('indexes', $index->getId(), $index); } } } } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); } /** @@ -222,8 +220,7 @@ class DatabaseV1 extends Worker protected function createIndex(Document $collection, Document $index, string $projectId): void { $dbForConsole = $this->getConsoleDB(); - $dbForInternal = $this->getInternalDB($projectId); - $dbForExternal = $this->getExternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); $event = 'database.indexes.update'; $collectionId = $collection->getId(); @@ -235,13 +232,13 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if(!$dbForExternal->createIndex('collection_' . $collectionId, $key, $type, $attributes, $lengths, $orders)) { + if(!$dbForProject->createIndex('collection_' . $collectionId, $key, $type, $attributes, $lengths, $orders)) { throw new Exception('Failed to create Index'); } - $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available')); + $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available')); } catch (\Throwable $th) { Console::error($th->getMessage()); - $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed')); + $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed')); } finally { $target = Realtime::fromPayload($event, $index, $project); @@ -258,7 +255,7 @@ class DatabaseV1 extends Worker ); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); } /** @@ -269,8 +266,7 @@ class DatabaseV1 extends Worker protected function deleteIndex(Document $collection, Document $index, string $projectId): void { $dbForConsole = $this->getConsoleDB(); - $dbForInternal = $this->getInternalDB($projectId); - $dbForExternal = $this->getExternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); $collectionId = $collection->getId(); $key = $index->getAttribute('key'); @@ -279,13 +275,13 @@ class DatabaseV1 extends Worker $project = $dbForConsole->getDocument('projects', $projectId); try { - if($status !== 'failed' && !$dbForExternal->deleteIndex('collection_' . $collectionId, $key)) { + if($status !== 'failed' && !$dbForProject->deleteIndex('collection_' . $collectionId, $key)) { throw new Exception('Failed to delete index'); } - $dbForInternal->deleteDocument('indexes', $index->getId()); + $dbForProject->deleteDocument('indexes', $index->getId()); } catch (\Throwable $th) { Console::error($th->getMessage()); - $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'stuck')); + $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'stuck')); } finally { $target = Realtime::fromPayload($event, $index, $project); @@ -302,6 +298,6 @@ class DatabaseV1 extends Worker ); } - $dbForInternal->deleteCachedDocument('collections', $collectionId); + $dbForProject->deleteCachedDocument('collections', $collectionId); } } diff --git a/app/workers/deletes.php b/app/workers/deletes.php index eca704771b..95f7d8aeab 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -100,18 +100,17 @@ class DeletesV1 extends Worker { $collectionId = $document->getId(); - $dbForInternal = $this->getInternalDB($projectId); - $dbForExternal = $this->getExternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); - $dbForExternal->deleteCollection($collectionId); + $dbForProject->deleteCollection($collectionId); $this->deleteByGroup('attributes', [ new Query('collectionId', Query::TYPE_EQUAL, [$collectionId]) - ], $dbForInternal); + ], $dbForProject); $this->deleteByGroup('indexes', [ new Query('collectionId', Query::TYPE_EQUAL, [$collectionId]) - ], $dbForInternal); + ], $dbForProject); } /** @@ -121,17 +120,17 @@ class DeletesV1 extends Worker protected function deleteUsageStats(int $timestamp1d, int $timestamp30m) { $this->deleteForProjectIds(function (string $projectId) use ($timestamp1d, $timestamp30m) { - $dbForInternal = $this->getInternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); // Delete Usage stats $this->deleteByGroup('stats', [ new Query('time', Query::TYPE_LESSER, [$timestamp1d]), new Query('period', Query::TYPE_EQUAL, ['1d']), - ], $dbForInternal); + ], $dbForProject); $this->deleteByGroup('stats', [ new Query('time', Query::TYPE_LESSER, [$timestamp30m]), new Query('period', Query::TYPE_EQUAL, ['30m']), - ], $dbForInternal); + ], $dbForProject); }); } @@ -146,7 +145,7 @@ class DeletesV1 extends Worker // Delete Memberships $this->deleteByGroup('memberships', [ new Query('teamId', Query::TYPE_EQUAL, [$teamId]) - ], $this->getInternalDB($projectId)); + ], $this->getProjectDB($projectId)); } /** @@ -157,8 +156,7 @@ class DeletesV1 extends Worker $projectId = $document->getId(); // Delete all DBs - $this->getExternalDB($projectId)->delete(); - $this->getInternalDB($projectId)->delete(); + $this->getProjectDB($projectId)->delete($projectId); // Delete all storage directories $uploads = new Local(APP_STORAGE_UPLOADS . '/app-' . $document->getId()); @@ -180,13 +178,13 @@ class DeletesV1 extends Worker // Delete Memberships and decrement team membership counts $this->deleteByGroup('memberships', [ new Query('userId', Query::TYPE_EQUAL, [$userId]) - ], $this->getInternalDB($projectId), function (Document $document) use ($projectId) { + ], $this->getProjectDB($projectId), function (Document $document) use ($projectId) { if ($document->getAttribute('confirm')) { // Count only confirmed members $teamId = $document->getAttribute('teamId'); - $team = $this->getInternalDB($projectId)->getDocument('teams', $teamId); + $team = $this->getProjectDB($projectId)->getDocument('teams', $teamId); if (!$team->isEmpty()) { - $team = $this->getInternalDB($projectId)->updateDocument('teams', $teamId, new Document(\array_merge($team->getArrayCopy(), [ + $team = $this->getProjectDB($projectId)->updateDocument('teams', $teamId, new Document(\array_merge($team->getArrayCopy(), [ 'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0 ]))); } @@ -200,11 +198,11 @@ class DeletesV1 extends Worker protected function deleteExecutionLogs(int $timestamp): void { $this->deleteForProjectIds(function (string $projectId) use ($timestamp) { - $dbForInternal = $this->getInternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); // Delete Executions $this->deleteByGroup('executions', [ new Query('dateCreated', Query::TYPE_LESSER, [$timestamp]) - ], $dbForInternal); + ], $dbForProject); }); } @@ -214,11 +212,11 @@ class DeletesV1 extends Worker protected function deleteRealtimeUsage(int $timestamp): void { $this->deleteForProjectIds(function (string $projectId) use ($timestamp) { - $dbForInternal = $this->getInternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); // Delete Dead Realtime Logs $this->deleteByGroup('realtime', [ new Query('timestamp', Query::TYPE_LESSER, [$timestamp]) - ], $dbForInternal); + ], $dbForProject); }); } @@ -232,8 +230,8 @@ class DeletesV1 extends Worker } $this->deleteForProjectIds(function (string $projectId) use ($timestamp) { - $dbForInternal = $this->getInternalDB($projectId); - $timeLimit = new TimeLimit("", 0, 1, $dbForInternal); + $dbForProject = $this->getProjectDB($projectId); + $timeLimit = new TimeLimit("", 0, 1, $dbForProject); $abuse = new Abuse($timeLimit); $status = $abuse->cleanup($timestamp); @@ -252,8 +250,8 @@ class DeletesV1 extends Worker throw new Exception('Failed to delete audit logs. No timestamp provided'); } $this->deleteForProjectIds(function (string $projectId) use ($timestamp) { - $dbForInternal = $this->getInternalDB($projectId); - $audit = new Audit($dbForInternal); + $dbForProject = $this->getProjectDB($projectId); + $audit = new Audit($dbForProject); $status = $audit->cleanup($timestamp); if (!$status) { throw new Exception('Failed to delete Audit logs for project' . $projectId); @@ -267,13 +265,13 @@ class DeletesV1 extends Worker */ protected function deleteFunction(Document $document, string $projectId): void { - $dbForInternal = $this->getInternalDB($projectId); + $dbForProject = $this->getProjectDB($projectId); $device = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId); // Delete Tags $this->deleteByGroup('tags', [ new Query('functionId', Query::TYPE_EQUAL, [$document->getId()]) - ], $dbForInternal, function (Document $document) use ($device) { + ], $dbForProject, function (Document $document) use ($device) { if ($device->delete($document->getAttribute('path', ''))) { Console::success('Delete code tag: ' . $document->getAttribute('path', '')); @@ -285,7 +283,7 @@ class DeletesV1 extends Worker // Delete Executions $this->deleteByGroup('executions', [ new Query('functionId', Query::TYPE_EQUAL, [$document->getId()]) - ], $dbForInternal); + ], $dbForProject); } diff --git a/app/workers/functions.php b/app/workers/functions.php index 67c59ff679..4444dc7b13 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -118,7 +118,7 @@ class FunctionsV1 extends Worker $userId = $this->args['userId'] ?? ''; $jwt = $this->args['jwt'] ?? ''; - $database = $this->getInternalDB($projectId); + $database = $this->getProjectDB($projectId); switch ($trigger) { case 'event': diff --git a/composer.lock b/composer.lock index 05a20f94be..92574f1a03 100644 --- a/composer.lock +++ b/composer.lock @@ -2142,12 +2142,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "414178de818ce50832d26b4f4826f10fef64c740" + "reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/414178de818ce50832d26b4f4826f10fef64c740", - "reference": "414178de818ce50832d26b4f4826f10fef64c740", + "url": "https://api.github.com/repos/utopia-php/database/zipball/a041dd2e7e947d29123ba5a32d6bbecf769e9a4d", + "reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d", "shasum": "" }, "require": { @@ -2197,7 +2197,7 @@ "issues": "https://github.com/utopia-php/database/issues", "source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace" }, - "time": "2021-12-23T22:38:30+00:00" + "time": "2021-12-27T11:08:47+00:00" }, { "name": "utopia-php/domains", diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index 864c0e2c43..ea486f5f9d 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -21,8 +21,7 @@ abstract class Worker const MAX_ATTEMPTS = 10; const SLEEP_TIME = 2; - const DATABASE_INTERNAL = 'internal'; - const DATABASE_EXTERNAL = 'external'; + const DATABASE_PROJECT = 'project'; const DATABASE_CONSOLE = 'console'; public function setUp(): void @@ -44,19 +43,9 @@ abstract class Worker * @param string $projectId * @return Database */ - protected function getInternalDB(string $projectId): Database + protected function getProjectDB(string $projectId): Database { - return $this->getDB(self::DATABASE_INTERNAL, $projectId); - } - - /** - * Get external project database - * @param string $projectId - * @return Database - */ - protected function getExternalDB(string $projectId): Database - { - return $this->getDB(self::DATABASE_EXTERNAL, $projectId); + return $this->getDB(self::DATABASE_PROJECT, $projectId); } /** @@ -82,13 +71,7 @@ abstract class Worker $sleep = self::SLEEP_TIME; // overwritten when necessary switch ($type) { - case self::DATABASE_INTERNAL: - if (!$projectId) { - throw new \Exception('ProjectID not provided - cannot get database'); - } - $namespace = "_project_{$projectId}"; - break; - case self::DATABASE_EXTERNAL: + case self::DATABASE_PROJECT: if (!$projectId) { throw new \Exception('ProjectID not provided - cannot get database'); } From ec5e1293004f81afef6084dca126a6b71419d011 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 13:49:33 +0100 Subject: [PATCH 11/24] fix: remove vendor mount --- app/views/install/compose.phtml | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 0a32f28489..0756d29c07 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -380,7 +380,7 @@ services: - _APP_REDIS_PASS mariadb: - image: appwrite/mariadb:1.2.0 # fix issues when upgrading using: mysql_upgrade -u root -p + image: mariadb:10.7 # fix issues when upgrading using: mysql_upgrade -u root -p container_name: appwrite-mariadb restart: unless-stopped networks: diff --git a/docker-compose.yml b/docker-compose.yml index 8ea8f6f9c3..6e8b5ca5bc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,7 +71,7 @@ services: - ./psalm.xml:/usr/src/code/psalm.xml - ./tests:/usr/src/code/tests - ./app:/usr/src/code/app - - ./vendor:/usr/src/code/vendor + # - ./vendor:/usr/src/code/vendor - ./docs:/usr/src/code/docs - ./src:/usr/src/code/src # - ./debug:/tmp From bb208fd05cf2895fff63888fc62078073779fc7a Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 14:07:57 +0100 Subject: [PATCH 12/24] fix: composer dependencies --- composer.json | 6 ++--- composer.lock | 69 +++++++++++++++++---------------------------------- 2 files changed, 26 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 689d4f219e..7fd4727215 100644 --- a/composer.json +++ b/composer.json @@ -39,13 +39,13 @@ "appwrite/php-runtimes": "0.6.*", "utopia-php/framework": "0.19.*", - "utopia-php/abuse": "dev-feat-use-namespace-as-table-prefix as 0.7.0", + "utopia-php/abuse": "0.7.*", "utopia-php/analytics": "0.2.*", - "utopia-php/audit": "dev-feat-use-namespace-as-table-prefix as 0.8.0", + "utopia-php/audit": "0.8.*", "utopia-php/cache": "0.4.*", "utopia-php/cli": "0.11.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0", + "utopia-php/database": "0.13.*", "utopia-php/locale": "0.4.*", "utopia-php/orchestration": "0.2.*", "utopia-php/registry": "0.5.*", diff --git a/composer.lock b/composer.lock index 92574f1a03..00e3ca58fd 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": "3410f6496e9bb8fd1dd0d996abf4a94f", + "content-hash": "2b1ed15e618832ee86b69cff2dcdd6ac", "packages": [ { "name": "adhocore/jwt", @@ -1820,22 +1820,22 @@ }, { "name": "utopia-php/abuse", - "version": "dev-feat-use-namespace-as-table-prefix", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "340774ba29828d0570ab9d91eadcd31e7a52d5d4" + "reference": "52fb20e39e2e9619948bc0a73b52e10caa71350d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/340774ba29828d0570ab9d91eadcd31e7a52d5d4", - "reference": "340774ba29828d0570ab9d91eadcd31e7a52d5d4", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/52fb20e39e2e9619948bc0a73b52e10caa71350d", + "reference": "52fb20e39e2e9619948bc0a73b52e10caa71350d", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0" + "utopia-php/database": ">=0.11 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -1867,9 +1867,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/feat-use-namespace-as-table-prefix" + "source": "https://github.com/utopia-php/abuse/tree/0.7.0" }, - "time": "2021-12-23T21:21:10+00:00" + "time": "2021-12-27T13:06:45+00:00" }, { "name": "utopia-php/analytics", @@ -1928,22 +1928,22 @@ }, { "name": "utopia-php/audit", - "version": "dev-feat-use-namespace-as-table-prefix", + "version": "0.8.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "02681f6b0bd048348c758c06ebfcc5e05f7c19e1" + "reference": "b46dc42614a69437c45eb229249b6a6d000122c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/02681f6b0bd048348c758c06ebfcc5e05f7c19e1", - "reference": "02681f6b0bd048348c758c06ebfcc5e05f7c19e1", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/b46dc42614a69437c45eb229249b6a6d000122c1", + "reference": "b46dc42614a69437c45eb229249b6a6d000122c1", "shasum": "" }, "require": { "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "dev-feat-database-and-namespace as 0.13.0" + "utopia-php/database": ">=0.11 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1975,9 +1975,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/feat-use-namespace-as-table-prefix" + "source": "https://github.com/utopia-php/audit/tree/0.8.0" }, - "time": "2021-12-23T21:11:58+00:00" + "time": "2021-12-27T13:05:56+00:00" }, { "name": "utopia-php/cache", @@ -2138,16 +2138,16 @@ }, { "name": "utopia-php/database", - "version": "dev-feat-database-and-namespace", + "version": "0.13.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d" + "reference": "2e13987364f4966ec8a36784d4fb5df3a84e4e78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/a041dd2e7e947d29123ba5a32d6bbecf769e9a4d", - "reference": "a041dd2e7e947d29123ba5a32d6bbecf769e9a4d", + "url": "https://api.github.com/repos/utopia-php/database/zipball/2e13987364f4966ec8a36784d4fb5df3a84e4e78", + "reference": "2e13987364f4966ec8a36784d4fb5df3a84e4e78", "shasum": "" }, "require": { @@ -2195,9 +2195,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/feat-database-and-namespace" + "source": "https://github.com/utopia-php/database/tree/0.13.0" }, - "time": "2021-12-27T11:08:47+00:00" + "time": "2021-12-27T12:59:50+00:00" }, { "name": "utopia-php/domains", @@ -6496,32 +6496,9 @@ "time": "2015-12-17T08:42:14+00:00" } ], - "aliases": [ - { - "package": "utopia-php/abuse", - "version": "dev-feat-use-namespace-as-table-prefix", - "alias": "0.7.0", - "alias_normalized": "0.7.0.0" - }, - { - "package": "utopia-php/audit", - "version": "dev-feat-use-namespace-as-table-prefix", - "alias": "0.8.0", - "alias_normalized": "0.8.0.0" - }, - { - "package": "utopia-php/database", - "version": "dev-feat-database-and-namespace", - "alias": "0.13.0", - "alias_normalized": "0.13.0.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/abuse": 20, - "utopia-php/audit": 20, - "utopia-php/database": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From 8122d8882b92f5ac4c0ab84d0a72a3d044025721 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 18:00:52 +0100 Subject: [PATCH 13/24] fix: collection level permissions cursor --- app/controllers/api/database.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 3716f5a956..3149445ab1 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -1728,7 +1728,9 @@ App::get('/v1/database/collections/:collectionId/documents') $cursorDocument = null; if (!empty($cursor)) { - $cursorDocument = $dbForProject->getDocument('collection_' . $collectionId, $cursor); + $cursorDocument = $collection->getAttribute('permission') === 'collection' + ? Authorization::skip(fn () => $dbForProject->getDocument('collection_' . $collectionId, $cursor)) + : $dbForProject->getDocument('collection_' . $collectionId, $cursor); if ($cursorDocument->isEmpty()) { throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400); From 9917cdb9ac964c11c1a387550c7f6babcbe4d114 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 18:07:35 +0100 Subject: [PATCH 14/24] fix: get attribute endpoint --- app/controllers/api/database.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 3149445ab1..15658a1e41 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -1177,13 +1177,13 @@ App::get('/v1/database/collections/:collectionId/attributes/:key') $collection = $dbForProject->getDocument('collections', $collectionId); - if (empty($collection)) { + if ($collection->isEmpty()) { throw new Exception('Collection not found', 404); } - $attribute = $collection->find('$id', $key, 'attributes'); + $attribute = $dbForProject->getDocument('attributes', $collectionId.'_'.$key); - if (!$attribute) { + if ($attribute->isEmpty()) { throw new Exception('Attribute not found', 404); } @@ -1245,7 +1245,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key') $attribute = $dbForProject->getDocument('attributes', $collectionId.'_'.$key); - if (empty($attribute->getId())) { + if ($attribute->isEmpty()) { throw new Exception('Attribute not found', 404); } From 447612b2d506845af41549520a5cb03370f0cba8 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 18:21:54 +0100 Subject: [PATCH 15/24] fix: database attributes tests --- tests/e2e/Services/Database/DatabaseBase.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/e2e/Services/Database/DatabaseBase.php b/tests/e2e/Services/Database/DatabaseBase.php index 28369de58e..f226b88acd 100644 --- a/tests/e2e/Services/Database/DatabaseBase.php +++ b/tests/e2e/Services/Database/DatabaseBase.php @@ -343,49 +343,49 @@ trait DatabaseBase // wait for database worker to create attributes sleep(30); - $stringResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$string['body']['key']}",array_merge([ + $stringResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$string['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $emailResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$email['body']['key']}",array_merge([ + $emailResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$email['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $enumResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$enum['body']['key']}",array_merge([ + $enumResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$enum['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $ipResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$ip['body']['key']}",array_merge([ + $ipResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$ip['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $urlResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$url['body']['key']}",array_merge([ + $urlResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$url['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $integerResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$integer['body']['key']}",array_merge([ + $integerResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$integer['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $floatResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$float['body']['key']}",array_merge([ + $floatResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$float['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $booleanResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$collectionId}_{$boolean['body']['key']}",array_merge([ + $booleanResponse = $this->client->call(Client::METHOD_GET, "/database/collections/{$collectionId}/attributes/{$boolean['body']['key']}",array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] From b16c4367d8d6127b3e6ae435fe52ad113bbdfd77 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Mon, 27 Dec 2021 18:38:51 +0100 Subject: [PATCH 16/24] fix: migration --- src/Appwrite/Migration/Version/V11.php | 60 +++++++++++--------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/src/Appwrite/Migration/Version/V11.php b/src/Appwrite/Migration/Version/V11.php index ece9ba04e4..d8b554d3a7 100644 --- a/src/Appwrite/Migration/Version/V11.php +++ b/src/Appwrite/Migration/Version/V11.php @@ -29,8 +29,7 @@ global $register; class V11 extends Migration { - protected Database $dbInternal; - protected Database $dbExternal; + protected Database $dbProject; protected Database $dbConsole; protected array $oldCollections; @@ -43,10 +42,12 @@ class V11 extends Migration if (!is_null($cache)) { $cacheAdapter = new Cache(new RedisCache($this->cache)); - $this->dbInternal = new Database(new MariaDB($this->db), $cacheAdapter); // namespace is set on execution - $this->dbExternal = new Database(new MariaDB($this->db), $cacheAdapter); // namespace is set on execution + $this->dbProject = new Database(new MariaDB($this->db), $cacheAdapter); // namespace is set on execution $this->dbConsole = new Database(new MariaDB($this->db), $cacheAdapter); - $this->dbConsole->setNamespace('project_console_internal'); + + $this->dbProject->setDefaultDatabase('appwrite'); + $this->dbConsole->setDefaultDatabase('appwrite'); + $this->dbConsole->setNamespace('_project_console'); } $this->newCollections = Config::getParam('collections', []); @@ -60,8 +61,7 @@ class V11 extends Migration $oldProject = $this->project; - $this->dbInternal->setNamespace('project_' . $oldProject->getId() . '_internal'); - $this->dbExternal->setNamespace('project_' . $oldProject->getId() . '_external'); + $this->dbProject->setNamespace('_project_' . $oldProject->getId()); Console::info(''); Console::info('------------------------------------'); @@ -85,26 +85,18 @@ class V11 extends Migration } /** - * Create internal DB tables + * Create internal tables */ - if (!$this->dbInternal->exists()) { - $this->dbInternal->create(); + if (!$this->dbProject->exists('appwrite')) { + $this->dbProject->create('appwrite'); Console::log('Created internal tables for : ' . $project->getAttribute('name') . ' (' . $project->getId() . ')'); } - /** - * Create external DB tables - */ - if (!$this->dbExternal->exists()) { - $this->dbExternal->create(); - Console::log('Created external tables for : ' . $project->getAttribute('name') . ' (' . $project->getId() . ')'); - } - /** * Create Audit tables */ - if ($this->dbInternal->getCollection(Audit::COLLECTION)->isEmpty()) { - $audit = new Audit($this->dbInternal); + if ($this->dbProject->getCollection(Audit::COLLECTION)->isEmpty()) { + $audit = new Audit($this->dbProject); $audit->setup(); Console::log('Created audit tables for : ' . $project->getAttribute('name') . ' (' . $project->getId() . ')'); } @@ -112,8 +104,8 @@ class V11 extends Migration /** * Create Abuse tables */ - if ($this->dbInternal->getCollection(TimeLimit::COLLECTION)->isEmpty()) { - $adapter = new TimeLimit("", 0, 1, $this->dbInternal); + if ($this->dbProject->getCollection(TimeLimit::COLLECTION)->isEmpty()) { + $adapter = new TimeLimit("", 0, 1, $this->dbProject); $adapter->setup(); Console::log('Created abuse tables for : ' . $project->getAttribute('name') . ' (' . $project->getId() . ')'); } @@ -122,7 +114,7 @@ class V11 extends Migration * Create internal collections for Project */ foreach ($this->newCollections as $key => $collection) { - if (!$this->dbInternal->getCollection($key)->isEmpty()) continue; // Skip if project collection already exists + if (!$this->dbProject->getCollection($key)->isEmpty()) continue; // Skip if project collection already exists $attributes = []; $indexes = []; @@ -149,7 +141,7 @@ class V11 extends Migration ]); } - $this->dbInternal->createCollection($key, $attributes, $indexes); + $this->dbProject->createCollection($key, $attributes, $indexes); } if ($this->options['migrateCollections']) { $this->migrateExternalCollections(); @@ -198,8 +190,8 @@ class V11 extends Migration } try { - if ($this->dbInternal->getDocument($new->getCollection(), $new->getId())->isEmpty()) { - $this->dbInternal->createDocument($new->getCollection(), $new); + if ($this->dbProject->getDocument($new->getCollection(), $new->getId())->isEmpty()) { + $this->dbProject->createDocument($new->getCollection(), $new); } } catch (\Throwable $th) { Console::error('Failed to update document: ' . $th->getMessage()); @@ -249,10 +241,10 @@ class V11 extends Migration $id = $oldCollection->getId(); $permissions = $oldCollection->getPermissions(); $name = $oldCollection->getAttribute('name'); - $newCollection = $this->dbExternal->getCollection($id); + $newCollection = $this->dbProject->getCollection('collection_' . $id); if ($newCollection->isEmpty()) { - $this->dbExternal->createCollection($id); + $this->dbProject->createCollection('collection_' . $id); /** * Migrate permissions */ @@ -263,13 +255,13 @@ class V11 extends Migration * Suffix collection name with a subsequent number to make it unique if possible. */ $suffix = 1; - while ($this->dbInternal->findOne('collections', [ + while ($this->dbProject->findOne('collections', [ new Query('name', Query::TYPE_EQUAL, [$name]) ])) { $name .= ' - ' . $suffix++; } - $this->dbInternal->createDocument('collections', new Document([ + $this->dbProject->createDocument('collections', new Document([ '$id' => $id, '$read' => [], '$write' => [], @@ -290,7 +282,7 @@ class V11 extends Migration foreach ($attributes as $attribute) { try { - $this->dbExternal->createAttribute( + $this->dbProject->createAttribute( collection: $attribute['$collection'], id: $attribute['$id'], type: $attribute['type'], @@ -304,7 +296,7 @@ class V11 extends Migration filters: $attribute['filters'] ); - $this->dbInternal->createDocument('attributes', new Document([ + $this->dbProject->createDocument('attributes', new Document([ '$id' => $attribute['$collection'] . '_' . $attribute['$id'], 'key' => $attribute['$id'], 'collectionId' => $attribute['$collection'], @@ -361,7 +353,7 @@ class V11 extends Migration Console::log('Migrating External Documents for Collection ' . $collection . ': ' . $offset . ' / ' . $this->oldProjectDB->getSum()); foreach ($allDocs as $document) { - if (!$this->dbExternal->getDocument($collection, $document->getId())->isEmpty()) { + if (!$this->dbProject->getDocument('collection_' . $collection, $document->getId())->isEmpty()) { continue; } go(function ($document) { @@ -398,7 +390,7 @@ class V11 extends Migration }, $document); $document = new Document($document->getArrayCopy()); $document = $this->migratePermissions($document); - $this->dbExternal->createDocument($collection, $document); + $this->dbProject->createDocument('collection_' . $collection, $document); } $offset += $this->limit; } From cf15c90c2aac40da507067831a330798c1863c59 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 11:26:46 +0100 Subject: [PATCH 17/24] fix: saving certificates --- app/workers/certificates.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/workers/certificates.php b/app/workers/certificates.php index d06d17d1e3..b7f899825a 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -160,7 +160,7 @@ class CertificatesV1 extends Worker 'certificateId' => $certificate->getId(), ])); - $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); + $certificate = $dbForConsole->updateDocument('domains', $certificate->getId(), $certificate); if(!$certificate) { throw new Exception('Failed saving domain to DB'); From 49ba7d5dfde8c87bf8747cd51c00275b9375a5fe Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 11:48:50 +0100 Subject: [PATCH 18/24] fix: users prefs default value --- app/config/collections.php | 2 +- app/controllers/api/account.php | 8 ++++---- app/controllers/api/teams.php | 2 +- app/controllers/api/users.php | 2 +- src/Appwrite/Migration/Version/V11.php | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index cde64ae385..6c517b34a0 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -1001,7 +1001,7 @@ $collections = [ 'size' => 16384, 'signed' => true, 'required' => false, - 'default' => [], + 'default' => new \stdClass(), 'array' => false, 'filters' => ['json'], ], diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index e3d951e861..ef00af00e0 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -102,7 +102,7 @@ App::post('/v1/account') 'registration' => \time(), 'reset' => false, 'name' => $name, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], @@ -500,7 +500,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'registration' => \time(), 'reset' => false, 'name' => $name, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], @@ -672,7 +672,7 @@ App::post('/v1/account/sessions/magic-url') 'passwordUpdate' => \time(), 'registration' => \time(), 'reset' => false, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], @@ -944,7 +944,7 @@ App::post('/v1/account/sessions/anonymous') 'registration' => \time(), 'reset' => false, 'name' => null, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 20bed66f53..c2f26159b5 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -333,7 +333,7 @@ App::post('/v1/teams/:teamId/memberships') 'registration' => \time(), 'reset' => false, 'name' => $name, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index a55a585384..61a9e24a41 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -62,7 +62,7 @@ App::post('/v1/users') 'registration' => \time(), 'reset' => false, 'name' => $name, - 'prefs' => [], + 'prefs' => new \stdClass(), 'sessions' => [], 'tokens' => [], 'memberships' => [], diff --git a/src/Appwrite/Migration/Version/V11.php b/src/Appwrite/Migration/Version/V11.php index d8b554d3a7..81d2ddb48a 100644 --- a/src/Appwrite/Migration/Version/V11.php +++ b/src/Appwrite/Migration/Version/V11.php @@ -514,7 +514,7 @@ class V11 extends Migration * Set default values for arrays if not set. */ if (empty($document->getAttribute('prefs', []))) { - $document->setAttribute('prefs', []); + $document->setAttribute('prefs', new \stdClass()); } if (empty($document->getAttribute('sessions', []))) { $document->setAttribute('sessions', []); From c675c048ac4a14fd0a811464c1c385d98fdd7472 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 11:48:55 +0100 Subject: [PATCH 19/24] fix: certificates --- app/controllers/general.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 2b52a03dbb..dabed27ee3 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -47,20 +47,20 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons } else { Authorization::disable(); - $certificate = $dbForConsole->findOne('certificates', [ + $domainDocument = $dbForConsole->findOne('domain', [ new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) ]); - if (empty($certificate)) { - $certificate = new Document([ + if (!$domainDocument) { + $domainDocument = new Document([ 'domain' => $domain->get(), ]); - $certificate = $dbForConsole->createDocument('certificates', $certificate); + $domainDocument = $dbForConsole->createDocument('domains', $domains); Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); Resque::enqueue('v1-certificates', 'CertificatesV1', [ - 'document' => $certificate, + 'document' => $domainDocument, 'domain' => $domain->get(), 'validateTarget' => false, 'validateCNAME' => false, @@ -74,7 +74,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons Config::setParam('domains', $domains); } - $localeParam = (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', '')); + $localeParam = (string) $request->getParam('locale', $request->getHeader('x-appwrite-locale', '')); if (\in_array($localeParam, Config::getParam('locale-codes'))) { $locale->setDefault($localeParam); From 9802058e4f9bb81420697cfa327d93d1eeed70de Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 12:02:39 +0100 Subject: [PATCH 20/24] fix: certificates and domain collection --- app/config/collections.php | 6 +++--- app/controllers/general.php | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 6c517b34a0..ee809e982d 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -729,7 +729,7 @@ $collections = [ 'format' => '', 'size' => Database::LENGTH_KEY, 'signed' => true, - 'required' => true, + 'required' => false, 'default' => null, 'array' => false, 'filters' => [], @@ -740,7 +740,7 @@ $collections = [ 'format' => '', 'size' => Database::LENGTH_KEY, 'signed' => true, - 'required' => true, + 'required' => false, 'default' => null, 'array' => false, 'filters' => [], @@ -751,7 +751,7 @@ $collections = [ 'format' => '', 'size' => 0, 'signed' => true, - 'required' => true, + 'required' => false, 'default' => null, 'array' => false, 'filters' => [], diff --git a/app/controllers/general.php b/app/controllers/general.php index dabed27ee3..98466dba1c 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -47,7 +47,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons } else { Authorization::disable(); - $domainDocument = $dbForConsole->findOne('domain', [ + $domainDocument = $dbForConsole->findOne('domains', [ new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()]) ]); @@ -55,7 +55,8 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons $domainDocument = new Document([ 'domain' => $domain->get(), ]); - $domainDocument = $dbForConsole->createDocument('domains', $domains); + + $domainDocument = $dbForConsole->createDocument('domains', $domainDocument); Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); From dc6d3565a0c71762ea304be7cb6b769fc51b67a2 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 12:06:00 +0100 Subject: [PATCH 21/24] feat: more informations to automatic domain certificate --- app/controllers/general.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/controllers/general.php b/app/controllers/general.php index 98466dba1c..deb36a1b45 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -54,6 +54,10 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons if (!$domainDocument) { $domainDocument = new Document([ 'domain' => $domain->get(), + 'tld' => $domain->getSuffix(), + 'registerable' => $domain->getRegisterable(), + 'verification' => false, + 'certificateId' => null, ]); $domainDocument = $dbForConsole->createDocument('domains', $domainDocument); From 9a1937d07073807d91d88083415f919d70e498f3 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 12:28:29 +0100 Subject: [PATCH 22/24] fix: certs worker env variables --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 6e8b5ca5bc..2efed94a41 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -288,6 +288,7 @@ services: - mariadb environment: - _APP_ENV + - _APP_DOMAIN_TARGET - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS - _APP_REDIS_HOST - _APP_REDIS_PORT From afde0cb6803631b77eca795f198fa7b73960fcc2 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 12:51:29 +0100 Subject: [PATCH 23/24] fix: increase connection pool --- app/init.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/init.php b/app/init.php index 5f593e702a..b1ea6391ec 100644 --- a/app/init.php +++ b/app/init.php @@ -392,7 +392,7 @@ $register->set('dbPool', function () { // Register DB connection ->withOptions([ PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed ]) - , 16); + , 64); return $pool; }); @@ -412,7 +412,7 @@ $register->set('redisPool', function () { ->withPort($redisPort) ->withAuth($redisAuth) ->withDbIndex(0) - , 16); + , 64); return $pool; }); From f48708ddf43ce59c9abd2da3fc3ceb21e51da5e3 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 28 Dec 2021 13:04:58 +0100 Subject: [PATCH 24/24] fix: use env var instead of hard coded value --- app/http.php | 4 ++-- app/init.php | 4 ++-- app/realtime.php | 6 +++--- app/tasks/usage.php | 4 ++-- src/Appwrite/Migration/Version/V11.php | 5 +++-- src/Appwrite/Resque/Worker.php | 3 ++- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/http.php b/app/http.php index abb2fd6f8c..13223edfbc 100644 --- a/app/http.php +++ b/app/http.php @@ -81,12 +81,12 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) { Console::success('[Setup] - Server database init started...'); $collections = Config::getParam('collections', []); /** @var array $collections */ - if(!$dbForConsole->exists('appwrite')) { + if(!$dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'))) { $redis->flushAll(); Console::success('[Setup] - Creating database: appwrite...'); - $dbForConsole->create('appwrite'); + $dbForConsole->create(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); } try { diff --git a/app/init.php b/app/init.php index b1ea6391ec..03788776fe 100644 --- a/app/init.php +++ b/app/init.php @@ -786,7 +786,7 @@ App::setResource('dbForProject', function($db, $cache, $project) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_project_'.$project->getId()); return $database; @@ -796,7 +796,7 @@ App::setResource('dbForConsole', function($db, $cache) { $cache = new Cache(new RedisCache($cache)); $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_project_console'); return $database; diff --git a/app/realtime.php b/app/realtime.php index 84e90557a7..a671e149a3 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -58,7 +58,7 @@ function getDatabase(Registry &$register, string $namespace) $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace($namespace); return [ @@ -341,7 +341,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_project_' . $project->getId()); /* @@ -446,7 +446,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $cache = new Cache(new RedisCache($redis)); $database = new Database(new MariaDB($db), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_project_' . $realtime->connections[$connection]['projectId']); /* diff --git a/app/tasks/usage.php b/app/tasks/usage.php index 24f5e86cfe..690da5e2ff 100644 --- a/app/tasks/usage.php +++ b/app/tasks/usage.php @@ -223,8 +223,8 @@ $cli $cacheAdapter = new Cache(new Redis($redis)); $dbForProject = new Database(new MariaDB($db), $cacheAdapter); $dbForConsole = new Database(new MariaDB($db), $cacheAdapter); - $dbForProject->setDefaultDatabase('appwrite'); - $dbForConsole->setDefaultDatabase('appwrite'); + $dbForProject->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + $dbForConsole->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $dbForConsole->setNamespace('_project_console'); $latestTime = []; diff --git a/src/Appwrite/Migration/Version/V11.php b/src/Appwrite/Migration/Version/V11.php index 81d2ddb48a..36a13383e3 100644 --- a/src/Appwrite/Migration/Version/V11.php +++ b/src/Appwrite/Migration/Version/V11.php @@ -11,6 +11,7 @@ use Redis; use Swoole\Runtime; use Throwable; use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\App; use Utopia\Audit\Audit; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -45,8 +46,8 @@ class V11 extends Migration $this->dbProject = new Database(new MariaDB($this->db), $cacheAdapter); // namespace is set on execution $this->dbConsole = new Database(new MariaDB($this->db), $cacheAdapter); - $this->dbProject->setDefaultDatabase('appwrite'); - $this->dbConsole->setDefaultDatabase('appwrite'); + $this->dbProject->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + $this->dbConsole->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $this->dbConsole->setNamespace('_project_console'); } diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index ea486f5f9d..a09d00ee5e 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -2,6 +2,7 @@ namespace Appwrite\Resque; +use Utopia\App; use Utopia\Cache\Cache; use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\CLI\Console; @@ -93,7 +94,7 @@ abstract class Worker $attempts++; $cache = new Cache(new RedisCache($register->get('cache'))); $database = new Database(new MariaDB($register->get('db')), $cache); - $database->setDefaultDatabase('appwrite'); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace($namespace); // Main DB if (!empty($projectId) && !$database->getDocument('projects', $projectId)->isEmpty()) { throw new \Exception("Project does not exist: {$projectId}");