From 26af9b7463732ba48039b4654041fe80725a5b0b Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 14 Feb 2024 23:05:01 +0200 Subject: [PATCH 01/51] usage logs updates --- src/Appwrite/Platform/Workers/Usage.php | 1 + src/Appwrite/Platform/Workers/UsageDump.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Usage.php b/src/Appwrite/Platform/Workers/Usage.php index 49f3344906..35c0e02cef 100644 --- a/src/Appwrite/Platform/Workers/Usage.php +++ b/src/Appwrite/Platform/Workers/Usage.php @@ -76,6 +76,7 @@ class Usage extends Action } $this->stats[$projectId]['project'] = $project; + $this->stats[$projectId]['receivedAt'] = DateTime::now(); foreach ($payload['metrics'] ?? [] as $metric) { $this->keys++; if (!isset($this->stats[$projectId]['keys'][$metric['key']])) { diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index f563578984..9f2e269d5f 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -59,12 +59,12 @@ class UsageDump extends Action foreach ($payload['stats'] ?? [] as $stats) { $project = new Document($stats['project'] ?? []); $numberOfKeys = !empty($stats['keys']) ? count($stats['keys']) : 0; - + $receivedAt = $stats['receivedAt'] ?? 'NONE'; if ($numberOfKeys === 0) { continue; } - console::log('[' . DateTime::now() . '] ProjectId [' . $project->getInternalId() . '] Database [' . $project['database'] . '] ' . $numberOfKeys . ' keys'); + console::log('[' . DateTime::now() . '] ProjectId [' . $project->getInternalId() . '] receivedAt [' . $receivedAt . '] ' . $numberOfKeys . ' keys'); try { $dbForProject = $getProjectDB($project); From dae01f707773ec5edbb714c7980e4bd6cb945613 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 14 Feb 2024 23:07:25 +0200 Subject: [PATCH 02/51] usage logs updates --- src/Appwrite/Platform/Workers/UsageDump.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index 9f2e269d5f..5a4324fd3e 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -64,7 +64,7 @@ class UsageDump extends Action continue; } - console::log('[' . DateTime::now() . '] ProjectId [' . $project->getInternalId() . '] receivedAt [' . $receivedAt . '] ' . $numberOfKeys . ' keys'); + console::log('[' . DateTime::now() . '] ProjectId [' . $project->getInternalId() . '] ReceivedAt [' . $receivedAt . '] ' . $numberOfKeys . ' keys'); try { $dbForProject = $getProjectDB($project); From 00db19257d0d0b49745d31102f1240f6810ea214 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 15 Feb 2024 11:57:24 +0530 Subject: [PATCH 03/51] Add health storage check --- app/controllers/api/health.php | 37 +++++++++++++++++++ docs/references/health/get-storage.md | 1 + .../Health/HealthCustomServerTest.php | 18 +++++++++ 3 files changed, 56 insertions(+) create mode 100644 docs/references/health/get-storage.md diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index a85f9da321..2f637be424 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -702,6 +702,43 @@ App::get('/v1/health/storage/local') $response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS); }); +App::get('/v1/health/storage') + ->desc('Get storage') + ->groups(['api', 'health']) + ->label('scope', 'health.read') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'health') + ->label('sdk.method', 'getStorage') + ->label('sdk.description', '/docs/references/health/get-storage.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_HEALTH_STATUS) + ->inject('response') + ->inject('deviceFiles') + ->action(function (Response $response, Device $deviceFiles) { + + $checkStart = \microtime(true); + + if (!$deviceFiles->write($deviceFiles->getPath('health.txt'), 'test', '')) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file'); + } + + if ($deviceFiles->read($deviceFiles->getPath('health.txt')) !== 'test') { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file'); + } + + if (!$deviceFiles->delete($deviceFiles->getPath('health.txt'))) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file'); + } + + $output = [ + 'status' => 'pass', + 'ping' => \round((\microtime(true) - $checkStart) / 1000) + ]; + + $response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS); + }); + App::get('/v1/health/anti-virus') ->desc('Get antivirus') ->groups(['api', 'health']) diff --git a/docs/references/health/get-storage.md b/docs/references/health/get-storage.md new file mode 100644 index 0000000000..ea73e88027 --- /dev/null +++ b/docs/references/health/get-storage.md @@ -0,0 +1 @@ +Check the Appwrite storage device is up and connection is successful. \ No newline at end of file diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index c817222c48..dde89a6a71 100644 --- a/tests/e2e/Services/Health/HealthCustomServerTest.php +++ b/tests/e2e/Services/Health/HealthCustomServerTest.php @@ -407,6 +407,24 @@ class HealthCustomServerTest extends Scope return []; } + public function testStorageSuccess(): array + { + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/health/storage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('pass', $response['body']['status']); + $this->assertIsInt($response['body']['ping']); + $this->assertLessThan(100, $response['body']['ping']); + + return []; + } + public function testStorageAntiVirusSuccess(): array { /** From 2a5f21e9827d92db3d4919d4d8fe69b112ac3f54 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 15 Feb 2024 17:12:37 +0200 Subject: [PATCH 04/51] Addressed comments --- app/worker.php | 5 +++-- src/Appwrite/Event/Mail.php | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/worker.php b/app/worker.php index 4cf0edbae6..0bf5ae89e1 100644 --- a/app/worker.php +++ b/app/worker.php @@ -253,7 +253,6 @@ try { Console::error($e->getMessage() . ', File: ' . $e->getFile() . ', Line: ' . $e->getLine()); } - $worker = $platform->getWorker(); $worker @@ -268,7 +267,8 @@ $worker ->inject('error') ->inject('logger') ->inject('log') - ->action(function (Throwable $error, ?Logger $logger, Log $log) { + ->inject('project') + ->action(function (Throwable $error, ?Logger $logger, Log $log, Document $project) { $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); if ($error instanceof PDOException) { @@ -284,6 +284,7 @@ $worker $log->setAction('appwrite-queue-' . App::getEnv('QUEUE')); $log->addTag('verboseType', get_class($error)); $log->addTag('code', $error->getCode()); + $log->addTag('projectId', $project->getInternalId() ?? 'n/a'); $log->addExtra('file', $error->getFile()); $log->addExtra('line', $error->getLine()); $log->addExtra('trace', $error->getTraceAsString()); diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index 9973dae403..ca8fe7d202 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -365,6 +365,7 @@ class Mail extends Event $client = new Client($this->queue, $this->connection); return $client->enqueue([ + 'project' => $this->project, 'recipient' => $this->recipient, 'name' => $this->name, 'subject' => $this->subject, From ed4319314af0610b2a353ac074245ccee0b8dd38 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 15 Feb 2024 17:15:10 +0200 Subject: [PATCH 05/51] Addressed comments --- app/worker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/worker.php b/app/worker.php index 0bf5ae89e1..de12bba6cb 100644 --- a/app/worker.php +++ b/app/worker.php @@ -284,7 +284,7 @@ $worker $log->setAction('appwrite-queue-' . App::getEnv('QUEUE')); $log->addTag('verboseType', get_class($error)); $log->addTag('code', $error->getCode()); - $log->addTag('projectId', $project->getInternalId() ?? 'n/a'); + $log->addTag('projectId', $project->getId() ?? 'n/a'); $log->addExtra('file', $error->getFile()); $log->addExtra('line', $error->getLine()); $log->addExtra('trace', $error->getTraceAsString()); From 3b1233eaa9d7e4ba705e6073697c21d6e747dffe Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:28:41 +0530 Subject: [PATCH 06/51] Add deviceFunctions and deviceBuilds as well --- app/controllers/api/health.php | 36 ++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 2f637be424..2cbf8add33 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -21,6 +21,20 @@ use Utopia\Validator\Multiple; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; +$checkStorageHealth = function (Device $device) { + if (!$device->write($device->getPath('health.txt'), 'test', '')) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); + } + + if ($device->read($device->getPath('health.txt')) !== 'test') { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); + } + + if (!$device->delete($device->getPath('health.txt'))) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); + } +}; + App::get('/v1/health') ->desc('Get HTTP') ->groups(['api', 'health']) @@ -715,20 +729,18 @@ App::get('/v1/health/storage') ->label('sdk.response.model', Response::MODEL_HEALTH_STATUS) ->inject('response') ->inject('deviceFiles') - ->action(function (Response $response, Device $deviceFiles) { - + ->inject('deviceFunctions') + ->inject('deviceBuilds') + ->action(function (Response $response, Device $deviceFiles, Device $deviceFunctions, Device $deviceBuilds) use ($checkStorageHealth) { + $devices = [$deviceFiles, $deviceFunctions, $deviceBuilds]; $checkStart = \microtime(true); - if (!$deviceFiles->write($deviceFiles->getPath('health.txt'), 'test', '')) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file'); - } - - if ($deviceFiles->read($deviceFiles->getPath('health.txt')) !== 'test') { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file'); - } - - if (!$deviceFiles->delete($deviceFiles->getPath('health.txt'))) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file'); + try { + foreach ($devices as $device) { + $checkStorageHealth($device); + } + } catch (Exception $e) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, $e->getMessage()); } $output = [ From e4a86d9777db3542f5b5de11da2772ac8975c7c1 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:19:54 +0530 Subject: [PATCH 07/51] Remove global function --- app/controllers/api/health.php | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 2cbf8add33..c007d629b6 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -21,20 +21,6 @@ use Utopia\Validator\Multiple; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; -$checkStorageHealth = function (Device $device) { - if (!$device->write($device->getPath('health.txt'), 'test', '')) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); - } - - if ($device->read($device->getPath('health.txt')) !== 'test') { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); - } - - if (!$device->delete($device->getPath('health.txt'))) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); - } -}; - App::get('/v1/health') ->desc('Get HTTP') ->groups(['api', 'health']) @@ -731,16 +717,22 @@ App::get('/v1/health/storage') ->inject('deviceFiles') ->inject('deviceFunctions') ->inject('deviceBuilds') - ->action(function (Response $response, Device $deviceFiles, Device $deviceFunctions, Device $deviceBuilds) use ($checkStorageHealth) { + ->action(function (Response $response, Device $deviceFiles, Device $deviceFunctions, Device $deviceBuilds) { $devices = [$deviceFiles, $deviceFunctions, $deviceBuilds]; $checkStart = \microtime(true); - try { - foreach ($devices as $device) { - $checkStorageHealth($device); + foreach ($devices as $device) { + if (!$device->write($device->getPath('health.txt'), 'test', '')) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); + } + + if ($device->read($device->getPath('health.txt')) !== 'test') { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot()); + } + + if (!$device->delete($device->getPath('health.txt'))) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot()); } - } catch (Exception $e) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, $e->getMessage()); } $output = [ From 2ab6156db4f9a9c454931b2dcf7a59714df2a916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 19 Feb 2024 14:08:15 +0000 Subject: [PATCH 08/51] Add smarter traefik load balancing with health check --- .env | 2 +- app/controllers/api/health.php | 10 +++++++++- app/controllers/web/home.php | 1 + app/http.php | 7 +++++++ docker-compose.yml | 9 ++++++--- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.env b/.env index b915f91516..56fde8a4fb 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ _APP_ENV=development _APP_LOCALE=en -_APP_WORKER_PER_CORE=6 +_APP_WORKER_PER_CORE=1 _APP_CONSOLE_WHITELIST_ROOT=disabled _APP_CONSOLE_WHITELIST_EMAILS= _APP_CONSOLE_WHITELIST_IPS= diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index a85f9da321..f6ab3e8eec 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -51,8 +51,16 @@ App::get('/v1/health/version') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_HEALTH_VERSION) + ->inject('http') ->inject('response') - ->action(function (Response $response) { + ->action(function (mixed $http, Response $response) { + $stats = $http->stats(); + \var_dump(\gethostname() . ': ' . $stats['idle_worker_num'] . '/' . $stats['worker_num']); + + if(($stats['idle_worker_num'] ?? 0) <= 1) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Can not process more requests at the moment.'); + } + $response->dynamic(new Document([ 'version' => APP_VERSION_STABLE ]), Response::MODEL_HEALTH_VERSION); }); diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index 27b2614c37..5a8a7e1a93 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -10,6 +10,7 @@ App::get('/versions') ->label('scope', 'public') ->inject('response') ->action(function (Response $response) { + \sleep(60); $platforms = Config::getParam('platforms'); $versions = [ diff --git a/app/http.php b/app/http.php index 5b32d8f134..4b740516ee 100644 --- a/app/http.php +++ b/app/http.php @@ -327,4 +327,11 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo } }); +$register->set('http', function () use ($http) { + return $http; +}); +App::setResource('http', function ($register) { + return $register->get('http'); +}, ['register']); + $http->start(); diff --git a/docker-compose.yml b/docker-compose.yml index de71e3937a..8e017c3e50 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,7 +44,9 @@ services: - appwrite appwrite: - container_name: appwrite + deploy: + mode: replicated + replicas: 3 <<: *x-logging image: appwrite-dev build: @@ -53,8 +55,6 @@ services: DEBUG: false TESTING: true VERSION: dev - ports: - - 9501:80 networks: - appwrite labels: @@ -62,6 +62,9 @@ services: - "traefik.constraint-label-stack=appwrite" - "traefik.docker.network=appwrite" - "traefik.http.services.appwrite_api.loadbalancer.server.port=80" + - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.path=/v1/health/version" + - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.interval=3s" + - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.timeout=2s" #http - traefik.http.routers.appwrite_api_http.entrypoints=appwrite_web - traefik.http.routers.appwrite_api_http.rule=PathPrefix(`/`) From 505b4815378622a1c3988c26e087c2fcc8dc6832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 19 Feb 2024 14:10:35 +0000 Subject: [PATCH 09/51] Revert "Add smarter traefik load balancing with health check" This reverts commit 2ab6156db4f9a9c454931b2dcf7a59714df2a916. --- .env | 2 +- app/controllers/api/health.php | 10 +--------- app/controllers/web/home.php | 1 - app/http.php | 7 ------- docker-compose.yml | 9 +++------ 5 files changed, 5 insertions(+), 24 deletions(-) diff --git a/.env b/.env index 56fde8a4fb..b915f91516 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ _APP_ENV=development _APP_LOCALE=en -_APP_WORKER_PER_CORE=1 +_APP_WORKER_PER_CORE=6 _APP_CONSOLE_WHITELIST_ROOT=disabled _APP_CONSOLE_WHITELIST_EMAILS= _APP_CONSOLE_WHITELIST_IPS= diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index f6ab3e8eec..a85f9da321 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -51,16 +51,8 @@ App::get('/v1/health/version') ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_HEALTH_VERSION) - ->inject('http') ->inject('response') - ->action(function (mixed $http, Response $response) { - $stats = $http->stats(); - \var_dump(\gethostname() . ': ' . $stats['idle_worker_num'] . '/' . $stats['worker_num']); - - if(($stats['idle_worker_num'] ?? 0) <= 1) { - throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Can not process more requests at the moment.'); - } - + ->action(function (Response $response) { $response->dynamic(new Document([ 'version' => APP_VERSION_STABLE ]), Response::MODEL_HEALTH_VERSION); }); diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index 5a8a7e1a93..27b2614c37 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -10,7 +10,6 @@ App::get('/versions') ->label('scope', 'public') ->inject('response') ->action(function (Response $response) { - \sleep(60); $platforms = Config::getParam('platforms'); $versions = [ diff --git a/app/http.php b/app/http.php index 4b740516ee..5b32d8f134 100644 --- a/app/http.php +++ b/app/http.php @@ -327,11 +327,4 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo } }); -$register->set('http', function () use ($http) { - return $http; -}); -App::setResource('http', function ($register) { - return $register->get('http'); -}, ['register']); - $http->start(); diff --git a/docker-compose.yml b/docker-compose.yml index 8e017c3e50..de71e3937a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,9 +44,7 @@ services: - appwrite appwrite: - deploy: - mode: replicated - replicas: 3 + container_name: appwrite <<: *x-logging image: appwrite-dev build: @@ -55,6 +53,8 @@ services: DEBUG: false TESTING: true VERSION: dev + ports: + - 9501:80 networks: - appwrite labels: @@ -62,9 +62,6 @@ services: - "traefik.constraint-label-stack=appwrite" - "traefik.docker.network=appwrite" - "traefik.http.services.appwrite_api.loadbalancer.server.port=80" - - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.path=/v1/health/version" - - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.interval=3s" - - "traefik.http.services.appwrite_api.loadbalancer.healthcheck.timeout=2s" #http - traefik.http.routers.appwrite_api_http.entrypoints=appwrite_web - traefik.http.routers.appwrite_api_http.rule=PathPrefix(`/`) From 1577be91721ce6d04a6a8a33b3607f407868632a Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 19 Feb 2024 21:36:14 +0200 Subject: [PATCH 10/51] usage/usage-dump queue health endpoints --- app/controllers/api/health.php | 55 +++++++++++++++++++ .../references/health/get-queue-usage-dump.md | 1 + docs/references/health/get-queue-usage.md | 1 + .../Health/HealthCustomServerTest.php | 48 ++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 docs/references/health/get-queue-usage-dump.md create mode 100644 docs/references/health/get-queue-usage.md diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index a85f9da321..f727492d3a 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -659,6 +659,60 @@ App::get('/v1/health/queue/functions') $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); }, ['response']); +App::get('/v1/health/queue/usage') + ->desc('Get usage queue') + ->groups(['api', 'health']) + ->label('scope', 'health.read') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'health') + ->label('sdk.method', 'getQueueUsage') + ->label('sdk.description', '/docs/references/health/get-queue-usage.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE) + ->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true) + ->inject('queue') + ->inject('response') + ->action(function (int|string $threshold, Connection $queue, Response $response) { + $threshold = \intval($threshold); + + $client = new Client(Event::USAGE_QUEUE_NAME, $queue); + $size = $client->getQueueSize(); + + if ($size >= $threshold) { + throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}."); + } + + $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); + }); + +App::get('/v1/health/queue/usage-dump') + ->desc('Get usage dump queue') + ->groups(['api', 'health']) + ->label('scope', 'health.read') + ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) + ->label('sdk.namespace', 'health') + ->label('sdk.method', 'getQueueUsage') + ->label('sdk.description', '/docs/references/health/get-queue-usage-dump.md') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE) + ->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true) + ->inject('queue') + ->inject('response') + ->action(function (int|string $threshold, Connection $queue, Response $response) { + $threshold = \intval($threshold); + + $client = new Client(Event::USAGE_DUMP_QUEUE_NAME, $queue); + $size = $client->getQueueSize(); + + if ($size >= $threshold) { + throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}."); + } + + $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); + }); + App::get('/v1/health/storage/local') ->desc('Get local storage') ->groups(['api', 'health']) @@ -755,6 +809,7 @@ App::get('/v1/health/queue/failed/:name') Event::MAILS_QUEUE_NAME, Event::FUNCTIONS_QUEUE_NAME, Event::USAGE_QUEUE_NAME, + Event::USAGE_DUMP_QUEUE_NAME, Event::WEBHOOK_CLASS_NAME, Event::CERTIFICATES_QUEUE_NAME, Event::BUILDS_QUEUE_NAME, diff --git a/docs/references/health/get-queue-usage-dump.md b/docs/references/health/get-queue-usage-dump.md new file mode 100644 index 0000000000..3c95da1b8a --- /dev/null +++ b/docs/references/health/get-queue-usage-dump.md @@ -0,0 +1 @@ +Get the number of projects containing metrics that are waiting to be processed in the Appwrite internal queue server. \ No newline at end of file diff --git a/docs/references/health/get-queue-usage.md b/docs/references/health/get-queue-usage.md new file mode 100644 index 0000000000..8e5b64e642 --- /dev/null +++ b/docs/references/health/get-queue-usage.md @@ -0,0 +1 @@ +Get the number of metrics that are waiting to be processed in the Appwrite internal queue server. \ No newline at end of file diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index c817222c48..1ea0020e3d 100644 --- a/tests/e2e/Services/Health/HealthCustomServerTest.php +++ b/tests/e2e/Services/Health/HealthCustomServerTest.php @@ -494,4 +494,52 @@ class HealthCustomServerTest extends Scope return []; } + + public function testUsageSuccess() + { + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['size']); + $this->assertLessThan(100, $response['body']['size']); + + /** + * Test for FAILURE + */ + $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage?threshold=0', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + $this->assertEquals(503, $response['headers']['status-code']); + } + + public function testUsageDumpSuccess() + { + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage-dump', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['size']); + $this->assertLessThan(100, $response['body']['size']); + + /** + * Test for FAILURE + */ + $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage-dump?threshold=0', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); + $this->assertEquals(503, $response['headers']['status-code']); + } } From c2ae330888571ed91ce00eef0f8bcb13121a4a6d Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 20 Feb 2024 09:14:48 +0545 Subject: [PATCH 11/51] fix bandwidth usage --- app/controllers/api/project.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 2269cb81c7..47b94d3093 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -144,9 +144,30 @@ App::get('/v1/project/usage') ]; }, $dbForProject->find('buckets')); + // merge network inbound + outbound + $projectBandwidth = []; + foreach ($usage[METRIC_NETWORK_INBOUND] as $item) { + $projectBandwidth[$item['date']] ??= 0; + $projectBandwidth[$item['date']] += $item['value']; + } + + foreach ($usage[METRIC_NETWORK_OUTBOUND] as $item) { + $projectBandwidth[$item['date']] ??= 0; + $projectBandwidth[$item['date']] += $item['value']; + } + + + $network = []; + foreach ($projectBandwidth as $date => $value) { + $network[] = [ + 'date' => $date, + 'value' => $value + ]; + } + $response->dynamic(new Document([ 'requests' => ($usage[METRIC_NETWORK_REQUESTS]), - 'network' => ($usage[METRIC_NETWORK_INBOUND] + $usage[METRIC_NETWORK_OUTBOUND]), + 'network' => $network, 'users' => ($usage[METRIC_USERS]), 'executions' => ($usage[METRIC_EXECUTIONS]), 'executionsTotal' => $total[METRIC_EXECUTIONS], From d60e7c641f4c714b3a4fb9536c1aa5dc85b1cdc5 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Tue, 20 Feb 2024 15:56:25 +0000 Subject: [PATCH 12/51] Add ARM64 to docker publish --- .github/workflows/publish.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0fc3fc2df3..195eefebcd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,6 +17,9 @@ jobs: fetch-depth: 2 submodules: recursive + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Login to Docker Hub uses: docker/login-action@v2 with: @@ -35,11 +38,11 @@ jobs: uses: docker/build-push-action@v4 with: context: . - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 build-args: | VERSION=${{ steps.meta.outputs.version }} VITE_APPWRITE_GROWTH_ENDPOINT=https://growth.appwrite.io/v1 VITE_GA_PROJECT=G-L7G2B6PLDS VITE_CONSOLE_MODE=cloud push: true - tags: ${{ steps.meta.outputs.tags }} \ No newline at end of file + tags: ${{ steps.meta.outputs.tags }} From cc8705253e8ba6c95dc85059dd63624fb5de388e Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 21 Feb 2024 10:12:20 +0000 Subject: [PATCH 13/51] Add Docker Buildx for multiplatform --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 195eefebcd..f914e662d3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,6 +20,9 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub uses: docker/login-action@v2 with: From 0dd2889de517c0a76b3b7c762ff3dacaef30bae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 21 Feb 2024 14:51:21 +0000 Subject: [PATCH 14/51] Fix double router curl --- app/controllers/general.php | 263 ++++++++++++++++++++++++++++++------ 1 file changed, 221 insertions(+), 42 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index bfec8b46be..e54d6c21e9 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -12,6 +12,7 @@ use Swoole\Http\Request as SwooleRequest; use Utopia\Cache\Cache; use Utopia\Pools\Group; use Appwrite\Utopia\Request; +use MaxMind\Db\Reader; use Appwrite\Utopia\Response; use Appwrite\Utopia\View; use Appwrite\Extend\Exception as AppwriteException; @@ -19,6 +20,9 @@ use Utopia\Config\Config; use Utopia\Domains\Domain; use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; +use Appwrite\Event\Event; +use Appwrite\Event\Usage; +use Appwrite\ID; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; @@ -38,6 +42,7 @@ use Appwrite\Utopia\Request\Filters\V13 as RequestV13; use Appwrite\Utopia\Request\Filters\V14 as RequestV14; use Appwrite\Utopia\Request\Filters\V15 as RequestV15; use Appwrite\Utopia\Request\Filters\V16 as RequestV16; +use Executor\Executor; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -45,7 +50,11 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleRequest, Request $request, Response $response) + +->inject('geodb') +Reader $geodb + +function router(App $utopia, Database $dbForConsole, Database $dbForProject, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -117,59 +126,214 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques $path .= '?' . $query; } + + $body = $swooleRequest->getContent() ?? ''; + $method = $swooleRequest->server['request_method']; + $requestHeaders = $request->getHeaders(); - $body = \json_encode([ - 'async' => false, - 'body' => $swooleRequest->getContent() ?? '', - 'method' => $swooleRequest->server['request_method'], - 'path' => $path, - 'headers' => $requestHeaders + $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + + if ($function->isEmpty() || !$function->getAttribute('enabled')) { + throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); + } + + $version = $function->getAttribute('version', 'v2'); + $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); + + $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; + + if (\is_null($runtime)) { + throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); + } + + $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); + + if ($deployment->getAttribute('resourceId') !== $function->getId()) { + throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); + } + + if ($deployment->isEmpty()) { + throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); + } + + /** Check if build has completed */ + $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); + if ($build->isEmpty()) { + throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND); + } + + if ($build->getAttribute('status') !== 'ready') { + throw new AppwriteException(AppwriteException::BUILD_NOT_READY); + } + + $permissions = $function->getAttribute('execute'); + + if (!(\in_array('any', $permissions)) && (\in_array('guests', $permissions))) { + throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"'); + } + + $headers = \array_merge([], $requestHeaders); + $headers['x-appwrite-trigger'] = 'http'; + $headers['x-appwrite-user-id'] = ''; + $headers['x-appwrite-user-jwt'] = ''; + $headers['x-appwrite-country-code'] = ''; + $headers['x-appwrite-continent-code'] = ''; + $headers['x-appwrite-continent-eu'] = 'false'; + + $ip = $headers['x-real-ip'] ?? ''; + if (!empty($ip)) { + $record = $geodb->get($ip); + + if ($record) { + $eu = Config::getParam('locale-eu'); + + $headers['x-appwrite-country-code'] = $record['country']['iso_code'] ?? ''; + $headers['x-appwrite-continent-code'] = $record['continent']['code'] ?? ''; + $headers['x-appwrite-continent-eu'] = (\in_array($record['country']['iso_code'], $eu)) ? 'true' : 'false'; + } + } + + $headersFiltered = []; + foreach ($headers as $key => $value) { + if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_REQUEST)) { + $headersFiltered[] = ['name' => $key, 'value' => $value]; + } + } + + $executionId = ID::unique(); + + $execution = new Document([ + '$id' => $executionId, + '$permissions' => [], + 'functionInternalId' => $function->getInternalId(), + 'functionId' => $function->getId(), + 'deploymentInternalId' => $deployment->getInternalId(), + 'deploymentId' => $deployment->getId(), + 'trigger' => 'http', // http / schedule / event + 'status' => 'processing', // waiting / processing / completed / failed + 'responseStatusCode' => 0, + 'responseHeaders' => [], + 'requestPath' => $path, + 'requestMethod' => $method, + 'requestHeaders' => $headersFiltered, + 'errors' => '', + 'logs' => '', + 'duration' => 0.0, + 'search' => implode(' ', [$functionId, $executionId]), ]); - $headers = [ - 'Content-Type: application/json', - 'Content-Length: ' . \strlen($body), - 'X-Appwrite-Project: ' . $projectId - ]; + $queueForEvents + ->setParam('functionId', $function->getId()) + ->setParam('executionId', $execution->getId()) + ->setContext('function', $function); - $ch = \curl_init(); - \curl_setopt($ch, CURLOPT_URL, "http://localhost/v1/functions/{$functionId}/executions"); - \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); - \curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - // \curl_setopt($ch, CURLOPT_HEADER, true); - \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - \curl_setopt($ch, CURLOPT_TIMEOUT, 30); + $durationStart = \microtime(true); - $executionResponse = \curl_exec($ch); - $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = \curl_error($ch); - $errNo = \curl_errno($ch); + $vars = []; - \curl_close($ch); - - if ($errNo !== 0) { - throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Internal error: " . $error); + // V2 vars + if ($version === 'v2') { + $vars = \array_merge($vars, [ + 'APPWRITE_FUNCTION_TRIGGER' => $headers['x-appwrite-trigger'] ?? '', + 'APPWRITE_FUNCTION_DATA' => $body ?? '', + 'APPWRITE_FUNCTION_USER_ID' => $headers['x-appwrite-user-id'] ?? '', + 'APPWRITE_FUNCTION_JWT' => $headers['x-appwrite-user-jwt'] ?? '' + ]); } - if ($statusCode >= 400) { - $error = \json_decode($executionResponse, true)['message']; - throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Execution error: " . $error); + // Shared vars + foreach ($function->getAttribute('varsProject', []) as $var) { + $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); } - $execution = \json_decode($executionResponse, true); + // Function vars + foreach ($function->getAttribute('vars', []) as $var) { + $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); + } - $contentType = 'text/plain'; - foreach ($execution['responseHeaders'] as $header) { - if (\strtolower($header['name']) === 'content-type') { - $contentType = $header['value']; + // Appwrite vars + $vars = \array_merge($vars, [ + 'APPWRITE_FUNCTION_ID' => $functionId, + 'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name'), + 'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(), + 'APPWRITE_FUNCTION_PROJECT_ID' => $project->getId(), + 'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'] ?? '', + 'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'] ?? '', + ]); + + /** Execute function */ + $executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); + try { + $version = $function->getAttribute('version', 'v2'); + $command = $runtime['startCommand']; + $command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"'; + $executionResponse = $executor->createExecution( + projectId: $project->getId(), + deploymentId: $deployment->getId(), + body: \strlen($body) > 0 ? $body : null, + variables: $vars, + timeout: $function->getAttribute('timeout', 0), + image: $runtime['image'], + source: $build->getAttribute('path', ''), + entrypoint: $deployment->getAttribute('entrypoint', ''), + version: $version, + path: $path, + method: $method, + headers: $headers, + runtimeEntrypoint: $command, + requestTimeout: 30 + ); + + $headersFiltered = []; + foreach ($executionResponse['headers'] as $key => $value) { + if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) { + $headersFiltered[] = ['name' => $key, 'value' => $value]; + } } - $response->setHeader($header['name'], $header['value']); + /** Update execution status */ + $status = $executionResponse['statusCode'] >= 400 ? 'failed' : 'completed'; + $execution->setAttribute('status', $status); + $execution->setAttribute('responseStatusCode', $executionResponse['statusCode']); + $execution->setAttribute('responseHeaders', $headersFiltered); + $execution->setAttribute('logs', $executionResponse['logs']); + $execution->setAttribute('errors', $executionResponse['errors']); + $execution->setAttribute('duration', $executionResponse['duration']); + } catch (\Throwable $th) { + $durationEnd = \microtime(true); + + $execution + ->setAttribute('duration', $durationEnd - $durationStart) + ->setAttribute('status', 'failed') + ->setAttribute('responseStatusCode', 500) + ->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode()); + Console::error($th->getMessage()); + } finally { + $queueForUsage + ->addMetric(METRIC_EXECUTIONS, 1) + ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) + ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project + ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function + ; } + if ($function->getAttribute('logging')) { + /** @var Document $execution */ + $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); + } + + $execution->setAttribute('logs', ''); + $execution->setAttribute('errors', ''); + + $headers = []; + foreach (($executionResponse['headers'] ?? []) as $key => $value) { + $headers[] = ['name' => $key, 'value' => $value]; + } + + $execution->setAttribute('responseBody', $executionResponse['body'] ?? ''); + $execution->setAttribute('responseHeaders', $headers); + $body = $execution['responseBody'] ?? ''; $encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name')); @@ -179,6 +343,15 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques } } + $contentType = 'text/plain'; + foreach ($execution['responseHeaders'] as $header) { + if (\strtolower($header['name']) === 'content-type') { + $contentType = $header['value']; + } + + $response->setHeader($header['name'], $header['value']); + } + $response ->setContentType($contentType) ->setStatusCode($execution['responseStatusCode'] ?? 200) @@ -205,13 +378,16 @@ App::init() ->inject('console') ->inject('project') ->inject('dbForConsole') + ->inject('dbForProject') ->inject('user') ->inject('locale') ->inject('localeCodes') ->inject('clients') ->inject('servers') ->inject('queueForCertificates') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates) { + ->inject('queueForEvents') + ->inject('queueForUsage') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Database $dbForProject, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage) { /* * Appwrite Router */ @@ -220,7 +396,7 @@ App::init() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { + if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage)) { return; } } @@ -571,7 +747,10 @@ App::options() ->inject('request') ->inject('response') ->inject('dbForConsole') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole) { + ->inject('dbForProject') + ->inject('queueForEvents') + ->inject('queueForUsage') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, Database $dbForProject, Event $queueForEvents, Usage $queueForUsage) { /* * Appwrite Router */ @@ -579,7 +758,7 @@ App::options() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { + if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage)) { return; } } From e3c261b9e49076787b9b08112d6a51a3466a085a Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:24:55 +0000 Subject: [PATCH 15/51] fix: msg91 --- composer.json | 2 +- composer.lock | 48 ++++++++++----------- src/Appwrite/Platform/Workers/Messaging.php | 31 +++++++++---- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index 41baf29d9a..795fb4ad30 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,7 @@ "utopia-php/image": "0.5.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.3.*", - "utopia-php/messaging": "0.2.*", + "utopia-php/messaging": "0.3.*", "utopia-php/migration": "0.3.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.5.*", diff --git a/composer.lock b/composer.lock index ca39c7d084..d30ad5f44b 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": "fd03f97115d752d1a94b533ccf570109", + "content-hash": "a8c299cb631eb98bbcf0a58a815f74ac", "packages": [ { "name": "adhocore/jwt", @@ -1551,16 +1551,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.2.0", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "2d0f474a106bb1da285f85e105c29b46085d3a43" + "reference": "d488223876f88f97bb76fd6681fed0df80558f62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/2d0f474a106bb1da285f85e105c29b46085d3a43", - "reference": "2d0f474a106bb1da285f85e105c29b46085d3a43", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/d488223876f88f97bb76fd6681fed0df80558f62", + "reference": "d488223876f88f97bb76fd6681fed0df80558f62", "shasum": "" }, "require": { @@ -1593,9 +1593,9 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.2.0" + "source": "https://github.com/utopia-php/messaging/tree/0.3.0" }, - "time": "2023-09-14T20:48:42+00:00" + "time": "2023-11-14T21:02:37+00:00" }, { "name": "utopia-php/migration", @@ -2417,16 +2417,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.36.2", + "version": "0.36.4", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "0aa67479d75f0e0cb7b60454031534d7f0abaece" + "reference": "8d932098009d62d37dda73cfe4ebc11f83e21405" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0aa67479d75f0e0cb7b60454031534d7f0abaece", - "reference": "0aa67479d75f0e0cb7b60454031534d7f0abaece", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/8d932098009d62d37dda73cfe4ebc11f83e21405", + "reference": "8d932098009d62d37dda73cfe4ebc11f83e21405", "shasum": "" }, "require": { @@ -2462,9 +2462,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.36.2" + "source": "https://github.com/appwrite/sdk-generator/tree/0.36.4" }, - "time": "2024-01-19T01:04:35+00:00" + "time": "2024-02-20T16:36:15+00:00" }, { "name": "doctrine/deprecations", @@ -3047,16 +3047,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.8.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc" + "reference": "bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fad452781b3d774e3337b0c0b245dd8e5a4455fc", - "reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353", + "reference": "bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353", "shasum": "" }, "require": { @@ -3099,9 +3099,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.1" }, - "time": "2024-01-11T11:49:22+00:00" + "time": "2024-01-18T19:15:27+00:00" }, { "name": "phpspec/prophecy", @@ -4657,16 +4657,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.8.1", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7" + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", "shasum": "" }, "require": { @@ -4733,7 +4733,7 @@ "type": "open_collective" } ], - "time": "2024-01-11T20:47:48+00:00" + "time": "2024-02-16T15:06:51+00:00" }, { "name": "swoole/ide-helper", diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 1f3e29c8d5..7414148981 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -88,14 +88,29 @@ class Messaging extends Action return; } - $sms = match ($this->dsn->getHost()) { - 'mock' => new Mock($this->user, $this->secret), // used for tests - 'twilio' => new Twilio($this->user, $this->secret), - 'text-magic' => new TextMagic($this->user, $this->secret), - 'telesign' => new Telesign($this->user, $this->secret), - 'msg91' => new Msg91($this->user, $this->secret), - 'vonage' => new Vonage($this->user, $this->secret), - default => null + + switch ($this->dsn->getHost()) { + case 'mock': + $sms = new Mock($this->user, $this->secret); // used for tests + break; + case 'twilio': + $sms = new Twilio($this->user, $this->secret); + break; + case 'text-magic': + $sms = new TextMagic($this->user, $this->secret); + break; + case 'telesign': + $sms = new Telesign($this->user, $this->secret); + break; + case 'msg91': + $sms = new Msg91($this->user, $this->secret); + $sms->setTemplate($this->dsn->getParam('template')); + break; + case 'vonage': + $sms = new Vonage($this->user, $this->secret); + break; + default: + $sms = null; }; if (empty(App::getEnv('_APP_SMS_PROVIDER'))) { From b2e1c162d25addd2bd7b3a4b97e5b96877fb6471 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:27:37 +0000 Subject: [PATCH 16/51] chore: fmt --- src/Appwrite/Platform/Workers/Messaging.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 7414148981..89d028b1a6 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -88,14 +88,14 @@ class Messaging extends Action return; } - + switch ($this->dsn->getHost()) { case 'mock': $sms = new Mock($this->user, $this->secret); // used for tests - break; + break; case 'twilio': $sms = new Twilio($this->user, $this->secret); - break; + break; case 'text-magic': $sms = new TextMagic($this->user, $this->secret); break; From 6567cff5dc2550ab279c8511219a9740cd3eb13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 21 Feb 2024 17:03:48 +0000 Subject: [PATCH 17/51] Fix missing todo --- app/controllers/general.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index e54d6c21e9..4486aa6d67 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -9,8 +9,6 @@ use Utopia\Logger\Logger; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Swoole\Http\Request as SwooleRequest; -use Utopia\Cache\Cache; -use Utopia\Pools\Group; use Appwrite\Utopia\Request; use MaxMind\Db\Reader; use Appwrite\Utopia\Response; @@ -50,11 +48,7 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); - -->inject('geodb') -Reader $geodb - -function router(App $utopia, Database $dbForConsole, Database $dbForProject, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage) +function router(App $utopia, Database $dbForConsole, Database $dbForProject, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -387,7 +381,8 @@ App::init() ->inject('queueForCertificates') ->inject('queueForEvents') ->inject('queueForUsage') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Database $dbForProject, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage) { + ->inject('geodb') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Database $dbForProject, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -396,7 +391,7 @@ App::init() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage)) { + if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } @@ -750,7 +745,8 @@ App::options() ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForUsage') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, Database $dbForProject, Event $queueForEvents, Usage $queueForUsage) { + ->inject('geodb') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, Database $dbForProject, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -758,7 +754,7 @@ App::options() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage)) { + if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } From b03783c588f042805800886ad524962f265b0c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 21 Feb 2024 18:14:24 +0100 Subject: [PATCH 18/51] Fix bigs until works --- app/controllers/general.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 4486aa6d67..d9f6e5f280 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -48,7 +48,7 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, Database $dbForProject, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) +function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -126,6 +126,10 @@ function router(App $utopia, Database $dbForConsole, Database $dbForProject, Swo $requestHeaders = $request->getHeaders(); + $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); + + $dbForProject = $getProjectDB($project); + $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty() || !$function->getAttribute('enabled')) { @@ -372,7 +376,7 @@ App::init() ->inject('console') ->inject('project') ->inject('dbForConsole') - ->inject('dbForProject') + ->inject('getProjectDB') ->inject('user') ->inject('locale') ->inject('localeCodes') @@ -382,7 +386,7 @@ App::init() ->inject('queueForEvents') ->inject('queueForUsage') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Database $dbForProject, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -391,7 +395,7 @@ App::init() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } @@ -742,11 +746,11 @@ App::options() ->inject('request') ->inject('response') ->inject('dbForConsole') - ->inject('dbForProject') + ->inject('getProjectDB') ->inject('queueForEvents') ->inject('queueForUsage') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, Database $dbForProject, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -754,7 +758,7 @@ App::options() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $dbForProject, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } From a8098831a366532b61eef591602555774b6a30ef Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 22 Feb 2024 12:21:48 +0530 Subject: [PATCH 19/51] Revert "usage/usage-dump queue health endpoints" --- .env | 2 +- app/config/collections.php | 28 +--- app/controllers/api/account.php | 2 +- app/controllers/api/avatars.php | 2 +- app/controllers/api/databases.php | 12 +- app/controllers/api/functions.php | 8 +- app/controllers/api/health.php | 55 -------- app/controllers/api/project.php | 8 +- app/controllers/api/storage.php | 9 +- app/controllers/api/users.php | 9 +- app/controllers/shared/api.php | 35 +++-- app/init.php | 2 +- docker-compose.yml | 30 +++-- .../references/health/get-queue-usage-dump.md | 1 - docs/references/health/get-queue-usage.md | 1 - src/Appwrite/Event/Delete.php | 15 --- src/Appwrite/Platform/Tasks/CalcTierStats.php | 2 +- .../Platform/Tasks/CreateInfMetric.php | 6 +- src/Appwrite/Platform/Workers/Deletes.php | 122 ++++++++++++++---- src/Appwrite/Platform/Workers/Hamster.php | 2 +- src/Appwrite/Platform/Workers/Usage.php | 24 ++-- src/Appwrite/Platform/Workers/UsageDump.php | 6 +- .../Specification/Format/OpenAPI3.php | 6 +- .../Specification/Format/Swagger2.php | 6 +- .../Health/HealthCustomServerTest.php | 48 ------- 25 files changed, 188 insertions(+), 253 deletions(-) delete mode 100644 docs/references/health/get-queue-usage-dump.md delete mode 100644 docs/references/health/get-queue-usage.md diff --git a/.env b/.env index 2373b618c2..b915f91516 100644 --- a/.env +++ b/.env @@ -78,7 +78,7 @@ _APP_MAINTENANCE_RETENTION_CACHE=2592000 _APP_MAINTENANCE_RETENTION_EXECUTION=1209600 _APP_MAINTENANCE_RETENTION_ABUSE=86400 _APP_MAINTENANCE_RETENTION_AUDIT=1209600 -_APP_USAGE_AGGREGATION_INTERVAL=30 +_APP_USAGE_AGGREGATION_INTERVAL=20 _APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000 _APP_MAINTENANCE_RETENTION_SCHEDULES=86400 _APP_USAGE_STATS=enabled diff --git a/app/config/collections.php b/app/config/collections.php index 3bc58eff56..e2f3c11be7 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -34,28 +34,6 @@ $commonCollections = [ 'array' => false, 'filters' => [], ], - [ - '$id' => 'resourceType', - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 255, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('mimeType'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 255, // https://tools.ietf.org/html/rfc4288#section-4.2 - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ '$id' => 'accessedAt', 'type' => Database::VAR_DATETIME, @@ -1349,10 +1327,10 @@ $commonCollections = [ ] ], - 'stats' => [ + 'stats_v2' => [ '$collection' => ID::custom(Database::METADATA), - '$id' => ID::custom('stats'), - 'name' => 'stats', + '$id' => ID::custom('stats_v2'), + 'name' => 'stats_v2', 'attributes' => [ [ '$id' => ID::custom('metric'), diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 17b2984471..68d2a544d8 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1791,7 +1791,7 @@ App::get('/v1/account/logs') } $response->dynamic(new Document([ - 'total' => $audit->countLogsByUser($user->getInternalId()), + 'total' => $audit->countLogsByUser($user->getId()), 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 5f2ea4c2da..e0d967eb00 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -76,7 +76,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro } if (empty($gitHubSession)) { - throw new Exception(Exception::USER_SESSION_NOT_FOUND, 'GitHub session not found.'); + throw new Exception(Exception::GENERAL_UNKNOWN, 'GitHub session not found.'); } $provider = $gitHubSession->getAttribute('provider', ''); diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 5fdb2edb2f..8684a7fae8 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -3563,7 +3563,7 @@ App::get('/v1/databases/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3571,7 +3571,7 @@ App::get('/v1/databases/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -3647,7 +3647,7 @@ App::get('/v1/databases/:databaseId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3655,7 +3655,7 @@ App::get('/v1/databases/:databaseId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -3733,7 +3733,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3741,7 +3741,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 45df54b709..d3913d180d 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -484,7 +484,7 @@ App::get('/v1/functions/:functionId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -492,7 +492,7 @@ App::get('/v1/functions/:functionId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -576,7 +576,7 @@ App::get('/v1/functions/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -584,7 +584,7 @@ App::get('/v1/functions/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index f7fea04fee..c007d629b6 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -659,60 +659,6 @@ App::get('/v1/health/queue/functions') $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); }, ['response']); -App::get('/v1/health/queue/usage') - ->desc('Get usage queue') - ->groups(['api', 'health']) - ->label('scope', 'health.read') - ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) - ->label('sdk.namespace', 'health') - ->label('sdk.method', 'getQueueUsage') - ->label('sdk.description', '/docs/references/health/get-queue-usage.md') - ->label('sdk.response.code', Response::STATUS_CODE_OK) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE) - ->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true) - ->inject('queue') - ->inject('response') - ->action(function (int|string $threshold, Connection $queue, Response $response) { - $threshold = \intval($threshold); - - $client = new Client(Event::USAGE_QUEUE_NAME, $queue); - $size = $client->getQueueSize(); - - if ($size >= $threshold) { - throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}."); - } - - $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); - }); - -App::get('/v1/health/queue/usage-dump') - ->desc('Get usage dump queue') - ->groups(['api', 'health']) - ->label('scope', 'health.read') - ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) - ->label('sdk.namespace', 'health') - ->label('sdk.method', 'getQueueUsage') - ->label('sdk.description', '/docs/references/health/get-queue-usage-dump.md') - ->label('sdk.response.code', Response::STATUS_CODE_OK) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE) - ->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true) - ->inject('queue') - ->inject('response') - ->action(function (int|string $threshold, Connection $queue, Response $response) { - $threshold = \intval($threshold); - - $client = new Client(Event::USAGE_DUMP_QUEUE_NAME, $queue); - $size = $client->getQueueSize(); - - if ($size >= $threshold) { - throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}."); - } - - $response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE); - }); - App::get('/v1/health/storage/local') ->desc('Get local storage') ->groups(['api', 'health']) @@ -850,7 +796,6 @@ App::get('/v1/health/queue/failed/:name') Event::MAILS_QUEUE_NAME, Event::FUNCTIONS_QUEUE_NAME, Event::USAGE_QUEUE_NAME, - Event::USAGE_DUMP_QUEUE_NAME, Event::WEBHOOK_CLASS_NAME, Event::CERTIFICATES_QUEUE_NAME, Event::BUILDS_QUEUE_NAME, diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index a067c45588..47b94d3093 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -73,7 +73,7 @@ App::get('/v1/project/usage') Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, &$total, &$stats) { foreach ($metrics['total'] as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -81,7 +81,7 @@ App::get('/v1/project/usage') } foreach ($metrics['period'] as $metric) { - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::greaterThanEqual('time', $firstDay), @@ -116,7 +116,7 @@ App::get('/v1/project/usage') $id = $function->getId(); $name = $function->getAttribute('name'); $metric = str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS); - $value = $dbForProject->findOne('stats', [ + $value = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -132,7 +132,7 @@ App::get('/v1/project/usage') $id = $bucket->getId(); $name = $bucket->getAttribute('name'); $metric = str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE); - $value = $dbForProject->findOne('stats', [ + $value = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index e4798fb51e..efe2515468 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1467,7 +1467,6 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') if ($deviceDeleted) { $queueForDeletes ->setType(DELETE_TYPE_CACHE_BY_RESOURCE) - ->setResourceType('bucket/' . $bucket->getId()) ->setResource('file/' . $fileId) ; @@ -1525,7 +1524,7 @@ App::get('/v1/storage/usage') $total = []; Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1533,7 +1532,7 @@ App::get('/v1/storage/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -1610,7 +1609,7 @@ App::get('/v1/storage/:bucketId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1618,7 +1617,7 @@ App::get('/v1/storage/:bucketId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index bbeef96f14..5ce2263f47 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -615,9 +615,6 @@ App::get('/v1/users/:userId/logs') $output[$i] = new Document([ 'event' => $log['event'], - 'userId' => ID::custom($log['data']['userId']), - 'userEmail' => $log['data']['userEmail'] ?? null, - 'userName' => $log['data']['userName'] ?? null, 'ip' => $log['ip'], 'time' => $log['time'], 'osCode' => $os['osCode'], @@ -646,7 +643,7 @@ App::get('/v1/users/:userId/logs') } $response->dynamic(new Document([ - 'total' => $audit->countLogsByUser($user->getInternalId()), + 'total' => $audit->countLogsByUser($user->getId()), 'logs' => $output, ]), Response::MODEL_LOG_LIST); }); @@ -1266,7 +1263,7 @@ App::get('/v1/users/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $count => $metric) { - $result = $dbForProject->findOne('stats', [ + $result = $dbForProject->findOne('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1274,7 +1271,7 @@ App::get('/v1/users/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats', [ + $results = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 0423741e6d..df6ec002cb 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -252,22 +252,24 @@ App::init() ; $useCache = $route->getLabel('cache', false); + if ($useCache) { $key = md5($request->getURI() . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER); - $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $cache = new Cache( new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) ); $timestamp = 60 * 60 * 24 * 30; $data = $cache->load($key, $timestamp); - if (!empty($data) && !$cacheLog->isEmpty()) { - $parts = explode('/', $cacheLog->getAttribute('resourceType')); + if (!empty($data)) { + $data = json_decode($data, true); + $parts = explode('/', $data['resourceType']); $type = $parts[0] ?? null; if ($type === 'bucket') { $bucketId = $parts[1] ?? null; - $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); + + $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -279,12 +281,11 @@ App::init() $fileSecurity = $bucket->getAttribute('fileSecurity', false); $validator = new Authorization(Database::PERMISSION_READ); $valid = $validator->isValid($bucket->getRead()); - if (!$fileSecurity && !$valid) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $parts = explode('/', $cacheLog->getAttribute('resource')); + $parts = explode('/', $data['resource']); $fileId = $parts[1] ?? null; if ($fileSecurity && !$valid) { @@ -301,8 +302,8 @@ App::init() $response ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $timestamp) . ' GMT') ->addHeader('X-Appwrite-Cache', 'hit') - ->setContentType($cacheLog->getAttribute('mimeType')) - ->send($data) + ->setContentType($data['contentType']) + ->send(base64_decode($data['payload'])) ; } else { $response->addHeader('X-Appwrite-Cache', 'miss'); @@ -533,6 +534,7 @@ App::shutdown() if ($useCache) { $resource = $resourceType = null; $data = $response->getPayload(); + if (!empty($data['payload'])) { $pattern = $route->getLabel('cache.resource', null); if (!empty($pattern)) { @@ -544,17 +546,22 @@ App::shutdown() $resourceType = $parseLabel($pattern, $responsePayload, $requestParams, $user); } - $key = md5($request->getURI() . '*' . implode('*', $request->getParams())) . '*' . APP_CACHE_BUSTER; - $signature = md5($data['payload']); - $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); + $key = md5($request->getURI() . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER); + $data = json_encode([ + 'resourceType' => $resourceType, + 'resource' => $resource, + 'contentType' => $response->getContentType(), + 'payload' => base64_encode($data['payload']), + ]) ; + + $signature = md5($data); + $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $accessedAt = $cacheLog->getAttribute('accessedAt', ''); $now = DateTime::now(); if ($cacheLog->isEmpty()) { Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([ '$id' => $key, 'resource' => $resource, - 'resourceType' => $resourceType, - 'mimeType' => $response->getContentType(), 'accessedAt' => $now, 'signature' => $signature, ]))); @@ -567,7 +574,7 @@ App::shutdown() $cache = new Cache( new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) ); - $cache->save($key, $data['payload']); + $cache->save($key, $data); } } } diff --git a/app/init.php b/app/init.php index f27da88d24..80c3670eec 100644 --- a/app/init.php +++ b/app/init.php @@ -112,7 +112,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours -const APP_CACHE_BUSTER = 330; +const APP_CACHE_BUSTER = 329; const APP_VERSION_STABLE = '1.4.13'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; diff --git a/docker-compose.yml b/docker-compose.yml index ed912dc8e2..de71e3937a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -928,7 +928,6 @@ services: # - appwrite # volumes: # - appwrite-uploads:/storage/uploads - # Dev Tools Start ------------------------------------------------------------------------------------------ # # The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack @@ -937,9 +936,8 @@ services: # # MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI. # RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks - # Redis Insight - A nice UI for exploring Redis data - # Adminer - A nice UI for exploring MariaDB data - # GraphQl Explorer - A nice UI for exploring GraphQL API + # RedisCommander - A nice UI for exploring Redis data + # Webgrind - A nice UI for exploring and debugging code-level stuff maildev: # used mainly for dev tests image: appwrite/mailcatcher:1.0.0 @@ -969,15 +967,21 @@ services: networks: - appwrite - redis-insight: - image: redis/redisinsight:latest - restart: unless-stopped - networks: - - appwrite - environment: - - REDIS_HOSTS=redis - ports: - - "8081:5540" + # redis-commander: + # image: rediscommander/redis-commander:latest + # restart: unless-stopped + # networks: + # - appwrite + # environment: + # - REDIS_HOSTS=redis + # ports: + # - "8081:8081" + # webgrind: + # image: 'jokkedk/webgrind:latest' + # volumes: + # - './debug:/tmp' + # ports: + # - '3001:80' graphql-explorer: container_name: appwrite-graphql-explorer diff --git a/docs/references/health/get-queue-usage-dump.md b/docs/references/health/get-queue-usage-dump.md deleted file mode 100644 index 3c95da1b8a..0000000000 --- a/docs/references/health/get-queue-usage-dump.md +++ /dev/null @@ -1 +0,0 @@ -Get the number of projects containing metrics that are waiting to be processed in the Appwrite internal queue server. \ No newline at end of file diff --git a/docs/references/health/get-queue-usage.md b/docs/references/health/get-queue-usage.md deleted file mode 100644 index 8e5b64e642..0000000000 --- a/docs/references/health/get-queue-usage.md +++ /dev/null @@ -1 +0,0 @@ -Get the number of metrics that are waiting to be processed in the Appwrite internal queue server. \ No newline at end of file diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index 064fbcefa9..57300feb72 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -10,7 +10,6 @@ class Delete extends Event { protected string $type = ''; protected ?Document $document = null; - protected ?string $resourceType = null; protected ?string $resource = null; protected ?string $datetime = null; protected ?string $hourlyUsageRetentionDatetime = null; @@ -108,19 +107,6 @@ class Delete extends Event return $this; } - /** - * Sets the resource type for the delete event. - * - * @param string $resourceType - * @return self - */ - public function setResourceType(string $resourceType): self - { - $this->resourceType = $resourceType; - - return $this; - } - /** * Returns the set document for the delete event. * @@ -147,7 +133,6 @@ class Delete extends Event 'type' => $this->type, 'document' => $this->document, 'resource' => $this->resource, - 'resourceType' => $this->resourceType, 'datetime' => $this->datetime, 'hourlyUsageRetentionDatetime' => $this->hourlyUsageRetentionDatetime ]); diff --git a/src/Appwrite/Platform/Tasks/CalcTierStats.php b/src/Appwrite/Platform/Tasks/CalcTierStats.php index 05a28b418a..2c904973a9 100644 --- a/src/Appwrite/Platform/Tasks/CalcTierStats.php +++ b/src/Appwrite/Platform/Tasks/CalcTierStats.php @@ -270,7 +270,7 @@ class CalcTierStats extends Action $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForProject->find('stats', [ + $requestDocs = $dbForProject->find('stats_v2', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/src/Appwrite/Platform/Tasks/CreateInfMetric.php b/src/Appwrite/Platform/Tasks/CreateInfMetric.php index 4b3f0e89fb..49b852ff6f 100644 --- a/src/Appwrite/Platform/Tasks/CreateInfMetric.php +++ b/src/Appwrite/Platform/Tasks/CreateInfMetric.php @@ -167,8 +167,8 @@ class CreateInfMetric extends Action try { $id = \md5("_inf_{$metric}"); - $dbForProject->deleteDocument('stats', $id); - $dbForProject->createDocument('stats', new Document([ + $dbForProject->deleteDocument('stats_v2', $id); + $dbForProject->createDocument('stats_v2', new Document([ '$id' => $id, 'metric' => $metric, 'period' => 'inf', @@ -190,7 +190,7 @@ class CreateInfMetric extends Action protected function getFromMetric(database $dbForProject, string $metric): int|float { - return $dbForProject->sum('stats', 'value', [ + return $dbForProject->sum('stats_v2', 'value', [ Query::equal('metric', [ $metric, ]), diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 37975979ce..96cb2d80cf 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -68,13 +68,18 @@ class Deletes extends Action $datetime = $payload['datetime'] ?? null; $hourlyUsageRetentionDatetime = $payload['hourlyUsageRetentionDatetime'] ?? null; $resource = $payload['resource'] ?? null; - $resourceType = $payload['resourceType'] ?? null; $document = new Document($payload['document'] ?? []); $project = new Document($payload['project'] ?? []); switch (strval($type)) { case DELETE_TYPE_DOCUMENT: switch ($document->getCollection()) { + case DELETE_TYPE_DATABASES: + $this->deleteDatabase($getProjectDB, $document, $project); + break; + case DELETE_TYPE_COLLECTIONS: + $this->deleteCollection($getProjectDB, $document, $project); + break; case DELETE_TYPE_PROJECTS: $this->deleteProject($dbForConsole, $getProjectDB, $getFilesDevice, $getFunctionsDevice, $getBuildsDevice, $getCacheDevice, $document); break; @@ -103,6 +108,10 @@ class Deletes extends Action $this->deleteRule($dbForConsole, $document); break; default: + if (\str_starts_with($document->getCollection(), 'database_')) { + $this->deleteCollection($getProjectDB, $document, $project); + break; + } Console::error('No lazy delete operation available for document of type: ' . $document->getCollection()); break; } @@ -136,7 +145,7 @@ class Deletes extends Action $this->deleteUsageStats($project, $getProjectDB, $hourlyUsageRetentionDatetime); break; case DELETE_TYPE_CACHE_BY_RESOURCE: - $this->deleteCacheByResource($project, $getProjectDB, $resource, $resourceType); + $this->deleteCacheByResource($project, $getProjectDB, $resource); break; case DELETE_TYPE_CACHE_BY_TIMESTAMP: $this->deleteCacheByDate($project, $getProjectDB, $datetime); @@ -194,37 +203,32 @@ class Deletes extends Action * @param string $resource * @return void * @throws Authorization - * @param string|null $resourceType - * @throws Exception */ - private function deleteCacheByResource(Document $project, callable $getProjectDB, string $resource, string $resourceType = null): void + private function deleteCacheByResource(Document $project, callable $getProjectDB, string $resource): void { $projectId = $project->getId(); $dbForProject = $getProjectDB($project); + $document = $dbForProject->findOne('cache', [Query::equal('resource', [$resource])]); - $cache = new Cache( - new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) - ); + if ($document) { + $cache = new Cache( + new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) + ); - $query[] = Query::equal('resource', [$resource]); - if (!empty($resourceType)) { - $query[] = Query::equal('resourceType', [$resourceType]); - } + $this->deleteById( + $document, + $dbForProject, + function ($document) use ($cache, $projectId) { + $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); - $this->deleteByGroup( - 'cache', - $query, - $dbForProject, - function (Document $document) use ($cache, $projectId) { - $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); - - if ($cache->purge($document->getId())) { - Console::success('Deleting cache file: ' . $path); - } else { - Console::error('Failed to delete cache file: ' . $path); + if ($cache->purge($document->getId())) { + Console::success('Deleting cache file: ' . $path); + } else { + Console::error('Failed to delete cache file: ' . $path); + } } - } - ); + ); + } } /** @@ -264,6 +268,72 @@ class Deletes extends Action ); } + /** + * @param callable $getProjectDB + * @param Document $document + * @param Document $project + * @return void + * @throws Exception + */ + private function deleteDatabase(callable $getProjectDB, Document $document, Document $project): void + { + $databaseId = $document->getId(); + $dbForProject = $getProjectDB($project); + + $this->deleteByGroup('database_' . $document->getInternalId(), [], $dbForProject, function ($document) use ($getProjectDB, $project) { + $this->deleteCollection($getProjectDB, $document, $project); + }); + + $dbForProject->deleteCollection('database_' . $document->getInternalId()); + $this->deleteAuditLogsByResource($getProjectDB, 'database/' . $databaseId, $project); + } + + /** + * @param callable $getProjectDB + * @param Document $document teams document + * @param Document $project + * @return void + * @throws Exception + */ + private function deleteCollection(callable $getProjectDB, Document $document, Document $project): void + { + $collectionId = $document->getId(); + $collectionInternalId = $document->getInternalId(); + $databaseId = $document->getAttribute('databaseId'); + $databaseInternalId = $document->getAttribute('databaseInternalId'); + + $dbForProject = $getProjectDB($project); + + $relationships = \array_filter( + $document->getAttribute('attributes'), + fn ($attribute) => $attribute['type'] === Database::VAR_RELATIONSHIP + ); + + foreach ($relationships as $relationship) { + if (!$relationship['twoWay']) { + continue; + } + $relatedCollection = $dbForProject->getDocument('database_' . $databaseInternalId, $relationship['relatedCollection']); + $dbForProject->deleteDocument('attributes', $databaseInternalId . '_' . $relatedCollection->getInternalId() . '_' . $relationship['twoWayKey']); + $dbForProject->deleteCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId()); + $dbForProject->deleteCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId()); + } + + $dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $document->getInternalId()); + + $this->deleteByGroup('attributes', [ + Query::equal('databaseInternalId', [$databaseInternalId]), + Query::equal('collectionInternalId', [$collectionInternalId]) + ], $dbForProject); + + $this->deleteByGroup('indexes', [ + Query::equal('databaseInternalId', [$databaseInternalId]), + Query::equal('collectionInternalId', [$collectionInternalId]) + ], $dbForProject); + + $this->deleteAuditLogsByResource($getProjectDB, 'database/' . $databaseId . '/collection/' . $collectionId, $project); + } + /** * @param Database $dbForConsole * @param callable $getProjectDB @@ -275,7 +345,7 @@ class Deletes extends Action { $dbForProject = $getProjectDB($project); // Delete Usage stats - $this->deleteByGroup('stats', [ + $this->deleteByGroup('stats_v2', [ Query::lessThan('time', $hourlyUsageRetentionDatetime), Query::equal('period', ['1h']), ], $dbForProject); diff --git a/src/Appwrite/Platform/Workers/Hamster.php b/src/Appwrite/Platform/Workers/Hamster.php index 6239f842e0..0fb705d0f7 100644 --- a/src/Appwrite/Platform/Workers/Hamster.php +++ b/src/Appwrite/Platform/Workers/Hamster.php @@ -286,7 +286,7 @@ class Hamster extends Action $limit = $periodValue['limit']; $period = $periodValue['period']; - $requestDocs = $dbForProject->find('stats', [ + $requestDocs = $dbForProject->find('stats_v2', [ Query::equal('period', [$period]), Query::equal('metric', [$metric]), Query::limit($limit), diff --git a/src/Appwrite/Platform/Workers/Usage.php b/src/Appwrite/Platform/Workers/Usage.php index 718dca8514..35c0e02cef 100644 --- a/src/Appwrite/Platform/Workers/Usage.php +++ b/src/Appwrite/Platform/Workers/Usage.php @@ -130,8 +130,8 @@ class Usage extends Action } break; case $document->getCollection() === 'databases': // databases - $collections = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_COLLECTIONS))); - $documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS))); + $collections = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_COLLECTIONS))); + $documents = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS))); if (!empty($collections['value'])) { $metrics[] = [ 'key' => METRIC_COLLECTIONS, @@ -149,7 +149,7 @@ class Usage extends Action case str_starts_with($document->getCollection(), 'database_') && !str_contains($document->getCollection(), 'collection'): //collections $parts = explode('_', $document->getCollection()); $databaseInternalId = $parts[1] ?? 0; - $documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $document->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS))); + $documents = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $document->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS))); if (!empty($documents['value'])) { $metrics[] = [ @@ -164,8 +164,8 @@ class Usage extends Action break; case $document->getCollection() === 'buckets': - $files = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES))); - $storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE))); + $files = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES))); + $storage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE))); if (!empty($files['value'])) { $metrics[] = [ @@ -183,13 +183,13 @@ class Usage extends Action break; case $document->getCollection() === 'functions': - $deployments = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS))); - $deploymentsStorage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE))); - $builds = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS))); - $buildsStorage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE))); - $buildsCompute = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE))); - $executions = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS))); - $executionsCompute = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE))); + $deployments = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS))); + $deploymentsStorage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE))); + $builds = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS))); + $buildsStorage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE))); + $buildsCompute = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE))); + $executions = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS))); + $executionsCompute = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE))); if (!empty($deployments['value'])) { $metrics[] = [ diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index 1d296a929e..5a4324fd3e 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -78,7 +78,7 @@ class UsageDump extends Action $id = \md5("{$time}_{$period}_{$key}"); try { - $dbForProject->createDocument('stats', new Document([ + $dbForProject->createDocument('stats_v2', new Document([ '$id' => $id, 'period' => $period, 'time' => $time, @@ -89,14 +89,14 @@ class UsageDump extends Action } catch (Duplicate $th) { if ($value < 0) { $dbForProject->decreaseDocumentAttribute( - 'stats', + 'stats_v2', $id, 'value', abs($value) ); } else { $dbForProject->increaseDocumentAttribute( - 'stats', + 'stats_v2', $id, 'value', $value diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index ce86235634..863966eedd 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -295,7 +295,7 @@ class OpenAPI3 extends Format switch ((!empty($validator)) ? \get_class($validator) : '') { case 'Utopia\Validator\Text': $node['schema']['type'] = $validator->getType(); - $node['schema']['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['schema']['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Utopia\Validator\Boolean': $node['schema']['type'] = $validator->getType(); @@ -303,14 +303,14 @@ class OpenAPI3 extends Format break; case 'Utopia\Database\Validator\UID': $node['schema']['type'] = $validator->getType(); - $node['schema']['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['schema']['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Appwrite\Utopia\Database\Validator\CustomId': if ($route->getLabel('sdk.methodType', '') === 'upload') { $node['schema']['x-upload-id'] = true; } $node['schema']['type'] = $validator->getType(); - $node['schema']['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['schema']['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Utopia\Database\Validator\DatetimeValidator': $node['schema']['type'] = $validator->getType(); diff --git a/src/Appwrite/Specification/Format/Swagger2.php b/src/Appwrite/Specification/Format/Swagger2.php index a458c30aa6..c6ae7a7ff1 100644 --- a/src/Appwrite/Specification/Format/Swagger2.php +++ b/src/Appwrite/Specification/Format/Swagger2.php @@ -297,7 +297,7 @@ class Swagger2 extends Format switch ((!empty($validator)) ? \get_class($validator) : '') { case 'Utopia\Validator\Text': $node['type'] = $validator->getType(); - $node['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Utopia\Validator\Boolean': $node['type'] = $validator->getType(); @@ -308,11 +308,11 @@ class Swagger2 extends Format $node['x-upload-id'] = true; } $node['type'] = $validator->getType(); - $node['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Utopia\Database\Validator\UID': $node['type'] = $validator->getType(); - $node['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>'; + $node['x-example'] = '[' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . ']'; break; case 'Utopia\Database\Validator\DatetimeValidator': $node['type'] = $validator->getType(); diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index 091b3bb781..dde89a6a71 100644 --- a/tests/e2e/Services/Health/HealthCustomServerTest.php +++ b/tests/e2e/Services/Health/HealthCustomServerTest.php @@ -512,52 +512,4 @@ class HealthCustomServerTest extends Scope return []; } - - public function testUsageSuccess() - { - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertIsInt($response['body']['size']); - $this->assertLessThan(100, $response['body']['size']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage?threshold=0', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - $this->assertEquals(503, $response['headers']['status-code']); - } - - public function testUsageDumpSuccess() - { - /** - * Test for SUCCESS - */ - $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage-dump', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertIsInt($response['body']['size']); - $this->assertLessThan(100, $response['body']['size']); - - /** - * Test for FAILURE - */ - $response = $this->client->call(Client::METHOD_GET, '/health/queue/usage-dump?threshold=0', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - $this->assertEquals(503, $response['headers']['status-code']); - } } From d2787c85553154597d6955d064deb85c316a2b44 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 22 Feb 2024 12:26:01 +0530 Subject: [PATCH 20/51] Revert "Fix: Router CURL" --- app/controllers/general.php | 275 +++++++----------------------------- 1 file changed, 48 insertions(+), 227 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index d9f6e5f280..bfec8b46be 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -9,8 +9,9 @@ use Utopia\Logger\Logger; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Swoole\Http\Request as SwooleRequest; +use Utopia\Cache\Cache; +use Utopia\Pools\Group; use Appwrite\Utopia\Request; -use MaxMind\Db\Reader; use Appwrite\Utopia\Response; use Appwrite\Utopia\View; use Appwrite\Extend\Exception as AppwriteException; @@ -18,9 +19,6 @@ use Utopia\Config\Config; use Utopia\Domains\Domain; use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; -use Appwrite\Event\Event; -use Appwrite\Event\Usage; -use Appwrite\ID; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; @@ -40,7 +38,6 @@ use Appwrite\Utopia\Request\Filters\V13 as RequestV13; use Appwrite\Utopia\Request\Filters\V14 as RequestV14; use Appwrite\Utopia\Request\Filters\V15 as RequestV15; use Appwrite\Utopia\Request\Filters\V16 as RequestV16; -use Executor\Executor; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -48,7 +45,7 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) +function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleRequest, Request $request, Response $response) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -120,226 +117,49 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $path .= '?' . $query; } - - $body = $swooleRequest->getContent() ?? ''; - $method = $swooleRequest->server['request_method']; - $requestHeaders = $request->getHeaders(); - $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); - - $dbForProject = $getProjectDB($project); - - $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); - - if ($function->isEmpty() || !$function->getAttribute('enabled')) { - throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); - } - - $version = $function->getAttribute('version', 'v2'); - $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); - - $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; - - if (\is_null($runtime)) { - throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); - } - - $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); - - if ($deployment->getAttribute('resourceId') !== $function->getId()) { - throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); - } - - if ($deployment->isEmpty()) { - throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); - } - - /** Check if build has completed */ - $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); - if ($build->isEmpty()) { - throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND); - } - - if ($build->getAttribute('status') !== 'ready') { - throw new AppwriteException(AppwriteException::BUILD_NOT_READY); - } - - $permissions = $function->getAttribute('execute'); - - if (!(\in_array('any', $permissions)) && (\in_array('guests', $permissions))) { - throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"'); - } - - $headers = \array_merge([], $requestHeaders); - $headers['x-appwrite-trigger'] = 'http'; - $headers['x-appwrite-user-id'] = ''; - $headers['x-appwrite-user-jwt'] = ''; - $headers['x-appwrite-country-code'] = ''; - $headers['x-appwrite-continent-code'] = ''; - $headers['x-appwrite-continent-eu'] = 'false'; - - $ip = $headers['x-real-ip'] ?? ''; - if (!empty($ip)) { - $record = $geodb->get($ip); - - if ($record) { - $eu = Config::getParam('locale-eu'); - - $headers['x-appwrite-country-code'] = $record['country']['iso_code'] ?? ''; - $headers['x-appwrite-continent-code'] = $record['continent']['code'] ?? ''; - $headers['x-appwrite-continent-eu'] = (\in_array($record['country']['iso_code'], $eu)) ? 'true' : 'false'; - } - } - - $headersFiltered = []; - foreach ($headers as $key => $value) { - if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_REQUEST)) { - $headersFiltered[] = ['name' => $key, 'value' => $value]; - } - } - - $executionId = ID::unique(); - - $execution = new Document([ - '$id' => $executionId, - '$permissions' => [], - 'functionInternalId' => $function->getInternalId(), - 'functionId' => $function->getId(), - 'deploymentInternalId' => $deployment->getInternalId(), - 'deploymentId' => $deployment->getId(), - 'trigger' => 'http', // http / schedule / event - 'status' => 'processing', // waiting / processing / completed / failed - 'responseStatusCode' => 0, - 'responseHeaders' => [], - 'requestPath' => $path, - 'requestMethod' => $method, - 'requestHeaders' => $headersFiltered, - 'errors' => '', - 'logs' => '', - 'duration' => 0.0, - 'search' => implode(' ', [$functionId, $executionId]), + $body = \json_encode([ + 'async' => false, + 'body' => $swooleRequest->getContent() ?? '', + 'method' => $swooleRequest->server['request_method'], + 'path' => $path, + 'headers' => $requestHeaders ]); - $queueForEvents - ->setParam('functionId', $function->getId()) - ->setParam('executionId', $execution->getId()) - ->setContext('function', $function); + $headers = [ + 'Content-Type: application/json', + 'Content-Length: ' . \strlen($body), + 'X-Appwrite-Project: ' . $projectId + ]; - $durationStart = \microtime(true); + $ch = \curl_init(); + \curl_setopt($ch, CURLOPT_URL, "http://localhost/v1/functions/{$functionId}/executions"); + \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); + \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + \curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + // \curl_setopt($ch, CURLOPT_HEADER, true); + \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + \curl_setopt($ch, CURLOPT_TIMEOUT, 30); - $vars = []; + $executionResponse = \curl_exec($ch); + $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = \curl_error($ch); + $errNo = \curl_errno($ch); - // V2 vars - if ($version === 'v2') { - $vars = \array_merge($vars, [ - 'APPWRITE_FUNCTION_TRIGGER' => $headers['x-appwrite-trigger'] ?? '', - 'APPWRITE_FUNCTION_DATA' => $body ?? '', - 'APPWRITE_FUNCTION_USER_ID' => $headers['x-appwrite-user-id'] ?? '', - 'APPWRITE_FUNCTION_JWT' => $headers['x-appwrite-user-jwt'] ?? '' - ]); + \curl_close($ch); + + if ($errNo !== 0) { + throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Internal error: " . $error); } - // Shared vars - foreach ($function->getAttribute('varsProject', []) as $var) { - $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); + if ($statusCode >= 400) { + $error = \json_decode($executionResponse, true)['message']; + throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Execution error: " . $error); } - // Function vars - foreach ($function->getAttribute('vars', []) as $var) { - $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); - } - - // Appwrite vars - $vars = \array_merge($vars, [ - 'APPWRITE_FUNCTION_ID' => $functionId, - 'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name'), - 'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(), - 'APPWRITE_FUNCTION_PROJECT_ID' => $project->getId(), - 'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'] ?? '', - 'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'] ?? '', - ]); - - /** Execute function */ - $executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); - try { - $version = $function->getAttribute('version', 'v2'); - $command = $runtime['startCommand']; - $command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"'; - $executionResponse = $executor->createExecution( - projectId: $project->getId(), - deploymentId: $deployment->getId(), - body: \strlen($body) > 0 ? $body : null, - variables: $vars, - timeout: $function->getAttribute('timeout', 0), - image: $runtime['image'], - source: $build->getAttribute('path', ''), - entrypoint: $deployment->getAttribute('entrypoint', ''), - version: $version, - path: $path, - method: $method, - headers: $headers, - runtimeEntrypoint: $command, - requestTimeout: 30 - ); - - $headersFiltered = []; - foreach ($executionResponse['headers'] as $key => $value) { - if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) { - $headersFiltered[] = ['name' => $key, 'value' => $value]; - } - } - - /** Update execution status */ - $status = $executionResponse['statusCode'] >= 400 ? 'failed' : 'completed'; - $execution->setAttribute('status', $status); - $execution->setAttribute('responseStatusCode', $executionResponse['statusCode']); - $execution->setAttribute('responseHeaders', $headersFiltered); - $execution->setAttribute('logs', $executionResponse['logs']); - $execution->setAttribute('errors', $executionResponse['errors']); - $execution->setAttribute('duration', $executionResponse['duration']); - } catch (\Throwable $th) { - $durationEnd = \microtime(true); - - $execution - ->setAttribute('duration', $durationEnd - $durationStart) - ->setAttribute('status', 'failed') - ->setAttribute('responseStatusCode', 500) - ->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode()); - Console::error($th->getMessage()); - } finally { - $queueForUsage - ->addMetric(METRIC_EXECUTIONS, 1) - ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) - ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project - ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function - ; - } - - if ($function->getAttribute('logging')) { - /** @var Document $execution */ - $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); - } - - $execution->setAttribute('logs', ''); - $execution->setAttribute('errors', ''); - - $headers = []; - foreach (($executionResponse['headers'] ?? []) as $key => $value) { - $headers[] = ['name' => $key, 'value' => $value]; - } - - $execution->setAttribute('responseBody', $executionResponse['body'] ?? ''); - $execution->setAttribute('responseHeaders', $headers); - - $body = $execution['responseBody'] ?? ''; - - $encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name')); - if ($encodingKey !== false) { - if (($execution['responseHeaders'][$encodingKey]['value'] ?? '') === 'base64') { - $body = \base64_decode($body); - } - } + $execution = \json_decode($executionResponse, true); $contentType = 'text/plain'; foreach ($execution['responseHeaders'] as $header) { @@ -350,6 +170,15 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $response->setHeader($header['name'], $header['value']); } + $body = $execution['responseBody'] ?? ''; + + $encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name')); + if ($encodingKey !== false) { + if (($execution['responseHeaders'][$encodingKey]['value'] ?? '') === 'base64') { + $body = \base64_decode($body); + } + } + $response ->setContentType($contentType) ->setStatusCode($execution['responseStatusCode'] ?? 200) @@ -376,17 +205,13 @@ App::init() ->inject('console') ->inject('project') ->inject('dbForConsole') - ->inject('getProjectDB') ->inject('user') ->inject('locale') ->inject('localeCodes') ->inject('clients') ->inject('servers') ->inject('queueForCertificates') - ->inject('queueForEvents') - ->inject('queueForUsage') - ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates) { /* * Appwrite Router */ @@ -395,7 +220,7 @@ App::init() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { return; } } @@ -746,11 +571,7 @@ App::options() ->inject('request') ->inject('response') ->inject('dbForConsole') - ->inject('getProjectDB') - ->inject('queueForEvents') - ->inject('queueForUsage') - ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole) { /* * Appwrite Router */ @@ -758,7 +579,7 @@ App::options() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { + if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { return; } } From c04f54da647aead11c0d9adeea7c4077e5f78546 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Thu, 22 Feb 2024 15:10:18 +0530 Subject: [PATCH 21/51] Revert "Revert "Fix: Router CURL"" --- app/controllers/general.php | 267 ++++++++++++++++++++++++++++++------ 1 file changed, 223 insertions(+), 44 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index bfec8b46be..d9f6e5f280 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -9,9 +9,8 @@ use Utopia\Logger\Logger; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Swoole\Http\Request as SwooleRequest; -use Utopia\Cache\Cache; -use Utopia\Pools\Group; use Appwrite\Utopia\Request; +use MaxMind\Db\Reader; use Appwrite\Utopia\Response; use Appwrite\Utopia\View; use Appwrite\Extend\Exception as AppwriteException; @@ -19,6 +18,9 @@ use Utopia\Config\Config; use Utopia\Domains\Domain; use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; +use Appwrite\Event\Event; +use Appwrite\Event\Usage; +use Appwrite\ID; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; @@ -38,6 +40,7 @@ use Appwrite\Utopia\Request\Filters\V13 as RequestV13; use Appwrite\Utopia\Request\Filters\V14 as RequestV14; use Appwrite\Utopia\Request\Filters\V15 as RequestV15; use Appwrite\Utopia\Request\Filters\V16 as RequestV16; +use Executor\Executor; use Utopia\Validator\Text; use Utopia\Validator\WhiteList; @@ -45,7 +48,7 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleRequest, Request $request, Response $response) +function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); @@ -117,59 +120,218 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques $path .= '?' . $query; } + + $body = $swooleRequest->getContent() ?? ''; + $method = $swooleRequest->server['request_method']; + $requestHeaders = $request->getHeaders(); - $body = \json_encode([ - 'async' => false, - 'body' => $swooleRequest->getContent() ?? '', - 'method' => $swooleRequest->server['request_method'], - 'path' => $path, - 'headers' => $requestHeaders + $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); + + $dbForProject = $getProjectDB($project); + + $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + + if ($function->isEmpty() || !$function->getAttribute('enabled')) { + throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); + } + + $version = $function->getAttribute('version', 'v2'); + $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); + + $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null; + + if (\is_null($runtime)) { + throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported'); + } + + $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', ''))); + + if ($deployment->getAttribute('resourceId') !== $function->getId()) { + throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); + } + + if ($deployment->isEmpty()) { + throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function'); + } + + /** Check if build has completed */ + $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''))); + if ($build->isEmpty()) { + throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND); + } + + if ($build->getAttribute('status') !== 'ready') { + throw new AppwriteException(AppwriteException::BUILD_NOT_READY); + } + + $permissions = $function->getAttribute('execute'); + + if (!(\in_array('any', $permissions)) && (\in_array('guests', $permissions))) { + throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"'); + } + + $headers = \array_merge([], $requestHeaders); + $headers['x-appwrite-trigger'] = 'http'; + $headers['x-appwrite-user-id'] = ''; + $headers['x-appwrite-user-jwt'] = ''; + $headers['x-appwrite-country-code'] = ''; + $headers['x-appwrite-continent-code'] = ''; + $headers['x-appwrite-continent-eu'] = 'false'; + + $ip = $headers['x-real-ip'] ?? ''; + if (!empty($ip)) { + $record = $geodb->get($ip); + + if ($record) { + $eu = Config::getParam('locale-eu'); + + $headers['x-appwrite-country-code'] = $record['country']['iso_code'] ?? ''; + $headers['x-appwrite-continent-code'] = $record['continent']['code'] ?? ''; + $headers['x-appwrite-continent-eu'] = (\in_array($record['country']['iso_code'], $eu)) ? 'true' : 'false'; + } + } + + $headersFiltered = []; + foreach ($headers as $key => $value) { + if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_REQUEST)) { + $headersFiltered[] = ['name' => $key, 'value' => $value]; + } + } + + $executionId = ID::unique(); + + $execution = new Document([ + '$id' => $executionId, + '$permissions' => [], + 'functionInternalId' => $function->getInternalId(), + 'functionId' => $function->getId(), + 'deploymentInternalId' => $deployment->getInternalId(), + 'deploymentId' => $deployment->getId(), + 'trigger' => 'http', // http / schedule / event + 'status' => 'processing', // waiting / processing / completed / failed + 'responseStatusCode' => 0, + 'responseHeaders' => [], + 'requestPath' => $path, + 'requestMethod' => $method, + 'requestHeaders' => $headersFiltered, + 'errors' => '', + 'logs' => '', + 'duration' => 0.0, + 'search' => implode(' ', [$functionId, $executionId]), ]); - $headers = [ - 'Content-Type: application/json', - 'Content-Length: ' . \strlen($body), - 'X-Appwrite-Project: ' . $projectId - ]; + $queueForEvents + ->setParam('functionId', $function->getId()) + ->setParam('executionId', $execution->getId()) + ->setContext('function', $function); - $ch = \curl_init(); - \curl_setopt($ch, CURLOPT_URL, "http://localhost/v1/functions/{$functionId}/executions"); - \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); - \curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - // \curl_setopt($ch, CURLOPT_HEADER, true); - \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - \curl_setopt($ch, CURLOPT_TIMEOUT, 30); + $durationStart = \microtime(true); - $executionResponse = \curl_exec($ch); - $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = \curl_error($ch); - $errNo = \curl_errno($ch); + $vars = []; - \curl_close($ch); - - if ($errNo !== 0) { - throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Internal error: " . $error); + // V2 vars + if ($version === 'v2') { + $vars = \array_merge($vars, [ + 'APPWRITE_FUNCTION_TRIGGER' => $headers['x-appwrite-trigger'] ?? '', + 'APPWRITE_FUNCTION_DATA' => $body ?? '', + 'APPWRITE_FUNCTION_USER_ID' => $headers['x-appwrite-user-id'] ?? '', + 'APPWRITE_FUNCTION_JWT' => $headers['x-appwrite-user-jwt'] ?? '' + ]); } - if ($statusCode >= 400) { - $error = \json_decode($executionResponse, true)['message']; - throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Execution error: " . $error); + // Shared vars + foreach ($function->getAttribute('varsProject', []) as $var) { + $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); } - $execution = \json_decode($executionResponse, true); + // Function vars + foreach ($function->getAttribute('vars', []) as $var) { + $vars[$var->getAttribute('key')] = $var->getAttribute('value', ''); + } - $contentType = 'text/plain'; - foreach ($execution['responseHeaders'] as $header) { - if (\strtolower($header['name']) === 'content-type') { - $contentType = $header['value']; + // Appwrite vars + $vars = \array_merge($vars, [ + 'APPWRITE_FUNCTION_ID' => $functionId, + 'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name'), + 'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(), + 'APPWRITE_FUNCTION_PROJECT_ID' => $project->getId(), + 'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'] ?? '', + 'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'] ?? '', + ]); + + /** Execute function */ + $executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST')); + try { + $version = $function->getAttribute('version', 'v2'); + $command = $runtime['startCommand']; + $command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"'; + $executionResponse = $executor->createExecution( + projectId: $project->getId(), + deploymentId: $deployment->getId(), + body: \strlen($body) > 0 ? $body : null, + variables: $vars, + timeout: $function->getAttribute('timeout', 0), + image: $runtime['image'], + source: $build->getAttribute('path', ''), + entrypoint: $deployment->getAttribute('entrypoint', ''), + version: $version, + path: $path, + method: $method, + headers: $headers, + runtimeEntrypoint: $command, + requestTimeout: 30 + ); + + $headersFiltered = []; + foreach ($executionResponse['headers'] as $key => $value) { + if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) { + $headersFiltered[] = ['name' => $key, 'value' => $value]; + } } - $response->setHeader($header['name'], $header['value']); + /** Update execution status */ + $status = $executionResponse['statusCode'] >= 400 ? 'failed' : 'completed'; + $execution->setAttribute('status', $status); + $execution->setAttribute('responseStatusCode', $executionResponse['statusCode']); + $execution->setAttribute('responseHeaders', $headersFiltered); + $execution->setAttribute('logs', $executionResponse['logs']); + $execution->setAttribute('errors', $executionResponse['errors']); + $execution->setAttribute('duration', $executionResponse['duration']); + } catch (\Throwable $th) { + $durationEnd = \microtime(true); + + $execution + ->setAttribute('duration', $durationEnd - $durationStart) + ->setAttribute('status', 'failed') + ->setAttribute('responseStatusCode', 500) + ->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode()); + Console::error($th->getMessage()); + } finally { + $queueForUsage + ->addMetric(METRIC_EXECUTIONS, 1) + ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) + ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project + ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function + ; } + if ($function->getAttribute('logging')) { + /** @var Document $execution */ + $execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution)); + } + + $execution->setAttribute('logs', ''); + $execution->setAttribute('errors', ''); + + $headers = []; + foreach (($executionResponse['headers'] ?? []) as $key => $value) { + $headers[] = ['name' => $key, 'value' => $value]; + } + + $execution->setAttribute('responseBody', $executionResponse['body'] ?? ''); + $execution->setAttribute('responseHeaders', $headers); + $body = $execution['responseBody'] ?? ''; $encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name')); @@ -179,6 +341,15 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques } } + $contentType = 'text/plain'; + foreach ($execution['responseHeaders'] as $header) { + if (\strtolower($header['name']) === 'content-type') { + $contentType = $header['value']; + } + + $response->setHeader($header['name'], $header['value']); + } + $response ->setContentType($contentType) ->setStatusCode($execution['responseStatusCode'] ?? 200) @@ -205,13 +376,17 @@ App::init() ->inject('console') ->inject('project') ->inject('dbForConsole') + ->inject('getProjectDB') ->inject('user') ->inject('locale') ->inject('localeCodes') ->inject('clients') ->inject('servers') ->inject('queueForCertificates') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates) { + ->inject('queueForEvents') + ->inject('queueForUsage') + ->inject('geodb') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -220,7 +395,7 @@ App::init() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } @@ -571,7 +746,11 @@ App::options() ->inject('request') ->inject('response') ->inject('dbForConsole') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole) { + ->inject('getProjectDB') + ->inject('queueForEvents') + ->inject('queueForUsage') + ->inject('geodb') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) { /* * Appwrite Router */ @@ -579,7 +758,7 @@ App::options() $mainDomain = App::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) { return; } } From 141cdf4c822ff7a6c9f46b339d62d5802f49dc72 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 23 Feb 2024 20:10:25 +0530 Subject: [PATCH 22/51] Fix content-type of file --- app/controllers/api/health.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index c007d629b6..d9faf998e6 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -722,7 +722,7 @@ App::get('/v1/health/storage') $checkStart = \microtime(true); foreach ($devices as $device) { - if (!$device->write($device->getPath('health.txt'), 'test', '')) { + if (!$device->write($device->getPath('health.txt'), 'test', 'text/plain')) { throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot()); } From ca1c83c2cf68a839f11a470034ff003959ee3e29 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sat, 24 Feb 2024 14:33:38 +0000 Subject: [PATCH 23/51] method to reset attachment --- src/Appwrite/Event/Mail.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index ca8fe7d202..bbd05a018f 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -338,6 +338,14 @@ class Mail extends Event return $this; } + /** + * Set attachment + * @param string $content + * @param string $filename + * @param string $encoding + * @param string $type + * @return self + */ public function setAttachment(string $content, string $filename, string $encoding = 'base64', string $type = 'plain/text') { $this->attachment = [ @@ -349,11 +357,27 @@ class Mail extends Event return $this; } + /** + * Get attachment + * + * @return array + */ public function getAttachment(): array { return $this->attachment; } + /** + * Reset attachment + * + * @return self + */ + public function resetAttachment(): self + { + $this->attachment = []; + return $this; + } + /** * Executes the event and sends it to the mails worker. * From ea484e593b9325e99e1dd45ed8a374595074d7c1 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sat, 24 Feb 2024 14:49:17 +0000 Subject: [PATCH 24/51] format --- src/Appwrite/Event/Mail.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index bbd05a018f..ac021e71a2 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -359,7 +359,7 @@ class Mail extends Event /** * Get attachment - * + * * @return array */ public function getAttachment(): array @@ -369,7 +369,7 @@ class Mail extends Event /** * Reset attachment - * + * * @return self */ public function resetAttachment(): self From d91a0e30481b0ade36ec837c866baf038124b91a Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sat, 24 Feb 2024 14:56:53 +0000 Subject: [PATCH 25/51] reset variables --- src/Appwrite/Event/Mail.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index ac021e71a2..6ded33e02e 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -378,6 +378,23 @@ class Mail extends Event return $this; } + /** + * Reset + * + * @return self + */ + public function reset(): self + { + $this->project = null; + $this->recipient = ''; + $this->name = ''; + $this->subject = ''; + $this->body = ''; + $this->variables = []; + $this->bodyTemplate = ''; + $this->attachment = []; + } + /** * Executes the event and sends it to the mails worker. * From 9fe0a5a31b71f4d2016ff7c2f355596c07adeb26 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sat, 24 Feb 2024 21:03:18 +0545 Subject: [PATCH 26/51] Update Mail.php --- src/Appwrite/Event/Mail.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index 6ded33e02e..9bdbf6044d 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -393,6 +393,7 @@ class Mail extends Event $this->variables = []; $this->bodyTemplate = ''; $this->attachment = []; + return $this; } /** From e7a847a417f891e0a5d217bc56899be25b3ece25 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 24 Feb 2024 19:01:00 +0100 Subject: [PATCH 27/51] Fixed ID class namespace --- app/controllers/general.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index d9f6e5f280..87008a7c4a 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -20,7 +20,6 @@ use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; use Appwrite\Event\Event; use Appwrite\Event\Usage; -use Appwrite\ID; use Appwrite\Network\Validator\Origin; use Appwrite\Utopia\Response\Filters\V11 as ResponseV11; use Appwrite\Utopia\Response\Filters\V12 as ResponseV12; @@ -33,6 +32,7 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Query; +use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Authorization; use Utopia\Validator\Hostname; use Appwrite\Utopia\Request\Filters\V12 as RequestV12; From b78725e650dbcf797ba9dba2f25dc69459f6f90a Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sat, 24 Feb 2024 19:12:27 +0100 Subject: [PATCH 28/51] Hide error messages from HTML templates --- app/controllers/general.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 87008a7c4a..e945189b24 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -936,10 +936,10 @@ App::error() ->setParam('development', App::isDevelopment()) ->setParam('projectName', $project->getAttribute('name')) ->setParam('projectURL', $project->getAttribute('url')) - ->setParam('message', $error->getMessage()) - ->setParam('type', $type) - ->setParam('code', $code) - ->setParam('trace', $trace); + ->setParam('message', $output['message'] ?? '') + ->setParam('type', $output['type'] ?? '') + ->setParam('code', $output['code'] ?? '') + ->setParam('trace', $output['trace'] ?? []); $response->html($layout->render()); } From bbcb5e8a6e5602ee0d1b11443f28ec2aa0ca5988 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:41:19 +0530 Subject: [PATCH 29/51] Change status code from 503 to 403 --- app/config/errors.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/errors.php b/app/config/errors.php index 7dedc373ef..9e1e806622 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -31,7 +31,7 @@ return [ Exception::GENERAL_SERVICE_DISABLED => [ 'name' => Exception::GENERAL_SERVICE_DISABLED, 'description' => 'The requested service is disabled. You can enable the service from the Appwrite console.', - 'code' => 503, + 'code' => 403, ], Exception::GENERAL_UNAUTHORIZED_SCOPE => [ 'name' => Exception::GENERAL_UNAUTHORIZED_SCOPE, From 260928942b628e6ca4a3b33346a13ff75c63eca3 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:58:57 +0530 Subject: [PATCH 30/51] Update tests --- tests/e2e/Services/Projects/ProjectsConsoleClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 4a3e25ba29..574ff7dcc5 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -1850,7 +1850,7 @@ class ProjectsConsoleClientTest extends Scope 'x-appwrite-project' => $id, ], $this->getHeaders())); - $this->assertEquals(503, $response['headers']['status-code']); + $this->assertEquals(403, $response['headers']['status-code']); $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ 'content-type' => 'application/json', @@ -1860,7 +1860,7 @@ class ProjectsConsoleClientTest extends Scope 'name' => 'Arsenal' ]); - $this->assertEquals(503, $response['headers']['status-code']); + $this->assertEquals(403, $response['headers']['status-code']); // Cleanup From 84f47dc1d218e234f3f55f6dad7ca4a6d91af71e Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 28 Feb 2024 20:21:35 +0200 Subject: [PATCH 31/51] adding limit to queue retry --- src/Appwrite/Platform/Tasks/QueueRetry.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index cba68f9936..bae5a59c45 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -7,6 +7,7 @@ use Utopia\CLI\Console; use Utopia\Platform\Action; use Utopia\Queue\Client; use Utopia\Queue\Connection; +use Utopia\Validator\Integer; use Utopia\Validator\WhiteList; class QueueRetry extends Action @@ -35,15 +36,17 @@ class QueueRetry extends Action Event::MIGRATIONS_QUEUE_NAME, Event::HAMSTER_CLASS_NAME ]), 'Queue name') + ->param('limit', 0, new Integer(true), 'jobs limit', true) ->inject('queue') - ->callback(fn ($name, $queue) => $this->action($name, $queue)); + ->callback(fn ($name, $limit, $queue) => $this->action($name, $limit, $queue)); } /** * @param string $name The name of the queue to retry jobs from + * @param int $limit * @param Connection $queue */ - public function action(string $name, Connection $queue): void + public function action(string $name, int $limit, Connection $queue): void { if (!$name) { Console::error('Missing required parameter $name'); @@ -59,6 +62,6 @@ class QueueRetry extends Action Console::log('Retrying failed jobs...'); - $queueClient->retry(); + $queueClient->retry($limit); } } From 53438acccebe3f0fd8d699f20051ac5e81f09a99 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 28 Feb 2024 21:01:42 +0200 Subject: [PATCH 32/51] adding limit to queue retry --- src/Appwrite/Platform/Tasks/QueueRetry.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index bae5a59c45..6c7714ff04 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -9,6 +9,7 @@ use Utopia\Queue\Client; use Utopia\Queue\Connection; use Utopia\Validator\Integer; use Utopia\Validator\WhiteList; +use Utopia\Validator\Wildcard; class QueueRetry extends Action { @@ -36,18 +37,24 @@ class QueueRetry extends Action Event::MIGRATIONS_QUEUE_NAME, Event::HAMSTER_CLASS_NAME ]), 'Queue name') - ->param('limit', 0, new Integer(true), 'jobs limit', true) + ->param('limit', null, new Wildcard(), 'jobs limit', true) ->inject('queue') ->callback(fn ($name, $limit, $queue) => $this->action($name, $limit, $queue)); } /** * @param string $name The name of the queue to retry jobs from - * @param int $limit + * @param mixed $limit * @param Connection $queue */ - public function action(string $name, int $limit, Connection $queue): void + public function action(string $name, mixed $limit, Connection $queue): void { + + if (!\is_numeric($limit) && $limit !== null) { + Console::error('$limit parameter should be an integer'); + return; + } + if (!$name) { Console::error('Missing required parameter $name'); return; From 658396b4a857739bb83f50461ae6f950c83ae133 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 28 Feb 2024 21:09:10 +0200 Subject: [PATCH 33/51] adding limit to queue retry --- src/Appwrite/Platform/Tasks/QueueRetry.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index 6c7714ff04..f34448d881 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -37,7 +37,7 @@ class QueueRetry extends Action Event::MIGRATIONS_QUEUE_NAME, Event::HAMSTER_CLASS_NAME ]), 'Queue name') - ->param('limit', null, new Wildcard(), 'jobs limit', true) + ->param('limit', 0, new Wildcard(), 'jobs limit', true) ->inject('queue') ->callback(fn ($name, $limit, $queue) => $this->action($name, $limit, $queue)); } @@ -50,18 +50,14 @@ class QueueRetry extends Action public function action(string $name, mixed $limit, Connection $queue): void { - if (!\is_numeric($limit) && $limit !== null) { - Console::error('$limit parameter should be an integer'); - return; - } - if (!$name) { Console::error('Missing required parameter $name'); return; } + $limit = (int)$limit; $queueClient = new Client($name, $queue); - + var_dump($limit); if ($queueClient->countFailedJobs() === 0) { Console::error('No failed jobs found.'); return; From 1a59361200e85cbea84dbda3642e1f5eb8da0570 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 28 Feb 2024 21:15:59 +0200 Subject: [PATCH 34/51] adding limit to queue retry --- src/Appwrite/Platform/Tasks/QueueRetry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index f34448d881..2781d9a3f7 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -57,7 +57,7 @@ class QueueRetry extends Action $limit = (int)$limit; $queueClient = new Client($name, $queue); - var_dump($limit); + if ($queueClient->countFailedJobs() === 0) { Console::error('No failed jobs found.'); return; From 0b4716721d80a25e86f2aeeb910de07f2f87e493 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 1 Mar 2024 16:16:29 +0000 Subject: [PATCH 35/51] chore: update composer --- composer.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.lock b/composer.lock index c83094b4de..c8fe99a704 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": "a8c299cb631eb98bbcf0a58a815f74ac", + "content-hash": "f7a4173bb5adeea3518f949fa883a282", "packages": [ { "name": "adhocore/jwt", @@ -156,11 +156,11 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.13.2", + "version": "0.13.3", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "214a37c2c66e0f2bc9c30fdfde66955d9fd084a1" + "reference": "5d93fc578a9a543bcdc9b2c0562d80a51d56c73d" }, "require": { "php": ">=8.0", @@ -195,7 +195,7 @@ "php", "runtimes" ], - "time": "2023-11-22T15:36:00+00:00" + "time": "2024-03-01T14:47:47+00:00" }, { "name": "chillerlan/php-qrcode", @@ -3043,16 +3043,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.8.1", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353" + "reference": "153ae662783729388a584b4361f2545e4d841e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353", - "reference": "bc3dc91a5e9b14aa06d1d9e90647c5c5a2cc5353", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", "shasum": "" }, "require": { @@ -3095,9 +3095,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" }, - "time": "2024-01-18T19:15:27+00:00" + "time": "2024-02-23T11:10:43+00:00" }, { "name": "phpspec/prophecy", From 868bba52aa65eb5d07118c167705716ddae891f4 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 1 Mar 2024 22:05:42 +0530 Subject: [PATCH 36/51] Update app/init.php Co-authored-by: Torsten Dittmann --- app/init.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/init.php b/app/init.php index 80c3670eec..9696b08f6c 100644 --- a/app/init.php +++ b/app/init.php @@ -112,7 +112,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours -const APP_CACHE_BUSTER = 329; +const APP_CACHE_BUSTER = 331; const APP_VERSION_STABLE = '1.4.13'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; From 45092a104975048b4ec5a7ddd69a777ebd06aaae Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 1 Mar 2024 22:10:25 +0530 Subject: [PATCH 37/51] Update docker-compose.yml --- docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a1a8c0c3ac..3d4c5d57be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -935,8 +935,9 @@ services: # # MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI. # RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks - # RedisCommander - A nice UI for exploring Redis data - # Webgrind - A nice UI for exploring and debugging code-level stuff + # Redis Insight - A nice UI for exploring Redis data + # Adminer - A nice UI for exploring MariaDB data + # GraphQl Explorer - A nice UI for exploring GraphQL API maildev: # used mainly for dev tests image: appwrite/mailcatcher:1.0.0 From fc498fd80fff82e9103986923fdbc2c763c0ed83 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 3 Mar 2024 08:19:36 +0545 Subject: [PATCH 38/51] update cover image for SDKs --- src/Appwrite/Platform/Tasks/SDKs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index 256b36d885..068da7c68e 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -74,7 +74,7 @@ class SDKs extends Action $spec = file_get_contents(__DIR__ . '/../../../../app/config/specs/swagger2-' . $version . '-' . $language['family'] . '.json'); - $cover = 'https://appwrite.io/images/github.png'; + $cover = 'https://github.com/appwrite/appwrite/raw/main/public/images/github.png'; $result = \realpath(__DIR__ . '/../../../../app') . '/sdks/' . $key . '-' . $language['key']; $resultExamples = \realpath(__DIR__ . '/../../../..') . '/docs/examples/' . $version . '/' . $key . '-' . $language['key']; $target = \realpath(__DIR__ . '/../../../../app') . '/sdks/git/' . $language['key'] . '/'; From 4d873eb5a2775fec0f476d40dc63524239b3c3d2 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 10:36:23 +0100 Subject: [PATCH 39/51] fix: stats collection name --- app/controllers/api/databases.php | 12 +++++----- app/controllers/api/functions.php | 8 +++---- app/controllers/api/project.php | 8 +++---- app/controllers/api/storage.php | 8 +++---- app/controllers/api/users.php | 4 ++-- src/Appwrite/Platform/Tasks/CalcTierStats.php | 2 +- .../Platform/Tasks/CreateInfMetric.php | 6 ++--- src/Appwrite/Platform/Workers/Deletes.php | 2 +- src/Appwrite/Platform/Workers/Hamster.php | 2 +- src/Appwrite/Platform/Workers/Usage.php | 24 +++++++++---------- src/Appwrite/Platform/Workers/UsageDump.php | 6 ++--- 11 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 5514672c52..6a9cb73a67 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -3687,7 +3687,7 @@ App::get('/v1/databases/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3695,7 +3695,7 @@ App::get('/v1/databases/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -3771,7 +3771,7 @@ App::get('/v1/databases/:databaseId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3779,7 +3779,7 @@ App::get('/v1/databases/:databaseId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -3857,7 +3857,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -3865,7 +3865,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index ccb429132b..0de6f28d57 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -501,7 +501,7 @@ App::get('/v1/functions/:functionId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -509,7 +509,7 @@ App::get('/v1/functions/:functionId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -593,7 +593,7 @@ App::get('/v1/functions/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -601,7 +601,7 @@ App::get('/v1/functions/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/project.php b/app/controllers/api/project.php index 14fb435e80..866ec8e993 100644 --- a/app/controllers/api/project.php +++ b/app/controllers/api/project.php @@ -73,7 +73,7 @@ App::get('/v1/project/usage') Authorization::skip(function () use ($dbForProject, $firstDay, $lastDay, $period, $metrics, &$total, &$stats) { foreach ($metrics['total'] as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -81,7 +81,7 @@ App::get('/v1/project/usage') } foreach ($metrics['period'] as $metric) { - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::greaterThanEqual('time', $firstDay), @@ -116,7 +116,7 @@ App::get('/v1/project/usage') $id = $function->getId(); $name = $function->getAttribute('name'); $metric = str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS); - $value = $dbForProject->findOne('stats_v2', [ + $value = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -132,7 +132,7 @@ App::get('/v1/project/usage') $id = $bucket->getId(); $name = $bucket->getAttribute('name'); $metric = str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE); - $value = $dbForProject->findOne('stats_v2', [ + $value = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 9c24c6401b..d0acdbe15e 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1539,7 +1539,7 @@ App::get('/v1/storage/usage') $total = []; Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1547,7 +1547,7 @@ App::get('/v1/storage/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), @@ -1624,7 +1624,7 @@ App::get('/v1/storage/:bucketId/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) { foreach ($metrics as $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -1632,7 +1632,7 @@ App::get('/v1/storage/:bucketId/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 405d80da09..8976510001 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -2122,7 +2122,7 @@ App::get('/v1/users/usage') Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { foreach ($metrics as $count => $metric) { - $result = $dbForProject->findOne('stats_v2', [ + $result = $dbForProject->findOne('stats', [ Query::equal('metric', [$metric]), Query::equal('period', ['inf']) ]); @@ -2130,7 +2130,7 @@ App::get('/v1/users/usage') $stats[$metric]['total'] = $result['value'] ?? 0; $limit = $days['limit']; $period = $days['period']; - $results = $dbForProject->find('stats_v2', [ + $results = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/src/Appwrite/Platform/Tasks/CalcTierStats.php b/src/Appwrite/Platform/Tasks/CalcTierStats.php index d8f7ad3537..5723e256d5 100644 --- a/src/Appwrite/Platform/Tasks/CalcTierStats.php +++ b/src/Appwrite/Platform/Tasks/CalcTierStats.php @@ -269,7 +269,7 @@ class CalcTierStats extends Action $limit = $periods[$range]['limit']; $period = $periods[$range]['period']; - $requestDocs = $dbForProject->find('stats_v2', [ + $requestDocs = $dbForProject->find('stats', [ Query::equal('metric', [$metric]), Query::equal('period', [$period]), Query::limit($limit), diff --git a/src/Appwrite/Platform/Tasks/CreateInfMetric.php b/src/Appwrite/Platform/Tasks/CreateInfMetric.php index 0e78e02bd8..cfb7486782 100644 --- a/src/Appwrite/Platform/Tasks/CreateInfMetric.php +++ b/src/Appwrite/Platform/Tasks/CreateInfMetric.php @@ -163,8 +163,8 @@ class CreateInfMetric extends Action try { $id = \md5("_inf_{$metric}"); - $dbForProject->deleteDocument('stats_v2', $id); - $dbForProject->createDocument('stats_v2', new Document([ + $dbForProject->deleteDocument('stats', $id); + $dbForProject->createDocument('stats', new Document([ '$id' => $id, 'metric' => $metric, 'period' => 'inf', @@ -186,7 +186,7 @@ class CreateInfMetric extends Action protected function getFromMetric(database $dbForProject, string $metric): int|float { - return $dbForProject->sum('stats_v2', 'value', [ + return $dbForProject->sum('stats', 'value', [ Query::equal('metric', [ $metric, ]), diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index f8d9d4cc36..51b2475171 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -474,7 +474,7 @@ class Deletes extends Action { $dbForProject = $getProjectDB($project); // Delete Usage stats - $this->deleteByGroup('stats_v2', [ + $this->deleteByGroup('stats', [ Query::lessThan('time', $hourlyUsageRetentionDatetime), Query::equal('period', ['1h']), ], $dbForProject); diff --git a/src/Appwrite/Platform/Workers/Hamster.php b/src/Appwrite/Platform/Workers/Hamster.php index 71d7e9012e..1069ff96fa 100644 --- a/src/Appwrite/Platform/Workers/Hamster.php +++ b/src/Appwrite/Platform/Workers/Hamster.php @@ -286,7 +286,7 @@ class Hamster extends Action $limit = $periodValue['limit']; $period = $periodValue['period']; - $requestDocs = $dbForProject->find('stats_v2', [ + $requestDocs = $dbForProject->find('stats', [ Query::equal('period', [$period]), Query::equal('metric', [$metric]), Query::limit($limit), diff --git a/src/Appwrite/Platform/Workers/Usage.php b/src/Appwrite/Platform/Workers/Usage.php index 7c7af24323..c84f57e0f2 100644 --- a/src/Appwrite/Platform/Workers/Usage.php +++ b/src/Appwrite/Platform/Workers/Usage.php @@ -128,8 +128,8 @@ class Usage extends Action } break; case $document->getCollection() === 'databases': // databases - $collections = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_COLLECTIONS))); - $documents = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS))); + $collections = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_COLLECTIONS))); + $documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS))); if (!empty($collections['value'])) { $metrics[] = [ 'key' => METRIC_COLLECTIONS, @@ -147,7 +147,7 @@ class Usage extends Action case str_starts_with($document->getCollection(), 'database_') && !str_contains($document->getCollection(), 'collection'): //collections $parts = explode('_', $document->getCollection()); $databaseInternalId = $parts[1] ?? 0; - $documents = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $document->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS))); + $documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $document->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS))); if (!empty($documents['value'])) { $metrics[] = [ @@ -162,8 +162,8 @@ class Usage extends Action break; case $document->getCollection() === 'buckets': - $files = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES))); - $storage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE))); + $files = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES))); + $storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE))); if (!empty($files['value'])) { $metrics[] = [ @@ -181,13 +181,13 @@ class Usage extends Action break; case $document->getCollection() === 'functions': - $deployments = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS))); - $deploymentsStorage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE))); - $builds = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS))); - $buildsStorage = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE))); - $buildsCompute = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE))); - $executions = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS))); - $executionsCompute = $dbForProject->getDocument('stats_v2', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE))); + $deployments = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS))); + $deploymentsStorage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(['{resourceType}', '{resourceInternalId}'], ['functions', $document->getInternalId()], METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE))); + $builds = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS))); + $buildsStorage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE))); + $buildsCompute = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE))); + $executions = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS))); + $executionsCompute = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{functionInternalId}', $document->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE))); if (!empty($deployments['value'])) { $metrics[] = [ diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index e4138df68a..da8995b631 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -75,7 +75,7 @@ class UsageDump extends Action $id = \md5("{$time}_{$period}_{$key}"); try { - $dbForProject->createDocument('stats_v2', new Document([ + $dbForProject->createDocument('stats', new Document([ '$id' => $id, 'period' => $period, 'time' => $time, @@ -86,14 +86,14 @@ class UsageDump extends Action } catch (Duplicate $th) { if ($value < 0) { $dbForProject->decreaseDocumentAttribute( - 'stats_v2', + 'stats', $id, 'value', abs($value) ); } else { $dbForProject->increaseDocumentAttribute( - 'stats_v2', + 'stats', $id, 'value', $value From b8b1d8629f6969565211340c5416ddde70a0b72b Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 11:09:19 +0100 Subject: [PATCH 40/51] fix: tests --- app/controllers/api/health.php | 10 ++--- phpunit.xml | 2 +- src/Appwrite/Platform/Workers/Messaging.php | 41 +-------------------- 3 files changed, 8 insertions(+), 45 deletions(-) diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 1b287e929c..2749013411 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -714,11 +714,11 @@ App::get('/v1/health/storage') ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) ->label('sdk.response.model', Response::MODEL_HEALTH_STATUS) ->inject('response') - ->inject('deviceFiles') - ->inject('deviceFunctions') - ->inject('deviceBuilds') - ->action(function (Response $response, Device $deviceFiles, Device $deviceFunctions, Device $deviceBuilds) { - $devices = [$deviceFiles, $deviceFunctions, $deviceBuilds]; + ->inject('deviceForFiles') + ->inject('deviceForFunctions') + ->inject('deviceForBuilds') + ->action(function (Response $response, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds) { + $devices = [$deviceForFiles, $deviceForFunctions, $deviceForBuilds]; $checkStart = \microtime(true); foreach ($devices as $device) { diff --git a/phpunit.xml b/phpunit.xml index 90ebd4225f..e772866051 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,7 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" + stopOnFailure="true" > diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index e493d8a7e9..53b0358766 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -2,14 +2,12 @@ namespace Appwrite\Platform\Workers; -use Appwrite\Auth\Auth; use Appwrite\Event\Usage; use Appwrite\Extend\Exception; use Appwrite\Messaging\Status as MessageStatus; use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Database\Validator\Authorization; use Utopia\DSN\DSN; use Utopia\Database\Database; use Utopia\Database\DateTime; @@ -389,41 +387,6 @@ class Messaging extends Action $log->addTag('type', $host); - if (empty($payload['message'])) { - Console::error('Message arg not found'); - return; - } - - - switch ($this->dsn->getHost()) { - case 'mock': - $sms = new Mock($this->user, $this->secret); // used for tests - break; - case 'twilio': - $sms = new Twilio($this->user, $this->secret); - break; - case 'text-magic': - $sms = new TextMagic($this->user, $this->secret); - break; - case 'telesign': - $sms = new Telesign($this->user, $this->secret); - break; - case 'msg91': - $sms = new Msg91($this->user, $this->secret); - $sms->setTemplate($this->dsn->getParam('template')); - break; - case 'vonage': - $sms = new Vonage($this->user, $this->secret); - break; - default: - $sms = null; - }; - - if (empty(App::getEnv('_APP_SMS_PROVIDER'))) { - Console::error('Skipped sms processing. No Phone provider has been set.'); - return; - } - $from = App::getEnv('_APP_SMS_FROM'); $provider = new Document([ @@ -477,8 +440,8 @@ class Messaging extends Action $adapter->send($data); $queueForUsage - ->setProject($project) ->addMetric(METRIC_MESSAGES, 1) + ->setProject($project) ->trigger(); } catch (\Throwable $e) { throw new \Exception('Failed sending to targets with error: ' . $e->getMessage()); @@ -686,4 +649,4 @@ class Messaging extends Action $badge ); } -} +} \ No newline at end of file From e4e40e20713ad60febeae63b00a2d903f5a3b7de Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 11:10:03 +0100 Subject: [PATCH 41/51] chore: run linter --- src/Appwrite/Platform/Workers/Messaging.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 53b0358766..3fbe30ccca 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -649,4 +649,4 @@ class Messaging extends Action $badge ); } -} \ No newline at end of file +} From e0b8144c56a9de9b0b7caabf72323893292c61da Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 11:10:52 +0100 Subject: [PATCH 42/51] revert: phpunit change --- phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index e772866051..90ebd4225f 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,7 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="true" + stopOnFailure="false" > From 4cac7f5edd838b111e6635fc3312bcd8127d2cf1 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 11:31:15 +0100 Subject: [PATCH 43/51] fix: merge conflicts --- app/controllers/general.php | 6 +++++- src/Appwrite/Auth/MFA/Challenge/Email.php | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 32c7fa8285..abfe9f41b9 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -374,11 +374,15 @@ App::init() ->inject('console') ->inject('project') ->inject('dbForConsole') + ->inject('getProjectDB') ->inject('locale') ->inject('localeCodes') ->inject('clients') + ->inject('geodb') + ->inject('queueForUsage') + ->inject('queueForEvents') ->inject('queueForCertificates') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Locale $locale, array $localeCodes, array $clients, Certificate $queueForCertificates) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage,Event $queueForEvents,Certificate $queueForCertificates) { /* * Appwrite Router */ diff --git a/src/Appwrite/Auth/MFA/Challenge/Email.php b/src/Appwrite/Auth/MFA/Challenge/Email.php index be860aba22..373b9db72b 100644 --- a/src/Appwrite/Auth/MFA/Challenge/Email.php +++ b/src/Appwrite/Auth/MFA/Challenge/Email.php @@ -3,6 +3,7 @@ namespace Appwrite\Auth\MFA\Challenge; use Appwrite\Auth\MFA\Challenge; +use Appwrite\Auth\MFA\Type; use Utopia\Database\Document; class Email extends Challenge From 32b34793e01a0c28ec91b53d586ab667cb964271 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Tue, 5 Mar 2024 11:34:04 +0100 Subject: [PATCH 44/51] fix: formatter --- app/controllers/general.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index abfe9f41b9..7a1621c22b 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -382,7 +382,7 @@ App::init() ->inject('queueForUsage') ->inject('queueForEvents') ->inject('queueForCertificates') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage,Event $queueForEvents,Certificate $queueForCertificates) { + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage, Event $queueForEvents, Certificate $queueForCertificates) { /* * Appwrite Router */ From a98323d8c913dd24828ae0f6b77364f6d1fca1b3 Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:47:07 +0100 Subject: [PATCH 45/51] chore: update executor, update appwrite/runtimes --- app/views/install/compose.phtml | 2 +- composer.lock | 103 +++++++++++++++++--------------- docker-compose.yml | 2 +- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 7b34feb8b1..0136dc664e 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -691,7 +691,7 @@ services: <<: *x-logging restart: unless-stopped stop_signal: SIGINT - image: openruntimes/executor:0.4.5 + image: openruntimes/executor:0.4.9 networks: - appwrite - runtimes diff --git a/composer.lock b/composer.lock index 79509e7d12..ae1746ba06 100644 --- a/composer.lock +++ b/composer.lock @@ -156,16 +156,16 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.13.2", + "version": "0.13.3", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "214a37c2c66e0f2bc9c30fdfde66955d9fd084a1" + "reference": "5d93fc578a9a543bcdc9b2c0562d80a51d56c73d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/runtimes/zipball/214a37c2c66e0f2bc9c30fdfde66955d9fd084a1", - "reference": "214a37c2c66e0f2bc9c30fdfde66955d9fd084a1", + "url": "https://api.github.com/repos/appwrite/runtimes/zipball/5d93fc578a9a543bcdc9b2c0562d80a51d56c73d", + "reference": "5d93fc578a9a543bcdc9b2c0562d80a51d56c73d", "shasum": "" }, "require": { @@ -204,9 +204,9 @@ ], "support": { "issues": "https://github.com/appwrite/runtimes/issues", - "source": "https://github.com/appwrite/runtimes/tree/0.13.2" + "source": "https://github.com/appwrite/runtimes/tree/0.13.3" }, - "time": "2023-11-22T15:36:00+00:00" + "time": "2024-03-01T14:47:47+00:00" }, { "name": "beberlei/assert", @@ -3136,20 +3136,21 @@ }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -3190,9 +3191,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -3531,16 +3538,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.30", + "version": "9.2.31", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", - "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", "shasum": "" }, "require": { @@ -3597,7 +3604,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" }, "funding": [ { @@ -3605,7 +3612,7 @@ "type": "github" } ], - "time": "2023-12-22T06:47:57+00:00" + "time": "2024-03-02T06:37:42+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4003,16 +4010,16 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", "shasum": "" }, "require": { @@ -4047,7 +4054,7 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" }, "funding": [ { @@ -4055,7 +4062,7 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-03-02T06:27:43+00:00" }, { "name": "sebastian/code-unit", @@ -4301,16 +4308,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", "shasum": "" }, "require": { @@ -4355,7 +4362,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" }, "funding": [ { @@ -4363,7 +4370,7 @@ "type": "github" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2024-03-02T06:30:58+00:00" }, { "name": "sebastian/environment", @@ -4430,16 +4437,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", "shasum": "" }, "require": { @@ -4495,7 +4502,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" }, "funding": [ { @@ -4503,20 +4510,20 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2024-03-02T06:33:00+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.6", + "version": "5.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bde739e7565280bda77be70044ac1047bc007e34" + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", - "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", "shasum": "" }, "require": { @@ -4559,7 +4566,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" }, "funding": [ { @@ -4567,7 +4574,7 @@ "type": "github" } ], - "time": "2023-08-02T09:26:13+00:00" + "time": "2024-03-02T06:35:11+00:00" }, { "name": "sebastian/lines-of-code", @@ -5287,16 +5294,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -5325,7 +5332,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -5333,7 +5340,7 @@ "type": "github" } ], - "time": "2023-11-20T00:12:19+00:00" + "time": "2024-03-03T12:36:25+00:00" }, { "name": "twig/twig", diff --git a/docker-compose.yml b/docker-compose.yml index eacee76fca..58dff56901 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -850,7 +850,7 @@ services: hostname: appwrite-executor <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.4.5 + image: openruntimes/executor:0.4.9 restart: unless-stopped networks: - appwrite From 8f187986d2d955ef141a8e3a14c1f6bf215322f4 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:13:43 +0100 Subject: [PATCH 46/51] feat: pint --- composer.json | 3 ++- composer.lock | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++- pint.json | 8 ++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 pint.json diff --git a/composer.json b/composer.json index 28dbde65be..0a14af20f7 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,8 @@ "squizlabs/php_codesniffer": "^3.7", "swoole/ide-helper": "5.0.2", "textalk/websocket": "1.5.7", - "utopia-php/fetch": "0.1.*" + "utopia-php/fetch": "0.1.*", + "laravel/pint": "^1.14" }, "provide": { "ext-phpiredis": "*" diff --git a/composer.lock b/composer.lock index ae1746ba06..6907425742 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": "733cdc4128cc298318cf487442d3efed", + "content-hash": "a0c585fabc25c78458734e1fbf9d30c8", "packages": [ { "name": "adhocore/jwt", @@ -2893,6 +2893,72 @@ ], "time": "2022-12-30T00:15:36+00:00" }, + { + "name": "laravel/pint", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "6b127276e3f263f7bb17d5077e9e0269e61b2a0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/6b127276e3f263f7bb17d5077e9e0269e61b2a0e", + "reference": "6b127276e3f263f7bb17d5077e9e0269e61b2a0e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.49.0", + "illuminate/view": "^10.43.0", + "larastan/larastan": "^2.8.1", + "laravel-zero/framework": "^10.3.0", + "mockery/mockery": "^1.6.7", + "nunomaduro/termwind": "^1.15.1", + "pestphp/pest": "^2.33.6" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2024-02-20T17:38:05+00:00" + }, { "name": "matthiasmullie/minify", "version": "1.3.71", diff --git a/pint.json b/pint.json new file mode 100644 index 0000000000..9a0a60b774 --- /dev/null +++ b/pint.json @@ -0,0 +1,8 @@ +{ + "preset": "psr12", + "exclude": [ + "./app/sdks", + "./tests/resources/functions", + "./app/console" + ] +} From 3ac8805b7d120442c98c10025c26ed7671b8d398 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:19:36 +0100 Subject: [PATCH 47/51] fix: config --- pint.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pint.json b/pint.json index 9a0a60b774..e00da8b88e 100644 --- a/pint.json +++ b/pint.json @@ -4,5 +4,14 @@ "./app/sdks", "./tests/resources/functions", "./app/console" - ] + ], + "rules": { + "array_indentation": true, + "single_import_per_statement": true, + "use_arrow_functions": true, + "simplified_null_return": true, + "ordered_imports": { + "sort_algorithm": "alpha" + } + } } From 64a9126398e614c1255699a6584fb44b9eb9d676 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:33:32 +0100 Subject: [PATCH 48/51] fix: config --- composer.json | 5 ++--- composer.lock | 12 ++++++------ pint.json | 8 ++++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 0a14af20f7..8d1cc0bd7d 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,8 @@ ], "scripts": { "test": "vendor/bin/phpunit", - "lint": "vendor/bin/phpcs", - "format": "vendor/bin/phpcbf" + "lint": "vendor/bin/pint --test", + "format": "vendor/bin/pint" }, "autoload": { "psr-4": { @@ -81,7 +81,6 @@ "ext-fileinfo": "*", "appwrite/sdk-generator": "0.37.0-rc.6", "phpunit/phpunit": "9.5.20", - "squizlabs/php_codesniffer": "^3.7", "swoole/ide-helper": "5.0.2", "textalk/websocket": "1.5.7", "utopia-php/fetch": "0.1.*", diff --git a/composer.lock b/composer.lock index 6907425742..1203807f50 100644 --- a/composer.lock +++ b/composer.lock @@ -3144,16 +3144,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.1", + "version": "v5.0.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", - "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", "shasum": "" }, "require": { @@ -3196,9 +3196,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" }, - "time": "2024-02-21T19:24:10+00:00" + "time": "2024-03-05T20:51:40+00:00" }, { "name": "phar-io/manifest", diff --git a/pint.json b/pint.json index e00da8b88e..14614b0208 100644 --- a/pint.json +++ b/pint.json @@ -8,10 +8,14 @@ "rules": { "array_indentation": true, "single_import_per_statement": true, - "use_arrow_functions": true, "simplified_null_return": true, "ordered_imports": { - "sort_algorithm": "alpha" + "sort_algorithm": "alpha", + "imports_order": [ + "const", + "class", + "function" + ] } } } From 0a1d572c72ad1e743441dc4adb7ccda113b6c092 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:34:21 +0100 Subject: [PATCH 49/51] chore: run formatter --- app/cli.php | 12 +- app/config/avatars/credit-cards.php | 2 +- app/config/runtimes-v2.php | 2 +- app/config/usage.php | 40 ++-- app/controllers/api/account.php | 90 ++++---- app/controllers/api/avatars.php | 4 +- app/controllers/api/databases.php | 196 +++++++++--------- app/controllers/api/functions.php | 94 ++++----- app/controllers/api/locale.php | 2 +- app/controllers/api/messaging.php | 5 +- app/controllers/api/migrations.php | 1 - app/controllers/api/project.php | 11 +- app/controllers/api/storage.php | 87 ++++---- app/controllers/api/teams.php | 34 +-- app/controllers/api/users.php | 62 +++--- app/controllers/api/vcs.php | 18 +- app/controllers/general.php | 45 ++-- app/controllers/mock.php | 12 +- app/controllers/shared/api.php | 18 +- app/controllers/shared/api/auth.php | 8 +- app/http.php | 16 +- app/init.php | 129 ++++++------ app/realtime.php | 28 +-- app/worker.php | 13 +- src/Appwrite/Auth/Auth.php | 2 +- src/Appwrite/Auth/OAuth2/Authentik.php | 20 +- src/Appwrite/Auth/OAuth2/Discord.php | 4 +- src/Appwrite/Auth/OAuth2/Mock.php | 1 - src/Appwrite/Auth/OAuth2/Oidc.php | 26 +-- src/Appwrite/Auth/OAuth2/PaypalSandbox.php | 2 - src/Appwrite/Auth/OAuth2/Podio.php | 2 +- src/Appwrite/Auth/OAuth2/Stripe.php | 1 - src/Appwrite/Auth/OAuth2/TradeshiftBox.php | 2 - src/Appwrite/Docker/Env.php | 2 - src/Appwrite/Event/Event.php | 6 +- src/Appwrite/Event/Messaging.php | 2 +- src/Appwrite/Event/Usage.php | 3 +- .../Event/Validator/FunctionEvent.php | 2 - src/Appwrite/GraphQL/Resolvers.php | 14 +- src/Appwrite/GraphQL/Schema.php | 2 +- src/Appwrite/GraphQL/Types/Assoc.php | 7 - src/Appwrite/GraphQL/Types/Mapper.php | 6 +- src/Appwrite/Messaging/Adapter/Realtime.php | 4 +- src/Appwrite/Migration/Migration.php | 10 +- src/Appwrite/Migration/Version/V15.php | 4 +- src/Appwrite/Migration/Version/V17.php | 6 +- src/Appwrite/Migration/Version/V19.php | 4 +- src/Appwrite/Migration/Version/V20.php | 2 +- src/Appwrite/Network/Validator/Origin.php | 2 +- src/Appwrite/Platform/Services/Tasks.php | 4 +- src/Appwrite/Platform/Services/Workers.php | 14 +- src/Appwrite/Platform/Tasks/CalcTierStats.php | 11 +- .../Platform/Tasks/CreateInfMetric.php | 4 +- .../Platform/Tasks/DeleteOrphanedProjects.php | 6 +- src/Appwrite/Platform/Tasks/Doctor.php | 24 +-- .../Platform/Tasks/GetMigrationStats.php | 6 +- src/Appwrite/Platform/Tasks/Hamster.php | 4 +- src/Appwrite/Platform/Tasks/Install.php | 2 +- src/Appwrite/Platform/Tasks/Maintenance.php | 2 +- src/Appwrite/Platform/Tasks/Migrate.php | 4 +- .../PatchRecreateRepositoriesDocuments.php | 2 +- src/Appwrite/Platform/Tasks/QueueRetry.php | 1 - src/Appwrite/Platform/Tasks/SDKs.php | 4 +- src/Appwrite/Platform/Tasks/SSL.php | 2 +- src/Appwrite/Platform/Tasks/ScheduleBase.php | 12 +- .../Platform/Tasks/ScheduleMessages.php | 11 +- src/Appwrite/Platform/Tasks/Specs.php | 4 +- src/Appwrite/Platform/Tasks/Vars.php | 2 +- src/Appwrite/Platform/Workers/Audits.php | 10 +- src/Appwrite/Platform/Workers/Builds.php | 80 +++---- .../Platform/Workers/Certificates.php | 4 +- src/Appwrite/Platform/Workers/Databases.php | 6 +- src/Appwrite/Platform/Workers/Deletes.php | 6 +- src/Appwrite/Platform/Workers/Functions.php | 4 +- src/Appwrite/Platform/Workers/Hamster.php | 7 +- src/Appwrite/Platform/Workers/Messaging.php | 11 +- src/Appwrite/Platform/Workers/Migrations.php | 20 +- src/Appwrite/Platform/Workers/Usage.php | 80 +++---- src/Appwrite/Platform/Workers/UsageDump.php | 4 +- src/Appwrite/Platform/Workers/Webhooks.php | 2 +- src/Appwrite/Specification/Format.php | 2 +- .../Specification/Format/OpenAPI3.php | 6 +- .../Database/Validator/Queries/Attributes.php | 2 - .../Database/Validator/Queries/Base.php | 13 +- .../Database/Validator/Queries/Projects.php | 2 - .../Database/Validator/Queries/Variables.php | 2 - src/Appwrite/Utopia/Request/Filters/V12.php | 6 +- src/Appwrite/Utopia/Request/Filters/V14.php | 2 +- src/Appwrite/Utopia/Request/Filters/V15.php | 2 +- src/Appwrite/Utopia/Request/Filters/V17.php | 2 +- src/Appwrite/Utopia/Response.php | 92 ++++---- src/Appwrite/Utopia/Response/Filters/V11.php | 6 +- .../Utopia/Response/Model/Execution.php | 2 +- src/Appwrite/Utopia/Response/Model/Func.php | 2 - .../Utopia/Response/Model/Message.php | 1 - src/Appwrite/Utopia/Response/Model/Rule.php | 2 - src/Appwrite/Vcs/Comment.php | 2 +- tests/e2e/General/HooksTest.php | 106 +++++----- tests/e2e/General/UsageTest.php | 4 +- tests/e2e/Scopes/Scope.php | 2 +- tests/e2e/Services/Account/AccountBase.php | 63 +++--- .../Account/AccountConsoleClientTest.php | 128 ++++++------ .../Account/AccountCustomClientTest.php | 2 +- .../Account/AccountCustomServerTest.php | 4 +- .../Avatars/AvatarsConsoleClientTest.php | 2 +- .../Avatars/AvatarsCustomClientTest.php | 2 +- .../e2e/Services/Databases/DatabasesBase.php | 4 +- .../Databases/DatabasesConsoleClientTest.php | 4 +- .../Databases/DatabasesCustomClientTest.php | 2 +- .../Databases/DatabasesCustomServerTest.php | 20 +- .../DatabasesPermissionsGuestTest.php | 2 +- .../DatabasesPermissionsTeamTest.php | 2 +- .../Functions/FunctionsConsoleClientTest.php | 4 +- .../Functions/FunctionsCustomServerTest.php | 5 +- tests/e2e/Services/GraphQL/AccountTest.php | 2 - tests/e2e/Services/GraphQL/AuthTest.php | 2 +- tests/e2e/Services/GraphQL/BatchTest.php | 14 +- tests/e2e/Services/GraphQL/ScopeTest.php | 1 - tests/e2e/Services/Health/HealthBase.php | 2 - .../Health/HealthCustomServerTest.php | 3 +- .../Locale/LocaleConsoleClientTest.php | 2 +- .../Locale/LocaleCustomClientTest.php | 2 +- .../Locale/LocaleCustomServerTest.php | 1 - tests/e2e/Services/Projects/ProjectsBase.php | 2 - .../Projects/ProjectsConsoleClientTest.php | 18 +- .../Projects/ProjectsCustomClientTest.php | 3 +- .../Projects/ProjectsCustomServerTest.php | 1 - tests/e2e/Services/Realtime/RealtimeBase.php | 2 +- .../Realtime/RealtimeConsoleClientTest.php | 2 +- .../Realtime/RealtimeCustomClientTest.php | 2 +- tests/e2e/Services/Storage/StorageBase.php | 1 - .../Storage/StorageConsoleClientTest.php | 2 +- .../Storage/StorageCustomClientTest.php | 59 +++--- .../Storage/StorageCustomServerTest.php | 24 +-- tests/e2e/Services/Teams/TeamsBase.php | 1 - tests/e2e/Services/Teams/TeamsBaseClient.php | 7 +- .../Services/Teams/TeamsConsoleClientTest.php | 10 +- .../Services/Teams/TeamsCustomClientTest.php | 2 +- .../Services/Teams/TeamsCustomServerTest.php | 1 - tests/e2e/Services/Users/UsersBase.php | 12 +- .../Services/Users/UsersConsoleClientTest.php | 4 +- .../Services/Users/UsersCustomServerTest.php | 1 - .../e2e/Services/VCS/VCSConsoleClientTest.php | 6 +- .../e2e/Services/VCS/VCSCustomClientTest.php | 6 +- .../e2e/Services/VCS/VCSCustomServerTest.php | 6 +- tests/e2e/Services/Webhooks/WebhooksBase.php | 17 +- .../Webhooks/WebhooksCustomClientTest.php | 3 +- .../Webhooks/WebhooksCustomServerTest.php | 1 - tests/extensions/TestHook.php | 1 - tests/unit/Auth/AuthTest.php | 2 +- .../Auth/Validator/PasswordDictionaryTest.php | 1 - .../unit/Messaging/MessagingChannelsTest.php | 2 +- tests/unit/Messaging/MessagingTest.php | 2 +- tests/unit/Usage/StatsTest.php | 12 +- tests/unit/Utopia/Request/Filters/V16Test.php | 1 - tests/unit/Utopia/Request/Filters/V17Test.php | 2 +- .../unit/Utopia/Response/Filters/V15Test.php | 4 +- .../unit/Utopia/Response/Filters/V16Test.php | 3 +- .../unit/Utopia/Response/Filters/V17Test.php | 5 +- tests/unit/Utopia/ResponseTest.php | 2 +- 160 files changed, 1049 insertions(+), 1130 deletions(-) diff --git a/app/cli.php b/app/cli.php index 559378bc57..1a8c785a30 100644 --- a/app/cli.php +++ b/app/cli.php @@ -3,29 +3,29 @@ require_once __DIR__ . '/init.php'; require_once __DIR__ . '/controllers/general.php'; -use Appwrite\Event\Delete; use Appwrite\Event\Certificate; +use Appwrite\Event\Delete; use Appwrite\Event\Func; use Appwrite\Event\Hamster; use Appwrite\Platform\Appwrite; -use Utopia\CLI\CLI; -use Utopia\Database\Validator\Authorization; -use Utopia\Platform\Service; use Utopia\App; -use Utopia\CLI\Console; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; +use Utopia\CLI\CLI; +use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log; +use Utopia\Platform\Service; use Utopia\Pools\Group; use Utopia\Queue\Connection; use Utopia\Registry\Registry; Authorization::disable(); -CLI::setResource('register', fn()=>$register); +CLI::setResource('register', fn () => $register); CLI::setResource('cache', function ($pools) { $list = Config::getParam('pools-cache', []); diff --git a/app/config/avatars/credit-cards.php b/app/config/avatars/credit-cards.php index aaef17ee3f..1aa22c4174 100644 --- a/app/config/avatars/credit-cards.php +++ b/app/config/avatars/credit-cards.php @@ -17,4 +17,4 @@ return [ 'visa' => ['name' => 'Visa', 'path' => __DIR__ . '/credit-cards/visa.png'], 'mir' => ['name' => 'MIR', 'path' => __DIR__ . '/credit-cards/mir.png'], 'maestro' => ['name' => 'Maestro', 'path' => __DIR__ . '/credit-cards/maestro.png'] - ]; +]; diff --git a/app/config/runtimes-v2.php b/app/config/runtimes-v2.php index c24aaa109e..d249946d05 100644 --- a/app/config/runtimes-v2.php +++ b/app/config/runtimes-v2.php @@ -4,8 +4,8 @@ * List of Appwrite Cloud Functions supported runtimes */ -use Utopia\App; use Appwrite\Runtimes\Runtimes; +use Utopia\App; $runtimes = new Runtimes('v2'); diff --git a/app/config/usage.php b/app/config/usage.php index 2179bcce54..a0d3f9f725 100644 --- a/app/config/usage.php +++ b/app/config/usage.php @@ -1,24 +1,24 @@ [ - 'period' => '1h', - 'limit' => 24, - 'factor' => 3600, - ], - '7d' => [ - 'period' => '1d', - 'limit' => 7, - 'factor' => 86400, - ], - '30d' => [ - 'period' => '1d', - 'limit' => 30, - 'factor' => 86400, - ], - '90d' => [ - 'period' => '1d', - 'limit' => 90, - 'factor' => 86400, - ], + '24h' => [ + 'period' => '1h', + 'limit' => 24, + 'factor' => 3600, + ], + '7d' => [ + 'period' => '1d', + 'limit' => 7, + 'factor' => 86400, + ], + '30d' => [ + 'period' => '1d', + 'limit' => 30, + 'factor' => 86400, + ], + '90d' => [ + 'period' => '1d', + 'limit' => 90, + 'factor' => 86400, + ], ]; diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index fa16965ceb..d038b61440 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -6,26 +6,25 @@ use Appwrite\Auth\MFA\Challenge; use Appwrite\Auth\MFA\Type; use Appwrite\Auth\MFA\Type\TOTP; use Appwrite\Auth\OAuth2\Exception as OAuth2Exception; +use Appwrite\Auth\Phrase; use Appwrite\Auth\Validator\Password; +use Appwrite\Auth\Validator\PasswordDictionary; +use Appwrite\Auth\Validator\PasswordHistory; +use Appwrite\Auth\Validator\PersonalData; use Appwrite\Auth\Validator\Phone; use Appwrite\Detector\Detector; +use Appwrite\Event\Delete; use Appwrite\Event\Event; use Appwrite\Event\Mail; -use Appwrite\Auth\Phrase; +use Appwrite\Event\Messaging; use Appwrite\Extend\Exception; +use Appwrite\Hooks\Hooks; use Appwrite\Network\Validator\Email; -use Utopia\Database\Exception\Query as QueryException; -use Utopia\Validator\Host; -use Utopia\Validator\URL; -use Utopia\Validator\Boolean; use Appwrite\OpenSSL\OpenSSL; use Appwrite\Template\Template; use Appwrite\URL\URL as URLParser; use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries\Identities; -use Utopia\Database\Validator\Queries; -use Utopia\Database\Validator\Query\Limit; -use Utopia\Database\Validator\Query\Offset; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; @@ -33,26 +32,27 @@ use Utopia\App; use Utopia\Audit\Audit as EventAudit; use Utopia\Config\Config; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\DateTime; +use Utopia\Database\Document; use Utopia\Database\Exception\Duplicate; +use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; -use Utopia\Database\Query; use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Queries; +use Utopia\Database\Validator\Query\Limit; +use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; use Utopia\Locale\Locale; use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; +use Utopia\Validator\Boolean; +use Utopia\Validator\Host; use Utopia\Validator\Text; +use Utopia\Validator\URL; use Utopia\Validator\WhiteList; -use Appwrite\Auth\Validator\PasswordHistory; -use Appwrite\Auth\Validator\PasswordDictionary; -use Appwrite\Auth\Validator\PersonalData; -use Appwrite\Event\Delete; -use Appwrite\Event\Messaging; -use Appwrite\Hooks\Hooks; $oauthDefaultSuccess = '/auth/oauth2/success'; $oauthDefaultFailure = '/auth/oauth2/failure'; @@ -160,9 +160,9 @@ App::post('/v1/account') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - $user = Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + $user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); try { - $target = Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ + $target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([ '$permissions' => [ Permission::read(Role::user($user->getId())), Permission::update(Role::user($user->getId())), @@ -338,9 +338,9 @@ App::get('/v1/account/sessions/oauth2/:provider') ->label('sdk.methodType', 'webAuth') ->label('abuse-limit', 50) ->label('abuse-key', 'ip:{ip}') - ->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn($node) => (!$node['mock'])))) . '.') - ->param('success', '', fn($clients) => new Host($clients), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) - ->param('failure', '', fn($clients) => new Host($clients), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) + ->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn ($node) => (!$node['mock'])))) . '.') + ->param('success', '', fn ($clients) => new Host($clients), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) + ->param('failure', '', fn ($clients) => new Host($clients), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) ->param('scopes', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) ->inject('request') ->inject('response') @@ -407,9 +407,9 @@ App::get('/v1/account/tokens/oauth2/:provider') ->label('sdk.methodType', 'webAuth') ->label('abuse-limit', 50) ->label('abuse-key', 'ip:{ip}') - ->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn($node) => (!$node['mock'])))) . '.') - ->param('success', '', fn($clients) => new Host($clients), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) - ->param('failure', '', fn($clients) => new Host($clients), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) + ->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn ($node) => (!$node['mock'])))) . '.') + ->param('success', '', fn ($clients) => new Host($clients), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) + ->param('failure', '', fn ($clients) => new Host($clients), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s 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.', true, ['clients']) ->param('scopes', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) ->inject('request') ->inject('response') @@ -775,7 +775,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - $userDoc = Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + $userDoc = Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); $dbForProject->createDocument('targets', new Document([ '$permissions' => [ Permission::read(Role::user($user->getId())), @@ -893,7 +893,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $query['secret'] = $secret; $query['userId'] = $user->getId(); - // If the `token` param is not set, we persist the session in a cookie + // If the `token` param is not set, we persist the session in a cookie } else { $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); @@ -1087,7 +1087,7 @@ App::post('/v1/account/tokens/magic-url') ->label('abuse-key', ['url:{url},email:{param-email}', 'url:{url},ip:{ip}']) ->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') ->param('email', '', new Email(), 'User email.') - ->param('url', '', fn($clients) => new Host($clients), 'URL to redirect the user back to your app from the magic URL login. 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.', true, ['clients']) + ->param('url', '', fn ($clients) => new Host($clients), 'URL to redirect the user back to your app from the magic URL login. 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.', true, ['clients']) ->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true) ->inject('request') ->inject('response') @@ -1815,7 +1815,7 @@ App::post('/v1/account/tokens/phone') $user->removeAttribute('$internalId'); Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); try { - $target = Authorization::skip(fn() => $dbForProject->createDocument('targets', new Document([ + $target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([ '$permissions' => [ Permission::read(Role::user($user->getId())), Permission::update(Role::user($user->getId())), @@ -1980,7 +1980,7 @@ App::post('/v1/account/sessions/anonymous') 'accessedAt' => DateTime::now(), ]); $user->removeAttribute('$internalId'); - Authorization::skip(fn() => $dbForProject->createDocument('users', $user)); + Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); // Create session token $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; @@ -2009,10 +2009,10 @@ App::post('/v1/account/sessions/anonymous') Authorization::setRole(Role::user($user->getId())->toString()); $session = $dbForProject->createDocument('sessions', $session-> setAttribute('$permissions', [ - Permission::read(Role::user($user->getId())), - Permission::update(Role::user($user->getId())), - Permission::delete(Role::user($user->getId())), - ])); + Permission::read(Role::user($user->getId())), + Permission::update(Role::user($user->getId())), + Permission::delete(Role::user($user->getId())), + ])); $dbForProject->purgeCachedDocument('users', $user->getId()); @@ -2082,13 +2082,13 @@ App::post('/v1/account/jwt') $response ->setStatusCode(Response::STATUS_CODE_CREATED) ->dynamic(new Document(['jwt' => $jwt->encode([ - // 'uid' => 1, - // 'aud' => 'http://site.com', - // 'scopes' => ['user'], - // 'iss' => 'http://api.mysite.com', - 'userId' => $user->getId(), - 'sessionId' => $current->getId(), - ])]), Response::MODEL_JWT); + // 'uid' => 1, + // 'aud' => 'http://site.com', + // 'scopes' => ['user'], + // 'iss' => 'http://api.mysite.com', + 'userId' => $user->getId(), + 'sessionId' => $current->getId(), + ])]), Response::MODEL_JWT); }); App::get('/v1/account') @@ -2835,7 +2835,7 @@ App::delete('/v1/account/sessions') if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { $session->setAttribute('current', true); - // If current session delete the cookies too + // If current session delete the cookies too $response ->addCookie(Auth::$cookieName . '_legacy', '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName, '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')); @@ -3139,7 +3139,7 @@ App::post('/v1/account/verification') ->label('sdk.response.model', Response::MODEL_TOKEN) ->label('abuse-limit', 10) ->label('abuse-key', 'url:{url},userId:{userId}') - ->param('url', '', fn($clients) => new Host($clients), 'URL to redirect the user back to your app from the verification 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']) // TODO add built-in confirm page + ->param('url', '', fn ($clients) => new Host($clients), 'URL to redirect the user back to your app from the verification 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']) // TODO add built-in confirm page ->inject('request') ->inject('response') ->inject('project') @@ -3308,7 +3308,7 @@ App::put('/v1/account/verification') ->inject('queueForEvents') ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { - $profile = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId)); + $profile = Authorization::skip(fn () => $dbForProject->getDocument('users', $userId)); if ($profile->isEmpty()) { throw new Exception(Exception::USER_NOT_FOUND); @@ -3480,7 +3480,7 @@ App::put('/v1/account/verification/phone') ->inject('queueForEvents') ->action(function (string $userId, string $secret, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) { - $profile = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId)); + $profile = Authorization::skip(fn () => $dbForProject->getDocument('users', $userId)); if ($profile->isEmpty()) { throw new Exception(Exception::USER_NOT_FOUND); @@ -4354,7 +4354,7 @@ App::delete('/v1/account/targets/:targetId/push') ->inject('response') ->inject('dbForProject') ->action(function (string $targetId, Event $queueForEvents, Delete $queueForDeletes, Document $user, Request $request, Response $response, Database $dbForProject) { - $target = Authorization::skip(fn() => $dbForProject->getDocument('targets', $targetId)); + $target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId)); if ($target->isEmpty()) { throw new Exception(Exception::USER_TARGET_NOT_FOUND); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index ffcfb8f10a..b393355085 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -3,6 +3,8 @@ use Appwrite\Extend\Exception; use Appwrite\URL\URL as URLParse; use Appwrite\Utopia\Response; +use chillerlan\QRCode\QRCode; +use chillerlan\QRCode\QROptions; use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -21,8 +23,6 @@ use Utopia\Validator\Range; use Utopia\Validator\Text; use Utopia\Validator\URL; use Utopia\Validator\WhiteList; -use chillerlan\QRCode\QRCode; -use chillerlan\QRCode\QROptions; $avatarCallback = function (string $type, string $code, int $width, int $height, int $quality, Response $response) { diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 6a9cb73a67..2b655ab5d8 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -45,8 +45,8 @@ use Utopia\Locale\Locale; use Utopia\Validator\ArrayList; use Utopia\Validator\Boolean; use Utopia\Validator\FloatValidator; -use Utopia\Validator\IP; use Utopia\Validator\Integer; +use Utopia\Validator\IP; use Utopia\Validator\JSON; use Utopia\Validator\Nullable; use Utopia\Validator\Range; @@ -752,7 +752,7 @@ App::post('/v1/databases/:databaseId/collections') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -813,7 +813,7 @@ App::get('/v1/databases/:databaseId/collections') ->inject('mode') ->action(function (string $databaseId, array $queries, string $search, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -875,7 +875,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId') ->inject('mode') ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -911,7 +911,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs') ->inject('geodb') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1017,7 +1017,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, Response $response, Database $dbForProject, string $mode, Event $queueForEvents) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1081,7 +1081,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId') ->inject('mode') ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1616,7 +1616,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relati $key ??= $relatedCollectionId; $twoWayKey ??= $collectionId; - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1719,7 +1719,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { /** @var Document $database */ - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -1753,7 +1753,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') if ($cursor) { $attributeId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn() => $dbForProject->find('attributes', [ + $cursorDocument = Authorization::skip(fn () => $dbForProject->find('attributes', [ Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('databaseInternalId', [$database->getInternalId()]), Query::equal('key', [$attributeId]), @@ -1807,7 +1807,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2300,7 +2300,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2413,7 +2413,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2437,7 +2437,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes') } // Convert Document[] to array of attribute metadata - $oldAttributes = \array_map(fn($a) => $a->getArrayCopy(), $collection->getAttribute('attributes')); + $oldAttributes = \array_map(fn ($a) => $a->getArrayCopy(), $collection->getAttribute('attributes')); $oldAttributes[] = [ 'key' => '$id', @@ -2575,7 +2575,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject) { /** @var Document $database */ - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2598,14 +2598,14 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes') /** * Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries */ - $cursor = \array_filter($queries, function ($query) { + $cursor = \array_filter($queries, function ($query) { return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]); - }); - $cursor = reset($cursor); + }); + $cursor = reset($cursor); if ($cursor) { $indexId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn() => $dbForProject->find('indexes', [ + $cursorDocument = Authorization::skip(fn () => $dbForProject->find('indexes', [ Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('databaseInternalId', [$database->getInternalId()]), Query::equal('key', [$indexId]), @@ -2645,7 +2645,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->inject('dbForProject') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2688,7 +2688,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->inject('queueForEvents') ->action(function (string $databaseId, string $collectionId, string $key, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { - $db = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $db = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($db->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -2771,7 +2771,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, '$id is not allowed for creating new documents, try update instead'); } - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -2780,7 +2780,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -2848,7 +2848,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -2868,7 +2868,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($relations as &$relation) { @@ -2882,7 +2882,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') } if ($relation instanceof Document) { $current = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId()) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId()) ); if ($current->isEmpty()) { @@ -2912,13 +2912,13 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $checkPermissions($collection, $document, Database::PERMISSION_CREATE); - try { - $document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document); - } catch (StructureException $exception) { - throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); - } catch (DuplicateException $exception) { - throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); - } + try { + $document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document); + } catch (StructureException $exception) { + throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); + } catch (DuplicateException $exception) { + throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); + } // Add $collectionId and $databaseId for all documents $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { @@ -2927,7 +2927,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -2942,7 +2942,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($related as $relation) { @@ -2988,7 +2988,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') ->inject('dbForProject') ->inject('mode') ->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -2996,7 +2996,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3020,7 +3020,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') if ($cursor) { $documentId = $cursor->getValue(); - $cursorDocument = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($cursorDocument->isEmpty()) { throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Document '{$documentId}' for the 'cursor' value not found."); @@ -3050,7 +3050,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -3066,7 +3066,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') } $relatedCollectionId = $relationship->getAttribute('relatedCollection'); - $relatedCollection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)); + $relatedCollection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)); foreach ($relations as $index => $doc) { if ($doc instanceof Document) { @@ -3145,7 +3145,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen ->inject('dbForProject') ->inject('mode') ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -3154,7 +3154,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3184,7 +3184,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -3199,7 +3199,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($related as $relation) { @@ -3237,7 +3237,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen ->inject('geodb') ->action(function (string $databaseId, string $collectionId, string $documentId, array $queries, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -3357,7 +3357,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD); } - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -3366,7 +3366,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3374,7 +3374,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum // Read permission should not be required for update /** @var Document $document */ - $document = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($document->isEmpty()) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); @@ -3419,7 +3419,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum $setCollection = (function (Document $collection, Document $document) use (&$setCollection, $dbForProject, $database) { $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -3439,7 +3439,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($relations as &$relation) { @@ -3453,7 +3453,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum $relation = new Document($relation); } if ($relation instanceof Document) { - $oldDocument = Authorization::skip(fn() => $dbForProject->getDocument( + $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument( 'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId() )); @@ -3487,7 +3487,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum try { $document = $dbForProject->withRequestTimestamp( $requestTimestamp, - fn() => $dbForProject->updateDocument( + fn () => $dbForProject->updateDocument( 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document->getId(), $newDocument @@ -3508,7 +3508,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -3523,7 +3523,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($related as $relation) { @@ -3576,7 +3576,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu ->inject('queueForEvents') ->inject('mode') ->action(function (string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $queueForEvents, string $mode) { - $database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId)); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -3585,14 +3585,14 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu throw new Exception(Exception::DATABASE_NOT_FOUND); } - $collection = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); + $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId)); if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception(Exception::COLLECTION_NOT_FOUND); } // Read permission should not be required for delete - $document = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); + $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId)); if ($document->isEmpty()) { throw new Exception(Exception::DOCUMENT_NOT_FOUND); @@ -3618,7 +3618,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $relationships = \array_filter( $collection->getAttribute('attributes', []), - fn($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP ); foreach ($relationships as $relationship) { @@ -3633,7 +3633,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu $relatedCollectionId = $relationship->getAttribute('relatedCollection'); $relatedCollection = Authorization::skip( - fn() => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) + fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId) ); foreach ($related as $relation) { @@ -3715,19 +3715,19 @@ App::get('/v1/databases/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, 'databasesTotal' => $usage[$metrics[0]]['total'], @@ -3799,19 +3799,19 @@ App::get('/v1/databases/:databaseId/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, @@ -3840,9 +3840,9 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') ->inject('dbForProject') ->action(function (string $databaseId, string $range, string $collectionId, Response $response, Database $dbForProject) { - $database = $dbForProject->getDocument('databases', $databaseId); - $collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); - $collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId()); + $database = $dbForProject->getDocument('databases', $databaseId); + $collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); + $collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId()); if ($collection->isEmpty()) { throw new Exception(Exception::COLLECTION_NOT_FOUND); @@ -3885,19 +3885,19 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 0de6f28d57..e4b353dd0d 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -8,44 +8,44 @@ use Appwrite\Event\Event; use Appwrite\Event\Func; use Appwrite\Event\Usage; use Appwrite\Event\Validator\FunctionEvent; -use Appwrite\Utopia\Response\Model\Rule; use Appwrite\Extend\Exception; -use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Messaging\Adapter\Realtime; +use Appwrite\Task\Validator\Cron; +use Appwrite\Utopia\Database\Validator\CustomId; +use Appwrite\Utopia\Database\Validator\Queries\Deployments; +use Appwrite\Utopia\Database\Validator\Queries\Executions; +use Appwrite\Utopia\Database\Validator\Queries\Functions; +use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Model\Rule; +use Executor\Executor; +use MaxMind\Db\Reader; +use Utopia\App; +use Utopia\CLI\Console; +use Utopia\Config\Config; +use Utopia\Database\Database; +use Utopia\Database\DateTime; +use Utopia\Database\Document; +use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Query as QueryException; -use Utopia\Validator\Assoc; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Roles; use Utopia\Database\Validator\UID; use Utopia\Storage\Device; use Utopia\Storage\Validator\File; use Utopia\Storage\Validator\FileExt; use Utopia\Storage\Validator\FileSize; use Utopia\Storage\Validator\Upload; -use Appwrite\Utopia\Response; use Utopia\Swoole\Request; -use Appwrite\Task\Validator\Cron; -use Appwrite\Utopia\Database\Validator\Queries\Deployments; -use Appwrite\Utopia\Database\Validator\Queries\Executions; -use Appwrite\Utopia\Database\Validator\Queries\Functions; -use Utopia\App; -use Utopia\Database\Database; -use Utopia\Database\Document; -use Utopia\Database\DateTime; -use Utopia\Database\Query; -use Utopia\Database\Validator\Authorization; use Utopia\Validator\ArrayList; -use Utopia\Validator\Text; -use Utopia\Validator\Range; -use Utopia\Validator\WhiteList; -use Utopia\Config\Config; -use Executor\Executor; -use Utopia\CLI\Console; -use Utopia\Database\Validator\Roles; +use Utopia\Validator\Assoc; use Utopia\Validator\Boolean; -use Utopia\Database\Exception\Duplicate as DuplicateException; -use MaxMind\Db\Reader; +use Utopia\Validator\Range; +use Utopia\Validator\Text; +use Utopia\Validator\WhiteList; use Utopia\VCS\Adapter\Git\GitHub; use Utopia\VCS\Exception\RepositoryNotFound; @@ -529,19 +529,19 @@ App::get('/v1/functions/:functionId/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, @@ -621,19 +621,19 @@ App::get('/v1/functions/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, 'functionsTotal' => $usage[$metrics[0]]['total'], diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php index 53f0c5bb25..abb47ab3c4 100644 --- a/app/controllers/api/locale.php +++ b/app/controllers/api/locale.php @@ -1,7 +1,7 @@ format($format); $metrics = [ - 'total' => [ + 'total' => [ METRIC_EXECUTIONS, METRIC_DOCUMENTS, METRIC_DATABASES, METRIC_USERS, METRIC_BUCKETS, METRIC_FILES_STORAGE - ], - 'period' => [ + ], + 'period' => [ METRIC_NETWORK_REQUESTS, METRIC_NETWORK_INBOUND, METRIC_NETWORK_OUTBOUND, METRIC_USERS, METRIC_EXECUTIONS - ] + ] ]; $factor = match ($period) { diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index d0acdbe15e..62b0ef64c8 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1,49 +1,48 @@ desc('Create bucket') @@ -636,7 +635,7 @@ App::post('/v1/storage/buckets/:bucketId/files') if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -683,7 +682,7 @@ App::post('/v1/storage/buckets/:bucketId/files') if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -766,7 +765,7 @@ App::get('/v1/storage/buckets/:bucketId/files') if ($fileSecurity && !$valid) { $cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $cursorDocument = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($cursorDocument->isEmpty()) { @@ -829,7 +828,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -899,7 +898,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1055,7 +1054,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1194,7 +1193,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if ($file->isEmpty()) { @@ -1353,7 +1352,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId') } // Read permission should not be required for update - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); if ($file->isEmpty()) { throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); @@ -1404,7 +1403,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId') throw new Exception(Exception::USER_UNAUTHORIZED); } } else { - $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } $queueForEvents @@ -1458,7 +1457,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') } // Read permission should not be required for delete - $file = Authorization::skip(fn() => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); if ($file->isEmpty()) { throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); @@ -1492,7 +1491,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') throw new Exception(Exception::USER_UNAUTHORIZED); } } else { - $deleted = Authorization::skip(fn() => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); + $deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); } if (!$deleted) { @@ -1567,19 +1566,19 @@ App::get('/v1/storage/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, 'bucketsTotal' => $usage[$metrics[0]]['total'], @@ -1653,19 +1652,19 @@ App::get('/v1/storage/:bucketId/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 5591f307aa..5d13fcfa6e 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -10,15 +10,10 @@ use Appwrite\Event\Mail; use Appwrite\Event\Messaging; use Appwrite\Extend\Exception; use Appwrite\Network\Validator\Email; -use Utopia\Database\Exception\Query as QueryException; -use Utopia\Validator\Host; use Appwrite\Template\Template; use Appwrite\Utopia\Database\Validator\CustomId; -use Utopia\Database\Validator\Queries; use Appwrite\Utopia\Database\Validator\Queries\Memberships; use Appwrite\Utopia\Database\Validator\Queries\Teams; -use Utopia\Database\Validator\Query\Limit; -use Utopia\Database\Validator\Query\Offset; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use MaxMind\Db\Reader; @@ -26,20 +21,25 @@ use Utopia\App; use Utopia\Audit\Audit; use Utopia\Config\Config; use Utopia\Database\Database; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Duplicate; +use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; -use Utopia\Database\Query; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Key; +use Utopia\Database\Validator\Queries; +use Utopia\Database\Validator\Query\Limit; +use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; use Utopia\Locale\Locale; use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; +use Utopia\Validator\Host; use Utopia\Validator\Text; App::post('/v1/teams') @@ -71,7 +71,7 @@ App::post('/v1/teams') $teamId = $teamId == 'unique()' ? ID::unique() : $teamId; try { - $team = Authorization::skip(fn() => $dbForProject->createDocument('teams', new Document([ + $team = Authorization::skip(fn () => $dbForProject->createDocument('teams', new Document([ '$id' => $teamId, '$permissions' => [ Permission::read(Role::team($teamId)), @@ -386,7 +386,7 @@ App::post('/v1/teams/:teamId/memberships') ->param('userId', '', new UID(), 'ID of the user to be added to a team.', true) ->param('phone', '', new Phone(), 'Phone number. Format this number with a leading \'+\' and a country code, e.g., +16175551212.', true) ->param('roles', [], new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.') - ->param('url', '', fn($clients) => new Host($clients), 'URL to redirect the user back to your app from the invitation 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.', true, ['clients']) // TODO add our own built-in confirm page + ->param('url', '', fn ($clients) => new Host($clients), 'URL to redirect the user back to your app from the invitation 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.', true, ['clients']) // TODO add our own built-in confirm page ->param('name', '', new Text(128), 'Name of the new team member. Max length: 128 chars.', true) ->inject('response') ->inject('project') @@ -470,7 +470,7 @@ App::post('/v1/teams/:teamId/memberships') try { $userId = ID::unique(); - $invitee = Authorization::skip(fn() => $dbForProject->createDocument('users', new Document([ + $invitee = Authorization::skip(fn () => $dbForProject->createDocument('users', new Document([ '$id' => $userId, '$permissions' => [ Permission::read(Role::any()), @@ -538,12 +538,12 @@ App::post('/v1/teams/:teamId/memberships') if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership try { - $membership = Authorization::skip(fn() => $dbForProject->createDocument('memberships', $membership)); + $membership = Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)); } catch (Duplicate $th) { throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS); } - Authorization::skip(fn() => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); + Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); $dbForProject->purgeCachedDocument('users', $invitee->getId()); } else { @@ -752,7 +752,7 @@ App::get('/v1/teams/:teamId/memberships') max: APP_LIMIT_COUNT ); - $memberships = array_filter($memberships, fn(Document $membership) => !empty($membership->getAttribute('userId'))); + $memberships = array_filter($memberships, fn (Document $membership) => !empty($membership->getAttribute('userId'))); $memberships = array_map(function ($membership) use ($dbForProject, $team) { $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); @@ -951,7 +951,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH); } - $team = Authorization::skip(fn() => $dbForProject->getDocument('teams', $teamId)); + $team = Authorization::skip(fn () => $dbForProject->getDocument('teams', $teamId)); if ($team->isEmpty()) { throw new Exception(Exception::TEAM_NOT_FOUND); @@ -982,7 +982,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') ->setAttribute('confirm', true) ; - Authorization::skip(fn() => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true))); + Authorization::skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true))); // Log user in @@ -1022,7 +1022,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') $dbForProject->purgeCachedDocument('users', $user->getId()); - Authorization::skip(fn() => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); + Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1)); $queueForEvents ->setParam('teamId', $team->getId()) @@ -1102,7 +1102,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId') $dbForProject->purgeCachedDocument('users', $user->getId()); if ($membership->getAttribute('confirm')) { // Count only confirmed members - Authorization::skip(fn() => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0)); + Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0)); } $queueForEvents diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 8976510001..d29712e000 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -4,48 +4,48 @@ use Appwrite\Auth\Auth; use Appwrite\Auth\MFA\Type; use Appwrite\Auth\MFA\Type\TOTP; use Appwrite\Auth\Validator\Password; +use Appwrite\Auth\Validator\PasswordDictionary; +use Appwrite\Auth\Validator\PasswordHistory; +use Appwrite\Auth\Validator\PersonalData; use Appwrite\Auth\Validator\Phone; use Appwrite\Detector\Detector; use Appwrite\Event\Delete; use Appwrite\Event\Event; +use Appwrite\Extend\Exception; +use Appwrite\Hooks\Hooks; use Appwrite\Network\Validator\Email; use Appwrite\Utopia\Database\Validator\CustomId; use Appwrite\Utopia\Database\Validator\Queries\Identities; use Appwrite\Utopia\Database\Validator\Queries\Targets; -use Utopia\Database\Exception\Query as QueryException; -use Utopia\Database\Validator\Queries; use Appwrite\Utopia\Database\Validator\Queries\Users; -use Utopia\Database\Validator\Query\Limit; -use Utopia\Database\Validator\Query\Offset; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; +use MaxMind\Db\Reader; use Utopia\App; use Utopia\Audit\Audit; use Utopia\Config\Config; +use Utopia\Database\Database; +use Utopia\Database\DateTime; +use Utopia\Database\Document; +use Utopia\Database\Exception\Duplicate; +use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -use Utopia\Locale\Locale; -use Appwrite\Extend\Exception; -use Utopia\Database\Document; -use Utopia\Database\DateTime; -use Utopia\Database\Exception\Duplicate; -use Utopia\Database\Validator\UID; -use Utopia\Database\Database; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Queries; +use Utopia\Database\Validator\Query\Limit; +use Utopia\Database\Validator\Query\Offset; +use Utopia\Database\Validator\UID; +use Utopia\Locale\Locale; use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; -use Utopia\Validator\WhiteList; -use Utopia\Validator\Text; use Utopia\Validator\Boolean; -use Utopia\Validator\Range; -use MaxMind\Db\Reader; use Utopia\Validator\Integer; -use Appwrite\Auth\Validator\PasswordHistory; -use Appwrite\Auth\Validator\PasswordDictionary; -use Appwrite\Auth\Validator\PersonalData; -use Appwrite\Hooks\Hooks; +use Utopia\Validator\Range; +use Utopia\Validator\Text; +use Utopia\Validator\WhiteList; /** TODO: Remove function when we move to using utopia/platform */ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks): Document @@ -2150,19 +2150,19 @@ App::get('/v1/users/usage') '1d' => 'Y-m-d\T00:00:00.000P', }; - foreach ($metrics as $metric) { - $usage[$metric]['total'] = $stats[$metric]['total']; - $usage[$metric]['data'] = []; - $leap = time() - ($days['limit'] * $days['factor']); - while ($leap < time()) { - $leap += $days['factor']; - $formatDate = date($format, $leap); - $usage[$metric]['data'][] = [ - 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, - 'date' => $formatDate, - ]; + foreach ($metrics as $metric) { + $usage[$metric]['total'] = $stats[$metric]['total']; + $usage[$metric]['data'] = []; + $leap = time() - ($days['limit'] * $days['factor']); + while ($leap < time()) { + $leap += $days['factor']; + $formatDate = date($format, $leap); + $usage[$metric]['data'][] = [ + 'value' => $stats[$metric]['data'][$formatDate]['value'] ?? 0, + 'date' => $formatDate, + ]; + } } - } $response->dynamic(new Document([ 'range' => $range, diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index 09ec5d7690..ea30d6b11d 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -1,23 +1,20 @@ getRegisterable() : '.' . $request->getHostname() ) diff --git a/app/controllers/mock.php b/app/controllers/mock.php index fc168ead26..f933c62e6e 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -3,19 +3,19 @@ global $utopia, $request, $response; use Appwrite\Extend\Exception; -use Utopia\Database\Document; -use Utopia\Validator\Host; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; use Utopia\Database\Database; -use Utopia\Validator\Text; -use Utopia\Validator\WhiteList; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; -use Utopia\Database\Validator\UID; -use Utopia\VCS\Adapter\Git\GitHub; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Database\Validator\UID; +use Utopia\Validator\Host; +use Utopia\Validator\Text; +use Utopia\Validator\WhiteList; +use Utopia\VCS\Adapter\Git\GitHub; App::get('/v1/mock/tests/general/oauth2') ->desc('OAuth Login') diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index f8d2a351ba..449ca9c405 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -9,22 +9,22 @@ use Appwrite\Event\Delete; use Appwrite\Event\Event; use Appwrite\Event\Func; use Appwrite\Event\Messaging; -use Appwrite\Extend\Exception; use Appwrite\Event\Usage; +use Appwrite\Extend\Exception; use Appwrite\Messaging\Adapter\Realtime; -use Appwrite\Utopia\Response; use Appwrite\Utopia\Request; -use Utopia\App; +use Appwrite\Utopia\Response; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\App; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; +use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; -use Utopia\Database\Validator\Authorization; -use Utopia\Config\Config; use Utopia\Database\Helpers\Role; +use Utopia\Database\Validator\Authorization; use Utopia\Validator\WhiteList; $parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) { @@ -677,10 +677,10 @@ App::shutdown() $now = DateTime::now(); if ($cacheLog->isEmpty()) { Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([ - '$id' => $key, - 'resource' => $resource, - 'accessedAt' => $now, - 'signature' => $signature, + '$id' => $key, + 'resource' => $resource, + 'accessedAt' => $now, + 'signature' => $signature, ]))); } elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) { $cacheLog->setAttribute('accessedAt', $now); diff --git a/app/controllers/shared/api/auth.php b/app/controllers/shared/api/auth.php index 2f436a1436..7f304454be 100644 --- a/app/controllers/shared/api/auth.php +++ b/app/controllers/shared/api/auth.php @@ -1,13 +1,13 @@ groups(['mfaProtected']) diff --git a/app/http.php b/app/http.php index 086260cb62..ddf25dd744 100644 --- a/app/http.php +++ b/app/http.php @@ -2,28 +2,28 @@ require_once __DIR__ . '/../vendor/autoload.php'; +use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Swoole\Constant; -use Swoole\Process; -use Swoole\Http\Server; use Swoole\Http\Request as SwooleRequest; use Swoole\Http\Response as SwooleResponse; +use Swoole\Http\Server; +use Swoole\Process; +use Utopia\Abuse\Adapters\TimeLimit; use Utopia\App; +use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; -use Utopia\Audit\Audit; -use Utopia\Abuse\Adapters\TimeLimit; -use Utopia\Database\Database; -use Utopia\Database\Document; -use Utopia\Swoole\Files; -use Appwrite\Utopia\Request; use Utopia\Logger\Log; use Utopia\Logger\Log\User; use Utopia\Pools\Group; +use Utopia\Swoole\Files; $http = new Server( host: "0.0.0.0", diff --git a/app/init.php b/app/init.php index c7c07c5501..5f8b0f3030 100644 --- a/app/init.php +++ b/app/init.php @@ -18,38 +18,56 @@ ini_set('display_startup_errors', 1); ini_set('default_socket_timeout', -1); error_reporting(E_ALL); +use Ahc\Jwt\JWT; +use Ahc\Jwt\JWTException; +use Appwrite\Auth\Auth; +use Appwrite\Event\Audit; +use Appwrite\Event\Build; +use Appwrite\Event\Certificate; +use Appwrite\Event\Database as EventDatabase; +use Appwrite\Event\Delete; +use Appwrite\Event\Event; +use Appwrite\Event\Func; +use Appwrite\Event\Mail; +use Appwrite\Event\Messaging; use Appwrite\Event\Migration; use Appwrite\Event\Usage; use Appwrite\Extend\Exception; -use Appwrite\Auth\Auth; -use Appwrite\Event\Audit; -use Appwrite\Event\Database as EventDatabase; -use Appwrite\Event\Event; -use Appwrite\Event\Mail; -use Appwrite\Event\Messaging; -use Appwrite\Event\Delete; +use Appwrite\GraphQL\Promises\Adapter\Swoole; use Appwrite\GraphQL\Schema; +use Appwrite\Hooks\Hooks; use Appwrite\Network\Validator\Email; use Appwrite\Network\Validator\Origin; use Appwrite\OpenSSL\OpenSSL; use Appwrite\URL\URL as AppwriteURL; +use MaxMind\Db\Reader; +use PHPMailer\PHPMailer\PHPMailer; +use Swoole\Database\PDOProxy; use Utopia\App; -use Utopia\Database\Adapter\SQL; -use Utopia\Database\Exception\Query as QueryException; -use Utopia\Logger\Logger; use Utopia\Cache\Adapter\Redis as RedisCache; +use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; +use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Database\Helpers\ID; +use Utopia\Database\Adapter\MariaDB; +use Utopia\Database\Adapter\MySQL; +use Utopia\Database\Adapter\SQL; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Validator\Structure; -use Utopia\Locale\Locale; +use Utopia\Domains\Validator\PublicDomain; use Utopia\DSN\DSN; -use Appwrite\GraphQL\Promises\Adapter\Swoole; +use Utopia\Locale\Locale; +use Utopia\Logger\Log; +use Utopia\Logger\Logger; +use Utopia\Pools\Group; +use Utopia\Pools\Pool; +use Utopia\Queue; +use Utopia\Queue\Connection; use Utopia\Registry\Registry; use Utopia\Storage\Device; use Utopia\Storage\Device\Backblaze; @@ -58,32 +76,13 @@ use Utopia\Storage\Device\Linode; use Utopia\Storage\Device\Local; use Utopia\Storage\Device\S3; use Utopia\Storage\Device\Wasabi; -use Utopia\Cache\Adapter\Sharding; -use Utopia\Database\Adapter\MariaDB; -use Utopia\Database\Adapter\MySQL; -use Utopia\Pools\Group; -use Utopia\Pools\Pool; -use Ahc\Jwt\JWT; -use Ahc\Jwt\JWTException; -use Appwrite\Event\Build; -use Appwrite\Event\Certificate; -use Appwrite\Event\Func; -use Appwrite\Hooks\Hooks; -use MaxMind\Db\Reader; -use PHPMailer\PHPMailer\PHPMailer; -use Swoole\Database\PDOProxy; -use Utopia\Logger\Log; -use Utopia\Queue; -use Utopia\Queue\Connection; use Utopia\Storage\Storage; -use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub; -use Utopia\Validator\Range; use Utopia\Validator\Hostname; use Utopia\Validator\IP; +use Utopia\Validator\Range; use Utopia\Validator\URL; use Utopia\Validator\WhiteList; -use Utopia\CLI\Console; -use Utopia\Domains\Validator\PublicDomain; +use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub; const APP_NAME = 'Appwrite'; const APP_DOMAIN = 'appwrite.io'; @@ -296,7 +295,7 @@ Database::addFilter( }, function (mixed $value) { if (is_null($value)) { - return null; + return; } return json_decode($value, true)['value']; @@ -350,7 +349,7 @@ Database::addFilter( Database::addFilter( 'subQueryAttributes', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { $attributes = $database->find('attributes', [ @@ -376,7 +375,7 @@ Database::addFilter( Database::addFilter( 'subQueryIndexes', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -391,7 +390,7 @@ Database::addFilter( Database::addFilter( 'subQueryPlatforms', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -405,7 +404,7 @@ Database::addFilter( Database::addFilter( 'subQueryKeys', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -419,7 +418,7 @@ Database::addFilter( Database::addFilter( 'subQueryWebhooks', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -433,7 +432,7 @@ Database::addFilter( Database::addFilter( 'subQuerySessions', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return Authorization::skip(fn () => $database->find('sessions', [ @@ -446,10 +445,10 @@ Database::addFilter( Database::addFilter( 'subQueryTokens', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn() => $database + return Authorization::skip(fn () => $database ->find('tokens', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -460,10 +459,10 @@ Database::addFilter( Database::addFilter( 'subQueryChallenges', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn() => $database + return Authorization::skip(fn () => $database ->find('challenges', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -474,10 +473,10 @@ Database::addFilter( Database::addFilter( 'subQueryAuthenticators', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn() => $database + return Authorization::skip(fn () => $database ->find('authenticators', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -488,10 +487,10 @@ Database::addFilter( Database::addFilter( 'subQueryMemberships', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn() => $database + return Authorization::skip(fn () => $database ->find('memberships', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY), @@ -502,7 +501,7 @@ Database::addFilter( Database::addFilter( 'subQueryVariables', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -531,7 +530,7 @@ Database::addFilter( }, function (mixed $value) { if (is_null($value)) { - return null; + return; } $value = json_decode($value, true); $key = App::getEnv('_APP_OPENSSL_KEY_V' . $value['version']); @@ -543,7 +542,7 @@ Database::addFilter( Database::addFilter( 'subQueryProjectVariables', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { return $database @@ -580,10 +579,10 @@ Database::addFilter( Database::addFilter( 'subQueryTargets', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { - return Authorization::skip(fn() => $database + return Authorization::skip(fn () => $database ->find('targets', [ Query::equal('userInternalId', [$document->getInternalId()]), Query::limit(APP_LIMIT_SUBQUERY) @@ -594,7 +593,7 @@ Database::addFilter( Database::addFilter( 'subQueryTopicTargets', function (mixed $value) { - return null; + return; }, function (mixed $value, Document $document, Database $database) { $targetIds = Authorization::skip(fn () => \array_map( @@ -724,7 +723,7 @@ $register->set('logger', function () { $providerConfig = App::getEnv('_APP_LOGGING_CONFIG', ''); if (empty($providerName) || empty($providerConfig)) { - return null; + return; } if (!Logger::hasProvider($providerName)) { @@ -1011,7 +1010,7 @@ foreach ($locales as $locale) { ]); // Runtime Execution -App::setResource('log', fn() => new Log()); +App::setResource('log', fn () => new Log()); App::setResource('logger', function ($register) { return $register->get('logger'); }, ['register']); @@ -1020,11 +1019,11 @@ App::setResource('hooks', function ($register) { return $register->get('hooks'); }, ['register']); -App::setResource('register', fn() => $register); -App::setResource('locale', fn() => new Locale(App::getEnv('_APP_LOCALE', 'en'))); +App::setResource('register', fn () => $register); +App::setResource('locale', fn () => new Locale(App::getEnv('_APP_LOCALE', 'en'))); App::setResource('localeCodes', function () { - return array_map(fn($locale) => $locale['code'], Config::getParam('locale-codes', [])); + return array_map(fn ($locale) => $locale['code'], Config::getParam('locale-codes', [])); }); // Queues @@ -1233,14 +1232,14 @@ App::setResource('project', function ($dbForConsole, $request, $console) { return $console; } - $project = Authorization::skip(fn() => $dbForConsole->getDocument('projects', $projectId)); + $project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId)); return $project; }, ['dbForConsole', 'request', 'console']); App::setResource('session', function (Document $user, Document $project) { if ($user->isEmpty()) { - return null; + return; } $sessions = $user->getAttribute('sessions', []); @@ -1248,7 +1247,7 @@ App::setResource('session', function (Document $user, Document $project) { $sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration); if (!$sessionId) { - return null; + return; } foreach ($sessions as $session) {/** @var Document $session */ @@ -1257,7 +1256,7 @@ App::setResource('session', function (Document $user, Document $project) { } } - return null; + return; }, ['user', 'project']); App::setResource('console', function () { @@ -1543,7 +1542,7 @@ App::setResource('schema', function ($utopia, $dbForProject) { }; $attributes = function (int $limit, int $offset) use ($dbForProject) { - $attrs = Authorization::skip(fn() => $dbForProject->find('attributes', [ + $attrs = Authorization::skip(fn () => $dbForProject->find('attributes', [ Query::limit($limit), Query::offset($offset), ])); diff --git a/app/realtime.php b/app/realtime.php index 663e8c9e7f..fd7d69bbf5 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -14,20 +14,20 @@ use Swoole\Timer; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\App; -use Utopia\CLI\Console; -use Utopia\Database\Helpers\ID; -use Utopia\Database\Helpers\Role; -use Utopia\Logger\Log; -use Utopia\Database\DateTime; -use Utopia\Database\Document; -use Utopia\Database\Query; -use Utopia\Database\Validator\Authorization; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; +use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; -use Utopia\WebSocket\Server; +use Utopia\Database\DateTime; +use Utopia\Database\Document; +use Utopia\Database\Helpers\ID; +use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; +use Utopia\Logger\Log; use Utopia\WebSocket\Adapter; +use Utopia\WebSocket\Server; /** * @var \Utopia\Registry\Registry $register @@ -340,7 +340,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) { $connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId])); $consoleDatabase = getConsoleDB(); - $project = Authorization::skip(fn() => $consoleDatabase->getDocument('projects', $projectId)); + $project = Authorization::skip(fn () => $consoleDatabase->getDocument('projects', $projectId)); $database = getProjectDB($project); $user = $database->getDocument('users', $userId); @@ -395,9 +395,9 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, Console::info("Connection open (user: {$connection})"); - App::setResource('pools', fn() => $register->get('pools')); - App::setResource('request', fn() => $request); - App::setResource('response', fn() => $response); + App::setResource('pools', fn () => $register->get('pools')); + App::setResource('request', fn () => $request); + App::setResource('response', fn () => $response); try { /** @var Document $project */ @@ -502,7 +502,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $database = getConsoleDB(); if ($projectId !== 'console') { - $project = Authorization::skip(fn() => $database->getDocument('projects', $projectId)); + $project = Authorization::skip(fn () => $database->getDocument('projects', $projectId)); $database = getProjectDB($project); } else { $project = null; diff --git a/app/worker.php b/app/worker.php index f29e8ade62..98a1e40a88 100644 --- a/app/worker.php +++ b/app/worker.php @@ -2,18 +2,17 @@ require_once __DIR__ . '/init.php'; -use Appwrite\Event\Event; use Appwrite\Event\Audit; use Appwrite\Event\Build; use Appwrite\Event\Certificate; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Delete; +use Appwrite\Event\Event; use Appwrite\Event\Func; use Appwrite\Event\Hamster; use Appwrite\Event\Mail; use Appwrite\Event\Messaging; use Appwrite\Event\Migration; -use Appwrite\Event\Phone; use Appwrite\Event\Usage; use Appwrite\Event\UsageDump; use Appwrite\Platform\Appwrite; @@ -27,14 +26,14 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; +use Utopia\Logger\Log; +use Utopia\Logger\Logger; use Utopia\Platform\Service; +use Utopia\Pools\Group; +use Utopia\Queue\Connection; use Utopia\Queue\Message; use Utopia\Queue\Server; use Utopia\Registry\Registry; -use Utopia\Logger\Log; -use Utopia\Logger\Logger; -use Utopia\Pools\Group; -use Utopia\Queue\Connection; use Utopia\Storage\Device\Local; Authorization::disable(); @@ -141,7 +140,7 @@ Server::setResource('cache', function (Registry $register) { return new Cache(new Sharding($adapters)); }, ['register']); -Server::setResource('log', fn() => new Log()); +Server::setResource('log', fn () => new Log()); Server::setResource('queueForUsage', function (Connection $queue) { return new Usage($queue); diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index a25c6123ea..1e8109622e 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -9,8 +9,8 @@ use Appwrite\Auth\Hash\Phpass; use Appwrite\Auth\Hash\Scrypt; use Appwrite\Auth\Hash\Scryptmodified; use Appwrite\Auth\Hash\Sha; -use Utopia\Database\Document; use Utopia\Database\DateTime; +use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Roles; diff --git a/src/Appwrite/Auth/OAuth2/Authentik.php b/src/Appwrite/Auth/OAuth2/Authentik.php index 16822e2c9f..5d2445088b 100644 --- a/src/Appwrite/Auth/OAuth2/Authentik.php +++ b/src/Appwrite/Auth/OAuth2/Authentik.php @@ -171,11 +171,11 @@ class Authentik extends OAuth2 return ''; } - /** - * @param string $accessToken - * - * @return array - */ + /** + * @param string $accessToken + * + * @return array + */ protected function getUser(string $accessToken): array { if (empty($this->user)) { @@ -199,11 +199,11 @@ class Authentik extends OAuth2 return $secret['clientSecret'] ?? ''; } - /** - * Extracts the authentik Domain from the JSON stored in appSecret - * - * @return string - */ + /** + * Extracts the authentik Domain from the JSON stored in appSecret + * + * @return string + */ protected function getAuthentikDomain(): string { $secret = $this->getAppSecret(); diff --git a/src/Appwrite/Auth/OAuth2/Discord.php b/src/Appwrite/Auth/OAuth2/Discord.php index b77ce6a236..a5ecdb5e3c 100644 --- a/src/Appwrite/Auth/OAuth2/Discord.php +++ b/src/Appwrite/Auth/OAuth2/Discord.php @@ -28,8 +28,8 @@ class Discord extends OAuth2 * @var array */ protected array $scopes = [ - 'identify', - 'email' + 'identify', + 'email' ]; /** diff --git a/src/Appwrite/Auth/OAuth2/Mock.php b/src/Appwrite/Auth/OAuth2/Mock.php index d2cb8c1c2a..61ce41d1b7 100644 --- a/src/Appwrite/Auth/OAuth2/Mock.php +++ b/src/Appwrite/Auth/OAuth2/Mock.php @@ -3,7 +3,6 @@ namespace Appwrite\Auth\OAuth2; use Appwrite\Auth\OAuth2; -use Utopia\Exception; class Mock extends OAuth2 { diff --git a/src/Appwrite/Auth/OAuth2/Oidc.php b/src/Appwrite/Auth/OAuth2/Oidc.php index de2eab65c8..670169fe89 100644 --- a/src/Appwrite/Auth/OAuth2/Oidc.php +++ b/src/Appwrite/Auth/OAuth2/Oidc.php @@ -168,11 +168,11 @@ class Oidc extends OAuth2 return ''; } - /** - * @param string $accessToken - * - * @return array - */ + /** + * @param string $accessToken + * + * @return array + */ protected function getUser(string $accessToken): array { if (empty($this->user)) { @@ -196,11 +196,11 @@ class Oidc extends OAuth2 return $secret['clientSecret'] ?? ''; } - /** - * Extracts the well known endpoint from the JSON stored in appSecret. - * - * @return string - */ + /** + * Extracts the well known endpoint from the JSON stored in appSecret. + * + * @return string + */ protected function getWellKnownEndpoint(): string { $secret = $this->getAppSecret(); @@ -266,9 +266,9 @@ class Oidc extends OAuth2 return $wellKnownConfiguration['userinfo_endpoint'] ?? ''; } - /** - * Get the well-known configuration using the well known endpoint - */ + /** + * Get the well-known configuration using the well known endpoint + */ protected function getWellKnownConfiguration(): array { if (empty($this->wellKnownConfiguration)) { diff --git a/src/Appwrite/Auth/OAuth2/PaypalSandbox.php b/src/Appwrite/Auth/OAuth2/PaypalSandbox.php index 0f56a09c21..e5ab612c0d 100644 --- a/src/Appwrite/Auth/OAuth2/PaypalSandbox.php +++ b/src/Appwrite/Auth/OAuth2/PaypalSandbox.php @@ -2,8 +2,6 @@ namespace Appwrite\Auth\OAuth2; -use Appwrite\Auth\OAuth2\Paypal; - class PaypalSandbox extends Paypal { protected string $environment = 'sandbox'; diff --git a/src/Appwrite/Auth/OAuth2/Podio.php b/src/Appwrite/Auth/OAuth2/Podio.php index e4194238d1..0b1f35414b 100644 --- a/src/Appwrite/Auth/OAuth2/Podio.php +++ b/src/Appwrite/Auth/OAuth2/Podio.php @@ -148,7 +148,7 @@ class Podio extends OAuth2 $user = $this->getUser($accessToken); $mails = $user['mails']; - $mainMailIndex = \array_search($user['mail'], \array_map(fn($m) => $m['mail'], $mails)); + $mainMailIndex = \array_search($user['mail'], \array_map(fn ($m) => $m['mail'], $mails)); $mainMain = $mails[$mainMailIndex]; if ($mainMain['verified'] ?? false) { diff --git a/src/Appwrite/Auth/OAuth2/Stripe.php b/src/Appwrite/Auth/OAuth2/Stripe.php index 5a959dbfcb..9d1c9206ad 100644 --- a/src/Appwrite/Auth/OAuth2/Stripe.php +++ b/src/Appwrite/Auth/OAuth2/Stripe.php @@ -3,7 +3,6 @@ namespace Appwrite\Auth\OAuth2; use Appwrite\Auth\OAuth2; -use Utopia\Exception; class Stripe extends OAuth2 { diff --git a/src/Appwrite/Auth/OAuth2/TradeshiftBox.php b/src/Appwrite/Auth/OAuth2/TradeshiftBox.php index 27a4c0a456..d960acf2d3 100644 --- a/src/Appwrite/Auth/OAuth2/TradeshiftBox.php +++ b/src/Appwrite/Auth/OAuth2/TradeshiftBox.php @@ -2,8 +2,6 @@ namespace Appwrite\Auth\OAuth2; -use Appwrite\Auth\OAuth2\Tradeshift; - class TradeshiftBox extends Tradeshift { protected string $environment = 'sandbox'; diff --git a/src/Appwrite/Docker/Env.php b/src/Appwrite/Docker/Env.php index bce12a95e6..51ec9e167c 100644 --- a/src/Appwrite/Docker/Env.php +++ b/src/Appwrite/Docker/Env.php @@ -2,8 +2,6 @@ namespace Appwrite\Docker; -use Exception; - class Env { /** diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index 9f71ef5ebc..fa9ddf1315 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -454,9 +454,9 @@ class Event if ($subCurrent === $current || $subCurrent === $key) { continue; } - $filtered1 = \array_filter($paramKeys, fn(string $k) => $k === $subCurrent); + $filtered1 = \array_filter($paramKeys, fn (string $k) => $k === $subCurrent); $events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered1, '*', $eventPattern)); - $filtered2 = \array_filter($paramKeys, fn(string $k) => $k === $current); + $filtered2 = \array_filter($paramKeys, fn (string $k) => $k === $current); $events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', \str_replace($filtered1, '*', $eventPattern))); $events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', $eventPattern)); } @@ -464,7 +464,7 @@ class Event if ($current === $key) { continue; } - $filtered = \array_filter($paramKeys, fn(string $k) => $k === $current); + $filtered = \array_filter($paramKeys, fn (string $k) => $k === $current); $events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered, '*', $eventPattern)); } } diff --git a/src/Appwrite/Event/Messaging.php b/src/Appwrite/Event/Messaging.php index f8ea9e472b..f97ff02d21 100644 --- a/src/Appwrite/Event/Messaging.php +++ b/src/Appwrite/Event/Messaging.php @@ -3,8 +3,8 @@ namespace Appwrite\Event; use Utopia\Database\Document; -use Utopia\Queue\Connection; use Utopia\Queue\Client; +use Utopia\Queue\Connection; class Messaging extends Event { diff --git a/src/Appwrite/Event/Usage.php b/src/Appwrite/Event/Usage.php index ded276e166..cf92e6ffef 100644 --- a/src/Appwrite/Event/Usage.php +++ b/src/Appwrite/Event/Usage.php @@ -2,10 +2,9 @@ namespace Appwrite\Event; -use Utopia\CLI\Console; +use Utopia\Database\Document; use Utopia\Queue\Client; use Utopia\Queue\Connection; -use Utopia\Database\Document; class Usage extends Event { diff --git a/src/Appwrite/Event/Validator/FunctionEvent.php b/src/Appwrite/Event/Validator/FunctionEvent.php index 6443b127ad..dceb2df1ae 100644 --- a/src/Appwrite/Event/Validator/FunctionEvent.php +++ b/src/Appwrite/Event/Validator/FunctionEvent.php @@ -2,8 +2,6 @@ namespace Appwrite\Event\Validator; -use Utopia\Config\Config; - class FunctionEvent extends Event { /** diff --git a/src/Appwrite/GraphQL/Resolvers.php b/src/Appwrite/GraphQL/Resolvers.php index 37bc1d922b..a1f6af0f3f 100644 --- a/src/Appwrite/GraphQL/Resolvers.php +++ b/src/Appwrite/GraphQL/Resolvers.php @@ -23,7 +23,7 @@ class Resolvers App $utopia, ?Route $route, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $route, $args, $context, $info) { /** @var App $utopia */ /** @var Response $response */ @@ -94,7 +94,7 @@ class Resolvers string $collectionId, callable $url, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $type, $args) { $utopia = $utopia->getResource('utopia:graphql', true); $request = $utopia->getResource('request', true); @@ -125,7 +125,7 @@ class Resolvers callable $url, callable $params, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) { $utopia = $utopia->getResource('utopia:graphql', true); $request = $utopia->getResource('request', true); @@ -161,7 +161,7 @@ class Resolvers callable $url, callable $params, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) { $utopia = $utopia->getResource('utopia:graphql', true); $request = $utopia->getResource('request', true); @@ -193,7 +193,7 @@ class Resolvers callable $url, callable $params, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $params, $type, $args) { $utopia = $utopia->getResource('utopia:graphql', true); $request = $utopia->getResource('request', true); @@ -223,7 +223,7 @@ class Resolvers string $collectionId, callable $url, ): callable { - return static fn($type, $args, $context, $info) => new Swoole( + return static fn ($type, $args, $context, $info) => new Swoole( function (callable $resolve, callable $reject) use ($utopia, $databaseId, $collectionId, $url, $type, $args) { $utopia = $utopia->getResource('utopia:graphql', true); $request = $utopia->getResource('request', true); @@ -263,7 +263,7 @@ class Resolvers } $request = clone $request; - $utopia->setResource('request', static fn() => $request); + $utopia->setResource('request', static fn () => $request); $response->setContentType(Response::CONTENT_TYPE_NULL); try { diff --git a/src/Appwrite/GraphQL/Schema.php b/src/Appwrite/GraphQL/Schema.php index 11f728e571..833ea9d032 100644 --- a/src/Appwrite/GraphQL/Schema.php +++ b/src/Appwrite/GraphQL/Schema.php @@ -230,7 +230,7 @@ class Schema 'args' => \array_merge( Mapper::args('id'), \array_map( - fn($attr) => $attr['type'] = Type::getNullableType($attr['type']), + fn ($attr) => $attr['type'] = Type::getNullableType($attr['type']), $attributes ) ), diff --git a/src/Appwrite/GraphQL/Types/Assoc.php b/src/Appwrite/GraphQL/Types/Assoc.php index a2099f9b22..f76b23dd7a 100644 --- a/src/Appwrite/GraphQL/Types/Assoc.php +++ b/src/Appwrite/GraphQL/Types/Assoc.php @@ -2,14 +2,7 @@ namespace Appwrite\GraphQL\Types; -use GraphQL\Language\AST\BooleanValueNode; -use GraphQL\Language\AST\FloatValueNode; -use GraphQL\Language\AST\IntValueNode; -use GraphQL\Language\AST\ListValueNode; use GraphQL\Language\AST\Node; -use GraphQL\Language\AST\ObjectValueNode; -use GraphQL\Language\AST\StringValueNode; -use GraphQL\Type\Definition\ScalarType; // https://github.com/webonyx/graphql-php/issues/129#issuecomment-309366803 class Assoc extends Json diff --git a/src/Appwrite/GraphQL/Types/Mapper.php b/src/Appwrite/GraphQL/Types/Mapper.php index 280d094a0c..36b246b28b 100644 --- a/src/Appwrite/GraphQL/Types/Mapper.php +++ b/src/Appwrite/GraphQL/Types/Mapper.php @@ -87,7 +87,7 @@ class Mapper $names = $route->getLabel('sdk.response.model', 'none'); $models = \is_array($names) - ? \array_map(static fn($m) => static::$models[$m], $names) + ? \array_map(static fn ($m) => static::$models[$m], $names) : [static::$models[$names]]; foreach ($models as $model) { @@ -150,7 +150,7 @@ class Mapper 'resolve' => static function ($object, $args, $context, $info) { $data = \array_filter( (array)$object, - fn($key) => !\str_starts_with($key, '_'), + fn ($key) => !\str_starts_with($key, '_'), ARRAY_FILTER_USE_KEY ); @@ -165,7 +165,7 @@ class Mapper $fields['status'] = [ 'type' => Type::string(), 'description' => 'Status', - 'resolve' => static fn($object, $args, $context, $info) => 'OK', + 'resolve' => static fn ($object, $args, $context, $info) => 'OK', ]; } diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 1925944664..792adfa5a4 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -2,10 +2,10 @@ namespace Appwrite\Messaging\Adapter; -use Utopia\Database\DateTime; -use Utopia\Database\Document; use Appwrite\Messaging\Adapter; use Utopia\App; +use Utopia\Database\DateTime; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 4038362720..cbcc7a9322 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -2,15 +2,15 @@ namespace Appwrite\Migration; +use Exception; use Swoole\Runtime; -use Utopia\Database\Document; -use Utopia\Database\Database; -use Utopia\Database\Query; +use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; -use Exception; -use Utopia\App; +use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; +use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; Runtime::enableCoroutine(SWOOLE_HOOK_ALL); diff --git a/src/Appwrite/Migration/Version/V15.php b/src/Appwrite/Migration/Version/V15.php index aaa8fd2373..e2de0422de 100644 --- a/src/Appwrite/Migration/Version/V15.php +++ b/src/Appwrite/Migration/Version/V15.php @@ -4,8 +4,6 @@ namespace Appwrite\Migration\Version; use Appwrite\Migration\Migration; use Appwrite\OpenSSL\OpenSSL; -use Exception; -use PDO; use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -1236,7 +1234,7 @@ class V15 extends Migration * skipping migration for 'cache' and 'variables'. * 'users' already migrated. */ - return null; + return; case '_metadata': /** diff --git a/src/Appwrite/Migration/Version/V17.php b/src/Appwrite/Migration/Version/V17.php index 4bdae76621..96c890c65d 100644 --- a/src/Appwrite/Migration/Version/V17.php +++ b/src/Appwrite/Migration/Version/V17.php @@ -266,9 +266,9 @@ class V17 extends Migration ])); break; case 'users': - /** - * Set hashOptions type - */ + /** + * Set hashOptions type + */ $document->setAttribute('hashOptions', array_merge($document->getAttribute('hashOptions', []), [ 'type' => $document->getAttribute('hash', Auth::DEFAULT_ALGO) ])); diff --git a/src/Appwrite/Migration/Version/V19.php b/src/Appwrite/Migration/Version/V19.php index a92fb0a5fb..7934c1aaa6 100644 --- a/src/Appwrite/Migration/Version/V19.php +++ b/src/Appwrite/Migration/Version/V19.php @@ -650,8 +650,8 @@ class V19 extends Migration { foreach ( $this->documentsIterator('attributes', [ - Query::equal('format', ['enum']), - Query::lessThan('size', Database::LENGTH_KEY) + Query::equal('format', ['enum']), + Query::lessThan('size', Database::LENGTH_KEY) ]) as $attribute ) { $attribute->setAttribute('size', Database::LENGTH_KEY); diff --git a/src/Appwrite/Migration/Version/V20.php b/src/Appwrite/Migration/Version/V20.php index a996fff171..14d193501b 100644 --- a/src/Appwrite/Migration/Version/V20.php +++ b/src/Appwrite/Migration/Version/V20.php @@ -81,7 +81,7 @@ class V20 extends Migration if ($collectionType === 'projects') { foreach ( $this->documentsIterator('attributes', [ - Query::equal('array', [true]), + Query::equal('array', [true]), ]) as $attribute ) { $foundIndex = false; diff --git a/src/Appwrite/Network/Validator/Origin.php b/src/Appwrite/Network/Validator/Origin.php index 508961ab9e..fe10d87e59 100644 --- a/src/Appwrite/Network/Validator/Origin.php +++ b/src/Appwrite/Network/Validator/Origin.php @@ -2,8 +2,8 @@ namespace Appwrite\Network\Validator; -use Utopia\Validator\Hostname; use Utopia\Validator; +use Utopia\Validator\Hostname; class Origin extends Validator { diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index e50c7c1ddc..f1fd1945c4 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -15,11 +15,11 @@ use Appwrite\Platform\Tasks\Migrate; use Appwrite\Platform\Tasks\PatchRecreateRepositoriesDocuments; use Appwrite\Platform\Tasks\QueueCount; use Appwrite\Platform\Tasks\QueueRetry; -use Appwrite\Platform\Tasks\SDKs; -use Appwrite\Platform\Tasks\SSL; use Appwrite\Platform\Tasks\ScheduleFunctions; use Appwrite\Platform\Tasks\ScheduleMessages; +use Appwrite\Platform\Tasks\SDKs; use Appwrite\Platform\Tasks\Specs; +use Appwrite\Platform\Tasks\SSL; use Appwrite\Platform\Tasks\Upgrade; use Appwrite\Platform\Tasks\Vars; use Appwrite\Platform\Tasks\Version; diff --git a/src/Appwrite/Platform/Services/Workers.php b/src/Appwrite/Platform/Services/Workers.php index 84700e82e3..4adf9b76cb 100644 --- a/src/Appwrite/Platform/Services/Workers.php +++ b/src/Appwrite/Platform/Services/Workers.php @@ -2,20 +2,20 @@ namespace Appwrite\Platform\Services; -use Utopia\Platform\Service; use Appwrite\Platform\Workers\Audits; -use Appwrite\Platform\Workers\Webhooks; -use Appwrite\Platform\Workers\Mails; -use Appwrite\Platform\Workers\Messaging; +use Appwrite\Platform\Workers\Builds; use Appwrite\Platform\Workers\Certificates; use Appwrite\Platform\Workers\Databases; -use Appwrite\Platform\Workers\Functions; -use Appwrite\Platform\Workers\Builds; use Appwrite\Platform\Workers\Deletes; +use Appwrite\Platform\Workers\Functions; use Appwrite\Platform\Workers\Hamster; +use Appwrite\Platform\Workers\Mails; +use Appwrite\Platform\Workers\Messaging; +use Appwrite\Platform\Workers\Migrations; use Appwrite\Platform\Workers\Usage; use Appwrite\Platform\Workers\UsageDump; -use Appwrite\Platform\Workers\Migrations; +use Appwrite\Platform\Workers\Webhooks; +use Utopia\Platform\Service; class Workers extends Service { diff --git a/src/Appwrite/Platform/Tasks/CalcTierStats.php b/src/Appwrite/Platform/Tasks/CalcTierStats.php index 5723e256d5..fc01881523 100644 --- a/src/Appwrite/Platform/Tasks/CalcTierStats.php +++ b/src/Appwrite/Platform/Tasks/CalcTierStats.php @@ -2,17 +2,16 @@ namespace Appwrite\Platform\Tasks; -use League\Csv\CannotInsertRecord; +use League\Csv\Writer; +use PHPMailer\PHPMailer\PHPMailer; use Utopia\App; -use Utopia\Database\Document; -use Utopia\Database\Validator\Authorization; -use Utopia\Platform\Action; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Query; -use League\Csv\Writer; -use PHPMailer\PHPMailer\PHPMailer; +use Utopia\Database\Validator\Authorization; +use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; use Utopia\Validator\Text; diff --git a/src/Appwrite/Platform/Tasks/CreateInfMetric.php b/src/Appwrite/Platform/Tasks/CreateInfMetric.php index cfb7486782..c50b6e09f9 100644 --- a/src/Appwrite/Platform/Tasks/CreateInfMetric.php +++ b/src/Appwrite/Platform/Tasks/CreateInfMetric.php @@ -2,13 +2,13 @@ namespace Appwrite\Platform\Tasks; +use Utopia\CLI\Console; +use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception; use Utopia\Database\Exception\Duplicate; use Utopia\Database\Query; use Utopia\Platform\Action; -use Utopia\CLI\Console; -use Utopia\Database\Database; use Utopia\Validator\Text; class CreateInfMetric extends Action diff --git a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php index 9b27176876..94879a4386 100644 --- a/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php +++ b/src/Appwrite/Platform/Tasks/DeleteOrphanedProjects.php @@ -3,13 +3,13 @@ namespace Appwrite\Platform\Tasks; use Utopia\App; +use Utopia\Cache\Cache; +use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Database\Database; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Platform\Action; -use Utopia\Cache\Cache; -use Utopia\CLI\Console; -use Utopia\Database\Database; use Utopia\Pools\Group; use Utopia\Registry\Registry; use Utopia\Validator\Boolean; diff --git a/src/Appwrite/Platform/Tasks/Doctor.php b/src/Appwrite/Platform/Tasks/Doctor.php index 739a23aaf4..2886dcd4dd 100644 --- a/src/Appwrite/Platform/Tasks/Doctor.php +++ b/src/Appwrite/Platform/Tasks/Doctor.php @@ -2,16 +2,16 @@ namespace Appwrite\Platform\Tasks; +use Appwrite\ClamAV\Network; use Utopia\App; use Utopia\CLI\Console; -use Appwrite\ClamAV\Network; -use Utopia\Logger\Logger; -use Utopia\Storage\Device\Local; -use Utopia\Storage\Storage; use Utopia\Config\Config; use Utopia\Domains\Domain; +use Utopia\Logger\Logger; use Utopia\Platform\Action; use Utopia\Registry\Registry; +use Utopia\Storage\Device\Local; +use Utopia\Storage\Storage; class Doctor extends Action { @@ -200,10 +200,10 @@ class Doctor extends Action foreach ( [ - 'Uploads' => APP_STORAGE_UPLOADS, - 'Cache' => APP_STORAGE_CACHE, - 'Config' => APP_STORAGE_CONFIG, - 'Certs' => APP_STORAGE_CERTIFICATES + 'Uploads' => APP_STORAGE_UPLOADS, + 'Cache' => APP_STORAGE_CACHE, + 'Config' => APP_STORAGE_CONFIG, + 'Certs' => APP_STORAGE_CERTIFICATES ] as $key => $volume ) { $device = new Local($volume); @@ -228,10 +228,10 @@ class Doctor extends Action foreach ( [ - 'Uploads' => APP_STORAGE_UPLOADS, - 'Cache' => APP_STORAGE_CACHE, - 'Config' => APP_STORAGE_CONFIG, - 'Certs' => APP_STORAGE_CERTIFICATES + 'Uploads' => APP_STORAGE_UPLOADS, + 'Cache' => APP_STORAGE_CACHE, + 'Config' => APP_STORAGE_CONFIG, + 'Certs' => APP_STORAGE_CERTIFICATES ] as $key => $volume ) { $device = new Local($volume); diff --git a/src/Appwrite/Platform/Tasks/GetMigrationStats.php b/src/Appwrite/Platform/Tasks/GetMigrationStats.php index ed10ac345b..dd43f75447 100644 --- a/src/Appwrite/Platform/Tasks/GetMigrationStats.php +++ b/src/Appwrite/Platform/Tasks/GetMigrationStats.php @@ -3,14 +3,14 @@ namespace Appwrite\Platform\Tasks; use League\Csv\CannotInsertRecord; +use League\Csv\Writer; +use PHPMailer\PHPMailer\PHPMailer; use Utopia\App; -use Utopia\Platform\Action; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Query; -use League\Csv\Writer; -use PHPMailer\PHPMailer\PHPMailer; +use Utopia\Platform\Action; use Utopia\Pools\Group; use Utopia\Registry\Registry; diff --git a/src/Appwrite/Platform/Tasks/Hamster.php b/src/Appwrite/Platform/Tasks/Hamster.php index 126ccd07df..7f8ef4041d 100644 --- a/src/Appwrite/Platform/Tasks/Hamster.php +++ b/src/Appwrite/Platform/Tasks/Hamster.php @@ -4,11 +4,11 @@ namespace Appwrite\Platform\Tasks; use Appwrite\Event\Hamster as EventHamster; use Utopia\App; -use Utopia\Platform\Action; use Utopia\CLI\Console; use Utopia\Database\Database; -use Utopia\Database\Query; use Utopia\Database\Document; +use Utopia\Database\Query; +use Utopia\Platform\Action; class Hamster extends Action { diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index c6107c6ba8..4abd267684 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -8,9 +8,9 @@ use Appwrite\Docker\Env; use Appwrite\Utopia\View; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Platform\Action; use Utopia\Validator\Boolean; use Utopia\Validator\Text; -use Utopia\Platform\Action; class Install extends Action { diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 3245a92448..55bcd488a0 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -7,8 +7,8 @@ use Appwrite\Event\Delete; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\Database; -use Utopia\Database\Document; use Utopia\Database\DateTime; +use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Platform\Action; diff --git a/src/Appwrite/Platform/Tasks/Migrate.php b/src/Appwrite/Platform/Tasks/Migrate.php index 682b9b5559..6e4fe38eb7 100644 --- a/src/Appwrite/Platform/Tasks/Migrate.php +++ b/src/Appwrite/Platform/Tasks/Migrate.php @@ -2,15 +2,15 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Platform\Action; -use Utopia\CLI\Console; use Appwrite\Migration\Migration; use Utopia\App; use Utopia\Cache\Cache; +use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; +use Utopia\Platform\Action; use Utopia\Registry\Registry; use Utopia\Validator\Text; diff --git a/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php b/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php index 93e6c527bb..9cf65d05b6 100644 --- a/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php +++ b/src/Appwrite/Platform/Tasks/PatchRecreateRepositoriesDocuments.php @@ -2,7 +2,6 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Platform\Action; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; @@ -10,6 +9,7 @@ use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; +use Utopia\Platform\Action; use Utopia\Validator\Text; class PatchRecreateRepositoriesDocuments extends Action diff --git a/src/Appwrite/Platform/Tasks/QueueRetry.php b/src/Appwrite/Platform/Tasks/QueueRetry.php index 2781d9a3f7..465152f21d 100644 --- a/src/Appwrite/Platform/Tasks/QueueRetry.php +++ b/src/Appwrite/Platform/Tasks/QueueRetry.php @@ -7,7 +7,6 @@ use Utopia\CLI\Console; use Utopia\Platform\Action; use Utopia\Queue\Client; use Utopia\Queue\Connection; -use Utopia\Validator\Integer; use Utopia\Validator\WhiteList; use Utopia\Validator\Wildcard; diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index f20ce038bc..014e33109e 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -2,8 +2,8 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Platform\Action; use Appwrite\SDK\Language\Android; +use Appwrite\SDK\Language\Apple; use Appwrite\SDK\Language\CLI; use Appwrite\SDK\Language\Dart; use Appwrite\SDK\Language\Deno; @@ -18,12 +18,12 @@ use Appwrite\SDK\Language\Python; use Appwrite\SDK\Language\REST; use Appwrite\SDK\Language\Ruby; use Appwrite\SDK\Language\Swift; -use Appwrite\SDK\Language\Apple; use Appwrite\SDK\Language\Web; use Appwrite\SDK\SDK; use Appwrite\Spec\Swagger2; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Platform\Action; class SDKs extends Action { diff --git a/src/Appwrite/Platform/Tasks/SSL.php b/src/Appwrite/Platform/Tasks/SSL.php index 12cb0d6be2..251d3a046b 100644 --- a/src/Appwrite/Platform/Tasks/SSL.php +++ b/src/Appwrite/Platform/Tasks/SSL.php @@ -2,11 +2,11 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Platform\Action; use Appwrite\Event\Certificate; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\Document; +use Utopia\Platform\Action; use Utopia\Validator\Boolean; use Utopia\Validator\Hostname; diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index fbb2320a34..81110f5216 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -2,18 +2,16 @@ namespace Appwrite\Platform\Tasks; -use Cron\CronExpression; use Swoole\Timer; use Utopia\App; -use Utopia\Database\Exception; -use Utopia\Platform\Action; use Utopia\CLI\Console; +use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Exception; use Utopia\Database\Query; -use Utopia\Database\Database; +use Utopia\Platform\Action; use Utopia\Pools\Group; -use Appwrite\Event\Func; use function Swoole\Coroutine\run; @@ -41,7 +39,7 @@ abstract class ScheduleBase extends Action ->inject('pools') ->inject('dbForConsole') ->inject('getProjectDB') - ->callback(fn(Group $pools, Database $dbForConsole, callable $getProjectDB) => $this->action($pools, $dbForConsole, $getProjectDB)); + ->callback(fn (Group $pools, Database $dbForConsole, callable $getProjectDB) => $this->action($pools, $dbForConsole, $getProjectDB)); } /** @@ -192,7 +190,7 @@ abstract class ScheduleBase extends Action Timer::tick( static::ENQUEUE_TIMER * 1000, - fn() => $this->enqueueResources($pools, $dbForConsole) + fn () => $this->enqueueResources($pools, $dbForConsole) ); $this->enqueueResources($pools, $dbForConsole); diff --git a/src/Appwrite/Platform/Tasks/ScheduleMessages.php b/src/Appwrite/Platform/Tasks/ScheduleMessages.php index 05b094ac58..8e52973a0c 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleMessages.php +++ b/src/Appwrite/Platform/Tasks/ScheduleMessages.php @@ -2,18 +2,9 @@ namespace Appwrite\Platform\Tasks; -use Appwrite\Event\Delete; -use Swoole\Timer; -use Utopia\Database\Document; -use Utopia\Platform\Action; -use Utopia\CLI\Console; -use Utopia\Database\DateTime; -use Utopia\Database\Query; +use Appwrite\Event\Messaging; use Utopia\Database\Database; use Utopia\Pools\Group; -use Appwrite\Event\Messaging; - -use function Swoole\Coroutine\run; class ScheduleMessages extends ScheduleBase { diff --git a/src/Appwrite/Platform/Tasks/Specs.php b/src/Appwrite/Platform/Tasks/Specs.php index d83312fad6..46c83fe2b1 100644 --- a/src/Appwrite/Platform/Tasks/Specs.php +++ b/src/Appwrite/Platform/Tasks/Specs.php @@ -2,8 +2,6 @@ namespace Appwrite\Platform\Tasks; -use Utopia\Platform\Action; -use Utopia\Validator\Text; use Appwrite\Specification\Format\OpenAPI3; use Appwrite\Specification\Format\Swagger2; use Appwrite\Specification\Specification; @@ -17,8 +15,10 @@ use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Adapter\MySQL; use Utopia\Database\Database; +use Utopia\Platform\Action; use Utopia\Registry\Registry; use Utopia\Request; +use Utopia\Validator\Text; use Utopia\Validator\WhiteList; class Specs extends Action diff --git a/src/Appwrite/Platform/Tasks/Vars.php b/src/Appwrite/Platform/Tasks/Vars.php index c97f77a9da..696073e568 100644 --- a/src/Appwrite/Platform/Tasks/Vars.php +++ b/src/Appwrite/Platform/Tasks/Vars.php @@ -3,8 +3,8 @@ namespace Appwrite\Platform\Tasks; use Utopia\App; -use Utopia\Config\Config; use Utopia\CLI\Console; +use Utopia\Config\Config; use Utopia\Platform\Action; class Vars extends Action diff --git a/src/Appwrite/Platform/Workers/Audits.php b/src/Appwrite/Platform/Workers/Audits.php index 53c16d8eb3..86ca59d3fd 100644 --- a/src/Appwrite/Platform/Workers/Audits.php +++ b/src/Appwrite/Platform/Workers/Audits.php @@ -71,11 +71,11 @@ class Audits extends Action ip: $ip, location: '', data: [ - 'userId' => $user->getId(), - 'userName' => $userName, - 'userEmail' => $userEmail, - 'mode' => $mode, - 'data' => $auditPayload, + 'userId' => $user->getId(), + 'userName' => $userName, + 'userEmail' => $userEmail, + 'mode' => $mode, + 'data' => $auditPayload, ] ); } diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index 5b2e5be761..b9f02a8f67 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -8,8 +8,8 @@ use Appwrite\Event\Usage; use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Response\Model\Deployment; use Appwrite\Vcs\Comment; -use Swoole\Coroutine as Co; use Executor\Executor; +use Swoole\Coroutine as Co; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -19,9 +19,9 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Restricted; -use Utopia\Database\Validator\Authorization; use Utopia\Database\Exception\Structure; use Utopia\Database\Helpers\ID; +use Utopia\Database\Validator\Authorization; use Utopia\Logger\Log; use Utopia\Platform\Action; use Utopia\Queue\Message; @@ -52,7 +52,7 @@ class Builds extends Action ->inject('dbForProject') ->inject('deviceForFunctions') ->inject('log') - ->callback(fn($message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $dbForConsole, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log)); + ->callback(fn ($message, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $dbForConsole, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log)); } /** @@ -281,7 +281,7 @@ class Builds extends Action * Send realtime Event */ $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $allEvents[0], payload: $build, project: $project @@ -357,7 +357,7 @@ class Builds extends Action /** Trigger Realtime */ $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $allEvents[0], payload: $build, project: $project @@ -421,48 +421,48 @@ class Builds extends Action $err = $error; } }), - Co\go(function () use ($executor, $project, $deployment, &$response, &$build, $dbForProject, $allEvents, &$err) { - try { - $executor->getLogs( - deploymentId: $deployment->getId(), - projectId: $project->getId(), - callback: function ($logs) use (&$response, &$build, $dbForProject, $allEvents, $project) { - if ($response === null) { - $build = $dbForProject->getDocument('builds', $build->getId()); + Co\go(function () use ($executor, $project, $deployment, &$response, &$build, $dbForProject, $allEvents, &$err) { + try { + $executor->getLogs( + deploymentId: $deployment->getId(), + projectId: $project->getId(), + callback: function ($logs) use (&$response, &$build, $dbForProject, $allEvents, $project) { + if ($response === null) { + $build = $dbForProject->getDocument('builds', $build->getId()); - if ($build->isEmpty()) { - throw new Exception('Build not found', 404); - } + if ($build->isEmpty()) { + throw new Exception('Build not found', 404); + } - $build = $build->setAttribute('logs', $build->getAttribute('logs', '') . $logs); - $build = $dbForProject->updateDocument('builds', $build->getId(), $build); + $build = $build->setAttribute('logs', $build->getAttribute('logs', '') . $logs); + $build = $dbForProject->updateDocument('builds', $build->getId(), $build); - /** + /** * Send realtime Event */ - $target = Realtime::fromPayload( + $target = Realtime::fromPayload( // Pass first, most verbose event pattern - event: $allEvents[0], - payload: $build, - project: $project - ); - Realtime::send( - projectId: 'console', - payload: $build->getArrayCopy(), - events: $allEvents, - channels: $target['channels'], - roles: $target['roles'] - ); - } + event: $allEvents[0], + payload: $build, + project: $project + ); + Realtime::send( + projectId: 'console', + payload: $build->getArrayCopy(), + events: $allEvents, + channels: $target['channels'], + roles: $target['roles'] + ); } - ); - } catch (\Throwable $error) { - if (empty($err)) { - $err = $error; } + ); + } catch (\Throwable $error) { + if (empty($err)) { + $err = $error; } - }), - ]); + } + }), + ]); if ($err) { throw $err; @@ -502,7 +502,7 @@ class Builds extends Action ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('schedule', $function->getAttribute('schedule')) ->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment'))); - Authorization::skip(fn() => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); + Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); } catch (\Throwable $th) { $endTime = DateTime::now(); $durationEnd = \microtime(true); @@ -521,7 +521,7 @@ class Builds extends Action * Send realtime Event */ $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $allEvents[0], payload: $build, project: $project diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index 13e85d473d..7cc32ca1c9 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -47,7 +47,7 @@ class Certificates extends Action ->inject('queueForEvents') ->inject('queueForFunctions') ->inject('log') - ->callback(fn(Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log) => $this->action($message, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log)); + ->callback(fn (Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log) => $this->action($message, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log)); } /** @@ -534,7 +534,7 @@ class Certificates extends Action 'ruleId' => $rule->getId(), ]); $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $allEvents[0], payload: $rule, project: $project diff --git a/src/Appwrite/Platform/Workers/Databases.php b/src/Appwrite/Platform/Workers/Databases.php index ae8ed31621..a5ac3b47d1 100644 --- a/src/Appwrite/Platform/Workers/Databases.php +++ b/src/Appwrite/Platform/Workers/Databases.php @@ -9,11 +9,11 @@ use Utopia\Audit\Audit; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; -use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Query; use Utopia\Logger\Log; use Utopia\Platform\Action; @@ -37,7 +37,7 @@ class Databases extends Action ->inject('dbForConsole') ->inject('dbForProject') ->inject('log') - ->callback(fn(Message $message, Database $dbForConsole, Database $dbForProject, Log $log) => $this->action($message, $dbForConsole, $dbForProject, $log)); + ->callback(fn (Message $message, Database $dbForConsole, Database $dbForProject, Log $log) => $this->action($message, $dbForConsole, $dbForProject, $log)); } /** @@ -613,7 +613,7 @@ class Databases extends Action array $events ): void { $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $events[0], payload: $attribute, project: $project, diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 51b2475171..9204960557 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -8,19 +8,19 @@ use Executor\Executor; use Throwable; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; +use Utopia\App; use Utopia\Audit\Audit; use Utopia\Cache\Adapter\Filesystem; use Utopia\Cache\Cache; -use Utopia\Database\Database; -use Utopia\App; use Utopia\CLI\Console; +use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; -use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Query; use Utopia\Logger\Log; use Utopia\Platform\Action; diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index f0a71f2bd4..05695d9e26 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -46,7 +46,7 @@ class Functions extends Action ->inject('queueForEvents') ->inject('queueForUsage') ->inject('log') - ->callback(fn(Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log) => $this->action($message, $dbForProject, $queueForFunctions, $queueForEvents, $queueForUsage, $log)); + ->callback(fn (Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log) => $this->action($message, $dbForProject, $queueForFunctions, $queueForEvents, $queueForUsage, $log)); } /** @@ -467,7 +467,7 @@ class Functions extends Action 'executionId' => $execution->getId() ]); $target = Realtime::fromPayload( - // Pass first, most verbose event pattern + // Pass first, most verbose event pattern event: $allEvents[0], payload: $execution ); diff --git a/src/Appwrite/Platform/Workers/Hamster.php b/src/Appwrite/Platform/Workers/Hamster.php index 1069ff96fa..b72b7f7030 100644 --- a/src/Appwrite/Platform/Workers/Hamster.php +++ b/src/Appwrite/Platform/Workers/Hamster.php @@ -10,14 +10,13 @@ use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Platform\Action; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; -use Utopia\Database\Document; -use Utopia\Queue\Message; -use Utopia\Logger\Log; +use Utopia\Platform\Action; use Utopia\Pools\Group; +use Utopia\Queue\Message; class Hamster extends Action { diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 3fbe30ccca..6ebedd41a3 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -3,24 +3,23 @@ namespace Appwrite\Platform\Workers; use Appwrite\Event\Usage; -use Appwrite\Extend\Exception; use Appwrite\Messaging\Status as MessageStatus; use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\DSN\DSN; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; +use Utopia\DSN\DSN; use Utopia\Logger\Log; use Utopia\Messaging\Adapter\Email as EmailAdapter; use Utopia\Messaging\Adapter\Email\Mailgun; -use Utopia\Messaging\Adapter\Email\SMTP; use Utopia\Messaging\Adapter\Email\Sendgrid; -use Utopia\Messaging\Adapter\Push as PushAdapter; +use Utopia\Messaging\Adapter\Email\SMTP; use Utopia\Messaging\Adapter\Push\APNS; +use Utopia\Messaging\Adapter\Push as PushAdapter; use Utopia\Messaging\Adapter\Push\FCM; use Utopia\Messaging\Adapter\SMS as SMSAdapter; use Utopia\Messaging\Adapter\SMS\Mock; @@ -60,7 +59,7 @@ class Messaging extends Action ->inject('deviceForFiles') ->inject('deviceForLocalFiles') ->inject('queueForUsage') - ->callback(fn(Message $message, Log $log, Database $dbForProject, Device $deviceForFiles, Device $deviceForLocalFiles, Usage $queueForUsage) => $this->action($message, $log, $dbForProject, $deviceForFiles, $deviceForLocalFiles, $queueForUsage)); + ->callback(fn (Message $message, Log $log, Database $dbForProject, Device $deviceForFiles, Device $deviceForLocalFiles, Usage $queueForUsage) => $this->action($message, $log, $dbForProject, $deviceForFiles, $deviceForLocalFiles, $queueForUsage)); } /** @@ -100,7 +99,7 @@ class Messaging extends Action case MESSAGE_SEND_TYPE_EXTERNAL: $message = $dbForProject->getDocument('messages', $payload['messageId']); - $this->sendExternalMessage($dbForProject, $message, $deviceForFiles, $deviceForLocalFiles,); + $this->sendExternalMessage($dbForProject, $message, $deviceForFiles, $deviceForLocalFiles, ); break; default: throw new \Exception('Unknown message type: ' . $type); diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index f73eee7f36..7bbfcfbce2 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -2,30 +2,30 @@ namespace Appwrite\Platform\Workers; +use Appwrite\Event\Event; +use Appwrite\Messaging\Adapter\Realtime; +use Appwrite\Permission; +use Appwrite\Role; use Exception; +use Utopia\CLI\Console; +use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Conflict; use Utopia\Database\Exception\Restricted; use Utopia\Database\Exception\Structure; -use Utopia\Platform\Action; -use Utopia\Queue\Message; -use Appwrite\Event\Event; -use Appwrite\Messaging\Adapter\Realtime; -use Appwrite\Permission; -use Appwrite\Role; -use Utopia\CLI\Console; -use Utopia\Database\Database; use Utopia\Database\Helpers\ID; use Utopia\Logger\Log; use Utopia\Migration\Destinations\Appwrite as DestinationsAppwrite; +use Utopia\Migration\Exception as MigrationException; use Utopia\Migration\Source; use Utopia\Migration\Sources\Appwrite; use Utopia\Migration\Sources\Firebase; use Utopia\Migration\Sources\NHost; use Utopia\Migration\Sources\Supabase; use Utopia\Migration\Transfer; -use Utopia\Migration\Exception as MigrationException; +use Utopia\Platform\Action; +use Utopia\Queue\Message; class Migrations extends Action { @@ -48,7 +48,7 @@ class Migrations extends Action ->inject('dbForProject') ->inject('dbForConsole') ->inject('log') - ->callback(fn(Message $message, Database $dbForProject, Database $dbForConsole, Log $log) => $this->action($message, $dbForProject, $dbForConsole, $log)); + ->callback(fn (Message $message, Database $dbForProject, Database $dbForConsole, Log $log) => $this->action($message, $dbForProject, $dbForConsole, $log)); } /** diff --git a/src/Appwrite/Platform/Workers/Usage.php b/src/Appwrite/Platform/Workers/Usage.php index c84f57e0f2..3227153e08 100644 --- a/src/Appwrite/Platform/Workers/Usage.php +++ b/src/Appwrite/Platform/Workers/Usage.php @@ -2,8 +2,8 @@ namespace Appwrite\Platform\Workers; -use Exception; use Appwrite\Event\UsageDump; +use Exception; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\DateTime; @@ -36,7 +36,7 @@ class Usage extends Action ->inject('getProjectDB') ->inject('queueForUsageDump') ->callback(function (Message $message, callable $getProjectDB, UsageDump $queueForUsageDump) { - $this->action($message, $getProjectDB, $queueForUsageDump); + $this->action($message, $getProjectDB, $queueForUsageDump); }); $this->lastTriggeredTime = time(); @@ -77,7 +77,7 @@ class Usage extends Action $this->stats[$projectId]['project'] = $project; $this->stats[$projectId]['receivedAt'] = DateTime::now(); foreach ($payload['metrics'] ?? [] as $metric) { - $this->keys++; + $this->keys++; if (!isset($this->stats[$projectId]['keys'][$metric['key']])) { $this->stats[$projectId]['keys'][$metric['key']] = $metric['value']; continue; @@ -103,15 +103,15 @@ class Usage extends Action } } - /** - * On Documents that tied by relations like functions>deployments>build || documents>collection>database || buckets>files. - * When we remove a parent document we need to deduct his children aggregation from the project scope. - * @param Document $project - * @param Document $document - * @param array $metrics - * @param callable $getProjectDB - * @return void - */ + /** + * On Documents that tied by relations like functions>deployments>build || documents>collection>database || buckets>files. + * When we remove a parent document we need to deduct his children aggregation from the project scope. + * @param Document $project + * @param Document $document + * @param array $metrics + * @param callable $getProjectDB + * @return void + */ private function reduce(Document $project, Document $document, array &$metrics, callable $getProjectDB): void { $dbForProject = $getProjectDB($project); @@ -122,8 +122,8 @@ class Usage extends Action $sessions = count($document->getAttribute(METRIC_SESSIONS, 0)); if (!empty($sessions)) { $metrics[] = [ - 'key' => METRIC_SESSIONS, - 'value' => ($sessions * -1), + 'key' => METRIC_SESSIONS, + 'value' => ($sessions * -1), ]; } break; @@ -132,15 +132,15 @@ class Usage extends Action $documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS))); if (!empty($collections['value'])) { $metrics[] = [ - 'key' => METRIC_COLLECTIONS, - 'value' => ($collections['value'] * -1), + 'key' => METRIC_COLLECTIONS, + 'value' => ($collections['value'] * -1), ]; } if (!empty($documents['value'])) { $metrics[] = [ - 'key' => METRIC_DOCUMENTS, - 'value' => ($documents['value'] * -1), + 'key' => METRIC_DOCUMENTS, + 'value' => ($documents['value'] * -1), ]; } break; @@ -151,12 +151,12 @@ class Usage extends Action if (!empty($documents['value'])) { $metrics[] = [ - 'key' => METRIC_DOCUMENTS, - 'value' => ($documents['value'] * -1), + 'key' => METRIC_DOCUMENTS, + 'value' => ($documents['value'] * -1), ]; $metrics[] = [ - 'key' => str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), - 'value' => ($documents['value'] * -1), + 'key' => str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), + 'value' => ($documents['value'] * -1), ]; } break; @@ -167,15 +167,15 @@ class Usage extends Action if (!empty($files['value'])) { $metrics[] = [ - 'key' => METRIC_FILES, - 'value' => ($files['value'] * -1), + 'key' => METRIC_FILES, + 'value' => ($files['value'] * -1), ]; } if (!empty($storage['value'])) { $metrics[] = [ - 'key' => METRIC_FILES_STORAGE, - 'value' => ($storage['value'] * -1), + 'key' => METRIC_FILES_STORAGE, + 'value' => ($storage['value'] * -1), ]; } break; @@ -191,50 +191,50 @@ class Usage extends Action if (!empty($deployments['value'])) { $metrics[] = [ - 'key' => METRIC_DEPLOYMENTS, - 'value' => ($deployments['value'] * -1), + 'key' => METRIC_DEPLOYMENTS, + 'value' => ($deployments['value'] * -1), ]; } if (!empty($deploymentsStorage['value'])) { $metrics[] = [ - 'key' => METRIC_DEPLOYMENTS_STORAGE, - 'value' => ($deploymentsStorage['value'] * -1), + 'key' => METRIC_DEPLOYMENTS_STORAGE, + 'value' => ($deploymentsStorage['value'] * -1), ]; } if (!empty($builds['value'])) { $metrics[] = [ - 'key' => METRIC_BUILDS, - 'value' => ($builds['value'] * -1), + 'key' => METRIC_BUILDS, + 'value' => ($builds['value'] * -1), ]; } if (!empty($buildsStorage['value'])) { $metrics[] = [ - 'key' => METRIC_BUILDS_STORAGE, - 'value' => ($buildsStorage['value'] * -1), + 'key' => METRIC_BUILDS_STORAGE, + 'value' => ($buildsStorage['value'] * -1), ]; } if (!empty($buildsCompute['value'])) { $metrics[] = [ - 'key' => METRIC_BUILDS_COMPUTE, - 'value' => ($buildsCompute['value'] * -1), + 'key' => METRIC_BUILDS_COMPUTE, + 'value' => ($buildsCompute['value'] * -1), ]; } if (!empty($executions['value'])) { $metrics[] = [ - 'key' => METRIC_EXECUTIONS, - 'value' => ($executions['value'] * -1), + 'key' => METRIC_EXECUTIONS, + 'value' => ($executions['value'] * -1), ]; } if (!empty($executionsCompute['value'])) { $metrics[] = [ - 'key' => METRIC_EXECUTIONS_COMPUTE, - 'value' => ($executionsCompute['value'] * -1), + 'key' => METRIC_EXECUTIONS_COMPUTE, + 'value' => ($executionsCompute['value'] * -1), ]; } break; diff --git a/src/Appwrite/Platform/Workers/UsageDump.php b/src/Appwrite/Platform/Workers/UsageDump.php index da8995b631..e1e62feb9f 100644 --- a/src/Appwrite/Platform/Workers/UsageDump.php +++ b/src/Appwrite/Platform/Workers/UsageDump.php @@ -4,11 +4,11 @@ namespace Appwrite\Platform\Workers; use Appwrite\Extend\Exception; use Utopia\App; +use Utopia\CLI\Console; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Duplicate; use Utopia\Platform\Action; -use Utopia\CLI\Console; -use Utopia\Database\DateTime; use Utopia\Queue\Message; class UsageDump extends Action diff --git a/src/Appwrite/Platform/Workers/Webhooks.php b/src/Appwrite/Platform/Workers/Webhooks.php index 979e0be381..da5a82999f 100644 --- a/src/Appwrite/Platform/Workers/Webhooks.php +++ b/src/Appwrite/Platform/Workers/Webhooks.php @@ -6,8 +6,8 @@ use Appwrite\Event\Mail; use Appwrite\Template\Template; use Exception; use Utopia\App; -use Utopia\Database\Document; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Query; use Utopia\Logger\Log; use Utopia\Platform\Action; diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index b0fcb3f540..30ce6470e1 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -2,10 +2,10 @@ namespace Appwrite\Specification; +use Appwrite\Utopia\Response\Model; use Utopia\App; use Utopia\Config\Config; use Utopia\Route; -use Appwrite\Utopia\Response\Model; abstract class Format { diff --git a/src/Appwrite/Specification/Format/OpenAPI3.php b/src/Appwrite/Specification/Format/OpenAPI3.php index 09c4b2ebc9..bc85d8e507 100644 --- a/src/Appwrite/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/Specification/Format/OpenAPI3.php @@ -432,9 +432,9 @@ class OpenAPI3 extends Format } if ($allowed) { - $node['schema']['enum'] = $validator->getList(); - $node['schema']['x-enum-name'] = $this->getEnumName($route->getLabel('sdk.namespace', ''), $method, $name); - $node['schema']['x-enum-keys'] = $this->getEnumKeys($route->getLabel('sdk.namespace', ''), $method, $name); + $node['schema']['enum'] = $validator->getList(); + $node['schema']['x-enum-name'] = $this->getEnumName($route->getLabel('sdk.namespace', ''), $method, $name); + $node['schema']['x-enum-keys'] = $this->getEnumKeys($route->getLabel('sdk.namespace', ''), $method, $name); } if ($validator->getType() === 'integer') { $node['format'] = 'int32'; diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Attributes.php b/src/Appwrite/Utopia/Database/Validator/Queries/Attributes.php index 1463316ad1..4a35c82b73 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Attributes.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Attributes.php @@ -2,8 +2,6 @@ namespace Appwrite\Utopia\Database\Validator\Queries; -use Utopia\Database\Validator\Query\Select; - class Attributes extends Base { public const ALLOWED_ATTRIBUTES = [ diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Base.php b/src/Appwrite/Utopia/Database/Validator/Queries/Base.php index d06111f60c..a3555c08dd 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Base.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Base.php @@ -2,16 +2,15 @@ namespace Appwrite\Utopia\Database\Validator\Queries; -use Appwrite\Extend\Exception; -use Utopia\Database\Validator\Queries; -use Utopia\Database\Validator\Query\Limit; -use Utopia\Database\Validator\Query\Offset; -use Utopia\Database\Validator\Query\Cursor; -use Utopia\Database\Validator\Query\Filter; -use Utopia\Database\Validator\Query\Order; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Validator\Queries; +use Utopia\Database\Validator\Query\Cursor; +use Utopia\Database\Validator\Query\Filter; +use Utopia\Database\Validator\Query\Limit; +use Utopia\Database\Validator\Query\Offset; +use Utopia\Database\Validator\Query\Order; class Base extends Queries { diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Projects.php b/src/Appwrite/Utopia/Database/Validator/Queries/Projects.php index 7fff26db7f..5a0befb739 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Projects.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Projects.php @@ -2,8 +2,6 @@ namespace Appwrite\Utopia\Database\Validator\Queries; -use Appwrite\Utopia\Database\Validator\Queries\Base; - class Projects extends Base { public const ALLOWED_ATTRIBUTES = [ diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php b/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php index 52c7abca1d..5d7a5e5cee 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Variables.php @@ -2,8 +2,6 @@ namespace Appwrite\Utopia\Database\Validator\Queries; -use Appwrite\Utopia\Database\Validator\Queries\Base; - class Variables extends Base { public const ALLOWED_ATTRIBUTES = [ diff --git a/src/Appwrite/Utopia/Request/Filters/V12.php b/src/Appwrite/Utopia/Request/Filters/V12.php index f2a65307ae..37a5232a14 100644 --- a/src/Appwrite/Utopia/Request/Filters/V12.php +++ b/src/Appwrite/Utopia/Request/Filters/V12.php @@ -23,17 +23,17 @@ class V12 extends Filter $content = $this->addId($content, 'teamId'); break; - // Status integer -> boolean + // Status integer -> boolean case "users.updateStatus": $content = $this->convertStatus($content); break; - // Deprecating order type + // Deprecating order type case "functions.listExecutions": $content = $this->removeOrderType($content); break; - // The rest (more complex) formats + // The rest (more complex) formats case "database.createDocument": $content = $this->addId($content, 'documentId'); $content = $this->removeParentProperties($content); diff --git a/src/Appwrite/Utopia/Request/Filters/V14.php b/src/Appwrite/Utopia/Request/Filters/V14.php index 7130307f0d..f42a351024 100644 --- a/src/Appwrite/Utopia/Request/Filters/V14.php +++ b/src/Appwrite/Utopia/Request/Filters/V14.php @@ -2,8 +2,8 @@ namespace Appwrite\Utopia\Request\Filters; -use Appwrite\Utopia\Request\Filter; use Appwrite\Migration\Version\V13 as MigrationV13; +use Appwrite\Utopia\Request\Filter; class V14 extends Filter { diff --git a/src/Appwrite/Utopia/Request/Filters/V15.php b/src/Appwrite/Utopia/Request/Filters/V15.php index 318096fe0d..52e9c4a72a 100644 --- a/src/Appwrite/Utopia/Request/Filters/V15.php +++ b/src/Appwrite/Utopia/Request/Filters/V15.php @@ -5,8 +5,8 @@ namespace Appwrite\Utopia\Request\Filters; use Appwrite\Utopia\Request\Filter; use Utopia\Database\Database; use Utopia\Database\Helpers\Permission; -use Utopia\Database\Query; use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; class V15 extends Filter { diff --git a/src/Appwrite/Utopia/Request/Filters/V17.php b/src/Appwrite/Utopia/Request/Filters/V17.php index d7a4039d7e..83ec62a168 100644 --- a/src/Appwrite/Utopia/Request/Filters/V17.php +++ b/src/Appwrite/Utopia/Request/Filters/V17.php @@ -24,7 +24,7 @@ class V17 extends Filter case 'account.updateRecovery': unset($content['passwordAgain']); break; - // Queries + // Queries case 'account.listIdentities': case 'account.listLogs': case 'databases.list': diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 77e86212f1..22043b9f26 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -2,10 +2,6 @@ namespace Appwrite\Utopia; -use Exception; -use Utopia\Swoole\Response as SwooleResponse; -use Swoole\Http\Response as SwooleHTTPResponse; -use Utopia\Database\Document; use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response\Model\Account; @@ -16,80 +12,83 @@ use Appwrite\Utopia\Response\Model\AlgoPhpass; use Appwrite\Utopia\Response\Model\AlgoScrypt; use Appwrite\Utopia\Response\Model\AlgoScryptModified; use Appwrite\Utopia\Response\Model\AlgoSha; -use Appwrite\Utopia\Response\Model\None; use Appwrite\Utopia\Response\Model\Any; use Appwrite\Utopia\Response\Model\Attribute; -use Appwrite\Utopia\Response\Model\AttributeList; -use Appwrite\Utopia\Response\Model\AttributeString; -use Appwrite\Utopia\Response\Model\AttributeInteger; -use Appwrite\Utopia\Response\Model\AttributeFloat; use Appwrite\Utopia\Response\Model\AttributeBoolean; +use Appwrite\Utopia\Response\Model\AttributeDatetime; use Appwrite\Utopia\Response\Model\AttributeEmail; use Appwrite\Utopia\Response\Model\AttributeEnum; +use Appwrite\Utopia\Response\Model\AttributeFloat; +use Appwrite\Utopia\Response\Model\AttributeInteger; use Appwrite\Utopia\Response\Model\AttributeIP; -use Appwrite\Utopia\Response\Model\AttributeURL; -use Appwrite\Utopia\Response\Model\AttributeDatetime; +use Appwrite\Utopia\Response\Model\AttributeList; use Appwrite\Utopia\Response\Model\AttributeRelationship; +use Appwrite\Utopia\Response\Model\AttributeString; +use Appwrite\Utopia\Response\Model\AttributeURL; use Appwrite\Utopia\Response\Model\AuthProvider; use Appwrite\Utopia\Response\Model\BaseList; use Appwrite\Utopia\Response\Model\Branch; +use Appwrite\Utopia\Response\Model\Bucket; +use Appwrite\Utopia\Response\Model\Build; use Appwrite\Utopia\Response\Model\Collection; -use Appwrite\Utopia\Response\Model\Database; +use Appwrite\Utopia\Response\Model\ConsoleVariables; use Appwrite\Utopia\Response\Model\Continent; use Appwrite\Utopia\Response\Model\Country; use Appwrite\Utopia\Response\Model\Currency; +use Appwrite\Utopia\Response\Model\Database; +use Appwrite\Utopia\Response\Model\Deployment; +use Appwrite\Utopia\Response\Model\Detection; use Appwrite\Utopia\Response\Model\Document as ModelDocument; use Appwrite\Utopia\Response\Model\Error; use Appwrite\Utopia\Response\Model\ErrorDev; use Appwrite\Utopia\Response\Model\Execution; -use Appwrite\Utopia\Response\Model\Build; use Appwrite\Utopia\Response\Model\File; -use Appwrite\Utopia\Response\Model\Bucket; -use Appwrite\Utopia\Response\Model\ConsoleVariables; use Appwrite\Utopia\Response\Model\Func; -use Appwrite\Utopia\Response\Model\Identity; -use Appwrite\Utopia\Response\Model\Index; -use Appwrite\Utopia\Response\Model\JWT; -use Appwrite\Utopia\Response\Model\Key; -use Appwrite\Utopia\Response\Model\Language; -use Appwrite\Utopia\Response\Model\User; -use Appwrite\Utopia\Response\Model\Session; -use Appwrite\Utopia\Response\Model\Team; -use Appwrite\Utopia\Response\Model\Locale; -use Appwrite\Utopia\Response\Model\Log; -use Appwrite\Utopia\Response\Model\Membership; -use Appwrite\Utopia\Response\Model\Metric; -use Appwrite\Utopia\Response\Model\Phone; -use Appwrite\Utopia\Response\Model\Platform; -use Appwrite\Utopia\Response\Model\Project; -use Appwrite\Utopia\Response\Model\Deployment; -use Appwrite\Utopia\Response\Model\Detection; use Appwrite\Utopia\Response\Model\Headers; -use Appwrite\Utopia\Response\Model\TemplateEmail; -use Appwrite\Utopia\Response\Model\Token; -use Appwrite\Utopia\Response\Model\Webhook; -use Appwrite\Utopia\Response\Model\Preferences; use Appwrite\Utopia\Response\Model\HealthAntivirus; use Appwrite\Utopia\Response\Model\HealthCertificate; use Appwrite\Utopia\Response\Model\HealthQueue; use Appwrite\Utopia\Response\Model\HealthStatus; use Appwrite\Utopia\Response\Model\HealthTime; use Appwrite\Utopia\Response\Model\HealthVersion; -use Appwrite\Utopia\Response\Model\MFAChallenge; +use Appwrite\Utopia\Response\Model\Identity; +use Appwrite\Utopia\Response\Model\Index; use Appwrite\Utopia\Response\Model\Installation; +use Appwrite\Utopia\Response\Model\JWT; +use Appwrite\Utopia\Response\Model\Key; +use Appwrite\Utopia\Response\Model\Language; +use Appwrite\Utopia\Response\Model\Locale; use Appwrite\Utopia\Response\Model\LocaleCode; -use Appwrite\Utopia\Response\Model\MetricBreakdown; -use Appwrite\Utopia\Response\Model\Provider; +use Appwrite\Utopia\Response\Model\Log; +use Appwrite\Utopia\Response\Model\Membership; use Appwrite\Utopia\Response\Model\Message; +use Appwrite\Utopia\Response\Model\Metric; +use Appwrite\Utopia\Response\Model\MetricBreakdown; +use Appwrite\Utopia\Response\Model\MFAChallenge; use Appwrite\Utopia\Response\Model\MFAFactors; use Appwrite\Utopia\Response\Model\MFARecoveryCodes; use Appwrite\Utopia\Response\Model\MFAType; -use Appwrite\Utopia\Response\Model\Subscriber; -use Appwrite\Utopia\Response\Model\Topic; +use Appwrite\Utopia\Response\Model\Migration; +use Appwrite\Utopia\Response\Model\MigrationFirebaseProject; +use Appwrite\Utopia\Response\Model\MigrationReport; +use Appwrite\Utopia\Response\Model\Mock; +use Appwrite\Utopia\Response\Model\None; +use Appwrite\Utopia\Response\Model\Phone; +use Appwrite\Utopia\Response\Model\Platform; +use Appwrite\Utopia\Response\Model\Preferences; +use Appwrite\Utopia\Response\Model\Project; +use Appwrite\Utopia\Response\Model\Provider; use Appwrite\Utopia\Response\Model\ProviderRepository; +use Appwrite\Utopia\Response\Model\Rule; use Appwrite\Utopia\Response\Model\Runtime; +use Appwrite\Utopia\Response\Model\Session; +use Appwrite\Utopia\Response\Model\Subscriber; use Appwrite\Utopia\Response\Model\Target; +use Appwrite\Utopia\Response\Model\Team; +use Appwrite\Utopia\Response\Model\TemplateEmail; use Appwrite\Utopia\Response\Model\TemplateSMS; +use Appwrite\Utopia\Response\Model\Token; +use Appwrite\Utopia\Response\Model\Topic; use Appwrite\Utopia\Response\Model\UsageBuckets; use Appwrite\Utopia\Response\Model\UsageCollection; use Appwrite\Utopia\Response\Model\UsageDatabase; @@ -99,13 +98,14 @@ use Appwrite\Utopia\Response\Model\UsageFunctions; use Appwrite\Utopia\Response\Model\UsageProject; use Appwrite\Utopia\Response\Model\UsageStorage; use Appwrite\Utopia\Response\Model\UsageUsers; +use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; -use Appwrite\Utopia\Response\Model\Migration; -use Appwrite\Utopia\Response\Model\MigrationFirebaseProject; -use Appwrite\Utopia\Response\Model\MigrationReport; +use Appwrite\Utopia\Response\Model\Webhook; +use Exception; +use Swoole\Http\Response as SwooleHTTPResponse; // Keep last -use Appwrite\Utopia\Response\Model\Mock; -use Appwrite\Utopia\Response\Model\Rule; +use Utopia\Database\Document; +use Utopia\Swoole\Response as SwooleResponse; /** * @method int getStatusCode() diff --git a/src/Appwrite/Utopia/Response/Filters/V11.php b/src/Appwrite/Utopia/Response/Filters/V11.php index 8fa22f42b2..9d6459915d 100644 --- a/src/Appwrite/Utopia/Response/Filters/V11.php +++ b/src/Appwrite/Utopia/Response/Filters/V11.php @@ -42,7 +42,7 @@ class V11 extends Filter $parsedResponse = $this->parseFunctionsList($content); break; - // Convert status from boolean to int + // Convert status from boolean to int case Response::MODEL_USER: $parsedResponse = $this->parseStatus($content); break; @@ -50,7 +50,7 @@ class V11 extends Filter $parsedResponse = $this->parseUserList($content); break; - // Convert all Health responses back to original + // Convert all Health responses back to original case Response::MODEL_HEALTH_STATUS: $parsedResponse = $this->parseHealthStatus($content); break; @@ -67,7 +67,7 @@ class V11 extends Filter $parsedResponse = $this->parseHealthAntivirus($content); break; - // Complex filters + // Complex filters case Response::MODEL_COLLECTION: $parsedResponse = $this->parseCollection($content); break; diff --git a/src/Appwrite/Utopia/Response/Model/Execution.php b/src/Appwrite/Utopia/Response/Model/Execution.php index 3ff171dfff..fbd9619a40 100644 --- a/src/Appwrite/Utopia/Response/Model/Execution.php +++ b/src/Appwrite/Utopia/Response/Model/Execution.php @@ -84,7 +84,7 @@ class Execution extends Model 'description' => 'HTTP response body. This will return empty unless execution is created as synchronous.', 'default' => '', 'example' => 'Developers are awesome.', - ]) + ]) ->addRule('responseHeaders', [ 'type' => Response::MODEL_HEADERS, 'description' => 'HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous.', diff --git a/src/Appwrite/Utopia/Response/Model/Func.php b/src/Appwrite/Utopia/Response/Model/Func.php index e32735b38e..0c8d4d42d2 100644 --- a/src/Appwrite/Utopia/Response/Model/Func.php +++ b/src/Appwrite/Utopia/Response/Model/Func.php @@ -4,8 +4,6 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -use stdClass; -use Utopia\Database\Document; class Func extends Model { diff --git a/src/Appwrite/Utopia/Response/Model/Message.php b/src/Appwrite/Utopia/Response/Model/Message.php index f6502bd75a..e52b6836c5 100644 --- a/src/Appwrite/Utopia/Response/Model/Message.php +++ b/src/Appwrite/Utopia/Response/Model/Message.php @@ -5,7 +5,6 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; use Utopia\Database\DateTime; -use Utopia\Database\Document as DatabaseDocument; class Message extends Model { diff --git a/src/Appwrite/Utopia/Response/Model/Rule.php b/src/Appwrite/Utopia/Response/Model/Rule.php index 077455b4a7..932591b90f 100644 --- a/src/Appwrite/Utopia/Response/Model/Rule.php +++ b/src/Appwrite/Utopia/Response/Model/Rule.php @@ -4,8 +4,6 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -use stdClass; -use Utopia\Database\Document; class Rule extends Model { diff --git a/src/Appwrite/Vcs/Comment.php b/src/Appwrite/Vcs/Comment.php index 1107e0ee70..35f76b6fd0 100644 --- a/src/Appwrite/Vcs/Comment.php +++ b/src/Appwrite/Vcs/Comment.php @@ -2,8 +2,8 @@ namespace Appwrite\Vcs; -use Utopia\Database\Document; use Utopia\App; +use Utopia\Database\Document; class Comment { diff --git a/tests/e2e/General/HooksTest.php b/tests/e2e/General/HooksTest.php index f4933428d1..d67c3256d9 100644 --- a/tests/e2e/General/HooksTest.php +++ b/tests/e2e/General/HooksTest.php @@ -70,63 +70,63 @@ class HooksTest extends Scope /** * Setup blocked user */ - $email = uniqid() . 'user@localhost.test'; - $password = 'password'; + $email = uniqid() . 'user@localhost.test'; + $password = 'password'; - $response = $this->client->call(Client::METHOD_POST, '/v1/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => $password, - ]); - - $id = $response['body']['$id']; - - $this->assertEquals(201, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_POST, '/v1/account/sessions/email', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], [ - 'email' => $email, - 'password' => $password, - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - - $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; - $cookie = 'a_session_' . $this->getProject()['$id'] . '=' . $session; - - $response = $this->client->call(Client::METHOD_GET, '/v1/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => $cookie, - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - - $response = $this->client->call(Client::METHOD_PATCH, '/v1/account/status', [ + $response = $this->client->call(Client::METHOD_POST, '/v1/account', [ 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => $cookie, - ], [ - 'status' => false, - ]); + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], [ + 'userId' => ID::unique(), + 'email' => $email, + 'password' => $password, + ]); - $this->assertEquals(200, $response['headers']['status-code']); + $id = $response['body']['$id']; - $response = $this->client->call(Client::METHOD_GET, '/v1/account', [ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => $cookie, - ]); + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, '/v1/account/sessions/email', [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], [ + 'email' => $email, + 'password' => $password, + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; + $cookie = 'a_session_' . $this->getProject()['$id'] . '=' . $session; + + $response = $this->client->call(Client::METHOD_GET, '/v1/account', [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => $cookie, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, '/v1/account/status', [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => $cookie, + ], [ + 'status' => false, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, '/v1/account', [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => $cookie, + ]); $this->assertEquals(401, $response['headers']['status-code']); diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 7df5143ecf..59df8b6420 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -3,12 +3,12 @@ namespace Tests\E2E\General; use Appwrite\Tests\Retry; +use CURLFile; +use DateTime; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use CURLFile; -use DateTime; use Tests\E2E\Services\Functions\FunctionsBase; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; diff --git a/tests/e2e/Scopes/Scope.php b/tests/e2e/Scopes/Scope.php index ed405cb7c0..3213ff4c5d 100644 --- a/tests/e2e/Scopes/Scope.php +++ b/tests/e2e/Scopes/Scope.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Scopes; use Appwrite\Tests\Retryable; -use Tests\E2E\Client; use PHPUnit\Framework\TestCase; +use Tests\E2E\Client; use Utopia\Database\Helpers\ID; abstract class Scope extends TestCase diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index ebb9ea644c..d61f44ca1b 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\Account; use Tests\E2E\Client; use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Datetime as DatetimeValidator; -use Utopia\Database\Query; trait AccountBase { @@ -277,43 +276,43 @@ trait AccountBase public function testDeleteAccount(): void { - $email = uniqid() . 'user@localhost.test'; - $password = 'password'; - $name = 'User Name'; + $email = uniqid() . 'user@localhost.test'; + $password = 'password'; + $name = 'User Name'; - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => $password, - 'name' => $name, - ]); + $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => $email, + 'password' => $password, + 'name' => $name, + ]); - $this->assertEquals($response['headers']['status-code'], 201); + $this->assertEquals($response['headers']['status-code'], 201); - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'email' => $email, + 'password' => $password, + ]); - $this->assertEquals($response['headers']['status-code'], 201); + $this->assertEquals($response['headers']['status-code'], 201); - $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; + $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; - $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ])); + $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ])); - $this->assertEquals($response['headers']['status-code'], 204); + $this->assertEquals($response['headers']['status-code'], 204); } } diff --git a/tests/e2e/Services/Account/AccountConsoleClientTest.php b/tests/e2e/Services/Account/AccountConsoleClientTest.php index 97a3374536..1df9ef6c18 100644 --- a/tests/e2e/Services/Account/AccountConsoleClientTest.php +++ b/tests/e2e/Services/Account/AccountConsoleClientTest.php @@ -2,10 +2,10 @@ namespace Tests\E2E\Services\Account; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectConsole; -use Tests\E2E\Scopes\SideClient; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectConsole; +use Tests\E2E\Scopes\Scope; +use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\ID; class AccountConsoleClientTest extends Scope @@ -16,76 +16,76 @@ class AccountConsoleClientTest extends Scope public function testDeleteAccount(): void { - $email = uniqid() . 'user@localhost.test'; - $password = 'password'; - $name = 'User Name'; + $email = uniqid() . 'user@localhost.test'; + $password = 'password'; + $name = 'User Name'; - $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'userId' => ID::unique(), - 'email' => $email, - 'password' => $password, - 'name' => $name, - ]); - - $this->assertEquals($response['headers']['status-code'], 201); - - $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ]), [ - 'email' => $email, - 'password' => $password, - ]); - - $this->assertEquals($response['headers']['status-code'], 201); - - $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; - - // create team - $team = $this->client->call(Client::METHOD_POST, '/teams', [ + $response = $this->client->call(Client::METHOD_POST, '/account', array_merge([ 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => $email, + 'password' => $password, + 'name' => $name, + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'email' => $email, + 'password' => $password, + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + + $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; + + // create team + $team = $this->client->call(Client::METHOD_POST, '/teams', [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ], [ 'teamId' => 'unique()', 'name' => 'myteam' - ]); - $this->assertEquals($team['headers']['status-code'], 201); + ]); + $this->assertEquals($team['headers']['status-code'], 201); - $teamId = $team['body']['$id']; + $teamId = $team['body']['$id']; - $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ])); + $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ])); - $this->assertEquals($response['headers']['status-code'], 400); + $this->assertEquals($response['headers']['status-code'], 400); - // DELETE TEAM - $response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $teamId, array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ])); - $this->assertEquals($response['headers']['status-code'], 204); - sleep(2); + // DELETE TEAM + $response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $teamId, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ])); + $this->assertEquals($response['headers']['status-code'], 204); + sleep(2); - $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ])); + $response = $this->client->call(Client::METHOD_DELETE, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ])); - $this->assertEquals($response['headers']['status-code'], 204); + $this->assertEquals($response['headers']['status-code'], 204); } } diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 7e713cfb74..23771712e8 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -4,8 +4,8 @@ namespace Tests\E2E\Services\Account; use Appwrite\Tests\Retry; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Account/AccountCustomServerTest.php b/tests/e2e/Services/Account/AccountCustomServerTest.php index e29110cf42..eb72a99913 100644 --- a/tests/e2e/Services/Account/AccountCustomServerTest.php +++ b/tests/e2e/Services/Account/AccountCustomServerTest.php @@ -6,8 +6,8 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Utopia\Database\Validator\Datetime as DatetimeValidator; use Utopia\Database\Helpers\ID; +use Utopia\Database\Validator\Datetime as DatetimeValidator; class AccountCustomServerTest extends Scope { @@ -112,7 +112,7 @@ class AccountCustomServerTest extends Scope ]); } - /** + /** * @depends testCreateAccountSession */ public function testGetAccount($data): array diff --git a/tests/e2e/Services/Avatars/AvatarsConsoleClientTest.php b/tests/e2e/Services/Avatars/AvatarsConsoleClientTest.php index a59d694114..bfd17ef1e9 100644 --- a/tests/e2e/Services/Avatars/AvatarsConsoleClientTest.php +++ b/tests/e2e/Services/Avatars/AvatarsConsoleClientTest.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Avatars; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectConsole; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; class AvatarsConsoleClientTest extends Scope diff --git a/tests/e2e/Services/Avatars/AvatarsCustomClientTest.php b/tests/e2e/Services/Avatars/AvatarsCustomClientTest.php index dc399971a0..edf09d5ba1 100644 --- a/tests/e2e/Services/Avatars/AvatarsCustomClientTest.php +++ b/tests/e2e/Services/Avatars/AvatarsCustomClientTest.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Avatars; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; class AvatarsCustomClientTest extends Scope diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index d91122e4fa..5c1f49399e 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -132,8 +132,8 @@ trait DatabasesBase Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/documents', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'queries' => [ diff --git a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php index 8a3f8d83a5..ca77cf2581 100644 --- a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php @@ -2,9 +2,9 @@ namespace Tests\E2E\Services\Databases; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; diff --git a/tests/e2e/Services/Databases/DatabasesCustomClientTest.php b/tests/e2e/Services/Databases/DatabasesCustomClientTest.php index f91fd4ff26..8484996058 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomClientTest.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Services\Databases; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\Database; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php index 1c5029d842..7ba6dbd189 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php @@ -3,10 +3,10 @@ namespace Tests\E2E\Services\Databases; use Appwrite\Extend\Exception as AppwriteException; +use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Tests\E2E\Client; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; @@ -1665,7 +1665,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('lorem', $attribute['default']); @@ -1807,7 +1807,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('torsten@appwrite.io', $attribute['default']); @@ -1950,7 +1950,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('127.0.0.1', $attribute['default']); @@ -2092,7 +2092,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('http://appwrite.io', $attribute['default']); @@ -2238,7 +2238,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals(123, $attribute['default']); @@ -2501,7 +2501,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals(123.456, $attribute['default']); @@ -2760,7 +2760,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals(true, $attribute['default']); @@ -2902,7 +2902,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('1975-06-12 14:12:55+02:00', $attribute['default']); @@ -3049,7 +3049,7 @@ class DatabasesCustomServerTest extends Scope 'x-appwrite-key' => $this->getProject()['apiKey'] ])); - $attribute = array_values(array_filter($new['body']['attributes'], fn(array $a) => $a['key'] === $key))[0] ?? null; + $attribute = array_values(array_filter($new['body']['attributes'], fn (array $a) => $a['key'] === $key))[0] ?? null; $this->assertNotNull($attribute); $this->assertFalse($attribute['required']); $this->assertEquals('lorem', $attribute['default']); diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php index b1d197f010..ca8753f374 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsGuestTest.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Services\Databases; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; diff --git a/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php b/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php index 8377b9c803..066d83a7ee 100644 --- a/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php +++ b/tests/e2e/Services/Databases/DatabasesPermissionsTeamTest.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Services\Databases; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 90252198dc..f72405008d 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -2,9 +2,9 @@ namespace Tests\E2E\Services\Functions; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 71d139a813..1b9edc4f02 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -8,7 +8,6 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; @@ -370,10 +369,10 @@ class FunctionsCustomServerTest extends Scope 'x-appwrite-mode' => 'admin', ]; - $variable = $this->client->call(Client::METHOD_POST, '/project/variables', $headers, [ + $variable = $this->client->call(Client::METHOD_POST, '/project/variables', $headers, [ 'key' => 'GLOBAL_VARIABLE', 'value' => 'Global Variable Value', - ]); + ]); $this->assertEquals(201, $variable['headers']['status-code']); diff --git a/tests/e2e/Services/GraphQL/AccountTest.php b/tests/e2e/Services/GraphQL/AccountTest.php index 7fe7e5cdd3..c17b8a5c24 100644 --- a/tests/e2e/Services/GraphQL/AccountTest.php +++ b/tests/e2e/Services/GraphQL/AccountTest.php @@ -6,9 +6,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\App; use Utopia\Database\Helpers\ID; -use Utopia\DSN\DSN; class AccountTest extends Scope { diff --git a/tests/e2e/Services/GraphQL/AuthTest.php b/tests/e2e/Services/GraphQL/AuthTest.php index b8689c1442..ecce29f2b3 100644 --- a/tests/e2e/Services/GraphQL/AuthTest.php +++ b/tests/e2e/Services/GraphQL/AuthTest.php @@ -7,8 +7,8 @@ use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\ID; -use Utopia\Database\Helpers\Role; use Utopia\Database\Helpers\Permission; +use Utopia\Database\Helpers\Role; class AuthTest extends Scope { diff --git a/tests/e2e/Services/GraphQL/BatchTest.php b/tests/e2e/Services/GraphQL/BatchTest.php index 7d154de802..de0534c749 100644 --- a/tests/e2e/Services/GraphQL/BatchTest.php +++ b/tests/e2e/Services/GraphQL/BatchTest.php @@ -77,17 +77,17 @@ class BatchTest extends Scope 'name' => 'Tester 1', ], ], - [ - 'query' => 'mutation CreateTeam($teamId: String! $name: String!) { + [ + 'query' => 'mutation CreateTeam($teamId: String! $name: String!) { teamsCreate(teamId: $teamId, name: $name) { name } }', - 'variables' => [ - 'teamId' => ID::unique(), - 'name' => 'Team 1', - ], - ]]; + 'variables' => [ + 'teamId' => ID::unique(), + 'name' => 'Team 1', + ], + ]]; $response = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/GraphQL/ScopeTest.php b/tests/e2e/Services/GraphQL/ScopeTest.php index ebf535268e..a270d6e660 100644 --- a/tests/e2e/Services/GraphQL/ScopeTest.php +++ b/tests/e2e/Services/GraphQL/ScopeTest.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\GraphQL; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\SideClient; use Tests\E2E\Scopes\SideServer; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Health/HealthBase.php b/tests/e2e/Services/Health/HealthBase.php index cbd0f97668..545cbc893f 100644 --- a/tests/e2e/Services/Health/HealthBase.php +++ b/tests/e2e/Services/Health/HealthBase.php @@ -2,8 +2,6 @@ namespace Tests\E2E\Services\Health; -use Tests\E2E\Client; - trait HealthBase { } diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index dde89a6a71..e9fe4b4f8c 100644 --- a/tests/e2e/Services/Health/HealthCustomServerTest.php +++ b/tests/e2e/Services/Health/HealthCustomServerTest.php @@ -3,9 +3,8 @@ namespace Tests\E2E\Services\Health; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; -use Tests\E2E\Scopes\SideClient; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; class HealthCustomServerTest extends Scope diff --git a/tests/e2e/Services/Locale/LocaleConsoleClientTest.php b/tests/e2e/Services/Locale/LocaleConsoleClientTest.php index 29b3150fed..c72e554df7 100644 --- a/tests/e2e/Services/Locale/LocaleConsoleClientTest.php +++ b/tests/e2e/Services/Locale/LocaleConsoleClientTest.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Locale; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectConsole; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; class LocaleConsoleClientTest extends Scope diff --git a/tests/e2e/Services/Locale/LocaleCustomClientTest.php b/tests/e2e/Services/Locale/LocaleCustomClientTest.php index b28584280e..6d6108dec1 100644 --- a/tests/e2e/Services/Locale/LocaleCustomClientTest.php +++ b/tests/e2e/Services/Locale/LocaleCustomClientTest.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Locale; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; class LocaleCustomClientTest extends Scope diff --git a/tests/e2e/Services/Locale/LocaleCustomServerTest.php b/tests/e2e/Services/Locale/LocaleCustomServerTest.php index 62d4e76802..1513f9b342 100644 --- a/tests/e2e/Services/Locale/LocaleCustomServerTest.php +++ b/tests/e2e/Services/Locale/LocaleCustomServerTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\Locale; -use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; diff --git a/tests/e2e/Services/Projects/ProjectsBase.php b/tests/e2e/Services/Projects/ProjectsBase.php index a9ccd73900..53d9626252 100644 --- a/tests/e2e/Services/Projects/ProjectsBase.php +++ b/tests/e2e/Services/Projects/ProjectsBase.php @@ -2,8 +2,6 @@ namespace Tests\E2E\Services\Projects; -use Tests\E2E\Client; - trait ProjectsBase { } diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index c2a4838625..6f60f01c73 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -4,11 +4,11 @@ namespace Tests\E2E\Services\Projects; use Appwrite\Auth\Auth; use Appwrite\Extend\Exception; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectConsole; -use Tests\E2E\Scopes\SideClient; use Tests\E2E\Client; use Tests\E2E\General\UsageTest; +use Tests\E2E\Scopes\ProjectConsole; +use Tests\E2E\Scopes\Scope; +use Tests\E2E\Scopes\SideClient; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; @@ -1496,9 +1496,9 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(400, $response['headers']['status-code']); - /** - * Reset - */ + /** + * Reset + */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1613,9 +1613,9 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(400, $response['headers']['status-code']); - /** - * Reset - */ + /** + * Reset + */ $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/password-history', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Projects/ProjectsCustomClientTest.php b/tests/e2e/Services/Projects/ProjectsCustomClientTest.php index 9dfd48ce50..25140309af 100644 --- a/tests/e2e/Services/Projects/ProjectsCustomClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsCustomClientTest.php @@ -2,10 +2,9 @@ namespace Tests\E2E\Services\Projects; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Tests\E2E\Client; class ProjectsCustomClientTest extends Scope { diff --git a/tests/e2e/Services/Projects/ProjectsCustomServerTest.php b/tests/e2e/Services/Projects/ProjectsCustomServerTest.php index 1c5b48f146..436d1df611 100644 --- a/tests/e2e/Services/Projects/ProjectsCustomServerTest.php +++ b/tests/e2e/Services/Projects/ProjectsCustomServerTest.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\Projects; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Tests\E2E\Client; class ProjectsCustomServerTest extends Scope { diff --git a/tests/e2e/Services/Realtime/RealtimeBase.php b/tests/e2e/Services/Realtime/RealtimeBase.php index 62bb7f5d3b..30c411ba93 100644 --- a/tests/e2e/Services/Realtime/RealtimeBase.php +++ b/tests/e2e/Services/Realtime/RealtimeBase.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Realtime; -use WebSocket\ConnectionException; use WebSocket\Client as WebSocketClient; +use WebSocket\ConnectionException; trait RealtimeBase { diff --git a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php index 82068f1301..6ab2874f8e 100644 --- a/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeConsoleClientTest.php @@ -4,8 +4,8 @@ namespace Tests\E2E\Services\Realtime; use CURLFile; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; use Tests\E2E\Services\Functions\FunctionsBase; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index a54a3142e4..9b73566bda 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -4,8 +4,8 @@ namespace Tests\E2E\Services\Realtime; use CURLFile; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\CLI\Console; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index b5023a2afd..78548ca1ac 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\Storage; use Appwrite\Extend\Exception; use CURLFile; use Tests\E2E\Client; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; diff --git a/tests/e2e/Services/Storage/StorageConsoleClientTest.php b/tests/e2e/Services/Storage/StorageConsoleClientTest.php index e75af0e1a3..5b6731b35e 100644 --- a/tests/e2e/Services/Storage/StorageConsoleClientTest.php +++ b/tests/e2e/Services/Storage/StorageConsoleClientTest.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Services\Storage; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; use Utopia\Database\Helpers\ID; diff --git a/tests/e2e/Services/Storage/StorageCustomClientTest.php b/tests/e2e/Services/Storage/StorageCustomClientTest.php index 12fc006968..c723fba50a 100644 --- a/tests/e2e/Services/Storage/StorageCustomClientTest.php +++ b/tests/e2e/Services/Storage/StorageCustomClientTest.php @@ -4,10 +4,9 @@ namespace Tests\E2E\Services\Storage; use CURLFile; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -125,18 +124,18 @@ class StorageCustomClientTest extends Scope * Test for SUCCESS */ $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], ], [ - 'bucketId' => ID::unique(), - 'name' => 'Test Bucket', - 'permissions' => [ - Permission::read(Role::any()), - Permission::create(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), - ], + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], ]); $bucketId = $bucket['body']['$id']; @@ -144,11 +143,11 @@ class StorageCustomClientTest extends Scope $this->assertNotEmpty($bucketId); $file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', [ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], ], [ - 'fileId' => ID::unique(), - 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'permissions.png'), + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'permissions.png'), ]); $fileId = $file['body']['$id']; @@ -160,45 +159,45 @@ class StorageCustomClientTest extends Scope $this->assertEquals(47218, $file['body']['sizeOriginal']); $file = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(200, $file['headers']['status-code']); $file = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId . '/preview', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(200, $file['headers']['status-code']); $file = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId . '/download', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(200, $file['headers']['status-code']); $file = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId . '/view', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(200, $file['headers']['status-code']); $file = $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], [ - 'name' => 'permissions.png', + 'name' => 'permissions.png', ]); $this->assertEquals(200, $file['headers']['status-code']); $file = $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ]); $this->assertEquals(204, $file['headers']['status-code']); diff --git a/tests/e2e/Services/Storage/StorageCustomServerTest.php b/tests/e2e/Services/Storage/StorageCustomServerTest.php index 585f91070c..1dafd8ca06 100644 --- a/tests/e2e/Services/Storage/StorageCustomServerTest.php +++ b/tests/e2e/Services/Storage/StorageCustomServerTest.php @@ -85,8 +85,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets', array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) @@ -176,8 +176,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets/' . $id, array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) @@ -196,8 +196,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets/empty', array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) @@ -209,8 +209,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets/id-is-really-long-id-is-really-long-id-is-really-long-id-is-really-long', array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) @@ -277,8 +277,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets/' . $id, array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) @@ -291,8 +291,8 @@ class StorageCustomServerTest extends Scope '/storage/buckets/' . $id, array_merge( [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders() ) diff --git a/tests/e2e/Services/Teams/TeamsBase.php b/tests/e2e/Services/Teams/TeamsBase.php index 6b93b01aad..2328e4cdbf 100644 --- a/tests/e2e/Services/Teams/TeamsBase.php +++ b/tests/e2e/Services/Teams/TeamsBase.php @@ -3,7 +3,6 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Client; -use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; diff --git a/tests/e2e/Services/Teams/TeamsBaseClient.php b/tests/e2e/Services/Teams/TeamsBaseClient.php index dff1c85716..03dffac6aa 100644 --- a/tests/e2e/Services/Teams/TeamsBaseClient.php +++ b/tests/e2e/Services/Teams/TeamsBaseClient.php @@ -3,7 +3,6 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Client; -use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Query; @@ -635,9 +634,9 @@ trait TeamsBaseClient return $data; } - /** - * @depends testUpdateTeamMembershipRoles - */ + /** + * @depends testUpdateTeamMembershipRoles + */ public function testDeleteTeamMembership($data): array { $teamUid = $data['teamUid'] ?? ''; diff --git a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php index e86c18a8e2..d7293c351c 100644 --- a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php +++ b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php @@ -3,8 +3,8 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectConsole; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; use Utopia\Database\Helpers\ID; @@ -79,10 +79,10 @@ class TeamsConsoleClientTest extends Scope $user = $this->client->call(Client::METHOD_POST, '/account', [ 'content-type' => 'application/json', 'x-appwrite-project' => 'console'], [ - 'userId' => 'unique()', - 'email' => $email, - 'password' => $password, - 'name' => $name, + 'userId' => 'unique()', + 'email' => $email, + 'password' => $password, + 'name' => $name, ], false); $this->assertEquals(201, $user['headers']['status-code']); diff --git a/tests/e2e/Services/Teams/TeamsCustomClientTest.php b/tests/e2e/Services/Teams/TeamsCustomClientTest.php index 3b46cbcb7f..83a8080d1d 100644 --- a/tests/e2e/Services/Teams/TeamsCustomClientTest.php +++ b/tests/e2e/Services/Teams/TeamsCustomClientTest.php @@ -2,8 +2,8 @@ namespace Tests\E2E\Services\Teams; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; class TeamsCustomClientTest extends Scope diff --git a/tests/e2e/Services/Teams/TeamsCustomServerTest.php b/tests/e2e/Services/Teams/TeamsCustomServerTest.php index ccbb598934..325b5892fc 100644 --- a/tests/e2e/Services/Teams/TeamsCustomServerTest.php +++ b/tests/e2e/Services/Teams/TeamsCustomServerTest.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\Teams; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; -use Tests\E2E\Client; class TeamsCustomServerTest extends Scope { diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 81f6149c96..1737e0483d 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -957,22 +957,22 @@ trait UsersBase /** * Test for SUCCESS */ - $session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [ + $session = $this->client->call(Client::METHOD_POST, '/account/sessions/email', [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], [ + ], [ 'email' => 'users.service@updated.com', 'password' => 'password' - ]); + ]); $this->assertEquals($session['headers']['status-code'], 201); - $user = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/password', array_merge([ + $user = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/password', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ + ], $this->getHeaders()), [ 'password' => '', - ]); + ]); $this->assertEquals($user['headers']['status-code'], 200); $this->assertNotEmpty($user['body']['$id']); diff --git a/tests/e2e/Services/Users/UsersConsoleClientTest.php b/tests/e2e/Services/Users/UsersConsoleClientTest.php index 0f5c4602b2..967104f5db 100644 --- a/tests/e2e/Services/Users/UsersConsoleClientTest.php +++ b/tests/e2e/Services/Users/UsersConsoleClientTest.php @@ -2,9 +2,9 @@ namespace Tests\E2E\Services\Users; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; class UsersConsoleClientTest extends Scope diff --git a/tests/e2e/Services/Users/UsersCustomServerTest.php b/tests/e2e/Services/Users/UsersCustomServerTest.php index 6b9a990d4c..2442f1bf7d 100644 --- a/tests/e2e/Services/Users/UsersCustomServerTest.php +++ b/tests/e2e/Services/Users/UsersCustomServerTest.php @@ -2,7 +2,6 @@ namespace Tests\E2E\Services\Users; -use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 697fbdba91..5e04c81a86 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -2,16 +2,16 @@ namespace Tests\E2E\Services\VCS; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideConsole; use Utopia\App; +use Utopia\Cache\Adapter\None; +use Utopia\Cache\Cache; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\VCS\Adapter\Git\GitHub; -use Utopia\Cache\Adapter\None; -use Utopia\Cache\Cache; class VCSConsoleClientTest extends Scope { diff --git a/tests/e2e/Services/VCS/VCSCustomClientTest.php b/tests/e2e/Services/VCS/VCSCustomClientTest.php index 084255cd69..26ccc45990 100644 --- a/tests/e2e/Services/VCS/VCSCustomClientTest.php +++ b/tests/e2e/Services/VCS/VCSCustomClientTest.php @@ -2,10 +2,10 @@ namespace Tests\E2E\Services\VCS; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectCustom; -use Tests\E2E\Scopes\SideClient; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; +use Tests\E2E\Scopes\SideClient; class VCSCustomClientTest extends Scope { diff --git a/tests/e2e/Services/VCS/VCSCustomServerTest.php b/tests/e2e/Services/VCS/VCSCustomServerTest.php index dee4cd7ced..337acb373b 100644 --- a/tests/e2e/Services/VCS/VCSCustomServerTest.php +++ b/tests/e2e/Services/VCS/VCSCustomServerTest.php @@ -2,10 +2,10 @@ namespace Tests\E2E\Services\VCS; -use Tests\E2E\Scopes\Scope; -use Tests\E2E\Scopes\ProjectCustom; -use Tests\E2E\Scopes\SideServer; use Tests\E2E\Client; +use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; +use Tests\E2E\Scopes\SideServer; class VCSCustomServerTest extends Scope { diff --git a/tests/e2e/Services/Webhooks/WebhooksBase.php b/tests/e2e/Services/Webhooks/WebhooksBase.php index eff6cbc6a5..d9eb7e46ca 100644 --- a/tests/e2e/Services/Webhooks/WebhooksBase.php +++ b/tests/e2e/Services/Webhooks/WebhooksBase.php @@ -5,7 +5,6 @@ namespace Tests\E2E\Services\Webhooks; use Appwrite\Tests\Retry; use CURLFile; use Tests\E2E\Client; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -27,19 +26,19 @@ trait WebhooksBase * Create database */ $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'] + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] ]), [ - 'databaseId' => ID::unique(), - 'name' => 'Actors DB', + 'databaseId' => ID::unique(), + 'name' => 'Actors DB', ]); $databaseId = $database['body']['$id']; - /** - * Test for SUCCESS - */ + /** + * Test for SUCCESS + */ $actors = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], diff --git a/tests/e2e/Services/Webhooks/WebhooksCustomClientTest.php b/tests/e2e/Services/Webhooks/WebhooksCustomClientTest.php index 2f0d8e465e..f331db905b 100644 --- a/tests/e2e/Services/Webhooks/WebhooksCustomClientTest.php +++ b/tests/e2e/Services/Webhooks/WebhooksCustomClientTest.php @@ -4,10 +4,9 @@ namespace Tests\E2E\Services\Webhooks; use Appwrite\Tests\Retry; use Tests\E2E\Client; -use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; +use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Datetime as DatetimeValidator; diff --git a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php index 7f8031ce94..d31c981a03 100644 --- a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php +++ b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php @@ -8,7 +8,6 @@ use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideServer; use Utopia\CLI\Console; -use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; diff --git a/tests/extensions/TestHook.php b/tests/extensions/TestHook.php index 67c1215c4c..507296acb9 100644 --- a/tests/extensions/TestHook.php +++ b/tests/extensions/TestHook.php @@ -3,7 +3,6 @@ namespace Appwrite\Tests; use PHPUnit\Runner\AfterTestHook; -use Exception; class TestHook implements AfterTestHook { diff --git a/tests/unit/Auth/AuthTest.php b/tests/unit/Auth/AuthTest.php index ea6e9dc6c1..705da42879 100644 --- a/tests/unit/Auth/AuthTest.php +++ b/tests/unit/Auth/AuthTest.php @@ -3,12 +3,12 @@ namespace Tests\Unit\Auth; use Appwrite\Auth\Auth; +use PHPUnit\Framework\TestCase; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; -use PHPUnit\Framework\TestCase; use Utopia\Database\Validator\Roles; class AuthTest extends TestCase diff --git a/tests/unit/Auth/Validator/PasswordDictionaryTest.php b/tests/unit/Auth/Validator/PasswordDictionaryTest.php index 5c8d47923c..60b5ca7ae3 100644 --- a/tests/unit/Auth/Validator/PasswordDictionaryTest.php +++ b/tests/unit/Auth/Validator/PasswordDictionaryTest.php @@ -4,7 +4,6 @@ namespace Tests\Unit\Auth\Validator; use Appwrite\Auth\Validator\PasswordDictionary; use PHPUnit\Framework\TestCase; -use Utopia\Database\Document; class PasswordDictionaryTest extends TestCase { diff --git a/tests/unit/Messaging/MessagingChannelsTest.php b/tests/unit/Messaging/MessagingChannelsTest.php index 6fe7dda71f..8ba0374093 100644 --- a/tests/unit/Messaging/MessagingChannelsTest.php +++ b/tests/unit/Messaging/MessagingChannelsTest.php @@ -3,9 +3,9 @@ namespace Tests\Unit\Messaging; use Appwrite\Auth\Auth; -use Utopia\Database\Document; use Appwrite\Messaging\Adapter\Realtime; use PHPUnit\Framework\TestCase; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; diff --git a/tests/unit/Messaging/MessagingTest.php b/tests/unit/Messaging/MessagingTest.php index c2e3971945..c2b6490869 100644 --- a/tests/unit/Messaging/MessagingTest.php +++ b/tests/unit/Messaging/MessagingTest.php @@ -2,9 +2,9 @@ namespace Tests\Unit\Messaging; -use Utopia\Database\Document; use Appwrite\Messaging\Adapter\Realtime; use PHPUnit\Framework\TestCase; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; diff --git a/tests/unit/Usage/StatsTest.php b/tests/unit/Usage/StatsTest.php index 794caebdf5..c564b31c92 100644 --- a/tests/unit/Usage/StatsTest.php +++ b/tests/unit/Usage/StatsTest.php @@ -20,12 +20,12 @@ class StatsTest extends TestCase public function setUp(): void { $env = App::getEnv('_APP_CONNECTIONS_QUEUE', AppwriteURL::unparse([ - 'scheme' => 'redis', - 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => App::getEnv('_APP_REDIS_USER', ''), - 'pass' => App::getEnv('_APP_REDIS_PASS', ''), - ])); + 'scheme' => 'redis', + 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), + 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), + 'user' => App::getEnv('_APP_REDIS_USER', ''), + 'pass' => App::getEnv('_APP_REDIS_PASS', ''), + ])); $dsn = explode('=', $env); $dsn = count($dsn) > 1 ? $dsn[1] : $dsn[0]; diff --git a/tests/unit/Utopia/Request/Filters/V16Test.php b/tests/unit/Utopia/Request/Filters/V16Test.php index daa1d45a0d..322e24260a 100644 --- a/tests/unit/Utopia/Request/Filters/V16Test.php +++ b/tests/unit/Utopia/Request/Filters/V16Test.php @@ -4,7 +4,6 @@ namespace Tests\Unit\Utopia\Request\Filters; use Appwrite\Utopia\Request\Filter; use Appwrite\Utopia\Request\Filters\V16; -use Appwrite\Utopia\Response\Model; use PHPUnit\Framework\TestCase; class V16Test extends TestCase diff --git a/tests/unit/Utopia/Request/Filters/V17Test.php b/tests/unit/Utopia/Request/Filters/V17Test.php index 4c0e155ec5..3efa72c77a 100644 --- a/tests/unit/Utopia/Request/Filters/V17Test.php +++ b/tests/unit/Utopia/Request/Filters/V17Test.php @@ -72,7 +72,7 @@ class V17Test extends TestCase ] ], ] - ]; + ]; } /** diff --git a/tests/unit/Utopia/Response/Filters/V15Test.php b/tests/unit/Utopia/Response/Filters/V15Test.php index fc38e5320b..d65ffebc63 100644 --- a/tests/unit/Utopia/Response/Filters/V15Test.php +++ b/tests/unit/Utopia/Response/Filters/V15Test.php @@ -2,11 +2,11 @@ namespace Tests\Unit\Utopia\Response\Filters; -use Appwrite\Utopia\Response\Filters\V15; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filters\V15; +use PHPUnit\Framework\TestCase; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -use PHPUnit\Framework\TestCase; class V15Test extends TestCase { diff --git a/tests/unit/Utopia/Response/Filters/V16Test.php b/tests/unit/Utopia/Response/Filters/V16Test.php index 2078559b61..ba6fb837f2 100644 --- a/tests/unit/Utopia/Response/Filters/V16Test.php +++ b/tests/unit/Utopia/Response/Filters/V16Test.php @@ -2,9 +2,8 @@ namespace Tests\Unit\Utopia\Response\Filters; -use Appwrite\Utopia\Response\Filters\V16; -use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filters\V16; use Cron\CronExpression; use PHPUnit\Framework\TestCase; use Utopia\Database\DateTime; diff --git a/tests/unit/Utopia/Response/Filters/V17Test.php b/tests/unit/Utopia/Response/Filters/V17Test.php index 8f618c360e..dedaa996e1 100644 --- a/tests/unit/Utopia/Response/Filters/V17Test.php +++ b/tests/unit/Utopia/Response/Filters/V17Test.php @@ -2,12 +2,9 @@ namespace Tests\Unit\Utopia\Response\Filters; -use Appwrite\Utopia\Response\Filters\V17; -use Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; -use Cron\CronExpression; +use Appwrite\Utopia\Response\Filters\V17; use PHPUnit\Framework\TestCase; -use Utopia\Database\DateTime; class V17Test extends TestCase { diff --git a/tests/unit/Utopia/ResponseTest.php b/tests/unit/Utopia/ResponseTest.php index e4389b3953..e621036506 100644 --- a/tests/unit/Utopia/ResponseTest.php +++ b/tests/unit/Utopia/ResponseTest.php @@ -2,9 +2,9 @@ namespace Tests\Unit\Utopia; -use Exception; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filters\V11; +use Exception; use PHPUnit\Framework\TestCase; use Swoole\Http\Response as SwooleResponse; use Utopia\Database\Document; From 5490d46f059c017f835701711bca5bb75b73d157 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:35:02 +0100 Subject: [PATCH 50/51] fix: remove phpcs.xml --- phpcs.xml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 phpcs.xml diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 70e4df36ed..0000000000 --- a/phpcs.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - ./app - ./src - ./tests - - - ./app/sdks - - ./tests/resources/functions - - ./app/console - - - * - - - - * - - - - ./app - - \ No newline at end of file From e764b358a0a53c98eca427be6963262e5f8f64df Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 6 Mar 2024 18:36:26 +0100 Subject: [PATCH 51/51] fix: composer lock --- composer.lock | 82 +-------------------------------------------------- 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/composer.lock b/composer.lock index 1203807f50..c44a41b254 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": "a0c585fabc25c78458734e1fbf9d30c8", + "content-hash": "427cda6539f0edab82485bf43a257ad4", "packages": [ { "name": "adhocore/jwt", @@ -5038,86 +5038,6 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.9.0", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" - }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" - }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" - } - ], - "time": "2024-02-16T15:06:51+00:00" - }, { "name": "swoole/ide-helper", "version": "5.0.2",