From e56b30e6a6c9d7d5416383e7329ccc4738a645eb Mon Sep 17 00:00:00 2001 From: Serhat Aksakal <49079271+fanksin@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:10:44 +0300 Subject: [PATCH 01/28] Update tr.json --- app/config/locale/translations/tr.json | 56 ++++++++++++++------------ 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/app/config/locale/translations/tr.json b/app/config/locale/translations/tr.json index 6a94aeacae..e82317de01 100644 --- a/app/config/locale/translations/tr.json +++ b/app/config/locale/translations/tr.json @@ -3,30 +3,36 @@ "settings.locale": "tr", "settings.direction": "ltr", "emails.sender": "%s Takımı", - "emails.verification.subject": "", - "emails.verification.hello": "", - "emails.verification.body": "", - "emails.verification.footer": "", - "emails.verification.thanks": "", - "emails.verification.signature": "", - "emails.magicSession.subject": "", - "emails.magicSession.hello": "", - "emails.magicSession.body": "", - "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", - "emails.magicSession.signature": "", - "emails.recovery.subject": "", - "emails.recovery.hello": "", - "emails.recovery.body": "", - "emails.recovery.footer": "", - "emails.recovery.thanks": "", - "emails.recovery.signature": "", - "emails.invitation.subject": "", - "emails.invitation.hello": "", - "emails.invitation.body": "", - "emails.invitation.footer": "", - "emails.invitation.thanks": "", - "emails.invitation.signature": "", + "emails.verification.subject": "Hesabını Doğrula", + "emails.verification.hello": "Merhaba {{user}}", + "emails.verification.body": "Eposta adresini doğrulamak için bu bağlantıyı kullanın.", + "emails.verification.footer": "Eğer bu eposta adresini doğrulamak isteyen siz değilseniz devam etmeyin.", + "emails.verification.thanks": "Teşekkürler", + "emails.verification.signature": "{{project}} takımı", + "emails.magicSession.subject": "Giriş", + "emails.magicSession.hello": "Merhaba,", + "emails.magicSession.body": "Giriş yapmak için tıklayın.", + "emails.magicSession.footer": "Eğer bu eposta adresini kullanarak giriş yapmak istemediyseniz devam etmeyin.", + "emails.magicSession.thanks": "Teşekkürler", + "emails.magicSession.signature": "{{project}} takımı", + "emails.recovery.subject": "Şifremi Sıfırla", + "emails.recovery.hello": "Merhaba {{user}}", + "emails.recovery.body": "{{project}} şifrenizi sıfırlamak için bu bağlantıyı kullanın.", + "emails.recovery.footer": "Eğer şifre sıfırlama talebinde bulunmadıysanız devam etmeyin.", + "emails.recovery.thanks": "Teşekkürler", + "emails.recovery.signature": "{{project}} takımı", + "emails.invitation.subject": "%s üzerinde %s Takımına Davet", + "emails.invitation.hello": "Merhaba", + "emails.invitation.body": "Bu epostayı aldınız, çünkü {{owner}} sizi {{project}} üzerinde {{team}} takımının üyesi olmaya davet etti.", + "emails.invitation.footer": "Eğer ilgilenmiyorsanız devam etmeyin.", + "emails.invitation.thanks": "Teşekkürler", + "emails.invitation.signature": "{{project}} takımı", + "emails.certificate.subject": "%s için sertifika hatası", + "emails.certificate.hello": "Merhaba", + "emails.certificate.body": "Alan adınız '{{domain}}' için sertifika oluşturulamadı. Deneme sayısı {{attempt}} ve hata sebebi: {{error}}", + "emails.certificate.footer": "Geçmiş sertifikanız ilk denemeden sonra 30 gün daha geçerli kalacaktır. Bu konuyu araştırmanızı öneriyoruz, aksi taktirde alan adınız SSL sertifikasız kalacaktır.", + "emails.certificate.thanks": "Teşekkürler", + "emails.certificate.signature": "{{project}} takımı", "locale.country.unknown": "Bilinmeyen", "countries.af": "Afganistan", "countries.ao": "Angola", @@ -229,4 +235,4 @@ "continents.na": "Kuzey Amerika", "continents.oc": "Okyanusya", "continents.sa": "Güney Amerika" -} \ No newline at end of file +} From 92a307c164b00f1b888b3ea9bd2f52b98bbbc7be Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 13 Dec 2023 18:45:05 +0000 Subject: [PATCH 02/28] Fix user identity attaching to wrong user Suppose a user has 2 accounts on Appwrite: 1. joe@example.com 2. joe@gmail.com Prior to this PR, if joe@example.com created a Google OAuth2 session using his joe@gmail.com email, a new joe@gmail.com identity would be created linked to joe@example.com. This is especially problematic because if the user tried to create a Google OAuth2 session using joe@gmail.com, Appwrite would lookup the user via email and find the joe@gmail.com user, but then find an identity from joe@example.com. This mismatching user ID would then cause an error. This PR prevents an identity from being created if the email from the OAuth2 provider matches another user's email. --- app/controllers/api/account.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index c210b19f4f..54967fb502 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -550,11 +550,19 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') if (!$user->isEmpty()) { $userId = $user->getId(); - $identitiesWithMatchingEmail = $dbForProject->find('identities', [ + $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), Query::notEqual('userId', $userId), ]); - if (!empty($identitiesWithMatchingEmail)) { + if (!empty($identityWithMatchingEmail)) { + throw new Exception(Exception::USER_ALREADY_EXISTS); + } + + $userWithMatchingEmail = $dbForProject->find('users', [ + Query::equal('email', [$email]), + Query::notEqual('$id', $userId), + ]); + if (!empty($userWithMatchingEmail)) { throw new Exception(Exception::USER_ALREADY_EXISTS); } } From 6b6946e39bfd4a653ed2bd9dec57b3de301995d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=B7=E5=8D=8E=20=E5=88=98?= Date: Fri, 15 Dec 2023 20:40:04 +0000 Subject: [PATCH 03/28] chore: update console --- .gitmodules | 2 +- app/console | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index cc08f93fcf..0c2321bcfa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "app/console"] path = app/console url = https://github.com/appwrite/console - branch = 3.2.15 + branch = 3.2.16 diff --git a/app/console b/app/console index 94e4c1a730..0a007a3b1b 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 94e4c1a73024b0e974fbe6077674281f6e973c9d +Subproject commit 0a007a3b1b6eafc39dc19b7129f41643102f9676 From 6d17f8e87779b51e6eacd39297c2066c6af6bfee Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Fri, 15 Dec 2023 21:37:26 +0000 Subject: [PATCH 04/28] Fix user last activity not updating Add back a section of code that was mistakenly removed. --- app/controllers/shared/api.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index b37d76a816..1ea2fdc654 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -553,6 +553,22 @@ App::shutdown() ->setParam('project.{scope}.network.outbound', $response->getSize()) ->submit(); } + + /** + * Update user last activity + */ + if (!$user->isEmpty()) { + $accessedAt = $user->getAttribute('accessedAt', ''); + if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_USER_ACCCESS)) > $accessedAt) { + $user->setAttribute('accessedAt', DateTime::now()); + + if (APP_MODE_ADMIN !== $mode) { + $dbForProject->updateDocument('users', $user->getId(), $user); + } else { + $dbForConsole->updateDocument('users', $user->getId(), $user); + } + } + } }); App::init() From e41194ee3c6163c72ee7c3d24464e11088a720db Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Sat, 16 Dec 2023 17:42:29 +0000 Subject: [PATCH 05/28] Fix import to match class name The class is SMS rather than Sms. --- 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 76b86e4f0c..876ca50d0d 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -6,7 +6,7 @@ use Exception; use Utopia\App; use Utopia\CLI\Console; use Utopia\DSN\DSN; -use Utopia\Messaging\Messages\Sms; +use Utopia\Messaging\Messages\SMS; use Utopia\Messaging\Adapters\SMS\Mock; use Utopia\Messaging\Adapters\SMS\Msg91; use Utopia\Messaging\Adapters\SMS\Telesign; From d9319aa888efc966f48cc47703472afcf7fcf1b1 Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja Date: Sat, 23 Dec 2023 17:42:34 +0530 Subject: [PATCH 06/28] feat: added zoho oauth metadata --- app/config/providers.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/config/providers.php b/app/config/providers.php index 6ba54f28e4..9d7efc2f1e 100644 --- a/app/config/providers.php +++ b/app/config/providers.php @@ -362,6 +362,16 @@ return [ 'beta' => false, 'mock' => false, ], + 'zoho' => [ + 'name' => 'Zoho', + 'developers' => 'https://zoho.com/accounts/protocol/oauth.html', + 'icon' => 'icon-zoho', + 'enabled' => true, + 'sandbox' => false, + 'form' => false, + 'beta' => false, + 'mock' => false, + ], 'zoom' => [ 'name' => 'Zoom', 'developers' => 'https://marketplace.zoom.us/docs/guides/auth/oauth/', From 26ac88c32e3548c6b14add906e75ed512f4a8662 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 05:54:59 +0000 Subject: [PATCH 07/28] validate create permission while updating chunk uploaded file --- app/controllers/api/storage.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 1fae48dae0..d390f9ef1c 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -621,8 +621,13 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - - $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); + + // Validate create permission + $validator = new Authorization(Database::PERMISSION_CREATE); + if (!$validator->isValid($bucket->getCreate())) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -659,7 +664,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('chunksUploaded', $chunksUploaded) ->setAttribute('metadata', $metadata); - $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); + // Validate create permission + $validator = new Authorization(Database::PERMISSION_CREATE); + if (!$validator->isValid($bucket->getCreate())) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + $file = Authorization::skip(fn() => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); } } catch (AuthorizationException) { throw new Exception(Exception::USER_UNAUTHORIZED); From b6b1b396b384c4d4b6cc520586c0468753a7d14e Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:00:43 +0000 Subject: [PATCH 08/28] update chunk upload test --- tests/e2e/Services/Storage/StorageBase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 5463740761..be01d95368 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -74,10 +74,7 @@ trait StorageBase 'name' => 'Test Bucket 2', 'fileSecurity' => true, 'permissions' => [ - Permission::read(Role::any()), Permission::create(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), ], ]); $this->assertEquals(201, $bucket2['headers']['status-code']); From a6b4ade39b72bb595bd5c7c03063bf6d475437d8 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:06:18 +0000 Subject: [PATCH 09/28] update large file upload test to not include update permission --- tests/e2e/Services/Storage/StorageBase.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index be01d95368..eb6a52db6b 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -107,9 +107,7 @@ trait StorageBase 'fileId' => $fileId, 'file' => $curlFile, 'permissions' => [ - Permission::read(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()), + Permission::read(Role::any()) ], ]); $counter++; From cbd3e85b389400740973a9e8948b457062adcb9e Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Mon, 25 Dec 2023 06:07:28 +0000 Subject: [PATCH 10/28] fix formatting --- 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 d390f9ef1c..687971c2d0 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -621,7 +621,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - + // Validate create permission $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { From e8ff828039bd2e60c003d9a828b6ea5196a76052 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 01:31:25 +0000 Subject: [PATCH 11/28] fix for file extension not supported - the error occured with jfif extension, which is essentially a jpeg file --- app/controllers/api/storage.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 1fae48dae0..8600752734 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -915,6 +915,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } if (empty($output)) { + // when file extension is provided but it's not one of our + // supported outputs we fallback to `jpg` + if(!empty($type) && !array_key_exists($type, $outputs)) { + $type = 'jpg'; + } + // when file extension is not provided and the mime type is not one of our supported outputs // we fallback to `jpg` output format $output = empty($type) ? (array_search($mime, $outputs) ?? 'jpg') : $type; From 94a18ede78a89db8caf959d1aab723c6256e4b2f Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 01:35:10 +0000 Subject: [PATCH 12/28] fix formatting --- app/controllers/api/storage.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 8600752734..5ef810fec7 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -915,12 +915,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } if (empty($output)) { - // when file extension is provided but it's not one of our + // when file extension is provided but it's not one of our // supported outputs we fallback to `jpg` - if(!empty($type) && !array_key_exists($type, $outputs)) { + if (!empty($type) && !array_key_exists($type, $outputs)) { $type = 'jpg'; } - + // when file extension is not provided and the mime type is not one of our supported outputs // we fallback to `jpg` output format $output = empty($type) ? (array_search($mime, $outputs) ?? 'jpg') : $type; From 83a009dcba7955f9a2b317534b44b52ded571ddc Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 02:22:05 +0000 Subject: [PATCH 13/28] update tests for preview --- tests/e2e/Services/Storage/StorageBase.php | 28 ++++++++++++++++++++- tests/resources/disk-a/preview-test.jfif | Bin 0 -> 131958 bytes 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/resources/disk-a/preview-test.jfif diff --git a/tests/e2e/Services/Storage/StorageBase.php b/tests/e2e/Services/Storage/StorageBase.php index 5463740761..36d2ee2365 100644 --- a/tests/e2e/Services/Storage/StorageBase.php +++ b/tests/e2e/Services/Storage/StorageBase.php @@ -27,7 +27,7 @@ trait StorageBase 'name' => 'Test Bucket', 'fileSecurity' => true, 'maximumFileSize' => 2000000, //2MB - 'allowedFileExtensions' => ["jpg", "png"], + 'allowedFileExtensions' => ["jpg", "png", 'jfif'], 'permissions' => [ Permission::read(Role::any()), Permission::create(Role::any()), @@ -462,6 +462,32 @@ trait StorageBase $this->assertEquals('image/png', $file2['headers']['content-type']); $this->assertNotEmpty($file2['body']); + // upload JXL file for preview + $fileJfif = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/disk-a/preview-test.jfif'), 'image/jxl', 'preview-test.jfif'), + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + $this->assertEquals(201, $fileJfif['headers']['status-code']); + $this->assertNotEmpty($fileJfif['body']['$id']); + + // TEST preview JXL + $preview = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileJfif['body']['$id'] . '/preview', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $preview['headers']['status-code']); + $this->assertEquals('image/jpeg', $preview['headers']['content-type']); + $this->assertNotEmpty($preview['body']); + //new image preview features $file3 = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $data['fileId'] . '/preview', array_merge([ 'content-type' => 'application/json', diff --git a/tests/resources/disk-a/preview-test.jfif b/tests/resources/disk-a/preview-test.jfif new file mode 100644 index 0000000000000000000000000000000000000000..e50021f95d5254cdfd68dfaa91a8b851de46740b GIT binary patch literal 131958 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

