mirror of
https://github.com/appwrite/appwrite
synced 2026-05-21 16:08:22 +00:00
commit
3f9b4e92e9
8 changed files with 44 additions and 115 deletions
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.*",
|
||||
|
|
|
|||
60
composer.lock
generated
60
composer.lock
generated
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue