Merge remote-tracking branch 'origin/1.4.x' into chore-update-sdks
This commit is contained in:
commit
8b14d96151
18 changed files with 122 additions and 56 deletions
4
.github/workflows/linter.yml
vendored
4
.github/workflows/linter.yml
vendored
|
@ -18,6 +18,10 @@ jobs:
|
|||
|
||||
- run: git checkout HEAD^2
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: |
|
||||
docker run --rm -v $PWD:/app composer sh -c \
|
||||
"composer validate"
|
||||
- name: Run Linter
|
||||
run: |
|
||||
docker run --rm -v $PWD:/app composer sh -c \
|
||||
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,4 +1,4 @@
|
|||
[submodule "app/console"]
|
||||
path = app/console
|
||||
url = https://github.com/appwrite/console
|
||||
branch = 3.2.7
|
||||
branch = 3.2.8
|
||||
|
|
18
CHANGES.md
18
CHANGES.md
|
@ -1,3 +1,21 @@
|
|||
# Version 1.4.13
|
||||
|
||||
## Notable changes
|
||||
|
||||
* Change enum size validation in update controller [#7164](https://github.com/appwrite/appwrite/pull/7164)
|
||||
* Bump console to version 3.2.8 in [#7167](https://github.com/appwrite/appwrite/pull/7167)
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Fix error after adding bigger enum [#7162](https://github.com/appwrite/appwrite/pull/7162)
|
||||
* Add chunkId to abuse key to prevent rate limit for SDKs [#7154](https://github.com/appwrite/appwrite/pull/7154)
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
* Fix enum test case [#7163](https://github.com/appwrite/appwrite/pull/7163)
|
||||
* Add flag to send logs to logger [#7155](https://github.com/appwrite/appwrite/pull/7155)
|
||||
* Add a CI task to validate composer file and lock [#7142](https://github.com/appwrite/appwrite/pull/7142)
|
||||
|
||||
# Version 1.4.12
|
||||
|
||||
## Miscellaneous
|
||||
|
|
|
@ -66,7 +66,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
@ -78,7 +78,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
@ -88,7 +88,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。
|
||||
|
|
|
@ -76,7 +76,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
@ -88,7 +88,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
@ -98,7 +98,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.4.12
|
||||
appwrite/appwrite:1.4.13
|
||||
```
|
||||
|
||||
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.
|
||||
|
|
|
@ -209,6 +209,7 @@ return [
|
|||
'name' => Exception::USER_AUTH_METHOD_UNSUPPORTED,
|
||||
'description' => 'The requested authentication method is either disabled or unsupported. Please check the supported authentication methods in the Appwrite console.',
|
||||
'code' => 501,
|
||||
'publish' => false,
|
||||
],
|
||||
Exception::USER_PHONE_ALREADY_EXISTS => [
|
||||
'name' => Exception::USER_PHONE_ALREADY_EXISTS,
|
||||
|
@ -764,4 +765,12 @@ return [
|
|||
'description' => 'An error occurred on the provider\'s side. Please try again later.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Health */
|
||||
Exception::QUEUE_SIZE_EXCEEDED => [
|
||||
'name' => Exception::QUEUE_SIZE_EXCEEDED,
|
||||
'description' => 'Queue size threshold hit.',
|
||||
'code' => 503,
|
||||
'publish' => false
|
||||
],
|
||||
];
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 49d039ed07628155e7f56e2c997fcef90ecde267
|
||||
Subproject commit 6bf696aeb329d23e4ebe9d1e71edbd144cf2d58e
|
|
@ -1231,7 +1231,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
|
|||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('elements', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE, min: 0), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
|
||||
->param('elements', [], new ArrayList(new Text(DATABASE::LENGTH_KEY), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . DATABASE::LENGTH_KEY . ' characters long.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is attribute an array?', true)
|
||||
|
@ -1240,16 +1240,6 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
|
|||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, array $elements, ?bool $required, ?string $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) {
|
||||
// use length of longest string as attribute size
|
||||
$size = 0;
|
||||
foreach ($elements as $element) {
|
||||
$length = \strlen($element);
|
||||
if ($length === 0) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Each enum element must not be empty');
|
||||
}
|
||||
$size = ($length > $size) ? $length : $size;
|
||||
}
|
||||
|
||||
if (!is_null($default) && !in_array($default, $elements)) {
|
||||
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements');
|
||||
}
|
||||
|
@ -1257,7 +1247,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
|
|||
$attribute = createAttribute($databaseId, $collectionId, new Document([
|
||||
'key' => $key,
|
||||
'type' => Database::VAR_STRING,
|
||||
'size' => $size,
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'required' => $required,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
|
@ -1930,7 +1920,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/enum/
|
|||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', '', new Key(), 'Attribute Key.')
|
||||
->param('elements', null, new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
|
||||
->param('elements', null, new ArrayList(new Text(DATABASE::LENGTH_KEY), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . DATABASE::LENGTH_KEY . ' characters long.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Nullable(new Text(0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
|
||||
->inject('response')
|
||||
|
|
|
@ -355,7 +355,7 @@ App::get('/v1/health/queue/webhooks')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -382,7 +382,7 @@ App::get('/v1/health/queue/logs')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -409,7 +409,7 @@ App::get('/v1/health/queue/certificates')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -436,7 +436,7 @@ App::get('/v1/health/queue/builds')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -464,7 +464,7 @@ App::get('/v1/health/queue/databases')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -491,7 +491,7 @@ App::get('/v1/health/queue/deletes')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -518,7 +518,7 @@ App::get('/v1/health/queue/mails')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -545,7 +545,7 @@ App::get('/v1/health/queue/messaging')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -572,7 +572,7 @@ App::get('/v1/health/queue/migrations')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
@ -599,7 +599,7 @@ App::get('/v1/health/queue/functions')
|
|||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
|
|
@ -339,7 +339,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
->label('audits.resource', 'file/{response.$id}')
|
||||
->label('usage.metric', 'files.{scope}.requests.create')
|
||||
->label('usage.params', ['bucketId:{request.bucketId}'])
|
||||
->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}')
|
||||
->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId},chunkId:{chunkId}')
|
||||
->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT)
|
||||
->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT)
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
|
|
|
@ -608,8 +608,13 @@ App::error()
|
|||
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
$route = $utopia->getRoute();
|
||||
$publish = true;
|
||||
|
||||
if ($logger) {
|
||||
if ($error instanceof AppwriteException) {
|
||||
$publish = $error->isPublishable();
|
||||
}
|
||||
|
||||
if ($logger && $publish) {
|
||||
if ($error->getCode() >= 500 || $error->getCode() === 0) {
|
||||
try {
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
|
|
@ -121,13 +121,16 @@ App::init()
|
|||
$abuseKeyLabel = (!is_array($abuseKeyLabel)) ? [$abuseKeyLabel] : $abuseKeyLabel;
|
||||
|
||||
foreach ($abuseKeyLabel as $abuseKey) {
|
||||
$start = $request->getContentRangeStart();
|
||||
$end = $request->getContentRangeEnd();
|
||||
$timeLimit = new TimeLimit($abuseKey, $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $dbForProject);
|
||||
$timeLimit
|
||||
->setParam('{userId}', $user->getId())
|
||||
->setParam('{userAgent}', $request->getUserAgent(''))
|
||||
->setParam('{ip}', $request->getIP())
|
||||
->setParam('{url}', $request->getHostname() . $route->getPath())
|
||||
->setParam('{method}', $request->getMethod());
|
||||
->setParam('{method}', $request->getMethod())
|
||||
->setParam('{chunkId}', (int) ($start / ($end + 1 - $start)));
|
||||
$timeLimitArray[] = $timeLimit;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,8 +109,8 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return
|
|||
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 327;
|
||||
const APP_VERSION_STABLE = '1.4.12';
|
||||
const APP_CACHE_BUSTER = 328;
|
||||
const APP_VERSION_STABLE = '1.4.13';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
|
||||
|
|
|
@ -229,12 +229,16 @@ class Exception extends \Exception
|
|||
public const MIGRATION_PROVIDER_ERROR = 'migration_provider_error';
|
||||
|
||||
/** Realtime */
|
||||
public const REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid';
|
||||
public const REALTIME_TOO_MANY_MESSAGES = 'realtime_too_many_messages';
|
||||
public const REALTIME_POLICY_VIOLATION = 'realtime_policy_violation';
|
||||
public const REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid';
|
||||
public const REALTIME_TOO_MANY_MESSAGES = 'realtime_too_many_messages';
|
||||
public const REALTIME_POLICY_VIOLATION = 'realtime_policy_violation';
|
||||
|
||||
/** Health */
|
||||
public const QUEUE_SIZE_EXCEEDED = 'queue_size_exceeded';
|
||||
|
||||
protected string $type = '';
|
||||
protected array $errors = [];
|
||||
protected bool $publish = true;
|
||||
|
||||
public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int $code = null, \Throwable $previous = null)
|
||||
{
|
||||
|
@ -244,6 +248,7 @@ class Exception extends \Exception
|
|||
if (isset($this->errors[$type])) {
|
||||
$this->code = $this->errors[$type]['code'];
|
||||
$this->message = $this->errors[$type]['description'];
|
||||
$this->publish = $this->errors[$type]['publish'] ?? true;
|
||||
}
|
||||
|
||||
$this->message = $message ?? $this->message;
|
||||
|
@ -273,4 +278,14 @@ class Exception extends \Exception
|
|||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the log is publishable for the exception.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublishable(): bool
|
||||
{
|
||||
return $this->publish;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ abstract class Migration
|
|||
'1.4.9' => 'V19',
|
||||
'1.4.10' => 'V19',
|
||||
'1.4.11' => 'V19',
|
||||
'1.4.12' => 'V19'
|
||||
'1.4.12' => 'V19',
|
||||
'1.4.13' => 'V19'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Appwrite\Platform\Tasks;
|
|||
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Cache\Cache;
|
||||
|
@ -45,6 +46,17 @@ class DeleteOrphanedProjects extends Action
|
|||
/** @var array $collections */
|
||||
$collectionsConfig = Config::getParam('collections', [])['projects'] ?? [];
|
||||
|
||||
$collectionsConfig = array_merge([
|
||||
'audit' => [
|
||||
'$id' => ID::custom('audit'),
|
||||
'$collection' => Database::METADATA
|
||||
],
|
||||
'abuse' => [
|
||||
'$id' => ID::custom('abuse'),
|
||||
'$collection' => Database::METADATA
|
||||
]
|
||||
], $collectionsConfig);
|
||||
|
||||
/* Initialise new Utopia app */
|
||||
$app = new App('UTC');
|
||||
$console = $app->getResource('console');
|
||||
|
@ -80,6 +92,7 @@ class DeleteOrphanedProjects extends Action
|
|||
$dbForProject = new Database($adapter, $cache);
|
||||
$dbForProject->setDefaultDatabase('appwrite');
|
||||
$dbForProject->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
$collectionsCreated = 0;
|
||||
$cnt++;
|
||||
if ($dbForProject->exists($dbForProject->getDefaultDatabase(), Database::METADATA)) {
|
||||
|
@ -87,10 +100,8 @@ class DeleteOrphanedProjects extends Action
|
|||
}
|
||||
|
||||
$msg = '(' . $cnt . ') found (' . $collectionsCreated . ') collections on project (' . $project->getInternalId() . ') , database (' . $project['database'] . ')';
|
||||
/**
|
||||
* +2 = audit+abuse
|
||||
*/
|
||||
if ($collectionsCreated === (count($collectionsConfig) + 2)) {
|
||||
|
||||
if ($collectionsCreated >= count($collectionsConfig)) {
|
||||
Console::log($msg . ' ignoring....');
|
||||
continue;
|
||||
}
|
||||
|
@ -107,16 +118,26 @@ class DeleteOrphanedProjects extends Action
|
|||
Console::info('--Deleting collection (' . $collection->getId() . ') project no (' . $project->getInternalId() . ')');
|
||||
}
|
||||
}
|
||||
|
||||
if ($commit) {
|
||||
$dbForConsole->deleteDocument('projects', $project->getId());
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
if ($dbForProject->exists($dbForProject->getDefaultDatabase(), Database::METADATA)) {
|
||||
try {
|
||||
$dbForProject->deleteCollection(Database::METADATA);
|
||||
$dbForProject->deleteCachedCollection(Database::METADATA);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Metadata collection does not exist');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console::info('--Deleting project no (' . $project->getInternalId() . ')');
|
||||
|
||||
$orphans++;
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Error: ' . $th->getMessage());
|
||||
Console::error('Error: ' . $th->getMessage() . ' ' . $th->getTraceAsString());
|
||||
} finally {
|
||||
$pools
|
||||
->get($db)
|
||||
|
|
|
@ -978,7 +978,7 @@ trait DatabasesBase
|
|||
]);
|
||||
|
||||
$this->assertEquals(400, $badEnum['headers']['status-code']);
|
||||
$this->assertEquals('Each enum element must not be empty', $badEnum['body']['message']);
|
||||
$this->assertEquals('Invalid `elements` param: Value must a valid array and Value must be a valid string and at least 1 chars and no longer than 255 chars', $badEnum['body']['message']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ class HealthCustomServerTest extends Scope
|
|||
'name' => 'database_db_main',
|
||||
'threshold' => '0'
|
||||
]);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ class HealthCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
$this->assertEquals(500, $response['headers']['status-code']);
|
||||
$this->assertEquals(503, $response['headers']['status-code']);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue