From 00c45c2507e2aebb0dc5961149835e9073707cf2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Mar 2024 03:32:55 +0000 Subject: [PATCH 01/17] new environment for certificates and security emails --- .env | 3 ++- app/config/variables.php | 20 ++++++++++++++++++- app/console | 2 +- app/controllers/api/avatars.php | 2 +- app/init.php | 2 +- app/views/install/compose.phtml | 8 ++++---- docker-compose.yml | 8 ++++---- .../Platform/Workers/Certificates.php | 6 +++--- src/Appwrite/Platform/Workers/Webhooks.php | 2 +- 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.env b/.env index 09abb07be2..8d86049694 100644 --- a/.env +++ b/.env @@ -8,7 +8,8 @@ _APP_CONSOLE_COUNTRIES_DENYLIST=AQ _APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io _APP_SYSTEM_EMAIL_NAME=Appwrite _APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io -_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io +_APP_EMAIL_SECURITY=security@appwrite.io +_APP_EMAIL_CERTIFICATES=certificates@appwrite.io _APP_SYSTEM_RESPONSE_FORMAT= _APP_OPTIONS_ABUSE=disabled _APP_OPTIONS_ROUTER_PROTECTION=disabled diff --git a/app/config/variables.php b/app/config/variables.php index 185ab29d0c..cd6c492f9e 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -162,13 +162,31 @@ return [ ], [ 'name' => '_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', - 'description' => 'This is the email address used to issue SSL certificates for custom domains or the user agent in your webhooks payload.', + 'description' => 'Deprecated since 1.5.1 use _APP_EMAIL_SECURITY and _APP_EMAIL_CERTIFICATES instead', 'introduction' => '0.7.0', 'default' => 'certs@appwrite.io', 'required' => false, 'question' => '', 'filter' => '' ], + [ + 'name' => '_APP_EMAIL_SECURITY', + 'description' => 'This is the email address used as the user agent in your webhooks payload.', + 'introduction' => '1.5.1', + 'default' => '', + 'required' => false, + 'question' => '', + 'filter' => '' + ], + [ + 'name' => '_APP_EMAIL_CERTIFICATES', + 'description' => 'This is the email address used to issue SSL certificates for custom domains', + 'introduction' => '1.5.1', + 'default' => '', + 'required' => false, + 'question' => '', + 'filter' => '' + ], [ 'name' => '_APP_USAGE_STATS', 'description' => 'This variable allows you to disable the collection and displaying of usage stats. This value is set to \'enabled\' by default, to disable the usage stats set the value to \'disabled\'. When disabled, it\'s recommended to turn off the Worker Usage container to reduce resource usage.', diff --git a/app/console b/app/console index d75ef00fb0..0a007a3b1b 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit d75ef00fb088c909bf8fdc5b12c2fe25ed270b43 +Subproject commit 0a007a3b1b6eafc39dc19b7129f41643102f9676 diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 6304482b14..771f7cebbc 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -349,7 +349,7 @@ App::get('/v1/avatars/favicon') CURLOPT_USERAGENT => \sprintf( APP_USERAGENT, App::getEnv('_APP_VERSION', 'UNKNOWN'), - App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + App::getEnv('_APP_EMAIL_SECURITY', APP_EMAIL_SECURITY) ), ]); diff --git a/app/init.php b/app/init.php index 4b70b2601b..20d427f66c 100644 --- a/app/init.php +++ b/app/init.php @@ -1004,7 +1004,7 @@ foreach ($locales as $locale) { 'user_agent' => \sprintf( APP_USERAGENT, App::getEnv('_APP_VERSION', 'UNKNOWN'), - App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + App::getEnv('_APP_EMAIL_SECURITY', APP_EMAIL_SECURITY) ), 'timeout' => 2, ], diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 354ef4ea49..1f5ee606e7 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -81,7 +81,7 @@ services: - _APP_CONSOLE_HOSTNAMES - _APP_SYSTEM_EMAIL_NAME - _APP_SYSTEM_EMAIL_ADDRESS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_SYSTEM_RESPONSE_FORMAT - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION @@ -251,7 +251,7 @@ services: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER @@ -427,7 +427,7 @@ services: - _APP_DOMAIN - _APP_DOMAIN_TARGET - _APP_DOMAIN_FUNCTIONS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_CERTIFICATES - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER @@ -549,7 +549,7 @@ services: - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - _APP_DOMAIN_TARGET - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER diff --git a/docker-compose.yml b/docker-compose.yml index 58dff56901..097de3c9b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -102,7 +102,7 @@ services: - _APP_CONSOLE_HOSTNAMES - _APP_SYSTEM_EMAIL_NAME - _APP_SYSTEM_EMAIL_ADDRESS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_SYSTEM_RESPONSE_FORMAT - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION @@ -285,7 +285,7 @@ services: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -474,7 +474,7 @@ services: - _APP_DOMAIN - _APP_DOMAIN_TARGET - _APP_DOMAIN_FUNCTIONS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_CERTIFICATES - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER @@ -612,7 +612,7 @@ services: - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - _APP_DOMAIN_TARGET - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index 7cc32ca1c9..2c1707b1c8 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -134,9 +134,9 @@ class Certificates extends Action try { // Email for alerts is required by LetsEncrypt - $email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); + $email = App::getEnv('_APP_EMAIL_CERTIFICATES'); if (empty($email)) { - throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate.'); + throw new Exception('You must set a valid security email address (_APP_EMAIL_CERTIFICATES) to issue an SSL certificate.'); } // Validate domain and DNS records. Skip if job is forced @@ -473,7 +473,7 @@ class Certificates extends Action ->setBody($body) ->setName('Appwrite Administrator') ->setVariables($emailVariables) - ->setRecipient(App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')) + ->setRecipient(App::getEnv('_APP_EMAIL_CERTIFICATES')) ->trigger(); } diff --git a/src/Appwrite/Platform/Workers/Webhooks.php b/src/Appwrite/Platform/Workers/Webhooks.php index da5a82999f..857f552eda 100644 --- a/src/Appwrite/Platform/Workers/Webhooks.php +++ b/src/Appwrite/Platform/Workers/Webhooks.php @@ -104,7 +104,7 @@ class Webhooks extends Action \curl_setopt($ch, CURLOPT_USERAGENT, \sprintf( APP_USERAGENT, App::getEnv('_APP_VERSION', 'UNKNOWN'), - App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + App::getEnv('_APP_EMAIL_SECURITY', APP_EMAIL_SECURITY) )); \curl_setopt( $ch, From b61e0f08f67fddec1b438984ad0409fa02b006ff Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 6 May 2024 00:58:23 +0000 Subject: [PATCH 02/17] make required --- app/config/variables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/variables.php b/app/config/variables.php index cd6c492f9e..f18dac5d73 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -183,7 +183,7 @@ return [ 'description' => 'This is the email address used to issue SSL certificates for custom domains', 'introduction' => '1.5.1', 'default' => '', - 'required' => false, + 'required' => true, 'question' => '', 'filter' => '' ], From be1c147658f49b7e39de9abb851a1ecc6078812b Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 6 May 2024 01:00:20 +0000 Subject: [PATCH 03/17] update console --- app/console | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/console b/app/console index 0a007a3b1b..f483d9631d 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 0a007a3b1b6eafc39dc19b7129f41643102f9676 +Subproject commit f483d9631d6f21e94aedb20b5c37c56fea06c23e From 1a42d118f64b6af90ffa6787e58079e1dcd34e05 Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Sat, 1 Jun 2024 19:18:35 +0530 Subject: [PATCH 04/17] add: test to validate user-id isn't overridden. --- .../Functions/FunctionsCustomClientTest.php | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 119c1a2223..0acf297ea7 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -716,4 +716,92 @@ class FunctionsCustomClientTest extends Scope return []; } + + public function testExecutionWithUserId(): array + { + /** + * Test for SUCCESS + */ + $projectId = $this->getProject()['$id']; + $apikey = $this->getProject()['apiKey']; + + $function = $this->client->call(Client::METHOD_POST, '/functions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ], [ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::any()->toString()], + 'runtime' => 'node-18.0', + 'entrypoint' => 'index.js' + ]); + + $functionId = $function['body']['$id'] ?? ''; + + $this->assertEquals(201, $function['headers']['status-code']); + + $folder = 'node'; + $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + $this->packageCode($folder); + + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ], [ + 'entrypoint' => 'index.js', + 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'activate' => true + ]); + + $deploymentId = $deployment['body']['$id'] ?? ''; + + $this->assertEquals(202, $deployment['headers']['status-code']); + + // Poll until deployment is built + while (true) { + $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/deployments/' . $deploymentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + if ( + $deployment['headers']['status-code'] >= 400 + || \in_array($deployment['body']['status'], ['ready', 'failed']) + ) { + break; + } + + \sleep(1); + } + + $this->assertEquals('ready', $deployment['body']['status']); + + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'x-appwrite-user-id' => "665b0df20031bdf527fb", + ]); + + $output = json_decode($execution['body']['responseBody'], true); + $this->assertNotEquals('665b0df20031bdf527fb', $this->getUser()['$id']); + $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); + // Client should never see logs and errors + $this->assertEmpty($execution['body']['logs']); + $this->assertEmpty($execution['body']['errors']); + + // Cleanup : Delete function + $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], []); + + $this->assertEquals(204, $response['headers']['status-code']); + + return []; + } } From 52f5a5c40c6a637a66cb34325cbd67034bd73b39 Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Mon, 3 Jun 2024 14:10:20 +0530 Subject: [PATCH 05/17] update test. --- .../Functions/FunctionsCustomClientTest.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 0acf297ea7..0adf11d057 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -783,15 +783,19 @@ class FunctionsCustomClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'x-appwrite-user-id' => "665b0df20031bdf527fb", + 'x-appwrite-event' => "OVERRIDDEN", + 'x-appwrite-trigger' => "OVERRIDDEN", + 'x-appwrite-user-id' => "OVERRIDDEN", + 'x-appwrite-user-jwt' => "OVERRIDDEN", ]); $output = json_decode($execution['body']['responseBody'], true); - $this->assertNotEquals('665b0df20031bdf527fb', $this->getUser()['$id']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_JWT']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_EVENT']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_TRIGGER']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_USER_ID']); + $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); - // Client should never see logs and errors - $this->assertEmpty($execution['body']['logs']); - $this->assertEmpty($execution['body']['errors']); // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ From b54a599960dbd21e52d8ef923bb4857f666eab9a Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Mon, 3 Jun 2024 14:13:08 +0530 Subject: [PATCH 06/17] update test name for clarity. --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 0adf11d057..e10aef840c 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -717,7 +717,7 @@ class FunctionsCustomClientTest extends Scope return []; } - public function testExecutionWithUserId(): array + public function testNonOverrideOfHeaders(): array { /** * Test for SUCCESS From 37da4a0cd39e20aa9a1be37c8ef7a401a5843783 Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Mon, 3 Jun 2024 14:19:59 +0530 Subject: [PATCH 07/17] review comments. --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index e10aef840c..0b8ea71aad 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -795,8 +795,6 @@ class FunctionsCustomClientTest extends Scope $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_TRIGGER']); $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_USER_ID']); - $this->assertEquals($this->getUser()['$id'], $output['APPWRITE_FUNCTION_USER_ID']); - // Cleanup : Delete function $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ 'content-type' => 'application/json', From f762d66c5e87c233beeb490d7f2fab96aca3e663 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 4 Jun 2024 01:31:05 +0000 Subject: [PATCH 08/17] fix typo --- src/Appwrite/Platform/Workers/Webhooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Webhooks.php b/src/Appwrite/Platform/Workers/Webhooks.php index a83183ec3e..88ca7871f2 100644 --- a/src/Appwrite/Platform/Workers/Webhooks.php +++ b/src/Appwrite/Platform/Workers/Webhooks.php @@ -103,7 +103,7 @@ class Webhooks extends Action \curl_setopt($ch, CURLOPT_MAXFILESIZE, self::MAX_FILE_SIZE); \curl_setopt($ch, CURLOPT_USERAGENT, \sprintf( APP_USERAGENT, - App::getEnv('_APP_VERSION', 'UNKNOWN'), + System::getEnv('_APP_VERSION', 'UNKNOWN'), System::getEnv('_APP_EMAIL_SECURITY', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)) )); \curl_setopt( From cccda2a46cc7ee348864ae6c7be56bff1966c271 Mon Sep 17 00:00:00 2001 From: Bishwajeet Parhi Date: Wed, 5 Jun 2024 23:34:01 +0530 Subject: [PATCH 09/17] fix: Don't set target attribute if no existing Target found --- app/controllers/api/account.php | 4 +++- app/controllers/api/users.php | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index e1ddeb6b68..20ce2541c5 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -290,7 +290,9 @@ App::post('/v1/account') $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + } } $dbForProject->purgeCachedDocument('users', $user->getId()); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index abfcb34a5a..9d08fcf784 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -138,7 +138,9 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + } } } @@ -160,7 +162,9 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + } } } From 485b8eeb8b2461f46a877cbc017baeaf487a9c33 Mon Sep 17 00:00:00 2001 From: Bishwajeet Parhi Date: Wed, 5 Jun 2024 23:53:31 +0530 Subject: [PATCH 10/17] chore: misc test assertions improvements --- .../Account/AccountCustomClientTest.php | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 23771712e8..b1f7c85cd9 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -150,7 +150,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertEquals($response['body']['name'], $name); $this->assertArrayHasKey('accessedAt', $response['body']); @@ -294,7 +294,7 @@ class AccountCustomClientTest extends Scope $this->assertIsNumeric($response['body']['total']); $this->assertEquals("user.create", $response['body']['logs'][2]['event']); $this->assertEquals(filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP), $response['body']['logs'][2]['ip']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['logs'][2]['time'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['logs'][2]['time'])); $this->assertEquals('Windows', $response['body']['logs'][1]['osName']); $this->assertEquals('WIN', $response['body']['logs'][1]['osCode']); @@ -327,7 +327,6 @@ class AccountCustomClientTest extends Scope $this->assertEquals('desktop', $response['body']['logs'][2]['deviceName']); $this->assertEquals('', $response['body']['logs'][2]['deviceBrand']); $this->assertEquals('', $response['body']['logs'][2]['deviceModel']); - $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); $this->assertEquals('--', $response['body']['logs'][2]['countryCode']); $this->assertEquals('Unknown', $response['body']['logs'][2]['countryName']); @@ -343,7 +342,7 @@ class AccountCustomClientTest extends Scope ] ]); - $this->assertEquals($responseLimit['headers']['status-code'], 200); + $this->assertEquals(200, $responseLimit['headers']['status-code']); $this->assertIsArray($responseLimit['body']['logs']); $this->assertNotEmpty($responseLimit['body']['logs']); $this->assertCount(1, $responseLimit['body']['logs']); @@ -382,7 +381,7 @@ class AccountCustomClientTest extends Scope ] ]); - $this->assertEquals($responseLimitOffset['headers']['status-code'], 200); + $this->assertEquals(200, $responseLimitOffset['headers']['status-code']); $this->assertIsArray($responseLimitOffset['body']['logs']); $this->assertNotEmpty($responseLimitOffset['body']['logs']); $this->assertCount(1, $responseLimitOffset['body']['logs']); @@ -430,7 +429,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertEquals($response['body']['name'], $newName); @@ -497,7 +496,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -587,7 +586,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $newEmail); /** @@ -629,7 +628,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $data['email']); $this->assertEquals($response['body']['name'], $data['name']); @@ -771,7 +770,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $lastEmail = $this->getLastEmail(); @@ -1073,7 +1072,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $lastEmail = $this->getLastEmail(); @@ -1668,7 +1667,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -1756,13 +1755,11 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals($response['body']['$id'], $userId); - $this->assertEquals($response['body']['name'], 'User Name'); - $this->assertEquals($response['body']['email'], 'useroauth@localhost.test'); + $this->assertEquals('User Name', $response['body']['name']); + $this->assertEquals('useroauth@localhost.test', $response['body']['email']); // Since we only support one oauth user, let's also check updateSession here - $this->assertEquals(200, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_GET, '/account/sessions/current', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -1808,7 +1805,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals($response['body']['provider'], 'anonymous'); + $this->assertEquals('anonymous', $response['body']['provider']); $sessionID = $response['body']['$id']; @@ -1821,7 +1818,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals($response['body']['provider'], 'anonymous'); + $this->assertEquals('anonymous', $response['body']['provider']); $response = $this->client->call(Client::METHOD_GET, '/account/sessions/97823askjdkasd80921371980', array_merge([ 'origin' => 'http://localhost', @@ -1934,7 +1931,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $userId = $response['body']['userId']; @@ -2085,7 +2082,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -2127,7 +2124,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['phone'], $newPhone); /** @@ -2240,7 +2237,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $smsRequest = $this->getLastRequest(); @@ -2327,7 +2324,7 @@ class AccountCustomClientTest extends Scope $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); $this->assertEmpty($response['body']['phrase']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $userId = $response['body']['userId']; @@ -2452,7 +2449,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertTrue($response['body']['emailVerification']); @@ -2512,7 +2509,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ From c179e89fdf0f6ebc2044eeaae8a2d47b207b1f48 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 9 Jun 2024 01:03:40 +0000 Subject: [PATCH 11/17] update to use latest platform with module --- app/cli.php | 2 +- app/worker.php | 5 -- composer.json | 2 +- composer.lock | 67 +++++++++++----------- src/Appwrite/Platform/Appwrite.php | 6 +- src/Appwrite/Platform/Modules/Core.php | 17 ++++++ src/Appwrite/Platform/Services/Tasks.php | 2 +- src/Appwrite/Platform/Services/Workers.php | 2 +- 8 files changed, 57 insertions(+), 46 deletions(-) create mode 100644 src/Appwrite/Platform/Modules/Core.php diff --git a/app/cli.php b/app/cli.php index da7d23c18d..d132f25b1a 100644 --- a/app/cli.php +++ b/app/cli.php @@ -202,7 +202,7 @@ CLI::setResource('logError', function (Registry $register) { }, ['register']); $platform = new Appwrite(); -$platform->init(Service::TYPE_CLI); +$platform->init(Service::TYPE_TASK); $cli = $platform->getCli(); diff --git a/app/worker.php b/app/worker.php index 60358ad6b2..7037614f8e 100644 --- a/app/worker.php +++ b/app/worker.php @@ -284,11 +284,6 @@ if (!isset($args[1])) { \array_shift($args); $workerName = $args[0]; -$workerIndex = $args[1] ?? ''; - -if (!empty($workerIndex)) { - $workerName .= '_' . $workerIndex; -} if (\str_starts_with($workerName, 'databases')) { $queueName = System::getEnv('_APP_QUEUE_NAME', 'database_db_main'); diff --git a/composer.json b/composer.json index 205fe308f0..82e3e15a05 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/messaging": "0.11.*", "utopia-php/migration": "0.4.*", "utopia-php/orchestration": "0.9.*", - "utopia-php/platform": "0.5.*", + "utopia-php/platform": "0.7.*", "utopia-php/pools": "0.5.*", "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.7.*", diff --git a/composer.lock b/composer.lock index 8acbbed541..5d31e14570 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "53996479cd4ba0c73dbc72d46b240be0", + "content-hash": "18bab1e5f72cc82896aef9e64bf566e8", "packages": [ { "name": "adhocore/jwt", @@ -1427,16 +1427,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "0.37.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", "shasum": "" }, "require": { @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/0.37.1" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-06-05T18:03:59+00:00" }, { "name": "utopia-php/analytics", @@ -1522,16 +1522,16 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "0.39.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", "shasum": "" }, "require": { @@ -1563,9 +1563,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/0.39.1" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-06-05T19:28:22+00:00" }, { "name": "utopia-php/cache", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.10", + "version": "0.49.11", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec" + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/216209121bc97a2010f67a39c561fafe1e936bec", - "reference": "216209121bc97a2010f67a39c561fafe1e936bec", + "url": "https://api.github.com/repos/utopia-php/database/zipball/4f4b35d99ecdee971c3042279bb1ac8264825030", + "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.10" + "source": "https://github.com/utopia-php/database/tree/0.49.11" }, - "time": "2024-05-20T02:14:20+00:00" + "time": "2024-05-30T12:40:27+00:00" }, { "name": "utopia-php/domains", @@ -2327,16 +2327,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.2", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3" + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", "shasum": "" }, "require": { @@ -2344,7 +2344,8 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.33.*" + "utopia-php/framework": "0.33.*", + "utopia-php/queue": "0.7.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2370,9 +2371,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.2" + "source": "https://github.com/utopia-php/platform/tree/0.7.0" }, - "time": "2024-05-22T12:50:35+00:00" + "time": "2024-05-08T17:00:55+00:00" }, { "name": "utopia-php/pools", @@ -3824,16 +3825,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -3865,9 +3866,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-05-06T12:04:23+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5613,5 +5614,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Platform/Appwrite.php b/src/Appwrite/Platform/Appwrite.php index 05224799f3..6b3eb077fa 100644 --- a/src/Appwrite/Platform/Appwrite.php +++ b/src/Appwrite/Platform/Appwrite.php @@ -2,15 +2,13 @@ namespace Appwrite\Platform; -use Appwrite\Platform\Services\Tasks; -use Appwrite\Platform\Services\Workers; +use Appwrite\Platform\Modules\Core; use Utopia\Platform\Platform; class Appwrite extends Platform { public function __construct() { - $this->addService('tasks', new Tasks()); - $this->addService('workers', new Workers()); + parent::__construct(new Core()); } } diff --git a/src/Appwrite/Platform/Modules/Core.php b/src/Appwrite/Platform/Modules/Core.php new file mode 100644 index 0000000000..355747e3ab --- /dev/null +++ b/src/Appwrite/Platform/Modules/Core.php @@ -0,0 +1,17 @@ +addService('tasks', new Tasks()); + $this->addService('workers', new Workers()); + } + +} \ No newline at end of file diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index ac1f99eec3..31465d2f26 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -22,7 +22,7 @@ class Tasks extends Service { public function __construct() { - $this->type = self::TYPE_CLI; + $this->type = Service::TYPE_TASK; $this ->addAction(Doctor::getName(), new Doctor()) ->addAction(Install::getName(), new Install()) diff --git a/src/Appwrite/Platform/Services/Workers.php b/src/Appwrite/Platform/Services/Workers.php index 62a7fcf3fb..0e79f4257c 100644 --- a/src/Appwrite/Platform/Services/Workers.php +++ b/src/Appwrite/Platform/Services/Workers.php @@ -20,7 +20,7 @@ class Workers extends Service { public function __construct() { - $this->type = self::TYPE_WORKER; + $this->type = Service::TYPE_WORKER; $this ->addAction(Audits::getName(), new Audits()) ->addAction(Builds::getName(), new Builds()) From 26413566dc07098b0b4db0917240bac51c01259e Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 9 Jun 2024 11:36:35 +0000 Subject: [PATCH 12/17] fix format --- src/Appwrite/Platform/Modules/Core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Modules/Core.php b/src/Appwrite/Platform/Modules/Core.php index 355747e3ab..859ca3b529 100644 --- a/src/Appwrite/Platform/Modules/Core.php +++ b/src/Appwrite/Platform/Modules/Core.php @@ -14,4 +14,4 @@ class Core extends Module $this->addService('workers', new Workers()); } -} \ No newline at end of file +} From 190560b8ef4604f81eae7a3f2aa393839066e875 Mon Sep 17 00:00:00 2001 From: Bishwajeet Parhi Date: Tue, 11 Jun 2024 21:17:25 +0530 Subject: [PATCH 13/17] chore: append attributes instead of replace --- app/controllers/api/account.php | 2 +- app/controllers/api/users.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 20ce2541c5..6f0345cfdc 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -291,7 +291,7 @@ App::post('/v1/account') Query::equal('identifier', [$email]), ]); if($existingTarget) { - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 9d08fcf784..193f3f095e 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -139,7 +139,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e Query::equal('identifier', [$email]), ]); if($existingTarget) { - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } } @@ -163,7 +163,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e Query::equal('identifier', [$phone]), ]); if($existingTarget) { - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } } From 897ae1c859315aa56cf4528ebc5cce4ee569764d Mon Sep 17 00:00:00 2001 From: choir27 Date: Wed, 12 Jun 2024 10:47:48 -0400 Subject: [PATCH 14/17] docs: update text description in request table --- app/controllers/api/teams.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index d003fcfd37..5891fb67f0 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -387,7 +387,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. This parameter is not required when an API key is supplied. 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') From 84d9b4befe0c10218bb4d6e3205eae6f6d6dbb23 Mon Sep 17 00:00:00 2001 From: choir27 Date: Thu, 13 Jun 2024 09:59:20 -0400 Subject: [PATCH 15/17] docs: fix hyperlink in storage code snippet --- app/controllers/api/storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 9215d99345..1dd3bb597c 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -351,7 +351,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->label('sdk.response.model', Response::MODEL_FILE) ->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).') ->param('fileId', '', new CustomId(), 'File 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('file', [], new File(), 'Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/storage#file-input).', skipValidation: true) + ->param('file', [], new File(), 'Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/products/storage/upload-download#input-file).', skipValidation: true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->inject('request') ->inject('response') From dbfae9455273433b9a090efcb9c1d43b2c2c4fd7 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 20 Jun 2024 17:28:21 +0900 Subject: [PATCH 16/17] Fix certificate emails --- .../templates/email-certificate-failed.tpl | 4 ++- app/config/locale/translations/en.json | 6 +++++ .../Platform/Workers/Certificates.php | 26 +++---------------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/app/config/locale/templates/email-certificate-failed.tpl b/app/config/locale/templates/email-certificate-failed.tpl index 18751ff412..0363fc6538 100644 --- a/app/config/locale/templates/email-certificate-failed.tpl +++ b/app/config/locale/templates/email-certificate-failed.tpl @@ -4,7 +4,9 @@
-

{{error}}

+

+ {{error}} +

diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index 72bb9c099e..8c908ae5ab 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -43,6 +43,12 @@ "emails.invitation.footer": "If you are not interested, you can ignore this message.", "emails.invitation.thanks": "Thanks", "emails.invitation.signature": "{{project}} team", + "emails.certificate.subject": "Certificate failure for %s", + "emails.certificate.hello": "Hello", + "emails.certificate.body": "Certificate for your domain '{{domain}}' could not be generated. This is attempt no. {{attempt}}, and the failure was caused by: {{error}}", + "emails.certificate.footer": "Your previous certificate will be valid for 30 days since the first failure. We highly recommend investigating this case, otherwise your domain will end up without a valid SSL communication.", + "emails.certificate.thanks": "Thanks", + "emails.certificate.signature": "{{project}} team", "sms.verification.body": "{{secret}}", "locale.country.unknown": "Unknown", "countries.af": "Afghanistan", diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index ad6cf09fa7..c7a4034a45 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -439,40 +439,22 @@ class Certificates extends Action $locale = new Locale(System::getEnv('_APP_LOCALE', 'en')); - // Send mail to administratore mail + // Send mail to administrator mail $template = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-certificate-failed.tpl'); $template->setParam('{{domain}}', $domain); $template->setParam('{{error}}', \nl2br($errorMessage)); $template->setParam('{{attempts}}', $attempt); - - // TODO: Use setbodyTemplate once #7307 is merged - $subject = 'Certificate failed to generate'; - $body = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl'); - - $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); - - $message = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-inner-base.tpl'); - $message - ->setParam('{{body}}', $locale->getText("emails.certificate.body"), escapeHtml: false) - ->setParam('{{hello}}', $locale->getText("emails.certificate.hello")) - ->setParam('{{footer}}', $locale->getText("emails.certificate.footer")) - ->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks")) - ->setParam('{{signature}}', $locale->getText("emails.certificate.signature")); - $body = $message->render(); + $body = $template->render(); $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - 'domain' => $domain, - 'error' => '
' . $errorMessage . '
', - 'attempt' => $attempt, - 'project' => 'Console', - 'redirect' => 'https://' . $domain, ]; $queueForMails - ->setSubject($subject) + ->setSubject('Certificate failed to generate') ->setBody($body) ->setName('Appwrite Administrator') + ->setbodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl') ->setVariables($emailVariables) ->setRecipient(System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'))) ->trigger(); From ea95e80cbfeeb3be73c181e83637d1be8dcbda61 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 20 Jun 2024 17:47:16 +0900 Subject: [PATCH 17/17] Use localised subject string --- src/Appwrite/Platform/Workers/Certificates.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index c7a4034a45..58dc1dd28a 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -450,8 +450,10 @@ class Certificates extends Action 'direction' => $locale->getText('settings.direction'), ]; + $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); + $queueForMails - ->setSubject('Certificate failed to generate') + ->setSubject($subject) ->setBody($body) ->setName('Appwrite Administrator') ->setbodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl')