Merge branch '1.7.x' into 'fix-teams-deletion'.

This commit is contained in:
Darshan 2025-05-30 14:25:22 +05:30
commit f7f746a543
38 changed files with 423 additions and 352 deletions

2
.env
View file

@ -85,7 +85,7 @@ _APP_COMPUTE_RUNTIMES_NETWORK=runtimes
_APP_EXECUTOR_SECRET=your-secret-key
_APP_EXECUTOR_HOST=http://exc1/v1
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.32
_APP_MAINTENANCE_INTERVAL=86400
_APP_MAINTENANCE_START_TIME=12:00
_APP_MAINTENANCE_RETENTION_CACHE=2592000

View file

@ -72,7 +72,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
### Windows
@ -84,7 +84,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
#### PowerShell
@ -94,7 +94,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。

View file

@ -78,7 +78,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
### Windows
@ -90,7 +90,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
#### PowerShell
@ -100,7 +100,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.7.3
appwrite/appwrite:1.7.4
```
Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation.

View file

@ -1439,13 +1439,6 @@ return [
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_roles'),
'type' => Database::INDEX_KEY,
'attributes' => ['roles'],
'lengths' => [128],
'orders' => [],
],
],
],

View file

@ -217,7 +217,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '6.2.3',
'version' => '7.0.0',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -8049,6 +8049,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/components\/schemas\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -8204,7 +8227,10 @@
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
}

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -7530,6 +7530,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/components\/schemas\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -7688,7 +7711,10 @@
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
}

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -8049,6 +8049,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/components\/schemas\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -8204,7 +8227,10 @@
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
}

View file

@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -7530,6 +7530,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/components\/schemas\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -7688,7 +7711,10 @@
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
}

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -8178,6 +8178,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/definitions\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -8323,13 +8346,16 @@
"documents": {
"type": "array",
"description": "Array of document data as JSON objects. May contain partial documents.",
"default": [],
"default": null,
"x-example": null,
"items": {
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
]

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -7649,6 +7649,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/definitions\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -7797,13 +7820,16 @@
"documents": {
"type": "array",
"description": "Array of document data as JSON objects. May contain partial documents.",
"default": [],
"default": null,
"x-example": null,
"items": {
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
]

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -8178,6 +8178,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/definitions\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -8323,13 +8346,16 @@
"documents": {
"type": "array",
"description": "Array of document data as JSON objects. May contain partial documents.",
"default": [],
"default": null,
"x-example": null,
"items": {
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
]

View file

@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.7.0",
"version": "1.7.4",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@ -7649,6 +7649,29 @@
}
],
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
},
{
"name": "createDocuments",
"auth": {
"Key": []
},
"parameters": [
"databaseId",
"collectionId",
"documents"
],
"required": [
"databaseId",
"collectionId",
"documents"
],
"responses": [
{
"code": 201,
"model": "#\/definitions\/documentList"
}
],
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
}
],
"auth": {
@ -7797,13 +7820,16 @@
"documents": {
"type": "array",
"description": "Array of document data as JSON objects. May contain partial documents.",
"default": [],
"default": null,
"x-example": null,
"items": {
"type": "object"
}
}
}
},
"required": [
"documents"
]
}
}
]

View file

@ -14,7 +14,7 @@ return [
],
'DART' => [
'name' => 'dart',
'versions' => ['3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
'versions' => ['3.8', '3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
],
'GO' => [
'name' => 'go',
@ -38,6 +38,6 @@ return [
],
'FLUTTER' => [
'name' => 'flutter',
'versions' => ['3.24']
'versions' => ['3.32', '3.24']
],
];

View file

@ -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);
});
@ -4598,7 +4581,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents')
))
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID.')
->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', true, ['plan'])
->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', false, ['plan'])
->inject('response')
->inject('dbForProject')
->inject('queueForStatsUsage')

View file

@ -293,7 +293,13 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
// VCS branch preview
if (!empty($providerBranch)) {
$domain = "branch-{$providerBranch}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
$branchPrefix = substr($providerBranch, 0, 16);
if (strlen($providerBranch) > 16) {
$remainingChars = substr($providerBranch, 16);
$branchPrefix .= '-' . substr(hash('sha256', $remainingChars), 0, 7);
}
$resourceProjectHash = substr(hash('sha256', $resource->getId() . $project->getId()), 0, 7);
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
@ -324,7 +330,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
// VCS commit preview
if (!empty($providerCommitHash)) {
$domain = "commit-{$providerCommitHash}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
$domain = "commit-" . substr($providerCommitHash, 0, 16) . ".{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(

View file

@ -37,8 +37,8 @@ const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours
const APP_RESOURCE_TOKEN_ACCESS = 24 * 60 * 60; // 24 hours
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
const APP_CACHE_BUSTER = 4319;
const APP_VERSION_STABLE = '1.7.3';
const APP_CACHE_BUSTER = 4320;
const APP_VERSION_STABLE = '1.7.4';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
@ -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';

View file

@ -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');
}
}

View file

@ -177,7 +177,7 @@ $image = $this->getParam('image', '');
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: <?php echo $organization; ?>/console:6.0.11
image: <?php echo $organization; ?>/console:6.0.13
restart: unless-stopped
networks:
- appwrite
@ -864,7 +864,7 @@ $image = $this->getParam('image', '');
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.7.14
image: openruntimes/executor:0.7.20
networks:
- appwrite
- runtimes

View file

@ -61,7 +61,7 @@
"utopia-php/image": "0.8.*",
"utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.6.*",
"utopia-php/messaging": "0.17.*",
"utopia-php/messaging": "0.18.*",
"utopia-php/migration": "0.9.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
@ -76,17 +76,17 @@
"utopia-php/vcs": "0.10.*",
"utopia-php/websocket": "0.3.*",
"matomo/device-detector": "6.1.*",
"dragonmantank/cron-expression": "3.3.2",
"phpmailer/phpmailer": "6.9.1",
"chillerlan/php-qrcode": "4.3.4",
"adhocore/jwt": "1.1.2",
"dragonmantank/cron-expression": "3.3.*",
"phpmailer/phpmailer": "6.9.*",
"chillerlan/php-qrcode": "4.3.*",
"adhocore/jwt": "1.1.*",
"spomky-labs/otphp": "^10.0",
"webonyx/graphql-php": "14.11.*",
"league/csv": "9.14.*"
},
"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.*",

183
composer.lock generated
View file

@ -4,27 +4,27 @@
"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": "de0a0fb794f826fcc412c788185b69f4",
"packages": [
{
"name": "adhocore/jwt",
"version": "1.1.2",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/adhocore/php-jwt.git",
"reference": "6c434af7170090bb7a8880d2bc220a2254ba7899"
"reference": "ad417603d9d45578b6af2089ad5b78f101c82367"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899",
"reference": "6c434af7170090bb7a8880d2bc220a2254ba7899",
"url": "https://api.github.com/repos/adhocore/php-jwt/zipball/ad417603d9d45578b6af2089ad5b78f101c82367",
"reference": "ad417603d9d45578b6af2089ad5b78f101c82367",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^6.5 || ^7.5"
"phpunit/phpunit": "^7.5 || ^8.5"
},
"type": "library",
"autoload": {
@ -53,15 +53,19 @@
],
"support": {
"issues": "https://github.com/adhocore/php-jwt/issues",
"source": "https://github.com/adhocore/php-jwt/tree/1.1.2"
"source": "https://github.com/adhocore/php-jwt/tree/1.1.3"
},
"funding": [
{
"url": "https://paypal.me/ji10",
"type": "custom"
},
{
"url": "https://github.com/adhocore",
"type": "github"
}
],
"time": "2021-02-20T09:56:44+00:00"
"time": "2025-02-18T01:00:50+00:00"
},
{
"name": "appwrite/appwrite",
@ -157,16 +161,16 @@
},
{
"name": "appwrite/php-runtimes",
"version": "0.19.0",
"version": "0.19.1",
"source": {
"type": "git",
"url": "https://github.com/appwrite/runtimes.git",
"reference": "8d21483efc19b9d977e323188989ee67a188464b"
"reference": "7bd0cc3cb97de625d7b07230bd91b121f88e72ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/8d21483efc19b9d977e323188989ee67a188464b",
"reference": "8d21483efc19b9d977e323188989ee67a188464b",
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/7bd0cc3cb97de625d7b07230bd91b121f88e72ae",
"reference": "7bd0cc3cb97de625d7b07230bd91b121f88e72ae",
"shasum": ""
},
"require": {
@ -206,9 +210,9 @@
],
"support": {
"issues": "https://github.com/appwrite/runtimes/issues",
"source": "https://github.com/appwrite/runtimes/tree/0.19.0"
"source": "https://github.com/appwrite/runtimes/tree/0.19.1"
},
"time": "2025-03-25T22:37:51+00:00"
"time": "2025-05-27T07:12:56+00:00"
},
{
"name": "beberlei/assert",
@ -565,16 +569,16 @@
},
{
"name": "dragonmantank/cron-expression",
"version": "v3.3.2",
"version": "v3.3.3",
"source": {
"type": "git",
"url": "https://github.com/dragonmantank/cron-expression.git",
"reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8"
"reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8",
"reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8",
"url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
"reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
"shasum": ""
},
"require": {
@ -614,7 +618,7 @@
],
"support": {
"issues": "https://github.com/dragonmantank/cron-expression/issues",
"source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2"
"source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3"
},
"funding": [
{
@ -622,7 +626,7 @@
"type": "github"
}
],
"time": "2022-09-10T18:51:20+00:00"
"time": "2023-08-10T19:36:49+00:00"
},
{
"name": "giggsey/libphonenumber-for-php-lite",
@ -709,16 +713,16 @@
},
{
"name": "google/protobuf",
"version": "v4.31.0",
"version": "v4.31.1",
"source": {
"type": "git",
"url": "https://github.com/protocolbuffers/protobuf-php.git",
"reference": "d59e31ce4bf0e4b48728e90c4d880839edb5be07"
"reference": "2b028ce8876254e2acbeceea7d9b573faad41864"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/d59e31ce4bf0e4b48728e90c4d880839edb5be07",
"reference": "d59e31ce4bf0e4b48728e90c4d880839edb5be07",
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/2b028ce8876254e2acbeceea7d9b573faad41864",
"reference": "2b028ce8876254e2acbeceea7d9b573faad41864",
"shasum": ""
},
"require": {
@ -747,9 +751,9 @@
"proto"
],
"support": {
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.31.0"
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.31.1"
},
"time": "2025-05-14T16:17:23+00:00"
"time": "2025-05-28T18:52:35+00:00"
},
{
"name": "league/csv",
@ -2553,16 +2557,16 @@
},
{
"name": "symfony/http-client",
"version": "v7.2.4",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6"
"reference": "57e4fb86314015a695a750ace358d07a7e37b8a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/78981a2ffef6437ed92d4d7e2a86a82f256c6dc6",
"reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6",
"url": "https://api.github.com/repos/symfony/http-client/zipball/57e4fb86314015a695a750ace358d07a7e37b8a9",
"reference": "57e4fb86314015a695a750ace358d07a7e37b8a9",
"shasum": ""
},
"require": {
@ -2628,7 +2632,7 @@
"http"
],
"support": {
"source": "https://github.com/symfony/http-client/tree/v7.2.4"
"source": "https://github.com/symfony/http-client/tree/v7.3.0"
},
"funding": [
{
@ -2644,7 +2648,7 @@
"type": "tidelift"
}
],
"time": "2025-02-13T10:27:23+00:00"
"time": "2025-05-02T08:23:16+00:00"
},
{
"name": "symfony/http-client-contracts",
@ -3499,16 +3503,16 @@
},
{
"name": "utopia-php/database",
"version": "0.69.5",
"version": "0.69.6",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "4abe53609dfc23b2ea82884d12b149df6a8af2f5"
"reference": "42bfc0d87de4ade26cfd9915aaad84912761466b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/4abe53609dfc23b2ea82884d12b149df6a8af2f5",
"reference": "4abe53609dfc23b2ea82884d12b149df6a8af2f5",
"url": "https://api.github.com/repos/utopia-php/database/zipball/42bfc0d87de4ade26cfd9915aaad84912761466b",
"reference": "42bfc0d87de4ade26cfd9915aaad84912761466b",
"shasum": ""
},
"require": {
@ -3549,9 +3553,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.69.5"
"source": "https://github.com/utopia-php/database/tree/0.69.6"
},
"time": "2025-05-17T08:01:51+00:00"
"time": "2025-05-29T10:36:03+00:00"
},
{
"name": "utopia-php/detector",
@ -3948,16 +3952,16 @@
},
{
"name": "utopia-php/messaging",
"version": "0.17.0",
"version": "0.18.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/messaging.git",
"reference": "c51915d0e030db3a3add37f1561751d18b2d9a85"
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/c51915d0e030db3a3add37f1561751d18b2d9a85",
"reference": "c51915d0e030db3a3add37f1561751d18b2d9a85",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/c151aa5d4d475c788ca15c210b5b2017e21c41d6",
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6",
"shasum": ""
},
"require": {
@ -3993,9 +3997,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/messaging/issues",
"source": "https://github.com/utopia-php/messaging/tree/0.17.0"
"source": "https://github.com/utopia-php/messaging/tree/0.18.0"
},
"time": "2025-05-12T16:14:08+00:00"
"time": "2025-05-15T05:00:03+00:00"
},
{
"name": "utopia-php/migration",
@ -4378,16 +4382,16 @@
},
{
"name": "utopia-php/storage",
"version": "0.18.12",
"version": "0.18.13",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/storage.git",
"reference": "9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97"
"reference": "3d8ce53ae042173bf230445e996056c5f65ded22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/storage/zipball/9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97",
"reference": "9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97",
"url": "https://api.github.com/repos/utopia-php/storage/zipball/3d8ce53ae042173bf230445e996056c5f65ded22",
"reference": "3d8ce53ae042173bf230445e996056c5f65ded22",
"shasum": ""
},
"require": {
@ -4430,9 +4434,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/storage/issues",
"source": "https://github.com/utopia-php/storage/tree/0.18.12"
"source": "https://github.com/utopia-php/storage/tree/0.18.13"
},
"time": "2025-05-15T07:55:58+00:00"
"time": "2025-05-26T13:10:35+00:00"
},
{
"name": "utopia-php/swoole",
@ -4816,16 +4820,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 +4865,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",
@ -7262,23 +7266,24 @@
},
{
"name": "symfony/console",
"version": "v7.2.6",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218"
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
"url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3",
"symfony/string": "^6.4|^7.0"
"symfony/string": "^7.2"
},
"conflict": {
"symfony/dependency-injection": "<6.4",
@ -7335,7 +7340,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.2.6"
"source": "https://github.com/symfony/console/tree/v7.3.0"
},
"funding": [
{
@ -7351,11 +7356,11 @@
"type": "tidelift"
}
],
"time": "2025-04-07T19:09:28+00:00"
"time": "2025-05-24T10:34:04+00:00"
},
{
"name": "symfony/filesystem",
"version": "v7.2.0",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@ -7401,7 +7406,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v7.2.0"
"source": "https://github.com/symfony/filesystem/tree/v7.3.0"
},
"funding": [
{
@ -7421,16 +7426,16 @@
},
{
"name": "symfony/finder",
"version": "v7.2.2",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb"
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb",
"url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
"shasum": ""
},
"require": {
@ -7465,7 +7470,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v7.2.2"
"source": "https://github.com/symfony/finder/tree/v7.3.0"
},
"funding": [
{
@ -7481,20 +7486,20 @@
"type": "tidelift"
}
],
"time": "2024-12-30T19:00:17+00:00"
"time": "2024-12-30T19:00:26+00:00"
},
{
"name": "symfony/options-resolver",
"version": "v7.2.0",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50"
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50",
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca",
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca",
"shasum": ""
},
"require": {
@ -7532,7 +7537,7 @@
"options"
],
"support": {
"source": "https://github.com/symfony/options-resolver/tree/v7.2.0"
"source": "https://github.com/symfony/options-resolver/tree/v7.3.0"
},
"funding": [
{
@ -7548,7 +7553,7 @@
"type": "tidelift"
}
],
"time": "2024-11-20T11:17:29+00:00"
"time": "2025-04-04T13:12:05+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -7866,16 +7871,16 @@
},
{
"name": "symfony/process",
"version": "v7.2.5",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
"url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"shasum": ""
},
"require": {
@ -7907,7 +7912,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.2.5"
"source": "https://github.com/symfony/process/tree/v7.3.0"
},
"funding": [
{
@ -7923,20 +7928,20 @@
"type": "tidelift"
}
],
"time": "2025-03-13T12:21:46+00:00"
"time": "2025-04-17T09:11:12+00:00"
},
{
"name": "symfony/string",
"version": "v7.2.6",
"version": "v7.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931"
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
"shasum": ""
},
"require": {
@ -7994,7 +7999,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v7.2.6"
"source": "https://github.com/symfony/string/tree/v7.3.0"
},
"funding": [
{
@ -8010,7 +8015,7 @@
"type": "tidelift"
}
],
"time": "2025-04-20T20:18:16+00:00"
"time": "2025-04-20T20:19:01+00:00"
},
{
"name": "textalk/websocket",

View file

@ -213,7 +213,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:6.0.11
image: appwrite/console:6.0.13
restart: unless-stopped
networks:
- appwrite
@ -951,7 +951,7 @@ services:
hostname: exc1
<<: *x-logging
stop_signal: SIGINT
image: openruntimes/executor:0.7.16
image: openruntimes/executor:0.7.20
restart: unless-stopped
networks:
- appwrite

View file

@ -0,0 +1,6 @@
appwrite databases upsertDocument \
--databaseId <DATABASE_ID> \
--collectionId <COLLECTION_ID> \
--documentId <DOCUMENT_ID> \
--data '{ "key": "value" }' \

View file

@ -1,4 +1,4 @@
appwrite databases upsertDocuments \
--databaseId <DATABASE_ID> \
--collectionId <COLLECTION_ID> \
--documents one two three

View file

@ -88,6 +88,7 @@ abstract class Migration
'1.7.1' => 'V22',
'1.7.2' => 'V22',
'1.7.3' => 'V22',
'1.7.4' => 'V22',
];
/**

View file

@ -150,9 +150,9 @@ class V22 extends Migration
];
foreach ($indexes as $index) {
try {
$this->createIndexFromCollection($this->dbForProject, $id, $index);
$this->dbForProject->deleteIndex($id, $index);
} catch (Throwable $th) {
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
Console::warning("Failed to delete index \"$index\" from {$id}: {$th->getMessage()}");
}
}
$this->dbForProject->purgeCachedCollection($id);

View file

@ -4,7 +4,6 @@ namespace Appwrite\Platform\Modules\Compute;
use Appwrite\Event\Build;
use Appwrite\Extend\Exception;
use Appwrite\Query;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
@ -235,38 +234,4 @@ class Base extends Action
return $deployment;
}
protected function listRules(Document $project, array $queries, Database $database, callable $callback): void
{
$limit = 100;
$cursor = null;
do {
$queries = \array_merge([
Query::limit($limit),
Query::equal("projectInternalId", [$project->getInternalId()])
], $queries);
if ($cursor !== null) {
$queries[] = Query::cursorAfter($cursor);
}
$results = $database->find('rules', $queries);
$total = \count($results);
if ($total > 0) {
$cursor = $results[$total - 1];
}
if ($total < $limit) {
$cursor = null;
}
foreach ($results as $document) {
if (is_callable($callback)) {
$callback($document);
}
}
} while (!\is_null($cursor));
}
}

View file

@ -5,7 +5,6 @@ namespace Appwrite\Platform\Modules\Functions\Http\Functions\Deployment;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Compute\Base;
use Appwrite\Query;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
@ -13,6 +12,7 @@ use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
@ -89,8 +89,6 @@ class Update extends Base
throw new Exception(Exception::BUILD_NOT_READY);
}
$oldDeploymentInternalId = $function->getAttribute('deploymentInternalId', '');
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
@ -106,24 +104,20 @@ class Update extends Base
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$queries = [
Query::equal('trigger', 'manual'),
Query::equal('trigger', ['manual']),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceType", ["function"]),
Query::equal("deploymentResourceInternalId", [$function->getInternalId()]),
Query::equal("deploymentVcsProviderBranch", [""]),
Query::equal("projectInternalId", [$project->getInternalId()])
];
if (empty($oldDeploymentInternalId)) {
$queries[] = Query::equal("deploymentInternalId", [""]);
} else {
$queries[] = Query::equal("deploymentInternalId", [$oldDeploymentInternalId]);
}
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment) {
Authorization::skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
});
Authorization::skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
}, $queries));
$queueForEvents
->setParam('functionId', $function->getId())

View file

@ -1075,8 +1075,6 @@ class Builds extends Action
$resource->setAttribute('live', true);
switch ($resource->getCollection()) {
case 'functions':
$oldDeploymentInternalId = $resource->getAttribute('deploymentInternalId', '');
$resource->setAttribute('deploymentId', $deployment->getId());
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
$resource->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
@ -1088,26 +1086,20 @@ class Builds extends Action
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['function']),
Query::equal('trigger', ['manual']),
Query::equal('deploymentVcsProviderBranch', ['']),
Query::equal("projectInternalId", [$project->getInternalId()])
];
if (empty($oldDeploymentInternalId)) {
$queries[] = Query::equal("deploymentInternalId", [""]);
} else {
$queries[] = Query::equal("deploymentInternalId", [$oldDeploymentInternalId]);
}
$rulesUpdated = false;
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment, &$rulesUpdated) {
$dbForPlatform->forEach('rules', function (Document $rule) use ($dbForPlatform, $deployment, &$rulesUpdated) {
$rulesUpdated = true;
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
});
}, $queries);
break;
case 'sites':
$oldDeploymentInternalId = $resource->getAttribute('deploymentInternalId', '');
$resource->setAttribute('deploymentId', $deployment->getId());
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
$resource->setAttribute('deploymentScreenshotDark', $deployment->getAttribute('screenshotDark', ''));
@ -1120,20 +1112,16 @@ class Builds extends Action
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['site']),
Query::equal('trigger', ['manual']),
Query::equal('deploymentVcsProviderBranch', ['']),
Query::equal("projectInternalId", [$project->getInternalId()])
];
if (empty($oldDeploymentInternalId)) {
$queries[] = Query::equal("deploymentInternalId", [""]);
} else {
$queries[] = Query::equal("deploymentInternalId", [$oldDeploymentInternalId]);
}
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment) {
$dbForPlatform->forEach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
});
}, $queries);
break;
}
@ -1144,7 +1132,13 @@ class Builds extends Action
$branchName = $deployment->getAttribute('providerBranch');
if (!empty($branchName)) {
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = "branch-{$branchName}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
$branchPrefix = substr($branchName, 0, 16);
if (strlen($branchName) > 16) {
$remainingChars = substr($branchName, 16);
$branchPrefix .= '-' . substr(hash('sha256', $remainingChars), 0, 7);
}
$resourceProjectHash = substr(hash('sha256', $resource->getId() . $project->getId()), 0, 7);
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
$ruleId = md5($domain);
try {
@ -1175,19 +1169,22 @@ class Builds extends Action
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
}
$this->listRules($project, [
$queries = [
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['site']),
Query::equal("deploymentVcsProviderBranch", [$branchName]),
Query::equal("trigger", ['manual']),
], $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment) {
Query::equal("projectInternalId", [$project->getInternalId()])
];
$dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
});
}, $queries);
}
}
@ -1490,38 +1487,4 @@ class Builds extends Action
}
}
}
protected function listRules(Document $project, array $queries, Database $database, callable $callback): void
{
$limit = 100;
$cursor = null;
do {
$queries = \array_merge([
Query::limit($limit),
Query::equal("projectInternalId", [$project->getInternalId()])
], $queries);
if ($cursor !== null) {
$queries[] = Query::cursorAfter($cursor);
}
$results = $database->find('rules', $queries);
$total = \count($results);
if ($total > 0) {
$cursor = $results[$total - 1];
}
if ($total < $limit) {
$cursor = null;
}
foreach ($results as $document) {
if (is_callable($callback)) {
$callback($document);
}
}
} while (!\is_null($cursor));
}
}

View file

@ -347,10 +347,16 @@ class Create extends Action
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'value' => $deployment->getId(),
'deploymentId' => $deployment->isEmpty() ? '' : $deployment->getId(),
'deploymentInternalId' => $deployment->isEmpty() ? '' : $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $site->getId(),
'deploymentResourceInternalId' => $site->getInternalId(),
'status' => 'verified',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
'owner' => 'Appwrite',
'region' => $project->getAttribute('region')
]))
);
} else {

View file

@ -5,13 +5,14 @@ namespace Appwrite\Platform\Modules\Sites\Http\Sites\Deployment;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Compute\Base;
use Appwrite\Query;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
@ -86,8 +87,6 @@ class Update extends Base
throw new Exception(Exception::BUILD_NOT_READY);
}
$oldDeploymentInternalId = $site->getAttribute('deploymentInternalId', '');
$site = $dbForProject->updateDocument('sites', $site->getId(), new Document(array_merge($site->getArrayCopy(), [
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
@ -97,24 +96,20 @@ class Update extends Base
])));
$queries = [
Query::equal('trigger', 'manual'),
Query::equal('trigger', ['manual']),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceType", ["site"]),
Query::equal("deploymentResourceInternalId", [$site->getInternalId()]),
Query::equal("deploymentVcsProviderBranch", [""]),
Query::equal("projectInternalId", [$project->getInternalId()])
];
if (empty($oldDeploymentInternalId)) {
$queries[] = Query::equal("deploymentInternalId", [""]);
} else {
$queries[] = Query::equal("deploymentInternalId", [$oldDeploymentInternalId]);
}
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment) {
Authorization::skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
});
Authorization::skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
}, $queries));
$queueForEvents
->setParam('siteId', $site->getId())

View file

@ -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,
])
;
}

View file

@ -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');

View file

@ -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