diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 4860f7a967..277bfae16a 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -1347,17 +1347,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string ->inject('dbForProject') ->inject('queueForDatabase') ->inject('queueForEvents') - ->inject('plan') - ->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, array $plan) { - if ($encrypt && !empty($plan) && !($plan['databasesAllowEncrypt'] ?? false)) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Encrypted string attributes are not available on your plan. Please upgrade to create encrypted string attributes.'); - } - if ($encrypt && $size < APP_DATABASE_ENCRYPT_SIZE_MIN) { - throw new Exception( - Exception::GENERAL_BAD_REQUEST, - "Size too small. Encrypted strings require a minimum size of " . APP_DATABASE_ENCRYPT_SIZE_MIN . " characters." - ); - } + ->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { // Ensure attribute default is within required size $validator = new Text($size, 0); if (!is_null($default) && !$validator->isValid($default)) { @@ -1378,7 +1368,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string 'array' => $array, 'filters' => $filters, ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - $attribute->setAttribute('encrypt', $encrypt); + $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) ->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING); @@ -2057,13 +2047,6 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') throw new Exception(Exception::GENERAL_QUERY_INVALID); } - foreach ($attributes as $attribute) { - if ($attribute->getAttribute('type') === Database::VAR_STRING) { - $filters = $attribute->getAttribute('filters', []); - $attribute->setAttribute('encrypt', in_array('encrypt', $filters)); - } - } - $response->dynamic(new Document([ 'attributes' => $attributes, 'total' => $total, @@ -2128,7 +2111,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') $type = $attribute->getAttribute('type'); $format = $attribute->getAttribute('format'); $options = $attribute->getAttribute('options', []); - $filters = $attribute->getAttribute('filters', []); + foreach ($options as $key => $option) { $attribute->setAttribute($key, $option); } @@ -2148,7 +2131,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') }, default => Response::MODEL_ATTRIBUTE, }; - $attribute->setAttribute('encrypt', in_array('encrypt', $filters)); + $response->dynamic($attribute, $model); }); diff --git a/app/init/constants.php b/app/init/constants.php index ebf79086a7..99881a4381 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -51,7 +51,6 @@ const APP_DATABASE_TIMEOUT_MILLISECONDS_API = 15 * 1000; // 15 seconds const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes const APP_DATABASE_TIMEOUT_MILLISECONDS_TASK = 300 * 1000; // 5 minutes const APP_DATABASE_QUERY_MAX_VALUES = 500; -const APP_DATABASE_ENCRYPT_SIZE_MIN = 150; const APP_STORAGE_UPLOADS = '/storage/uploads'; const APP_STORAGE_SITES = '/storage/sites'; const APP_STORAGE_FUNCTIONS = '/storage/functions'; diff --git a/app/init/database/filters.php b/app/init/database/filters.php index c470329706..f110fe1554 100644 --- a/app/init/database/filters.php +++ b/app/init/database/filters.php @@ -77,21 +77,12 @@ Database::addFilter( ]); foreach ($attributes as $attribute) { - $attributeType = $attribute->getAttribute('type'); - - switch ($attributeType) { - case Database::VAR_RELATIONSHIP: - $options = $attribute->getAttribute('options'); - foreach ($options as $key => $value) { - $attribute->setAttribute($key, $value); - } - $attribute->removeAttribute('options'); - break; - - case Database::VAR_STRING: - $filters = $attribute->getAttribute('filters', []); - $attribute->setAttribute('encrypt', in_array('encrypt', $filters)); - break; + if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) { + $options = $attribute->getAttribute('options'); + foreach ($options as $key => $value) { + $attribute->setAttribute($key, $value); + } + $attribute->removeAttribute('options'); } } diff --git a/composer.json b/composer.json index 7e445cd36b..328791c56f 100644 --- a/composer.json +++ b/composer.json @@ -86,7 +86,7 @@ }, "require-dev": { "ext-fileinfo": "*", - "appwrite/sdk-generator": "0.40.*", + "appwrite/sdk-generator": "0.41.*", "phpunit/phpunit": "9.*", "swoole/ide-helper": "5.1.2", "phpstan/phpstan": "1.8.*", diff --git a/composer.lock b/composer.lock index ef067116d0..f5b3f796c8 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": "9f5de64d73e2ef73d796fa64f2baf232", + "content-hash": "a4b3f30b815230a17c33310f62ffb18d", "packages": [ { "name": "adhocore/jwt", @@ -2486,16 +2486,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -2508,7 +2508,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -2533,7 +2533,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -2549,7 +2549,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/http-client", @@ -2648,16 +2648,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v3.5.2", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" + "reference": "75d7043853a42837e68111812f4d964b01e5101c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", - "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c", + "reference": "75d7043853a42837e68111812f4d964b01e5101c", "shasum": "" }, "require": { @@ -2670,7 +2670,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -2706,7 +2706,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0" }, "funding": [ { @@ -2722,7 +2722,7 @@ "type": "tidelift" } ], - "time": "2024-12-07T08:49:48+00:00" + "time": "2025-04-29T11:18:49+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2883,16 +2883,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.5.1", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { @@ -2910,7 +2910,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -2946,7 +2946,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -2962,7 +2962,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "tbachert/spi", @@ -4816,16 +4816,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.40.19", + "version": "0.41.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "05b53cf30c59fe5934d57207fefbc8ae8feb5dbf" + "reference": "96316272a3cee1a3abf5b9f05ae49ebbff03725e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/05b53cf30c59fe5934d57207fefbc8ae8feb5dbf", - "reference": "05b53cf30c59fe5934d57207fefbc8ae8feb5dbf", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/96316272a3cee1a3abf5b9f05ae49ebbff03725e", + "reference": "96316272a3cee1a3abf5b9f05ae49ebbff03725e", "shasum": "" }, "require": { @@ -4861,9 +4861,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.40.19" + "source": "https://github.com/appwrite/sdk-generator/tree/0.41.0" }, - "time": "2025-05-24T22:49:50+00:00" + "time": "2025-05-26T09:47:45+00:00" }, { "name": "doctrine/annotations", @@ -8242,7 +8242,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -8266,5 +8266,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Utopia/Response/Model/AttributeString.php b/src/Appwrite/Utopia/Response/Model/AttributeString.php index fded48fddc..12bb42009d 100644 --- a/src/Appwrite/Utopia/Response/Model/AttributeString.php +++ b/src/Appwrite/Utopia/Response/Model/AttributeString.php @@ -24,13 +24,6 @@ class AttributeString extends Attribute 'required' => false, 'example' => 'default', ]) - ->addRule('encrypt', [ - 'type' => self::TYPE_BOOLEAN, - 'description' => 'Defines whether this attribute is encrypted or not.', - 'default' => false, - 'required' => false, - 'example' => false, - ]) ; } diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php index 9aed3684de..7c0060ecaa 100644 --- a/tests/e2e/Services/Databases/DatabasesBase.php +++ b/tests/e2e/Services/Databases/DatabasesBase.php @@ -298,7 +298,7 @@ trait DatabasesBase $this->assertEquals($title['body']['type'], 'string'); $this->assertEquals($title['body']['size'], 256); $this->assertEquals($title['body']['required'], true); - $this->assertFalse($title['body']['encrypt']); + $this->assertEquals(202, $description['headers']['status-code']); $this->assertEquals($description['body']['key'], 'description'); $this->assertEquals($description['body']['type'], 'string'); diff --git a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php index e66207b215..829960b54f 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php @@ -686,18 +686,6 @@ class DatabasesCustomServerTest extends Scope 'size' => 256, 'required' => true, ]); - // checking size test - $lastName = $this->client->call(Client::METHOD_POST, $attributesPath . '/string', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'key' => 'lastName', - 'size' => 149, - 'required' => true, - 'encrypt' => true - ]); - $this->assertEquals("Size too small. Encrypted strings require a minimum size of " . APP_DATABASE_ENCRYPT_SIZE_MIN . " characters.", $lastName['body']['message']); $lastName = $this->client->call(Client::METHOD_POST, $attributesPath . '/string', array_merge([ 'content-type' => 'application/json', @@ -707,16 +695,9 @@ class DatabasesCustomServerTest extends Scope 'key' => 'lastName', 'size' => 256, 'required' => true, - 'encrypt' => true + 'encrypt' => true, ]); - $this->assertTrue($lastName['body']['encrypt']); - sleep(1); - $response = $this->client->call(Client::METHOD_GET, $attributesPath . '/lastName', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ])); - $this->assertTrue($response['body']['encrypt']); + /** * Check status of every attribute @@ -760,24 +741,6 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $document['headers']['status-code']); $this->assertEquals('Jonah', $document['body']['firstName']); $this->assertEquals('Jameson', $document['body']['lastName']); - - - $actors = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $actors['body']['$id'], array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), []); - $attributes = $actors['body']['attributes']; - foreach ($attributes as $attribute) { - $this->assertArrayHasKey('encrypt', $attribute); - if ($attribute['key'] === 'firstName') { - $this->assertFalse($attribute['encrypt']); - } - if ($attribute['key'] === 'lastName') { - $this->assertTrue($attribute['encrypt']); - } - } - } public function testDeleteAttribute(): array