diff --git a/CHANGES.md b/CHANGES.md index 7063f6db3..3e2c161a1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,17 @@ +# Version 0.6.2 (PRE-RELEASE) + +## Features + +- New route in Locale API to fetch list of languages + +## Bug Fixes + +- Fixed custom domain not setting correct domain +- Fixed wrong SDK method type in avatars browser route +- Fixed bug denied public documents (*) to be accessed by guest users +- Fixed cache control issue not allowing collection UI to update properly +- Added missing webhooks events in the console + # Version 0.6.1 (PRE-RELEASE) ## Bug Fixes diff --git a/Dockerfile b/Dockerfile index 159d453d6..fe84acfe6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,6 +53,7 @@ ENV TZ=Asia/Tel_Aviv \ _APP_OPTIONS_ABUSE=enabled \ _APP_OPENSSL_KEY_V1=your-secret-key \ _APP_STORAGE_LIMIT=104857600 \ + _APP_STORAGE_ANTIVIRUS=enabled \ _APP_REDIS_HOST=redis \ _APP_REDIS_PORT=6379 \ _APP_DB_HOST=mariadb \ diff --git a/README.md b/README.md index c7cc4f9ec..ac9e9bc1b 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,9 @@ [![Twitter Account](https://badgen.net/twitter/follow/appwrite_io?label=twitter)](https://twitter.com/appwrite_io) [![Follow Appwrite on StackShare](https://badgen.net/badge/follow%20on/stackshare/blue)](https://stackshare.io/appwrite) +Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker microservices. Appwrite abstract the complexity and repetitiveness required to build a modern backend API from scratch to allow you to build secure apps faster. -Appwrite is a simple self-hosted backend server for web and mobile developers with a shiny dashboard and a very easy-to-use REST API. - -Appwrite API services aim to make developer's life a lot easier by hiding the complexity of common and repetitive software development tasks. - -Using Appwrite, you can easily manage user authentication with multiple sign-in methods, a database for storing and querying user and team data, storage and file management, image manipulation and cropping, schedule cron tasks and many other features to help you get more results in faster times and with a lot less code. - -Appwrite can also integrate really well with your backend. Appwrite can work behind your own proxy facing your internal network, or alongside your own custom backend. You can use Appwrite server SDK to integrate your backend with Appwrite's APIs and webhooks. +Using Appwrite, you can easily integrate your app with user authentication & multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, schedule CRON tasks, and [more services](https://appwrite.io/docs). [https://appwrite.io](https://appwrite.io) @@ -30,10 +25,15 @@ Appwrite can also integrate really well with your backend. Appwrite can work beh Table of Contents: - [Installation](#installation) - - [Changing Port Number](#changing-port-number) + - [Unix](#unix) + - [Windows](#windows) + - [CMD](#cmd) + - [PowerShell](#powershell) - [Getting Started](#getting-started) - [Services](#services) - [SDKs](#sdks) + - [Client](#client) + - [Server](#server) - [Security](#security) - [Follow Us](#follow-us) - [Contributing](#contributing) @@ -45,6 +45,8 @@ Appwrite backend server is designed to run in a container environment. Running y The easiest way to start running your Appwrite server is by running our docker-compose file. Before running the installation command make sure you have [Docker](https://www.docker.com/products/docker-desktop) installed on your machine: +### Unix + ```bash docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ @@ -53,20 +55,39 @@ docker run -it --rm \ appwrite/install ``` +### Windows + +#### CMD + +```cmd +docker run -it --rm ^ + --volume //var/run/docker.sock:/var/run/docker.sock ^ + --volume "%cd%"/appwrite:/install/appwrite:rw ^ + -e version=0.6.1 ^ + appwrite/install +``` + +#### PowerShell + +```powershell +docker run -it --rm , + --volume /var/run/docker.sock:/var/run/docker.sock , + --volume ${pwd}/appwrite:/install/appwrite:rw , + -e version=0.6.1 , + appwrite/install +``` + 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. -For advanced production and custom installation, check out our Docker [environment variables](docs/tutorials/environment-variables.md) docs. - -### Changing Port Number - -In case your port 80 is already taken, change the port number in the command above. Make sure to set the correct endpoint in your selected SDK, including your new port number. +For advanced production and custom installation, check out our Docker [environment variables](docs/tutorials/environment-variables.md) docs. You can also use our public [docker-compose.yml](https://appwrite.io/docker-compose.yml) file to manually set up and environment. ## Getting Started Getting started with Appwrite is as easy as creating a new project, choosing your platform and integrating its SDK in your code. You can easily get started with your platform of choice by reading one of our Getting Started tutorials. * [Getting Started for Web](https://appwrite.io/docs/getting-started-for-web) +* [Getting Started for Flutter](https://appwrite.io/docs/getting-started-for-flutter) * [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server) * Getting Started for Android (soon...) * Getting Started for iOS (soon...) @@ -81,22 +102,25 @@ Getting started with Appwrite is as easy as creating a new project, choosing you * [**Locale**](https://appwrite.io/docs/locale) - Track your user's location, and manage your app locale-based data. * [**Avatars**](https://appwrite.io/docs/avatars) - Manage your users' avatars, countries' flags, browser icons, credit card symbols, and generate QR codes. -For the complete API documentation, visit [https://appwrite.io/docs](https://appwrite.io/docs). For more tutorials, news and announcements check out our [blog](https://medium.com/appwrite-io). +For the complete API documentation, visit [https://appwrite.io/docs](https://appwrite.io/docs). For more tutorials, news and announcements check out our [blog](https://medium.com/appwrite-io) and [Discord Server](https://discord.gg/GSeTUeA). ### SDKs -Currently, we support only a few SDK libraries and are constantly working on including new ones. - Below is a list of currently supported platforms and languages. If you wish to help us add support to your platform of choice, you can go over to our [SDK Generator](https://github.com/appwrite/sdk-generator) project and view our [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md). -* ✅ [JS](https://github.com/appwrite/sdk-for-js) (Maintained by the Appwrite Team) +#### Client +* ✅ [Web](https://github.com/appwrite/sdk-for-js) (Maintained by the Appwrite Team) +* ✅ [Flutter](https://github.com/appwrite/sdk-for-flutter) (Maintained by the Appwrite Team) + +#### Server * ✅ [NodeJS](https://github.com/appwrite/sdk-for-node) (Maintained by the Appwrite Team) * ✅ [PHP](https://github.com/appwrite/sdk-for-php) (Maintained by the Appwrite Team) +* ✅ [Ruby](https://github.com/appwrite/sdk-for-ruby) - **Beta** (Maintained by the Appwrite Team) +* ✅ [Python](https://github.com/appwrite/sdk-for-python) - **Beta** (Maintained by the Appwrite Team) * ✅ [Go](https://github.com/appwrite/sdk-for-go) **Work in progress** (Maintained by the Appwrite Team) * ✅ [Dart](https://github.com/appwrite/sdk-for-dart) **Work in progress** (Maintained by the Appwrite Team) -* ✅ [Ruby](https://github.com/appwrite/sdk-for-ruby) - **Work in progress** (Maintained by the Appwrite Team) -* ✅ [Python](https://github.com/appwrite/sdk-for-python) - **Work in progress** (Maintained by the Appwrite Team) -* ✳️ Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)! + +Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)! ## Security diff --git a/app/app.php b/app/app.php index e22d5dc24..a438950f3 100644 --- a/app/app.php +++ b/app/app.php @@ -86,7 +86,7 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $ //->addHeader('X-Frame-Options', ($refDomain == 'http://localhost') ? 'SAMEORIGIN' : 'ALLOW-FROM ' . $refDomain) ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version, Cache-Control, Expires, Pragma') ->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $refDomain) ->addHeader('Access-Control-Allow-Credentials', 'true') @@ -246,7 +246,7 @@ $utopia->options(function () use ($request, $response) { $response ->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE') - ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version, X-Fallback-Cookies') + ->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version, Cache-Control, Expires, Pragma, X-Fallback-Cookies') ->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies') ->addHeader('Access-Control-Allow-Origin', $origin) ->addHeader('Access-Control-Allow-Credentials', 'true') diff --git a/app/config/events.php b/app/config/events.php new file mode 100644 index 000000000..aeee6849f --- /dev/null +++ b/app/config/events.php @@ -0,0 +1,58 @@ + [ + 'description' => 'This event triggers when the account is created.', + ], + 'account.update.email' => [ + 'description' => 'This event triggers when the account email address is updated.', + ], + 'account.update.name' => [ + 'description' => 'This event triggers when the account name is updated.', + ], + 'account.update.password' => [ + 'description' => 'This event triggers when the account password is updated.', + ], + 'account.update.prefs' => [ + 'description' => 'This event triggers when the account preferences are updated.', + ], + 'account.delete' => [ + 'description' => 'This event triggers when the account is deleted.', + ], + 'account.sessions.create' => [ + 'description' => 'This event triggers when the account session is created.', + ], + 'account.sessions.delete' => [ + 'description' => 'This event triggers when the account session is deleted.', + ], + 'database.collections.create' => [ + 'description' => 'This event triggers when a database collection is created.', + ], + 'database.collections.update' => [ + 'description' => 'This event triggers when a database collection is updated.', + ], + 'database.collections.delete' => [ + 'description' => 'This event triggers when a database collection is deleted.', + ], + 'database.documents.create' => [ + 'description' => 'This event triggers when a database document is created.', + ], + 'database.documents.patch' => [ + 'description' => 'This event triggers when a database document is patched.', + ], + 'database.documents.delete' => [ + 'description' => 'This event triggers when a database document is deleted.', + ], + 'storage.files.create' => [ + 'description' => 'This event triggers when a storage file is created.', + ], + 'storage.files.update' => [ + 'description' => 'This event triggers when a storage file is updated.', + ], + 'storage.files.delete' => [ + 'description' => 'This event triggers when a storage file is deleted.', + ], +]; \ No newline at end of file diff --git a/app/config/platforms.php b/app/config/platforms.php index 54d00fcbb..796f4ad39 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -29,7 +29,7 @@ return [ [ 'key' => 'flutter', 'name' => 'Flutter', - 'version' => '0.2.1', + 'version' => '0.2.2', 'url' => 'https://github.com/appwrite/sdk-for-flutter', 'enabled' => true, 'beta' => true, diff --git a/app/config/roles.php b/app/config/roles.php index e69078317..f462305d9 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -58,6 +58,7 @@ return [ 'public', 'home', 'console', + 'documents.read', 'files.read', 'locale.read', 'avatars.read', diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index 0e62ba9c6..bc493f8cc 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -114,6 +114,7 @@ $utopia->get('/v1/avatars/browsers/:code') ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) ->label('sdk.namespace', 'avatars') ->label('sdk.method', 'getBrowser') + ->label('sdk.methodType', 'location') ->label('sdk.description', '/docs/references/avatars/get-browser.md') ->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('browsers', $code, $width, $height, $quality); }); diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index 9e9ea0963..e244a6b46 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -218,7 +218,11 @@ $utopia->get('/v1/health/anti-virus') ->label('sdk.method', 'getAntiVirus') ->label('sdk.description', '/docs/references/health/get-storage-anti-virus.md') ->action( - function () use ($response) { + function () use ($request, $response) { + if($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled + throw new Exception('Anitvirus is disabled'); + } + $antiVirus = new Network('clamav', 3310); $response->json([ diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index dc1b8a27c..9f35733bc 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -1229,9 +1229,8 @@ $utopia->post('/v1/projects/:projectId/domains') ->param('projectId', null, function () { return new UID(); }, 'Project unique ID.') ->param('domain', null, function () { return new DomainValidator(); }, 'Domain name.') ->action( - function ($projectId) use ($request, $response, $consoleDB) { + function ($projectId, $domain) use ($request, $response, $consoleDB) { $project = $consoleDB->getDocument($projectId); - $domain = Config::getParam('domain'); if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) { throw new Exception('Project not found', 404); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 448eb9351..18a8c98c2 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -179,8 +179,6 @@ $utopia->post('/v1/storage/files') throw new Exception('File size not allowed', 400); } - $antiVirus = new Network('clamav', 3310); - /* * Models */ @@ -200,10 +198,14 @@ $utopia->post('/v1/storage/files') $mimeType = $device->getFileMimeType($path); // Get mime-type before compression and encryption - // Check if file size is exceeding allowed limit - if (!$antiVirus->fileScan($path)) { - $device->delete($path); - throw new Exception('Invalid file', 403); + if($request->getServer('_APP_STORAGE_ANTIVIRUS') === 'enabled') { // Check if scans are enabled + $antiVirus = new Network('clamav', 3310); + + // Check if file size is exceeding allowed limit + if (!$antiVirus->fileScan($path)) { + $device->delete($path); + throw new Exception('Invalid file', 403); + } } // Compression @@ -654,53 +656,53 @@ $utopia->delete('/v1/storage/files/:fileId') } ); -$utopia->get('/v1/storage/files/:fileId/scan') - ->desc('Scan Storage') - ->label('scope', 'god') - ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) - ->label('sdk.namespace', 'storage') - ->label('sdk.method', 'getFileScan') - ->label('sdk.hide', true) - ->param('fileId', '', function () { return new UID(); }, 'File unique ID.') - ->param('storage', 'local', function () { return new WhiteList(['local']);}) - ->action( - function ($fileId, $storage) use ($response, $request, $projectDB) { - $file = $projectDB->getDocument($fileId); +// $utopia->get('/v1/storage/files/:fileId/scan') +// ->desc('Scan Storage') +// ->label('scope', 'god') +// ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER]) +// ->label('sdk.namespace', 'storage') +// ->label('sdk.method', 'getFileScan') +// ->label('sdk.hide', true) +// ->param('fileId', '', function () { return new UID(); }, 'File unique ID.') +// ->param('storage', 'local', function () { return new WhiteList(['local']);}) +// ->action( +// function ($fileId, $storage) use ($response, $request, $projectDB) { +// $file = $projectDB->getDocument($fileId); - if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) { - throw new Exception('File not found', 404); - } +// if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) { +// throw new Exception('File not found', 404); +// } - $path = $file->getAttribute('path', ''); +// $path = $file->getAttribute('path', ''); - if (!file_exists($path)) { - throw new Exception('File not found in '.$path, 404); - } +// if (!file_exists($path)) { +// throw new Exception('File not found in '.$path, 404); +// } - $compressor = new GZIP(); - $device = Storage::getDevice($storage); +// $compressor = new GZIP(); +// $device = Storage::getDevice($storage); - $source = $device->read($path); +// $source = $device->read($path); - if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt - $source = OpenSSL::decrypt( - $source, - $file->getAttribute('fileOpenSSLCipher'), - $request->getServer('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')), - 0, - hex2bin($file->getAttribute('fileOpenSSLIV')), - hex2bin($file->getAttribute('fileOpenSSLTag')) - ); - } +// if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt +// $source = OpenSSL::decrypt( +// $source, +// $file->getAttribute('fileOpenSSLCipher'), +// $request->getServer('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')), +// 0, +// hex2bin($file->getAttribute('fileOpenSSLIV')), +// hex2bin($file->getAttribute('fileOpenSSLTag')) +// ); +// } - $source = $compressor->decompress($source); +// $source = $compressor->decompress($source); - $antiVirus = new Network('clamav', 3310); +// $antiVirus = new Network('clamav', 3310); - //var_dump($antiVirus->ping()); - //var_dump($antiVirus->version()); - //var_dump($antiVirus->fileScan('/storage/uploads/app-1/5/9/f/e/59fecaed49645.pdf')); +// //var_dump($antiVirus->ping()); +// //var_dump($antiVirus->version()); +// //var_dump($antiVirus->fileScan('/storage/uploads/app-1/5/9/f/e/59fecaed49645.pdf')); - //$response->json($antiVirus->continueScan($device->getRoot())); - } - ); +// //$response->json($antiVirus->continueScan($device->getRoot())); +// } +// ); diff --git a/app/controllers/shared/web.php b/app/controllers/shared/web.php index 9f148817a..42afb283e 100644 --- a/app/controllers/shared/web.php +++ b/app/controllers/shared/web.php @@ -31,7 +31,7 @@ $layout ->setParam('env', $utopia->getEnv()) ; -$utopia->shutdown(function () use ($utopia, $response, $request, $layout) { +$utopia->init(function () use ($utopia, $response, $request, $layout) { $time = (60 * 60 * 24 * 45); // 45 days cache $isDev = (\Utopia\App::ENV_TYPE_DEVELOPMENT == Config::getParam('env')); diff --git a/app/controllers/web/console.php b/app/controllers/web/console.php index 70f32693f..480c4ff9b 100644 --- a/app/controllers/web/console.php +++ b/app/controllers/web/console.php @@ -133,7 +133,11 @@ $utopia->get('/console/webhooks') ->label('scope', 'console') ->action(function () use ($layout) { $page = new View(__DIR__.'/../../views/console/webhooks/index.phtml'); - + + $page + ->setParam('events', Config::getParam('events', [])) + ; + $layout ->setParam('title', APP_NAME.' - Webhooks') ->setParam('body', $page); @@ -183,7 +187,7 @@ $utopia->get('/console/database/collection') ->label('permission', 'public') ->label('scope', 'console') ->param('id', '', function () { return new UID(); }, 'Collection unique ID.') - ->action(function ($id) use ($layout, $projectDB) { + ->action(function ($id) use ($response, $layout, $projectDB) { Authorization::disable(); $collection = $projectDB->getDocument($id, false); Authorization::reset(); @@ -197,10 +201,18 @@ $utopia->get('/console/database/collection') $page ->setParam('collection', $collection) ; - + $layout ->setParam('title', APP_NAME.' - Database Collection') - ->setParam('body', $page); + ->setParam('body', $page) + ; + + $response + ->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0') + ->addHeader('Expires', 0) + ->addHeader('Pragma', 'no-cache') + ; + }); $utopia->get('/console/database/document') diff --git a/app/init.php b/app/init.php index f07ab8333..88e58cef7 100644 --- a/app/init.php +++ b/app/init.php @@ -54,6 +54,7 @@ $response = new Response(); /* * ENV vars */ +Config::load('events', __DIR__.'/../app/config/events.php'); Config::load('providers', __DIR__.'/../app/config/providers.php'); Config::load('platforms', __DIR__.'/../app/config/platforms.php'); Config::load('locales', __DIR__.'/../app/config/locales.php'); diff --git a/app/sdks/client-flutter/CHANGELOG.md b/app/sdks/client-flutter/CHANGELOG.md index 0bb441e95..37f6a30a6 100644 --- a/app/sdks/client-flutter/CHANGELOG.md +++ b/app/sdks/client-flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.2 + +- Fixed an error that happend when the OAuth session creation request was sent before any other API call +- Fixed a bug in the Avatars service where location URL generation had syntax error + ## 0.2.1 - Fixed callback scheme diff --git a/app/sdks/client-flutter/README.md b/app/sdks/client-flutter/README.md index 8c17a5b4a..b0c261c11 100644 --- a/app/sdks/client-flutter/README.md +++ b/app/sdks/client-flutter/README.md @@ -2,9 +2,9 @@ [![pub package](https://img.shields.io/pub/v/appwrite.svg)](https://pub.dartlang.org/packages/appwrite) ![License](https://img.shields.io/github/license/appwrite/sdk-for-flutter.svg?v=1) -![Version](https://img.shields.io/badge/api%20version-0.6.0-blue.svg?v=1) +![Version](https://img.shields.io/badge/api%20version-0.6.1-blue.svg?v=1) -**This SDK is compatible with Appwrite server version 0.6.0. For older versions, please check previous releases.** +**This SDK is compatible with Appwrite server version 0.6.1. For older versions, please check previous releases.** Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. @@ -20,7 +20,7 @@ Add this to your package's `pubspec.yaml` file: ```yml dependencies: - appwrite: ^0.2.1 + appwrite: ^0.2.2 ``` You can install packages from the command line: diff --git a/app/sdks/client-flutter/lib/client.dart b/app/sdks/client-flutter/lib/client.dart index 3798a0852..d9e8eedf1 100644 --- a/app/sdks/client-flutter/lib/client.dart +++ b/app/sdks/client-flutter/lib/client.dart @@ -15,7 +15,7 @@ class Client { Map headers; Map config; bool selfSigned; - bool init = false; + bool initialized = false; Dio http; PersistCookieJar cookieJar; @@ -30,7 +30,7 @@ class Client { this.headers = { 'content-type': 'application/json', - 'x-sdk-version': 'appwrite:dart:0.2.1', + 'x-sdk-version': 'appwrite:dart:0.2.2', }; this.config = {}; @@ -76,6 +76,22 @@ class Client { return this; } + Future init() async { + if(!initialized) { + final Directory cookieDir = await _getCookiePath(); + + cookieJar = new PersistCookieJar(dir:cookieDir.path); + + this.http.options.baseUrl = this.endPoint; + this.http.options.validateStatus = (status) => status < 400; + this.http.interceptors.add(CookieManager(cookieJar)); + + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + + addHeader('Origin', 'appwrite-' + type + '://' + packageInfo.packageName); + } + } + Future call(HttpMethod method, {String path = '', Map headers = const {}, Map params = const {}}) async { if(selfSigned) { // Allow self signed requests @@ -85,21 +101,7 @@ class Client { }; } - if(!init) { - final Directory cookieDir = await _getCookiePath(); - - cookieJar = new PersistCookieJar(dir:cookieDir.path); - - this.http.options.baseUrl = this.endPoint; - this.http.options.validateStatus = (status) => status < 400; - this.http.interceptors.add(CookieManager(cookieJar)); - - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - - addHeader('Origin', 'appwrite-' + type + '://' + packageInfo.packageName); - - init = true; - } + await this.init(); // Origin is hardcoded for testing Options options = Options( diff --git a/app/sdks/client-flutter/lib/services/account.dart b/app/sdks/client-flutter/lib/services/account.dart index b191791ab..8cc237d10 100644 --- a/app/sdks/client-flutter/lib/services/account.dart +++ b/app/sdks/client-flutter/lib/services/account.dart @@ -325,9 +325,10 @@ class Account extends Service { return FlutterWebAuth.authenticate( url: url.toString(), callbackUrlScheme: "appwrite-callback-" + client.config['project'] - ).then((value) { + ).then((value) async { Uri url = Uri.parse(value); List cookies = [new Cookie(url.queryParameters['key'], url.queryParameters['secret'])]; + await client.init(); client.cookieJar.saveFromResponse(Uri.parse(client.endPoint), cookies); }); } diff --git a/app/sdks/client-flutter/lib/services/avatars.dart b/app/sdks/client-flutter/lib/services/avatars.dart index 2ce6ed263..db73c0de8 100644 --- a/app/sdks/client-flutter/lib/services/avatars.dart +++ b/app/sdks/client-flutter/lib/services/avatars.dart @@ -51,14 +51,14 @@ class Avatars extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get Favicon @@ -75,14 +75,14 @@ class Avatars extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get Country Flag @@ -102,14 +102,14 @@ class Avatars extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get Image from URL @@ -130,14 +130,14 @@ class Avatars extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get QR Code @@ -157,13 +157,13 @@ class Avatars extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } } \ No newline at end of file diff --git a/app/sdks/client-flutter/lib/services/storage.dart b/app/sdks/client-flutter/lib/services/storage.dart index 47497c769..696c15ee3 100644 --- a/app/sdks/client-flutter/lib/services/storage.dart +++ b/app/sdks/client-flutter/lib/services/storage.dart @@ -125,14 +125,14 @@ class Storage extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get File Preview @@ -155,14 +155,14 @@ class Storage extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } /// Get File for View @@ -179,13 +179,13 @@ class Storage extends Service { }; Uri endpoint = Uri.parse(client.endPoint); - Uri url = new Uri(scheme: endpoint.scheme, + Uri location = new Uri(scheme: endpoint.scheme, host: endpoint.host, port: endpoint.port, path: endpoint.path + path, queryParameters:params, ); - return url.toString(); + return location.toString(); } } \ No newline at end of file diff --git a/app/sdks/client-flutter/pubspec.yaml b/app/sdks/client-flutter/pubspec.yaml index 27d0115d0..2954cdb9e 100644 --- a/app/sdks/client-flutter/pubspec.yaml +++ b/app/sdks/client-flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: appwrite -version: 0.2.1 +version: 0.2.2 description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API homepage: https://appwrite.io repository: https://github.com/appwrite/sdk-for-flutter diff --git a/app/views/console/webhooks/index.phtml b/app/views/console/webhooks/index.phtml index d71dd99df..bcd001254 100644 --- a/app/views/console/webhooks/index.phtml +++ b/app/views/console/webhooks/index.phtml @@ -1,26 +1,6 @@ getParam('events', [])); ?>
diff --git a/build.sh b/build.sh index 43cbaf42d..c641709a8 100644 --- a/build.sh +++ b/build.sh @@ -3,6 +3,18 @@ RED='\033[0;31m' NC='\033[0m' # No Color +if [ -z "$1" ] +then + echo "Missing tag number" + exit 1 +fi + +if [ -z "$2" ] +then + echo "Missing version number" + exit 1 +fi + echo "Updating git repository $1 / $2" git fetch origin diff --git a/composer.lock b/composer.lock index 8515bf6cd..bc26085ac 100644 --- a/composer.lock +++ b/composer.lock @@ -485,12 +485,12 @@ "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "c8162bee934111d42b1db4869c09fb58926074c7" + "reference": "0d137e94480b275aadd1f2536a76d91cf580711c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c8162bee934111d42b1db4869c09fb58926074c7", - "reference": "c8162bee934111d42b1db4869c09fb58926074c7", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0d137e94480b275aadd1f2536a76d91cf580711c", + "reference": "0d137e94480b275aadd1f2536a76d91cf580711c", "shasum": "" }, "require": { @@ -498,7 +498,7 @@ "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1", "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.11" + "symfony/polyfill-intl-idn": "1.17.0" }, "require-dev": { "ext-curl": "*", @@ -544,7 +544,7 @@ "rest", "web service" ], - "time": "2020-05-19T12:55:02+00:00" + "time": "2020-05-23T18:58:46+00:00" }, { "name": "guzzlehttp/promises", @@ -1141,7 +1141,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "dev-master", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -1745,7 +1745,7 @@ "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator", - "reference": "e889aa5764f6cca683b5ccd83eed2e4632173937" + "reference": "69f8cfabf7f40cb9fb7198cdd9770afdd030a88a" }, "require": { "ext-curl": "*", @@ -1775,7 +1775,7 @@ } ], "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "time": "2020-05-23T14:30:05+00:00" + "time": "2020-05-24T05:26:35+00:00" }, { "name": "doctrine/instantiator", diff --git a/docker/nginx.conf b/docker/nginx.conf index 356eaa833..b1a569029 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -107,12 +107,6 @@ http { add_header Cache-Control "public"; } - location /proxy.html { - expires 1y; - access_log off; - add_header Cache-Control "public"; - } - #error_page 404 /404.html; # redirect server error pages to the static page /50x.html diff --git a/docs/sdks/dart/CHANGELOG.md b/docs/sdks/dart/CHANGELOG.md index fe5040967..e69de29bb 100644 --- a/docs/sdks/dart/CHANGELOG.md +++ b/docs/sdks/dart/CHANGELOG.md @@ -1,33 +0,0 @@ -## 0.1.1 - -- Updated flutter_web_auth version - -## 0.1.0 - -- Added examples file -- Some minor style fixes - -## 0.0.14 - -- Using MultipartFile for file uploads - -## 0.0.13 - -- Fix for file upload method - -## 0.0.12 - -- Added file upload support for storage service - -## 0.0.11 - -- Added integration with web auth plugin to support Appwrite OAuth API - -## 0.0.9 - -- Updated deafult params - -## 0.0.8 - -- Fixed compilation error in Client class -- Shorter description for package \ No newline at end of file diff --git a/docs/sdks/flutter/CHANGELOG.md b/docs/sdks/flutter/CHANGELOG.md index 0bb441e95..37f6a30a6 100644 --- a/docs/sdks/flutter/CHANGELOG.md +++ b/docs/sdks/flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.2 + +- Fixed an error that happend when the OAuth session creation request was sent before any other API call +- Fixed a bug in the Avatars service where location URL generation had syntax error + ## 0.2.1 - Fixed callback scheme diff --git a/docs/tutorials/environment-variables.md b/docs/tutorials/environment-variables.md index 99ca4d8d8..712c1f1e0 100644 --- a/docs/tutorials/environment-variables.md +++ b/docs/tutorials/environment-variables.md @@ -20,19 +20,23 @@ This is your server private secret key that is used to encrypt all sensitive dat Maximun file size allowed for file upload. The deafult value is 100MB limitation. You should pass your size limit value in bytes. +### _APP_STORAGE_ANTIVIRUS + +This variable allows you to disable the internal anti-virus scans. By default, this value is set to 'enabled' to cancel the scans, set the value to 'disabled'. When disabled, it's recommended to turn off the ClamAV container for better resource usage. + ### _APP_CONSOLE_WHITELIST_EMAILS -This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma. +This option allows you to limit creation of users to Appwrite console. This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma. ### _APP_CONSOLE_WHITELIST_DOMAINS -This option allows you to restrict access to Appwrite console for users sharing the same email domains. This option is very useful for team working with company emails domain. +This option allows you to limit creation of users to Appwrite console for users sharing the same email domains. This option is very useful for team working with company emails domain. To enable this option, pass a list of allowed email domains separated by a comma. ### _APP_CONSOLE_WHITELIST_IPS -This last option allows you to restrict access to Appwrite console for users sharing the same set of IP addresses. This option is very useful for team working with a VPN service or a company IP. +This last option allows you to limit creation of users in Appwrite console for users sharing the same set of IP addresses. This option is very useful for team working with a VPN service or a company IP. To enable/activate this option, pass a list of allowed IP addresses separated by a comma. @@ -130,4 +134,4 @@ This is the sender name value that will appear on email messages sent to develop ### _APP_SYSTEM_EMAIL_ADDRESS -This is the sender email address that will appear on email messages sent to developers from the Appwrite console. The default value is 'team@appwrite.io'. You should choose an email address that is allowed to be used from your SMTP server to avoid the server email ending in the users' SPAM folders. \ No newline at end of file +This is the sender email address that will appear on email messages sent to developers from the Appwrite console. The default value is 'team@appwrite.io'. You should choose an email address that is allowed to be used from your SMTP server to avoid the server email ending in the users' SPAM folders.