diff --git a/.env b/.env index 01e3d1616a..1f0e7a152e 100644 --- a/.env +++ b/.env @@ -32,6 +32,18 @@ _APP_STORAGE_DO_SPACES_ACCESS_KEY= _APP_STORAGE_DO_SPACES_SECRET= _APP_STORAGE_DO_SPACES_REGION=us-east-1 _APP_STORAGE_DO_SPACES_BUCKET= +_APP_STORAGE_BACKBLAZE_ACCESS_KEY= +_APP_STORAGE_BACKBLAZE_SECRET= +_APP_STORAGE_BACKBLAZE_REGION=us-west-004 +_APP_STORAGE_BACKBLAZE_BUCKET= +_APP_STORAGE_LINODE_ACCESS_KEY= +_APP_STORAGE_LINODE_SECRET= +_APP_STORAGE_LINODE_REGION=eu-central-1 +_APP_STORAGE_LINODE_BUCKET= +_APP_STORAGE_WASABI_ACCESS_KEY= +_APP_STORAGE_WASABI_SECRET= +_APP_STORAGE_WASABI_REGION=eu-central-1 +_APP_STORAGE_WASABI_BUCKET= _APP_STORAGE_ANTIVIRUS=disabled _APP_STORAGE_ANTIVIRUS_HOST=clamav _APP_STORAGE_ANTIVIRUS_PORT=3310 diff --git a/CHANGES.md b/CHANGES.md index 55a2764393..30b5b1e7db 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,27 @@ +# Version 0.14.2 + +## Features + +- Support for Backblaze adapter in Storage +- Support for Linode adapter in Storage +- Support for Wasabi adapter in Storage +- New Cloud Function Runtimes: + - Dart 2.17 + - Deno 1.21 + - Java 18 + - Node 18 +- Improved overall Migration speed + + +# Version 0.14.1 + +## Bugs +* Fixed scheduled Cloud Functions execution with cron-job by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3245 +* Fixed missing runtime icons by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3234 +* Fixed Google OAuth by @Meldiron in https://github.com/appwrite/appwrite/pull/3236 +* Fixed certificate generation when hostname was set to 'localhost' by @Meldiron in https://github.com/appwrite/appwrite/pull/3237 +* Fixed Installation overriding default env variables by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3241 + # Version 0.14.0 ## Features diff --git a/Dockerfile b/Dockerfile index 7f5df76148..e2b991cf6a 100755 --- a/Dockerfile +++ b/Dockerfile @@ -162,6 +162,18 @@ ENV _APP_SERVER=swoole \ _APP_STORAGE_DO_SPACES_SECRET= \ _APP_STORAGE_DO_SPACES_REGION= \ _APP_STORAGE_DO_SPACES_BUCKET= \ + _APP_STORAGE_BACKBLAZE_ACCESS_KEY= \ + _APP_STORAGE_BACKBLAZE_SECRET= \ + _APP_STORAGE_BACKBLAZE_REGION= \ + _APP_STORAGE_BACKBLAZE_BUCKET= \ + _APP_STORAGE_LINODE_ACCESS_KEY= \ + _APP_STORAGE_LINODE_SECRET= \ + _APP_STORAGE_LINODE_REGION= \ + _APP_STORAGE_LINODE_BUCKET= \ + _APP_STORAGE_WASABI_ACCESS_KEY= \ + _APP_STORAGE_WASABI_SECRET= \ + _APP_STORAGE_WASABI_REGION= \ + _APP_STORAGE_WASABI_BUCKET= \ _APP_REDIS_HOST=redis \ _APP_REDIS_PORT=6379 \ _APP_DB_HOST=mariadb \ diff --git a/README-CN.md b/README-CN.md index 826163ee2b..7a10dee770 100644 --- a/README-CN.md +++ b/README-CN.md @@ -59,7 +59,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:0.14.0 + appwrite/appwrite:0.14.2 ``` ### Windows @@ -71,7 +71,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:0.14.0 + appwrite/appwrite:0.14.2 ``` #### PowerShell @@ -81,7 +81,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:0.14.0 + appwrite/appwrite:0.14.2 ``` 运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。 diff --git a/README.md b/README.md index 7ca23330ec..e67e4f3bad 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,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:0.14.0 + appwrite/appwrite:0.14.2 ``` ### Windows @@ -74,7 +74,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:0.14.0 + appwrite/appwrite:0.14.2 ``` #### PowerShell @@ -84,7 +84,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:0.14.0 + appwrite/appwrite:0.14.2 ``` Once the Docker installation completes, 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 installation completes. diff --git a/app/config/platforms.php b/app/config/platforms.php index 53d64c34e4..3219ba06c3 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -15,7 +15,7 @@ return [ [ 'key' => 'web', 'name' => 'Web', - 'version' => '8.0.0', + 'version' => '8.0.1', 'url' => 'https://github.com/appwrite/sdk-for-web', 'package' => 'https://www.npmjs.com/package/appwrite', 'enabled' => true, @@ -180,7 +180,7 @@ return [ [ 'key' => 'cli', 'name' => 'Command Line', - 'version' => '0.17.0', + 'version' => '0.17.1', 'url' => 'https://github.com/appwrite/sdk-for-cli', 'package' => 'https://www.npmjs.com/package/appwrite-cli', 'enabled' => true, @@ -352,7 +352,7 @@ return [ [ 'key' => 'dart', 'name' => 'Dart', - 'version' => '5.0.0', + 'version' => '5.0.1', 'url' => 'https://github.com/appwrite/sdk-for-dart', 'package' => 'https://pub.dev/packages/dart_appwrite', 'enabled' => true, diff --git a/app/config/variables.php b/app/config/variables.php index 49f2d7cfee..e7c1ab7404 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -439,7 +439,7 @@ return [ ], [ 'name' => '_APP_STORAGE_DEVICE', - 'description' => 'Select default storage device. The default value is \'Local\'. List of supported adapters are \'Local\', \'S3\' and \'DOSpaces\'.', + 'description' => 'Select default storage device. The default value is \'Local\'. List of supported adapters are \'Local\', \'S3\', \'DOSpaces\', \'Backblaze\', \'Linode\' and \'Wasabi\'.', 'introduction' => '0.13.0', 'default' => 'Local', 'required' => false, @@ -509,6 +509,102 @@ return [ 'required' => false, 'question' => '', ], + [ + 'name' => '_APP_STORAGE_BACKBLAZE_ACCESS_KEY', + 'description' => 'Backblaze access key. Required when the storage adapter is set to Backblaze. Your Backblaze keyID will be your access key. You can get your keyID from your Backblaze console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_BACKBLAZE_SECRET', + 'description' => 'Backblaze secret key. Required when the storage adapter is set to Backblaze. Your Backblaze applicationKey will be your secret key. You can get your applicationKey from your Backblaze console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_BACKBLAZE_REGION', + 'description' => 'Backblaze region. Required when storage adapter is set to Backblaze. You can find your region info from your Backblaze console.', + 'introduction' => '0.14.2', + 'default' => 'us-west-004', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_BACKBLAZE_BUCKET', + 'description' => 'Backblaze bucket. Required when storage adapter is set to Backblaze. You can create your bucket from your Backblaze console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_LINODE_ACCESS_KEY', + 'description' => 'Linode object storage access key. Required when the storage adapter is set to Linode. You can get your access key from your Linode console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_LINODE_SECRET', + 'description' => 'Linode object storage secret key. Required when the storage adapter is set to Linode. You can get your secret key from your Linode console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_LINODE_REGION', + 'description' => 'Linode object storage region. Required when storage adapter is set to Linode. You can find your region info from your Linode console.', + 'introduction' => '0.14.2', + 'default' => 'eu-central-1', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_LINODE_BUCKET', + 'description' => 'Linode object storage bucket. Required when storage adapter is set to Linode. You can create buckets in your Linode console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_WASABI_ACCESS_KEY', + 'description' => 'Wasabi access key. Required when the storage adapter is set to Wasabi. You can get your access key from your Wasabi console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_WASABI_SECRET', + 'description' => 'Wasabi secret key. Required when the storage adapter is set to Wasabi. You can get your secret key from your Wasabi console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_WASABI_REGION', + 'description' => 'Wasabi region. Required when storage adapter is set to Wasabi. You can find your region info from your Wasabi console.', + 'introduction' => '0.14.2', + 'default' => 'eu-central-1', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_WASABI_BUCKET', + 'description' => 'Wasabi bucket. Required when storage adapter is set to Wasabi. You can create buckets in your Wasabi console.', + 'introduction' => '0.14.2', + 'default' => '', + 'required' => false, + 'question' => '', + ], ], ], [ diff --git a/app/executor.php b/app/executor.php index 2e957c624c..617fd2e945 100644 --- a/app/executor.php +++ b/app/executor.php @@ -17,7 +17,10 @@ use Utopia\Orchestration\Adapter\DockerCLI; use Utopia\Orchestration\Orchestration; use Utopia\Storage\Device; use Utopia\Storage\Device\Local; +use Utopia\Storage\Device\Backblaze; use Utopia\Storage\Device\DOSpaces; +use Utopia\Storage\Device\Linode; +use Utopia\Storage\Device\Wasabi; use Utopia\Storage\Device\S3; use Utopia\Storage\Storage; use Utopia\Swoole\Request; @@ -130,6 +133,27 @@ function getStorageDevice($root): Device { $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); $doSpacesAcl = 'private'; return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); + case Storage::DEVICE_BACKBLAZE: + $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); + $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); + $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); + $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); + $backblazeAcl = 'private'; + return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); + case Storage::DEVICE_LINODE: + $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); + $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); + $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); + $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); + $linodeAcl = 'private'; + return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); + case Storage::DEVICE_WASABI: + $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); + $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); + $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); + $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); + $wasabiAcl = 'private'; + return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); } } diff --git a/app/init.php b/app/init.php index 37dbf7d20b..7e501b84a6 100644 --- a/app/init.php +++ b/app/init.php @@ -56,9 +56,12 @@ use Swoole\Database\RedisPool; use Utopia\Database\Query; use Utopia\Storage\Device; use Utopia\Storage\Storage; +use Utopia\Storage\Device\Backblaze; +use Utopia\Storage\Device\DOSpaces; use Utopia\Storage\Device\Local; use Utopia\Storage\Device\S3; -use Utopia\Storage\Device\DOSpaces; +use Utopia\Storage\Device\Linode; +use Utopia\Storage\Device\Wasabi; const APP_NAME = 'Appwrite'; const APP_DOMAIN = 'appwrite.io'; @@ -74,8 +77,8 @@ const APP_LIMIT_ANTIVIRUS = 20000000; //20MB const APP_LIMIT_ENCRYPTION = 20000000; //20MB const APP_LIMIT_COMPRESSION = 20000000; //20MB const APP_LIMIT_ARRAY_PARAMS_SIZE = 100; // Default maximum of how many elements can there be in API parameter that expects array value -const APP_CACHE_BUSTER = 304; -const APP_VERSION_STABLE = '0.14.0'; +const APP_CACHE_BUSTER = 305; +const APP_VERSION_STABLE = '0.14.2'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; const APP_DATABASE_ATTRIBUTE_IP = 'ip'; @@ -878,6 +881,27 @@ function getDevice($root): Device { $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); $doSpacesAcl = 'private'; return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); + case Storage::DEVICE_BACKBLAZE: + $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); + $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); + $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); + $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); + $backblazeAcl = 'private'; + return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); + case Storage::DEVICE_LINODE: + $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); + $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); + $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); + $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); + $linodeAcl = 'private'; + return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); + case Storage::DEVICE_WASABI: + $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); + $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); + $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); + $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); + $wasabiAcl = 'private'; + return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); } } diff --git a/app/tasks/install.php b/app/tasks/install.php index 979e9b4697..77210a0c15 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -92,6 +92,7 @@ $cli $env = $service->getEnvironment()->list(); foreach ($env as $key => $value) { + if (is_null($value)) continue; foreach($vars as &$var) { if($var['name'] === $key) { $var['default'] = $value; @@ -108,6 +109,7 @@ $cli $env = new Env($data); foreach ($env->list() as $key => $value) { + if (is_null($value)) continue; foreach($vars as &$var) { if($var['name'] === $key) { $var['default'] = $value; diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 2a1738a9c3..6fa8335bfa 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -4,7 +4,6 @@ x-logging: &x-logging options: max-file: '5' max-size: '10m' - getParam('httpPort', ''); @@ -120,6 +119,18 @@ services: - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET - _APP_FUNCTIONS_SIZE_LIMIT - _APP_FUNCTIONS_TIMEOUT - _APP_FUNCTIONS_BUILD_TIMEOUT @@ -267,6 +278,18 @@ services: - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET @@ -432,6 +455,18 @@ services: - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET - DOCKERHUB_PULL_USERNAME - DOCKERHUB_PULL_PASSWORD diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 0f9d76f81e..98b8adc769 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -8,9 +8,6 @@ use Utopia\Database\Validator\Authorization; use Appwrite\Resque\Worker; use Executor\Executor; use Utopia\Storage\Device\Local; -use Utopia\Storage\Device\S3; -use Utopia\Storage\Device\DOSpaces; -use Utopia\Storage\Storage; use Utopia\Abuse\Abuse; use Utopia\Abuse\Adapters\TimeLimit; use Utopia\CLI\Console; @@ -577,27 +574,8 @@ class DeletesV1 extends Worker $dbForProject = $this->getProjectDB($projectId); $dbForProject->deleteCollection('bucket_' . $document->getInternalId()); - $device = new Local(APP_STORAGE_UPLOADS . '/app-' . $projectId); - - switch (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL)) { - case Storage::DEVICE_S3: - $s3AccessKey = App::getEnv('_APP_STORAGE_S3_ACCESS_KEY', ''); - $s3SecretKey = App::getEnv('_APP_STORAGE_S3_SECRET', ''); - $s3Region = App::getEnv('_APP_STORAGE_S3_REGION', ''); - $s3Bucket = App::getEnv('_APP_STORAGE_S3_BUCKET', ''); - $s3Acl = 'private'; - $device = new S3(APP_STORAGE_UPLOADS . '/app-' . $projectId, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl); - break; - case Storage::DEVICE_DO_SPACES: - $doSpacesAccessKey = App::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', ''); - $doSpacesSecretKey = App::getEnv('_APP_STORAGE_DO_SPACES_SECRET', ''); - $doSpacesRegion = App::getEnv('_APP_STORAGE_DO_SPACES_REGION', ''); - $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); - $doSpacesAcl = 'private'; - $device = new DOSpaces(APP_STORAGE_UPLOADS . '/app-' . $projectId, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); - break; - } - + $device = $this->getDevice(APP_STORAGE_UPLOADS.'/app-'.$projectId); + $device->deletePath($document->getId()); } } diff --git a/app/workers/functions.php b/app/workers/functions.php index b621d95f43..aa19591e2b 100644 --- a/app/workers/functions.php +++ b/app/workers/functions.php @@ -94,6 +94,7 @@ class FunctionsV1 extends Worker $user = new Document($this->args['user'] ?? []); $project = new Document($this->args['project'] ?? []); $execution = new Document($this->args['execution'] ?? []); + $function = new Document($this->args['function'] ?? []); switch ($type) { case 'http': @@ -117,8 +118,6 @@ class FunctionsV1 extends Worker case 'schedule': $scheduleOriginal = $execution->getAttribute('scheduleOriginal', ''); - $function = Authorization::skip(fn () => $database->getDocument('functions', $execution->getAttribute('functionId'))); - /* * 1. Get Original Task * 2. Check for updates @@ -133,6 +132,8 @@ class FunctionsV1 extends Worker */ // Reschedule + $function = Authorization::skip(fn () => $database->getDocument('functions', $function->getId())); + if (empty($function->getId())) { throw new Exception('Function not found (' . $function->getId() . ')'); } @@ -192,6 +193,7 @@ class FunctionsV1 extends Worker string $jwt = null ) { + $user ??= new Document(); $functionId = $function->getId(); $deploymentId = $function->getAttribute('deployment', ''); @@ -227,12 +229,12 @@ class FunctionsV1 extends Worker /** Create execution or update execution status */ $execution = Authorization::skip(function () use ($dbForProject, &$executionId, $functionId, $deploymentId, $trigger, $user) { - $execution = $dbForProject->getDocument('executions', $executionId); + $execution = $dbForProject->getDocument('executions', $executionId ?? ''); if ($execution->isEmpty()) { $executionId = $dbForProject->getId(); $execution = $dbForProject->createDocument('executions', new Document([ '$id' => $executionId, - '$read' => $user->getId() ? ['user:' . $user->getId()] : [], + '$read' => $user->isEmpty() ? [] : ['user:' . $user->getId()], '$write' => [], 'dateCreated' => time(), 'functionId' => $functionId, @@ -281,7 +283,7 @@ class FunctionsV1 extends Worker path: $build->getAttribute('outputPath', ''), vars: $vars, entrypoint: $deployment->getAttribute('entrypoint', ''), - data: $vars['APPWRITE_FUNCTION_DATA'], + data: $vars['APPWRITE_FUNCTION_DATA'] ?? '', runtime: $function->getAttribute('runtime', ''), timeout: $function->getAttribute('timeout', 0), baseImage: $runtime['image'] diff --git a/composer.json b/composer.json index 1cd1236d0f..4c0b510cca 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "utopia-php/preloader": "0.2.*", "utopia-php/domains": "1.1.*", "utopia-php/swoole": "0.3.*", - "utopia-php/storage": "0.7.*", + "utopia-php/storage": "0.9.*", "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.4.*", @@ -71,7 +71,7 @@ } ], "require-dev": { - "appwrite/sdk-generator": "0.18.6", + "appwrite/sdk-generator": "0.18.8", "phpunit/phpunit": "9.5.20", "swoole/ide-helper": "4.8.9", "textalk/websocket": "1.5.7", diff --git a/composer.lock b/composer.lock index 69aadee3ae..8b7549d3ce 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "69e0c12a4c4b22cf17727f5b8833b1ac", + "content-hash": "6764d068d2f6aa5e9eb8befd84c0c2c9", "packages": [ { "name": "adhocore/jwt", @@ -115,11 +115,11 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.9.0", + "version": "0.9.1", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "e8aa94aa42f45711e11cb1da401b442ecc2c32a4" + "reference": "01acf8741f539f64248d54a9f0f6c4d39195d16c" }, "require": { "php": ">=8.0", @@ -154,7 +154,7 @@ "php", "runtimes" ], - "time": "2022-05-16T10:54:14+00:00" + "time": "2022-05-19T11:48:16+00:00" }, { "name": "chillerlan/php-qrcode", @@ -2628,16 +2628,16 @@ }, { "name": "utopia-php/storage", - "version": "0.7.1", + "version": "0.9.0", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "1921d5da3d155c1e03b26f8f6184dba3a69cd5e4" + "reference": "c7912481a56e17cc86358fa8de57309de5e88ef7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/1921d5da3d155c1e03b26f8f6184dba3a69cd5e4", - "reference": "1921d5da3d155c1e03b26f8f6184dba3a69cd5e4", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/c7912481a56e17cc86358fa8de57309de5e88ef7", + "reference": "c7912481a56e17cc86358fa8de57309de5e88ef7", "shasum": "" }, "require": { @@ -2674,9 +2674,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.7.1" + "source": "https://github.com/utopia-php/storage/tree/0.9.0" }, - "time": "2022-02-20T13:27:43+00:00" + "time": "2022-05-19T11:05:45+00:00" }, { "name": "utopia-php/swoole", @@ -3075,16 +3075,16 @@ }, { "name": "appwrite/sdk-generator", - "version": "0.18.6", + "version": "0.18.8", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "c0914d9f4047fd7b86112c289d98e9161cf9d0b0" + "reference": "8ba45dfb74ff6062f96c0e4d10d7c4fae94768b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/c0914d9f4047fd7b86112c289d98e9161cf9d0b0", - "reference": "c0914d9f4047fd7b86112c289d98e9161cf9d0b0", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/8ba45dfb74ff6062f96c0e4d10d7c4fae94768b1", + "reference": "8ba45dfb74ff6062f96c0e4d10d7c4fae94768b1", "shasum": "" }, "require": { @@ -3119,9 +3119,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.18.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.18.8" }, - "time": "2022-05-17T15:09:23+00:00" + "time": "2022-05-19T10:34:06+00:00" }, { "name": "composer/pcre", diff --git a/docker-compose.yml b/docker-compose.yml index 159b811566..fd34920d62 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,30 @@ x-logging: &x-logging max-file: '5' max-size: '10m' +x-env-storage: &x-env-storage |- + _APP_STORAGE_DEVICE + _APP_STORAGE_S3_ACCESS_KEY + _APP_STORAGE_S3_SECRET + _APP_STORAGE_S3_REGION + _APP_STORAGE_S3_BUCKET + _APP_STORAGE_DO_SPACES_ACCESS_KEY + _APP_STORAGE_DO_SPACES_SECRET + _APP_STORAGE_DO_SPACES_REGION + _APP_STORAGE_DO_SPACES_BUCKET + _APP_STORAGE_BACKBLAZE_ACCESS_KEY + _APP_STORAGE_BACKBLAZE_SECRET + _APP_STORAGE_BACKBLAZE_REGION + _APP_STORAGE_BACKBLAZE_BUCKET + _APP_STORAGE_DO_SPACES_BUCKET + _APP_STORAGE_LINODE_ACCESS_KEY + _APP_STORAGE_LINODE_SECRET + _APP_STORAGE_LINODE_REGION + _APP_STORAGE_LINODE_BUCKET + _APP_STORAGE_WASABI_ACCESS_KEY + _APP_STORAGE_WASABI_SECRET + _APP_STORAGE_WASABI_REGION + _APP_STORAGE_WASABI_BUCKET + version: '3' services: @@ -133,15 +157,7 @@ services: - _APP_STORAGE_ANTIVIRUS - _APP_STORAGE_ANTIVIRUS_HOST - _APP_STORAGE_ANTIVIRUS_PORT - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET + - *x-env-storage - _APP_FUNCTIONS_SIZE_LIMIT - _APP_FUNCTIONS_TIMEOUT - _APP_FUNCTIONS_BUILD_TIMEOUT @@ -296,15 +312,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET + - *x-env-storage - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET @@ -481,15 +489,7 @@ services: - OPEN_RUNTIMES_NETWORK - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET + - *x-env-storage - DOCKERHUB_PULL_USERNAME - DOCKERHUB_PULL_PASSWORD diff --git a/docs/sdks/dart/CHANGELOG.md b/docs/sdks/dart/CHANGELOG.md index 7103bfa733..319398a285 100644 --- a/docs/sdks/dart/CHANGELOG.md +++ b/docs/sdks/dart/CHANGELOG.md @@ -1,3 +1,6 @@ +## 5.0.1 +* Code formatting fix + ## 5.0.0 * Support for Appwrite 0.14 * **BREAKING** `account.delete()` -> `account.updateStatus()` diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index b5c32733ea..e4e0e17a84 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -43,6 +43,8 @@ abstract class Migration '0.13.3' => 'V12', '0.13.4' => 'V12', '0.14.0' => 'V13', + '0.14.1' => 'V13', + '0.14.2' => 'V13', ]; /** @@ -123,21 +125,7 @@ abstract class Migration $old = $document->getArrayCopy(); $new = call_user_func($callback, $document); - foreach ($document as &$attr) { - if ($attr instanceof Document) { - $attr = call_user_func($callback, $attr); - } - - if (\is_array($attr)) { - foreach ($attr as &$child) { - if ($child instanceof Document) { - $child = call_user_func($callback, $child); - } - } - } - } - - if (!$this->check_diff_multi($new->getArrayCopy(), $old)) { + if (!self::hasDifference($new->getArrayCopy(), $old)) { return; } @@ -166,35 +154,28 @@ abstract class Migration /** * Checks 2 arrays for differences. - * - * @param array $array1 - * @param array $array2 - * @return array + * + * @param array $array1 + * @param array $array2 + * @return bool */ - public function check_diff_multi(array $array1, array $array2): array + public static function hasDifference(array $array1, array $array2): bool { - $result = array(); - - foreach ($array1 as $key => $val) { - if (is_array($val) && isset($array2[$key])) { - $tmp = $this->check_diff_multi($val, $array2[$key]); - if ($tmp) { - $result[$key] = $tmp; + foreach ($array1 as $key => $value) { + if (is_array($value)) { + if (!isset($array2[$key]) || !is_array($array2[$key])) { + return true; + } else { + if (self::hasDifference($value, $array2[$key])) { + return true; + } } - } elseif (!isset($array2[$key])) { - $result[$key] = null; - } elseif ($val !== $array2[$key]) { - $result[$key] = $array2[$key]; - } - - if (isset($array2[$key])) { - unset($array2[$key]); + } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) { + return true; } } - $result = array_merge($result, $array2); - - return $result; + return false; } /** diff --git a/src/Appwrite/Resque/Worker.php b/src/Appwrite/Resque/Worker.php index 88489b5412..686d1b8d81 100644 --- a/src/Appwrite/Resque/Worker.php +++ b/src/Appwrite/Resque/Worker.php @@ -12,6 +12,9 @@ use Utopia\Storage\Device; use Utopia\Storage\Storage; use Utopia\Storage\Device\Local; use Utopia\Storage\Device\DOSpaces; +use Utopia\Storage\Device\Linode; +use Utopia\Storage\Device\Wasabi; +use Utopia\Storage\Device\Backblaze; use Utopia\Storage\Device\S3; use Exception; @@ -259,7 +262,7 @@ abstract class Worker * @param string $root path of the device * @return Device */ - private function getDevice($root): Device + public function getDevice($root): Device { switch (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL)) { case Storage::DEVICE_LOCAL:default: @@ -278,6 +281,27 @@ abstract class Worker $doSpacesBucket = App::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', ''); $doSpacesAcl = 'private'; return new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl); + case Storage::DEVICE_BACKBLAZE: + $backblazeAccessKey = App::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', ''); + $backblazeSecretKey = App::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', ''); + $backblazeRegion = App::getEnv('_APP_STORAGE_BACKBLAZE_REGION', ''); + $backblazeBucket = App::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', ''); + $backblazeAcl = 'private'; + return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl); + case Storage::DEVICE_LINODE: + $linodeAccessKey = App::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', ''); + $linodeSecretKey = App::getEnv('_APP_STORAGE_LINODE_SECRET', ''); + $linodeRegion = App::getEnv('_APP_STORAGE_LINODE_REGION', ''); + $linodeBucket = App::getEnv('_APP_STORAGE_LINODE_BUCKET', ''); + $linodeAcl = 'private'; + return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl); + case Storage::DEVICE_WASABI: + $wasabiAccessKey = App::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', ''); + $wasabiSecretKey = App::getEnv('_APP_STORAGE_WASABI_SECRET', ''); + $wasabiRegion = App::getEnv('_APP_STORAGE_WASABI_REGION', ''); + $wasabiBucket = App::getEnv('_APP_STORAGE_WASABI_BUCKET', ''); + $wasabiAcl = 'private'; + return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl); } } } diff --git a/tests/unit/Migration/MigrationTest.php b/tests/unit/Migration/MigrationTest.php index 340e33772c..0c8c34cbc8 100644 --- a/tests/unit/Migration/MigrationTest.php +++ b/tests/unit/Migration/MigrationTest.php @@ -4,6 +4,7 @@ namespace Appwrite\Tests; use Appwrite\Migration\Migration; use PHPUnit\Framework\TestCase; +use ReflectionClass; use ReflectionMethod; use Utopia\Database\Document; @@ -36,12 +37,100 @@ abstract class MigrationTest extends TestCase */ public function testMigrationVersions() { - require_once __DIR__.'/../../../app/init.php'; + require_once __DIR__ . '/../../../app/init.php'; foreach (Migration::$versions as $class) { - $this->assertTrue(class_exists('Appwrite\\Migration\\Version\\'.$class)); + $this->assertTrue(class_exists('Appwrite\\Migration\\Version\\' . $class)); } // Test if current version exists - //$this->assertArrayHasKey(APP_VERSION_STABLE, Migration::$versions); + $this->assertArrayHasKey(APP_VERSION_STABLE, Migration::$versions); + } + + public function testHasDifference() + { + $this->assertFalse(Migration::hasDifference([], [])); + $this->assertFalse(Migration::hasDifference([ + 'bool' => true, + 'string' => 'abc', + 'int' => 123, + 'array' => ['a', 'b', 'c'], + 'assoc' => [ + 'a' => true, + 'b' => 'abc', + 'c' => 123, + 'd' => ['a', 'b', 'c'] + ] + ], [ + 'bool' => true, + 'string' => 'abc', + 'int' => 123, + 'array' => ['a', 'b', 'c'], + 'assoc' => [ + 'a' => true, + 'b' => 'abc', + 'c' => 123, + 'd' => ['a', 'b', 'c'] + ] + ])); + $this->assertFalse(Migration::hasDifference([ + 'bool' => true, + 'string' => 'abc', + 'int' => 123, + 'array' => ['a', 'b', 'c'], + 'assoc' => [ + 'a' => true, + 'b' => 'abc', + 'c' => 123, + 'd' => ['a', 'b', 'c'] + ] + ], [ + 'string' => 'abc', + 'assoc' => [ + 'a' => true, + 'b' => 'abc', + 'c' => 123, + 'd' => ['a', 'b', 'c'] + ], + 'int' => 123, + 'array' => ['a', 'b', 'c'], + 'bool' => true, + + ])); + $this->assertTrue(Migration::hasDifference([ + 'a' => true + ], [ + 'b' => true + ])); + $this->assertTrue(Migration::hasDifference([ + 'a' => 'true' + ], [ + 'a' => true + ])); + $this->assertTrue(Migration::hasDifference([ + 'a' => true + ], [ + 'a' => false + ])); + $this->assertTrue(Migration::hasDifference([ + 'nested' => [ + 'a' => true + ] + ], [ + 'nested' => [] + ])); + $this->assertTrue(Migration::hasDifference([ + 'assoc' => [ + 'bool' => true, + 'string' => 'abc', + 'int' => 123, + 'array' => ['a', 'b', 'c'] + ] + ], [ + 'nested' => [ + 'a' => true, + 'int' => '123', + 'array' => ['a', 'b', 'c'] + ] + ])); } }