Ru*<0cFRO#9N7PBF= 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 Date: Thu, 28 Dec 2023 11:26:45 +0000 Subject: [PATCH 14/28] improve order --- app/controllers/api/storage.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 5ef810fec7..533e5c73a6 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -872,14 +872,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::USER_UNAUTHORIZED); } - if ((\strpos($request->getAccept(), 'image/webp') === false) && ('webp' === $output)) { // Fallback webp to jpeg when no browser support - $output = 'jpg'; - } - - $inputs = Config::getParam('storage-inputs'); - $outputs = Config::getParam('storage-outputs'); - $fileLogos = Config::getParam('storage-logos'); - if ($fileSecurity && !$valid) { $file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); } else { @@ -890,6 +882,14 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); } + if ((\strpos($request->getAccept(), 'image/webp') === false) && ('webp' === $output)) { // Fallback webp to jpeg when no browser support + $output = 'jpg'; + } + + $inputs = Config::getParam('storage-inputs'); + $outputs = Config::getParam('storage-outputs'); + $fileLogos = Config::getParam('storage-logos'); + $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); $algorithm = $file->getAttribute('algorithm', 'none'); @@ -926,7 +926,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $output = empty($type) ? (array_search($mime, $outputs) ?? 'jpg') : $type; } - $source = $deviceFiles->read($path); if (!empty($cipher)) { // Decrypt From a28be2bf48f91291af3b5099d239e81052075d50 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 11:32:04 +0000 Subject: [PATCH 15/28] return when response is sent to prevent further execution --- app/controllers/api/storage.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 533e5c73a6..99aa16226b 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -1258,10 +1258,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') $response->send(substr($source, $start, ($end - $start + 1))); } $response->send($source); + return; } if (!empty($rangeHeader)) { $response->send($deviceFiles->read($path, $start, ($end - $start + 1))); + return; } $size = $deviceFiles->getFileSize($path); From 9cb5eb0180f94bba220c65b7b60f1e4815db7723 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 28 Dec 2023 11:42:40 +0000 Subject: [PATCH 16/28] use constants for compression type --- app/controllers/api/storage.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 99aa16226b..5a03edaf4a 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -892,7 +892,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); - $algorithm = $file->getAttribute('algorithm', 'none'); + $algorithm = $file->getAttribute('algorithm', COMPRESSION_TYPE_NONE); $cipher = $file->getAttribute('openSSLCipher'); $mime = $file->getAttribute('mimeType'); if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) App::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) { @@ -903,7 +903,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $fileLogos['default_image']; } - $algorithm = 'none'; + $algorithm = COMPRESSION_TYPE_NONE; $cipher = null; $background = (empty($background)) ? 'eceff1' : $background; $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); @@ -940,11 +940,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } switch ($algorithm) { - case 'zstd': + case COMPRESSION_TYPE_ZSTD: $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: $compressor = new GZIP(); $source = $compressor->decompress($source); break; @@ -1085,15 +1085,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ); } - switch ($file->getAttribute('algorithm', 'none')) { - case 'zstd': + switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { + case COMPRESSION_TYPE_ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } @@ -1236,15 +1236,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ); } - switch ($file->getAttribute('algorithm', 'none')) { - case 'zstd': + switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { + case COMPRESSION_TYPE_ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case 'gzip': + case COMPRESSION_TYPE_GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } From 1c236959ba776e2877b42fb3ddfa8f3ac118a1f2 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 29 Dec 2023 01:49:56 +0000 Subject: [PATCH 17/28] fix algorithm attribute on file if size is above read buffer size --- app/controllers/api/storage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 5a03edaf4a..aaa1df9d32 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -551,6 +551,11 @@ App::post('/v1/storage/buckets/:bucketId/files') break; } $data = $compressor->compress($data); + } else { + // reset the algorithm to none as we do not compress the file + // if file size exceedes the APP_STORAGE_READ_BUFFER + // regardless the bucket compression algoorithm + $algorithm = COMPRESSION_TYPE_NONE; } if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) { From 09cec17285f5152af42d7a36a6188854c820e7c2 Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja Date: Fri, 29 Dec 2023 17:43:07 +0000 Subject: [PATCH 18/28] added Zoho OAuth class --- src/Appwrite/Auth/OAuth2/Zoho.php | 164 ++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/Appwrite/Auth/OAuth2/Zoho.php diff --git a/src/Appwrite/Auth/OAuth2/Zoho.php b/src/Appwrite/Auth/OAuth2/Zoho.php new file mode 100644 index 0000000000..fefff9a9fb --- /dev/null +++ b/src/Appwrite/Auth/OAuth2/Zoho.php @@ -0,0 +1,164 @@ +authEndpoint . '?' . + \http_build_query([ + 'response_type' => 'code', + 'client_id' => $this->appID, + 'state' => \json_encode($this->state), + 'redirect_uri' => $this->callback, + 'scope' => \implode(' ', $this->getScopes()) + ]); + + return $url; + } + + + /** + * @param string $code + * + * @return array + */ + protected function getTokens(string $code): array + { + if (empty($this->tokens)) { + $this->tokens = \json_decode($this->request( + 'POST', + $this->endpoint . '/oauth/v2/token', + ["Content-Type: application/x-www-form-urlencoded"], + \http_build_query([ + 'grant_type' => 'authorization_code', + "client_id" => $this->appID, + "client_secret" => $this->appSecret, + "redirect_uri" => $this->callback, + 'code' => $code, + 'scope' => \implode(' ', $this->getScopes()), + ]) + ), true); + $this->user = (isset($this->tokens['id_token'])) ? \explode('.', $this->tokens['id_token']) : [0 => '', 1 => '']; + $this->user = (isset($this->user[1])) ? \json_decode(\base64_decode($this->user[1]), true) : []; + } + + return $this->tokens; + } + + + /** + * @param string $refreshToken + * + * @return array + */ + public function refreshTokens(string $refreshToken): array + { + + $this->tokens = \json_decode($this->request( + 'POST', + $this->endpoint . '/oauth/v2/token', + ['Content-Type: application/x-www-form-urlencoded'], + \http_build_query([ + 'grant_type' => 'refresh_token', + 'refresh_token' => $refreshToken, + 'client_id' => $this->appID, + 'client_secret' => $this->appSecret, + ]) + ), true); + + if (empty($this->tokens['refresh_token'])) { + $this->tokens['refresh_token'] = $refreshToken; + } + + $this->user = (isset($this->tokens['id_token'])) ? \explode('.', $this->tokens['id_token']) : [0 => '', 1 => '']; + $this->user = (isset($this->user[1])) ? \json_decode(\base64_decode($this->user[1]), true) : []; + + return $this->tokens; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserID(string $accessToken): string + { + return $this->user['sub'] ?? ''; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserEmail(string $accessToken): string + { + return $this->user['email'] ?? ''; + } + + /** + * @param string $accessToken + * + * @return bool + */ + public function isEmailVerified(string $accessToken): bool + { + return $this->user['email_verified'] ?? ''; + } + + /** + * @param string $accessToken + * + * @return string + */ + public function getUserName(string $accessToken): string + { + return $this->user['name'] ?? ''; + } +} \ No newline at end of file From c99976560d13a56401b808650e38d6d817005cf7 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:37:22 +0000 Subject: [PATCH 19/28] update utopia-storage --- composer.lock | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/composer.lock b/composer.lock index 3518396665..17f0325ded 100644 --- a/composer.lock +++ b/composer.lock @@ -1906,16 +1906,16 @@ }, { "name": "utopia-php/database", - "version": "0.45.2", + "version": "0.45.3", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788" + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/dc789f2c1fd8b5ee07ff883e11c9ad7970824788", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788", + "url": "https://api.github.com/repos/utopia-php/database/zipball/33b4e9a4a6c29f6bb7e108e134b283d585955789", + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789", "shasum": "" }, "require": { @@ -1956,9 +1956,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.45.2" + "source": "https://github.com/utopia-php/database/tree/0.45.3" }, - "time": "2023-11-15T03:38:47+00:00" + "time": "2023-12-28T11:12:26+00:00" }, { "name": "utopia-php/domains", @@ -2476,16 +2476,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.0", + "version": "0.5.1", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26" + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/229a7b1fa1f39afd1532f7a515326a6afc222a26", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285", + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285", "shasum": "" }, "require": { @@ -2493,7 +2493,7 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2519,9 +2519,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.0" + "source": "https://github.com/utopia-php/platform/tree/0.5.1" }, - "time": "2023-10-16T20:28:49+00:00" + "time": "2023-12-26T16:14:41+00:00" }, { "name": "utopia-php/pools", @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.1", + "version": "0.18.2", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824" + "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/983e6dee137012f9f57f126d3c79aab54e4e8824", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/130e7c4f305c2e1d5aa86226aaee25c9d5a41073", + "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.1" + "source": "https://github.com/utopia-php/storage/tree/0.18.2" }, - "time": "2023-10-24T14:44:19+00:00" + "time": "2023-12-31T11:33:28+00:00" }, { "name": "utopia-php/swoole", @@ -2904,23 +2904,23 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.2", + "version": "0.6.4", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee" + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/f135291b87cb45335fc6608722e7f89894bc33ee", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/b2595a50a4897a8c88319240810055b7a96efd6d", + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", "utopia-php/cache": "^0.8.0", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2947,9 +2947,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.2" + "source": "https://github.com/utopia-php/vcs/tree/0.6.4" }, - "time": "2023-11-08T15:36:03+00:00" + "time": "2023-12-26T15:38:19+00:00" }, { "name": "utopia-php/websocket", @@ -3487,16 +3487,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -3537,9 +3537,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -3891,16 +3891,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.4", + "version": "1.24.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", "shasum": "" }, "require": { @@ -3932,29 +3932,29 @@ "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.24.4" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" }, - "time": "2023-11-26T18:29:22+00:00" + "time": "2023-12-16T09:33:33+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4004,7 +4004,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.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -4012,7 +4012,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4651,20 +4651,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -4696,7 +4696,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -4704,7 +4704,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -4978,20 +4978,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5023,7 +5023,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -5031,7 +5031,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", From d070989f73c50b3515d1e5317673c22e69c7c570 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:46:27 +0000 Subject: [PATCH 20/28] update utopia storage --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 17f0325ded..acd65d61a1 100644 --- a/composer.lock +++ b/composer.lock @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.2", + "version": "0.18.3", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073" + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/130e7c4f305c2e1d5aa86226aaee25c9d5a41073", - "reference": "130e7c4f305c2e1d5aa86226aaee25c9d5a41073", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/faa0279519ac14f3501e8b138e0865ad9d12bff6", + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.2" + "source": "https://github.com/utopia-php/storage/tree/0.18.3" }, - "time": "2023-12-31T11:33:28+00:00" + "time": "2023-12-31T11:45:12+00:00" }, { "name": "utopia-php/swoole", From a2ad8700845b1b1b9c3e0fa4d0949798054a98a4 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 31 Dec 2023 11:46:45 +0000 Subject: [PATCH 21/28] use compression constant from utopia/storage --- app/controllers/api/storage.php | 35 ++++++++++--------- app/init.php | 4 --- src/Appwrite/Utopia/Response/Model/Bucket.php | 3 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index aaa1df9d32..91efb21f3e 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -44,6 +44,7 @@ use Utopia\Validator\Text; use Utopia\Validator\WhiteList; use Utopia\DSN\DSN; use Utopia\Swoole\Request; +use Utopia\Storage\Compression\Compression; App::post('/v1/storage/buckets') ->desc('Create bucket') @@ -67,7 +68,7 @@ App::post('/v1/storage/buckets') ->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true) ->param('maximumFileSize', (int) App::getEnv('_APP_STORAGE_LIMIT', 0), new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) - ->param('compression', COMPRESSION_TYPE_NONE, new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) + ->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) ->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true) ->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true) ->inject('response') @@ -241,7 +242,7 @@ App::put('/v1/storage/buckets/:bucketId') ->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true) ->param('maximumFileSize', null, new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true) ->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true) - ->param('compression', COMPRESSION_TYPE_NONE, new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) + ->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true) ->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true) ->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true) ->inject('response') @@ -538,14 +539,14 @@ App::post('/v1/storage/buckets/:bucketId/files') $fileHash = $deviceFiles->getFileHash($path); // Get file hash before compression and encryption $data = ''; // Compression - $algorithm = $bucket->getAttribute('compression', COMPRESSION_TYPE_NONE); - if ($fileSize <= APP_STORAGE_READ_BUFFER && $algorithm != COMPRESSION_TYPE_NONE) { + $algorithm = $bucket->getAttribute('compression', Compression::NONE); + if ($fileSize <= APP_STORAGE_READ_BUFFER && $algorithm != Compression::NONE) { $data = $deviceFiles->read($path); switch ($algorithm) { - case COMPRESSION_TYPE_ZSTD: + case Compression::ZSTD: $compressor = new Zstd(); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: default: $compressor = new GZIP(); break; @@ -555,7 +556,7 @@ App::post('/v1/storage/buckets/:bucketId/files') // reset the algorithm to none as we do not compress the file // if file size exceedes the APP_STORAGE_READ_BUFFER // regardless the bucket compression algoorithm - $algorithm = COMPRESSION_TYPE_NONE; + $algorithm = Compression::NONE; } if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) { @@ -897,7 +898,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $file->getAttribute('path'); $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); - $algorithm = $file->getAttribute('algorithm', COMPRESSION_TYPE_NONE); + $algorithm = $file->getAttribute('algorithm', Compression::NONE); $cipher = $file->getAttribute('openSSLCipher'); $mime = $file->getAttribute('mimeType'); if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) App::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) { @@ -908,7 +909,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $path = $fileLogos['default_image']; } - $algorithm = COMPRESSION_TYPE_NONE; + $algorithm = Compression::NONE; $cipher = null; $background = (empty($background)) ? 'eceff1' : $background; $type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION)); @@ -945,11 +946,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') } switch ($algorithm) { - case COMPRESSION_TYPE_ZSTD: + case Compression::ZSTD: $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: $compressor = new GZIP(); $source = $compressor->decompress($source); break; @@ -1090,15 +1091,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') ); } - switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { - case COMPRESSION_TYPE_ZSTD: + switch ($file->getAttribute('algorithm', Compression::NONE)) { + case Compression::ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } @@ -1241,15 +1242,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ); } - switch ($file->getAttribute('algorithm', COMPRESSION_TYPE_NONE)) { - case COMPRESSION_TYPE_ZSTD: + switch ($file->getAttribute('algorithm', Compression::NONE)) { + case Compression::ZSTD: if (empty($source)) { $source = $deviceFiles->read($path); } $compressor = new Zstd(); $source = $compressor->decompress($source); break; - case COMPRESSION_TYPE_GZIP: + case Compression::GZIP: if (empty($source)) { $source = $deviceFiles->read($path); } diff --git a/app/init.php b/app/init.php index 72bf75d41b..924122ac20 100644 --- a/app/init.php +++ b/app/init.php @@ -173,10 +173,6 @@ const DELETE_TYPE_SESSIONS = 'sessions'; const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp'; const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource'; const DELETE_TYPE_SCHEDULES = 'schedules'; -// Compression type -const COMPRESSION_TYPE_NONE = 'none'; -const COMPRESSION_TYPE_GZIP = 'gzip'; -const COMPRESSION_TYPE_ZSTD = 'zstd'; // Mail Types const MAIL_TYPE_VERIFICATION = 'verification'; const MAIL_TYPE_MAGIC_SESSION = 'magicSession'; diff --git a/src/Appwrite/Utopia/Response/Model/Bucket.php b/src/Appwrite/Utopia/Response/Model/Bucket.php index 3c5715efc2..f5261c026e 100644 --- a/src/Appwrite/Utopia/Response/Model/Bucket.php +++ b/src/Appwrite/Utopia/Response/Model/Bucket.php @@ -4,6 +4,7 @@ namespace Appwrite\Utopia\Response\Model; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; +use Utopia\Storage\Compression\Compression; class Bucket extends Model { @@ -68,7 +69,7 @@ class Bucket extends Model ]) ->addRule('compression', [ 'type' => self::TYPE_STRING, - 'description' => 'Compression algorithm choosen for compression. Will be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd).', + 'description' => 'Compression algorithm choosen for compression. Will be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd).', 'default' => '', 'example' => 'gzip', 'array' => false From acebe54e5e0ac576a10b6e983ffbe3011e889d17 Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja Date: Sun, 31 Dec 2023 19:27:12 +0530 Subject: [PATCH 22/28] fix: email verified false on null --- src/Appwrite/Auth/OAuth2/Zoho.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Zoho.php b/src/Appwrite/Auth/OAuth2/Zoho.php index fefff9a9fb..245f855958 100644 --- a/src/Appwrite/Auth/OAuth2/Zoho.php +++ b/src/Appwrite/Auth/OAuth2/Zoho.php @@ -149,7 +149,11 @@ class Zoho extends OAuth2 */ public function isEmailVerified(string $accessToken): bool { - return $this->user['email_verified'] ?? ''; + if ($this->user['email_verified'] ?? false) { + return true; + } + + return false; } /** From 70916ad1aa96a7b5e8ed24bd2ece83df29d4b5b9 Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja Date: Tue, 2 Jan 2024 10:13:46 +0530 Subject: [PATCH 23/28] fix: removed authEndpoint --- src/Appwrite/Auth/OAuth2/Zoho.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Appwrite/Auth/OAuth2/Zoho.php b/src/Appwrite/Auth/OAuth2/Zoho.php index 245f855958..5413bd05da 100644 --- a/src/Appwrite/Auth/OAuth2/Zoho.php +++ b/src/Appwrite/Auth/OAuth2/Zoho.php @@ -14,11 +14,6 @@ class Zoho extends OAuth2 */ private string $endpoint = 'https://accounts.zoho.com'; - /** - * @var string - */ - private string $authEndpoint = 'https://accounts.zoho.com/oauth/v2/auth'; - /** * @var array */ @@ -50,7 +45,7 @@ class Zoho extends OAuth2 */ public function getLoginURL(): string { - $url = $this->authEndpoint . '?' . + $url = $this->endpoint . '/oauth/v2/auth?' . \http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, From 879320e23ec198cd9049856301fbfb5342b9af40 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Tue, 2 Jan 2024 11:53:48 +0545 Subject: [PATCH 24/28] update comment regarding validation --- app/controllers/api/storage.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index e668ec2552..011f83f4b4 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -628,7 +628,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); - // Validate create permission + /** + * Validate create permission and skip authorization in updateDocument + * Without this, the file creation will fail when user doesn't have update permission + * However as with chunk upload even if we are updating, we are essentially creating a file + * adding it's new chunk so we validate create permission instead of update + */ $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); @@ -670,7 +675,12 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('chunksUploaded', $chunksUploaded) ->setAttribute('metadata', $metadata); - // Validate create permission + /** + * Validate create permission and skip authorization in updateDocument + * Without this, the file creation will fail when user doesn't have update permission + * However as with chunk upload even if we are updating, we are essentially creating a file + * adding it's new chunk so we validate create permission instead of update + */ $validator = new Authorization(Database::PERMISSION_CREATE); if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); From c4ab4ca16a70e793902c429f6367dfb13610f9af Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja <70762626+UtkarshAhuja2003@users.noreply.github.com> Date: Tue, 2 Jan 2024 13:15:07 +0530 Subject: [PATCH 25/28] fix: lint errors --- src/Appwrite/Auth/OAuth2/Zoho.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Auth/OAuth2/Zoho.php b/src/Appwrite/Auth/OAuth2/Zoho.php index 5413bd05da..c2accfbb6d 100644 --- a/src/Appwrite/Auth/OAuth2/Zoho.php +++ b/src/Appwrite/Auth/OAuth2/Zoho.php @@ -160,4 +160,4 @@ class Zoho extends OAuth2 { return $this->user['name'] ?? ''; } -} \ No newline at end of file +} From 554e9f93b6ad3721d3e0721fb956d5a1742e28a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 2 Jan 2024 10:59:35 +0000 Subject: [PATCH 26/28] Implement max password length --- app/controllers/api/account.php | 6 +- composer.lock | 120 +++++++++--------- src/Appwrite/Auth/Validator/Password.php | 6 +- .../Auth/Validator/PasswordDictionary.php | 2 +- tests/e2e/Services/Account/AccountBase.php | 30 +++++ .../Auth/Validator/PasswordDictionaryTest.php | 11 ++ 6 files changed, 110 insertions(+), 65 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 68e3261a8d..4057634f5e 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -69,7 +69,7 @@ App::post('/v1/account') ->label('abuse-limit', 10) ->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('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be at least 8 chars.', false, ['project', 'passwordsDictionary']) + ->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be between 8 and 256 chars.', false, ['project', 'passwordsDictionary']) ->param('name', '', new Text(128), 'User name. Max length: 128 chars.', true) ->inject('request') ->inject('response') @@ -2724,8 +2724,8 @@ App::put('/v1/account/recovery') ->label('abuse-key', 'url:{url},userId:{param-userId}') ->param('userId', '', new UID(), 'User ID.') ->param('secret', '', new Text(256), 'Valid reset token.') - ->param('password', '', new Password(), 'New user password. Must be at least 8 chars.') - ->param('passwordAgain', '', new Password(), 'Repeat new user password. Must be at least 8 chars.') + ->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be between 8 and 256 chars.', false, ['project', 'passwordsDictionary']) + ->param('passwordAgain', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'Repeat new user password. Must be between 8 and 256 chars.', false, ['project', 'passwordsDictionary']) ->inject('response') ->inject('user') ->inject('dbForProject') diff --git a/composer.lock b/composer.lock index 9f8e84e023..acd65d61a1 100644 --- a/composer.lock +++ b/composer.lock @@ -1906,16 +1906,16 @@ }, { "name": "utopia-php/database", - "version": "0.45.2", + "version": "0.45.3", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788" + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/dc789f2c1fd8b5ee07ff883e11c9ad7970824788", - "reference": "dc789f2c1fd8b5ee07ff883e11c9ad7970824788", + "url": "https://api.github.com/repos/utopia-php/database/zipball/33b4e9a4a6c29f6bb7e108e134b283d585955789", + "reference": "33b4e9a4a6c29f6bb7e108e134b283d585955789", "shasum": "" }, "require": { @@ -1956,9 +1956,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.45.2" + "source": "https://github.com/utopia-php/database/tree/0.45.3" }, - "time": "2023-11-15T03:38:47+00:00" + "time": "2023-12-28T11:12:26+00:00" }, { "name": "utopia-php/domains", @@ -2476,16 +2476,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.0", + "version": "0.5.1", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26" + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/229a7b1fa1f39afd1532f7a515326a6afc222a26", - "reference": "229a7b1fa1f39afd1532f7a515326a6afc222a26", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285", + "reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285", "shasum": "" }, "require": { @@ -2493,7 +2493,7 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2519,9 +2519,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.0" + "source": "https://github.com/utopia-php/platform/tree/0.5.1" }, - "time": "2023-10-16T20:28:49+00:00" + "time": "2023-12-26T16:14:41+00:00" }, { "name": "utopia-php/pools", @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.1", + "version": "0.18.3", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824" + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/983e6dee137012f9f57f126d3c79aab54e4e8824", - "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/faa0279519ac14f3501e8b138e0865ad9d12bff6", + "reference": "faa0279519ac14f3501e8b138e0865ad9d12bff6", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.1" + "source": "https://github.com/utopia-php/storage/tree/0.18.3" }, - "time": "2023-10-24T14:44:19+00:00" + "time": "2023-12-31T11:45:12+00:00" }, { "name": "utopia-php/swoole", @@ -2904,23 +2904,23 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.2", + "version": "0.6.4", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee" + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/f135291b87cb45335fc6608722e7f89894bc33ee", - "reference": "f135291b87cb45335fc6608722e7f89894bc33ee", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/b2595a50a4897a8c88319240810055b7a96efd6d", + "reference": "b2595a50a4897a8c88319240810055b7a96efd6d", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", "utopia-php/cache": "^0.8.0", - "utopia-php/framework": "0.31.*" + "utopia-php/framework": "0.*.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2947,9 +2947,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.2" + "source": "https://github.com/utopia-php/vcs/tree/0.6.4" }, - "time": "2023-11-08T15:36:03+00:00" + "time": "2023-12-26T15:38:19+00:00" }, { "name": "utopia-php/websocket", @@ -3487,16 +3487,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -3537,9 +3537,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -3891,16 +3891,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.4", + "version": "1.24.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc", + "reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc", "shasum": "" }, "require": { @@ -3932,29 +3932,29 @@ "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.24.4" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5" }, - "time": "2023-11-26T18:29:22+00:00" + "time": "2023-12-16T09:33:33+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4004,7 +4004,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.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -4012,7 +4012,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4651,20 +4651,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -4696,7 +4696,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -4704,7 +4704,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -4978,20 +4978,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5023,7 +5023,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -5031,7 +5031,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -5847,5 +5847,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Auth/Validator/Password.php b/src/Appwrite/Auth/Validator/Password.php index 93a9f74114..ffb72467e5 100644 --- a/src/Appwrite/Auth/Validator/Password.php +++ b/src/Appwrite/Auth/Validator/Password.php @@ -20,7 +20,7 @@ class Password extends Validator */ public function getDescription(): string { - return 'Password must be at least 8 characters'; + return 'Password must be between 8 and 256 characters long.'; } /** @@ -40,6 +40,10 @@ class Password extends Validator return false; } + if (\strlen($value) > 256) { + return false; + } + return true; } diff --git a/src/Appwrite/Auth/Validator/PasswordDictionary.php b/src/Appwrite/Auth/Validator/PasswordDictionary.php index 003d68bc73..e128f497f5 100644 --- a/src/Appwrite/Auth/Validator/PasswordDictionary.php +++ b/src/Appwrite/Auth/Validator/PasswordDictionary.php @@ -27,7 +27,7 @@ class PasswordDictionary extends Password */ public function getDescription(): string { - return 'Password must be at least 8 characters and should not be one of the commonly used password.'; + return 'Password must be between 8 and 265 characters long, and should not be one of the commonly used password.'; } /** diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index e6f5feaa84..fe9983d9b8 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -94,6 +94,36 @@ trait AccountBase $this->assertEquals($response['headers']['status-code'], 400); + $shortPassword = 'short'; + $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' => 'shortpass@appwrite.io', + 'password' => $shortPassword + ]); + + $this->assertEquals($response['headers']['status-code'], 400); + + $longPassword = ''; + for ($i = 0; $i < 257; $i++) { // 256 is the limit + $longPassword .= 'p'; + } + + $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' => 'longpass@appwrite.io', + 'password' => $longPassword, + ]); + + $this->assertEquals($response['headers']['status-code'], 400); + return [ 'id' => $id, 'email' => $email, diff --git a/tests/unit/Auth/Validator/PasswordDictionaryTest.php b/tests/unit/Auth/Validator/PasswordDictionaryTest.php index fd7f51ff16..5c8d47923c 100644 --- a/tests/unit/Auth/Validator/PasswordDictionaryTest.php +++ b/tests/unit/Auth/Validator/PasswordDictionaryTest.php @@ -24,5 +24,16 @@ class PasswordDictionaryTest extends TestCase $this->assertEquals($this->object->isValid('123456'), false); $this->assertEquals($this->object->isValid('password'), false); $this->assertEquals($this->object->isValid('myPasswordIsRight'), true); + + $pass = ''; // 256 chars + for ($i = 0; $i < 256; $i++) { + $pass .= 'p'; + } + + $this->assertEquals($this->object->isValid($pass), true); + + $pass .= 'p'; // 257 chars + + $this->assertEquals($this->object->isValid($pass), false); } } From d18d187a075fb94a3290f1e474d85e08bdefc581 Mon Sep 17 00:00:00 2001 From: Utkarsh Ahuja Date: Wed, 3 Jan 2024 11:20:59 +0530 Subject: [PATCH 27/28] fix: base changed --- app/config/{providers.php => oAuthProviders.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/config/{providers.php => oAuthProviders.php} (100%) diff --git a/app/config/providers.php b/app/config/oAuthProviders.php similarity index 100% rename from app/config/providers.php rename to app/config/oAuthProviders.php From 10dfadbbc70857c0188ad55b39fbbd452e84b53f Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 2 Jan 2024 22:42:17 +0000 Subject: [PATCH 28/28] Create an enum for Message status --- src/Appwrite/Enum/MessageStatus.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/Appwrite/Enum/MessageStatus.php diff --git a/src/Appwrite/Enum/MessageStatus.php b/src/Appwrite/Enum/MessageStatus.php new file mode 100644 index 0000000000..77ac1a2575 --- /dev/null +++ b/src/Appwrite/Enum/MessageStatus.php @@ -0,0 +1,27 @@ +