Merge branch 'master' of github.com:appwrite/appwrite into functions

This commit is contained in:
Eldad Fux
2020-06-13 18:18:26 +03:00
711 changed files with 10323 additions and 1889 deletions
View File
+49
View File
@@ -1,3 +1,52 @@
# Version 0.7.0 (NOT-RELEASED)
## Features
- New route in Locale API to fetch a list of languages
- Added option to force HTTPS connection to the Appwrite server (_APP_OPTIONS_FORCE_HTTPS)
- Added Google Fonts to Appwrite for offline availability
- Added a new route in the Avatars API to get user initials avatar
- Added option to delete team from the console
- Added option to view team members from the console
- Added option to join a user to any team from the console
- Added support for Brotli compression
## Bug Fixes
- Fixed output of /v1/health/queue/certificates returning wrong data
- Fixed bug where team members count was wrong in some cases
- Fixed network calculation for uploaded files
- Fixed a UI bug preventing float values in numeric fields
- Fixed scroll positioning when moving rules order up & down
- Fixed missing validation for database documents key length (32 chars)
## Security
- Access to Health API now requires authentication with an API Key with access to `health.read` scope allowed
# Version 0.6.2 (PRE-RELEASE)
## Features
- New OAuth adapter for sign-in with Apple
## 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
- Fixed a bug where single permission tag in the console was not being saved
- Added missing webhooks events in the console
- Added missing option to delete project
- Fixed a bug where the session was not set properly when the API used an IP with a non-standard port as hostname
- Fixed bug where requests number on the dashboard was hidden when the number got too long
- Permission fields are not required for file creation or update
## Security
- [low severity] Patch for email library (https://github.com/advisories/GHSA-f7hx-fqxw-rvvj)
# Version 0.6.1 (PRE-RELEASE)
## Bug Fixes
+49 -26
View File
@@ -11,28 +11,25 @@ ENV TZ=Asia/Tel_Aviv \
RUN \
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests ca-certificates software-properties-common curl git openssl && \
apt-get install -y --no-install-recommends --no-install-suggests ca-certificates software-properties-common wget git openssl && \
LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests make php$PHP_VERSION php$PHP_VERSION-dev zip unzip php$PHP_VERSION-zip && \
# Redis Extension
curl -L -o phpredis-$PHP_REDIS_VERSION.tar https://github.com/phpredis/phpredis/tarball/$PHP_REDIS_VERSION && \
mkdir phpredis-$PHP_REDIS_VERSION && tar xf phpredis-$PHP_REDIS_VERSION.tar -C phpredis-$PHP_REDIS_VERSION --strip-components 1 && \
wget -q https://github.com/phpredis/phpredis/archive/$PHP_REDIS_VERSION.tar.gz && \
tar -xf $PHP_REDIS_VERSION.tar.gz && \
cd phpredis-$PHP_REDIS_VERSION && \
phpize$PHP_VERSION && \
./configure && \
make && \
# # XHprof Extension
# git clone "https://github.com/tideways/php-xhprof-extension.git" && \
# cd php-xhprof-extension && \
# phpize$PHP_VERSION && \
# ./configure && \
# make && \
# make install && \
# ls -ll && \
# ls -ll modules && \
# Composer
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
wget https://getcomposer.org/composer.phar && \
chmod +x ./composer.phar && \
mv ./composer.phar /usr/bin/composer && \
#Brotli
cd / && \
git clone https://github.com/eustas/ngx_brotli.git && \
cd ngx_brotli && git submodule update --init && cd ..
WORKDIR /usr/local/src/
@@ -60,8 +57,10 @@ ENV TZ=Asia/Tel_Aviv \
_APP_HOME=https://appwrite.io \
_APP_EDITION=community \
_APP_OPTIONS_ABUSE=enabled \
_APP_OPTIONS_FORCE_HTTPS=disabled \
_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 \
@@ -82,35 +81,59 @@ ENV TZ=Asia/Tel_Aviv \
#ENV _APP_SMTP_PASSWORD ''
COPY --from=builder /phpredis-5.2.1/modules/redis.so /usr/lib/php/20190902/
#COPY --from=builder /phpredis-5.2.1/php-xhprof-extension/modules/tideways_xhprof.so /usr/lib/php/20190902/
COPY --from=builder /phpredis-5.2.1/modules/redis.so /usr/lib/php/20190902/
COPY --from=builder /ngx_brotli /ngx_brotli
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN \
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests curl ca-certificates software-properties-common openssl gnupg docker.io && \
apt-get install -y --no-install-recommends --no-install-suggests wget ca-certificates software-properties-common build-essential libpcre3-dev zlib1g-dev libssl-dev openssl gnupg htop supervisor docker.io && \
LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \
add-apt-repository universe && \
add-apt-repository ppa:certbot/certbot && \
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests htop supervisor php$PHP_VERSION php$PHP_VERSION-fpm \
apt-get install -y --no-install-recommends --no-install-suggests php$PHP_VERSION php$PHP_VERSION-fpm \
php$PHP_VERSION-mysqlnd php$PHP_VERSION-curl php$PHP_VERSION-imagick php$PHP_VERSION-mbstring php$PHP_VERSION-dom webp certbot && \
# Nginx
echo "deb http://nginx.org/packages/mainline/ubuntu/ bionic nginx" >> /etc/apt/sources.list.d/nginx.list && \
curl -o nginx_signing.key http://nginx.org/keys/nginx_signing.key && \
apt-key add nginx_signing.key && \
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests nginx && \
wget http://nginx.org/download/nginx-1.19.0.tar.gz && \
tar -xzvf nginx-1.19.0.tar.gz && rm nginx-1.19.0.tar.gz && \
cd nginx-1.19.0 && \
./configure --prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=www-data \
--group=www-data \
--build=Ubuntu \
--with-http_gzip_static_module \
--with-http_ssl_module \
--with-http_v2_module \
--add-module=/ngx_brotli && \
make && \
make install && \
rm -rf ../nginx-1.19.0 && \
# Redis Extension
echo extension=redis.so >> /etc/php/$PHP_VERSION/fpm/conf.d/redis.ini && \
echo extension=redis.so >> /etc/php/$PHP_VERSION/cli/conf.d/redis.ini && \
# XHProf Extension
#echo extension=tideways_xhprof.so >> /etc/php/$PHP_VERSION/fpm/conf.d/xhprof.ini && \
#echo extension=tideways_xhprof.so >> /etc/php/$PHP_VERSION/cli/conf.d/xhprof.ini && \
# XHprof Extension
# git clone "https://github.com/tideways/php-xhprof-extension.git" && \
# cd php-xhprof-extension && \
# phpize$PHP_VERSION && \
# ./configure && \
# make && \
# make install && \
# ls -ll && \
# ls -ll modules && \
# Cleanup
cd ../ && \
apt-get purge -y --auto-remove software-properties-common gnupg curl && \
apt-get purge -y --auto-remove wget software-properties-common build-essential libpcre3-dev zlib1g-dev libssl-dev gnupg && \
apt-get clean && \
rm -rf /ngx_brotli && \
rm -rf /var/lib/apt/lists/*
# Set Upload Limit (default to 100MB)
@@ -162,4 +185,4 @@ EXPOSE 80
WORKDIR /usr/share/nginx/html
CMD ["/bin/bash", "/usr/local/bin/start"]
CMD ["/bin/bash", "/usr/local/bin/start"]
+53 -29
View File
@@ -2,7 +2,7 @@
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/github-logo.png" alt="Appwrite Logo"></a>
<br />
<br />
<b>Simple Backend Server for your [Flutter / Vue / Angular / React / iOS / Android / *ANY OTHER*] Frontend App</b>
<b>A complete backend solution for your [Flutter / Vue / Angular / React / iOS / Android / *ANY OTHER*] client app</b>
<br />
<br />
</p>
@@ -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,58 +45,82 @@ 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 \
--volume "$(pwd)"/appwrite:/install/appwrite:rw \
-e version=0.6.1 \
-e version=0.6.2 \
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.2 ^
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.2 ,
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...)
### Services
* [**Account**](https://appwrite.io/docs/account) - Manage current user authentication and account. Track and manage the user sessions, devices, sign-in methods, and security logs.
* [**Users**](https://appwrite.io/docs/users) - Manage and list all project users when in admin mode.
* [**Teams**](https://appwrite.io/docs/teams) - Manage and group users in teams. Manage memberships, invites, and user roles within a team.
* [**Database**](https://appwrite.io/docs/database) - Manage database collections and documents. Read, create, update, and delete documents and filter lists of documents collections using an advanced filter with graph-like capabilities.
* [**Storage**](https://appwrite.io/docs/storage) - Manage storage files. Read, create, delete, and preview files. Manipulate the preview of your files to fit your app perfectly. All files are scanned by ClamAV and stored in a secure and encrypted way.
* [**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.
* [**Account**](https://appwrite.io/docs/client/account) - Manage current user authentication and account. Track and manage the user sessions, devices, sign-in methods, and security logs.
* [**Users**](https://appwrite.io/docs/server/users) - Manage and list all project users when in admin mode.
* [**Teams**](https://appwrite.io/docs/client/teams) - Manage and group users in teams. Manage memberships, invites, and user roles within a team.
* [**Database**](https://appwrite.io/docs/client/database) - Manage database collections and documents. Read, create, update, and delete documents and filter lists of documents collections using an advanced filter with graph-like capabilities.
* [**Storage**](https://appwrite.io/docs/client/storage) - Manage storage files. Read, create, delete, and preview files. Manipulate the preview of your files to fit your app perfectly. All files are scanned by ClamAV and stored in a secure and encrypted way.
* [**Locale**](https://appwrite.io/docs/client/locale) - Track your user's location, and manage your app locale-based data.
* [**Avatars**](https://appwrite.io/docs/client/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
+24 -9
View File
@@ -16,7 +16,7 @@ use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Event\Event;
use Appwrite\Network\Validators\Origin;
use Appwrite\Network\Validator\Origin;
/*
* Configuration files
@@ -28,6 +28,7 @@ $webhook = new Event('v1-webhooks', 'WebhooksV1');
$audit = new Event('v1-audits', 'AuditsV1');
$usage = new Event('v1-usage', 'UsageV1');
$functions = new Event('v1-functions', 'FunctionsV1');
$deletes = new Event('v1-deletes', 'DeletesV1');
/**
* Get All verified client URLs for both console and current projects
@@ -69,11 +70,12 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
$refDomain = $protocol.'://'.((in_array($origin, $clients))
? $origin : 'localhost') . (!empty($port) ? ':'.$port : '');
$selfDomain = new Domain(Config::getParam('domain'));
$selfDomain = new Domain(Config::getParam('hostname'));
$endDomain = new Domain($origin);
Config::setParam('domainVerification',
($selfDomain->getRegisterable() === $endDomain->getRegisterable()));
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
$endDomain->getRegisterable() !== '');
/*
* Security Headers
@@ -81,13 +83,21 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
* As recommended at:
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
*/
if ($request->getServer('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
if(Config::getParam('protocol') !== 'https') {
return $response->redirect('https://' . Config::getParam('domain').$request->getServer('REQUEST_URI'));
}
$response->addHeader('Strict-Transport-Security', 'max-age='.(60 * 60 * 24 * 126)); // 126 days
}
$response
->addHeader('Server', 'Appwrite')
->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url='.urlencode($request->getServer('REQUEST_URI')))
//->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')
@@ -103,6 +113,7 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
if(!$originValidator->isValid($origin)
&& in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
&& $route->getLabel('origin', false) !== '*'
&& empty($request->getHeader('X-Appwrite-Key', ''))) {
throw new Exception($originValidator->getDescription(), 403);
}
@@ -216,10 +227,10 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
;
});
$utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage, $mode, $project, $utopia) {
$utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage, $deletes, $mode, $project, $utopia) {
/*
* Trigger Events for background jobs
* Trigger events for background workers
*/
if (!empty($webhook->getParam('event'))) {
$webhook->trigger();
@@ -229,14 +240,18 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage
$audit->trigger();
}
if (!empty($deletes->getParam('document'))) {
$deletes->trigger();
}
$route = $utopia->match($request);
if($project->getId()
&& $mode !== APP_MODE_ADMIN
&& !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage and admin mode
$usage
->setParam('request', $request->getSize())
->setParam('request', $request->getSize() + $usage->getParam('storage'))
->setParam('response', $response->getSize())
->trigger()
;
@@ -248,7 +263,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')
+17 -17
View File
@@ -5,54 +5,54 @@
*/
return [
'account.create' => [
'description' => 'Triggers any time a new user register an account.',
'description' => 'This event triggers when the account is created.',
],
'account.update.email' => [
'description' => 'Triggers any time a a user updates his or her acoount email address.',
'description' => 'This event triggers when the account email address is updated.',
],
'account.update.name' => [
'description' => 'Triggers any time a a user updates his or her acoount name.',
'description' => 'This event triggers when the account name is updated.',
],
'account.update.password' => [
'description' => 'Triggers any time a a user updates his or her acoount password.',
'description' => 'This event triggers when the account password is updated.',
],
'account.update.prefs' => [
'description' => 'Triggers any time a a user updates his or her acoount preferences.',
'description' => 'This event triggers when the account preferences are updated.',
],
'account.delete' => [
'description' => 'Triggers any time a new user is deleting its account.',
'description' => 'This event triggers when the account is deleted.',
],
'account.sessions.create' => [
'description' => 'Triggers any time a user session is being created.',
'description' => 'This event triggers when the account session is created.',
],
'account.sessions.delete' => [
'description' => 'Triggers any time a user session is being deleted.',
'description' => 'This event triggers when the account session is deleted.',
],
'database.collections.create' => [
'description' => 'Triggers any time a new database collection is being created.',
'description' => 'This event triggers when a database collection is created.',
],
'database.collections.update' => [
'description' => 'Triggers any time a new database collection is being updated.',
'description' => 'This event triggers when a database collection is updated.',
],
'database.collections.delete' => [
'description' => 'Triggers any time a database collection is being deleted.',
'description' => 'This event triggers when a database collection is deleted.',
],
'database.documents.create' => [
'description' => 'Triggers any time a new database document is being created.',
'description' => 'This event triggers when a database document is created.',
],
'database.documents.patch' => [
'description' => 'Triggers any time a new database document is being updated.',
'description' => 'This event triggers when a database document is patched.',
],
'database.documents.delete' => [
'description' => 'Triggers any time a database document is being deleted.',
'description' => 'This event triggers when a database document is deleted.',
],
'storage.files.create' => [
'description' => 'Triggers any time a storage file has been created.',
'description' => 'This event triggers when a storage file is created.',
],
'storage.files.update' => [
'description' => 'Triggers any time a storage file has been updated.',
'description' => 'This event triggers when a storage file is updated.',
],
'storage.files.delete' => [
'description' => 'Triggers any time a file has been deleted.',
'description' => 'This event triggers when a storage file is deleted.',
],
];
+936
View File
@@ -0,0 +1,936 @@
<?php
/**
* List of languages classified in ISO 639-1.
*
* Source:
* https://gist.github.com/joshuabaker/d2775b5ada7d1601bcd7b31cb4081981
*/
return [
[
"code" => "aa",
"name" => "Afar",
"nativeName" => "Afar"
],
[
"code" => "ab",
"name" => "Abkhazian",
"nativeName" => "Аҧсуа"
],
[
"code" => "af",
"name" => "Afrikaans",
"nativeName" => "Afrikaans"
],
[
"code" => "ak",
"name" => "Akan",
"nativeName" => "Akana"
],
[
"code" => "am",
"name" => "Amharic",
"nativeName" => "አማርኛ"
],
[
"code" => "an",
"name" => "Aragonese",
"nativeName" => "Aragonés"
],
[
"code" => "ar",
"name" => "Arabic",
"nativeName" => "العربية"
],
[
"code" => "as",
"name" => "Assamese",
"nativeName" => "অসমীয়া"
],
[
"code" => "av",
"name" => "Avar",
"nativeName" => "Авар"
],
[
"code" => "ay",
"name" => "Aymara",
"nativeName" => "Aymar"
],
[
"code" => "az",
"name" => "Azerbaijani",
"nativeName" => "Azərbaycanca / آذربايجان"
],
[
"code" => "ba",
"name" => "Bashkir",
"nativeName" => "Башҡорт"
],
[
"code" => "be",
"name" => "Belarusian",
"nativeName" => "Беларуская"
],
[
"code" => "bg",
"name" => "Bulgarian",
"nativeName" => "Български"
],
[
"code" => "bh",
"name" => "Bihari",
"nativeName" => "भोजपुरी"
],
[
"code" => "bi",
"name" => "Bislama",
"nativeName" => "Bislama"
],
[
"code" => "bm",
"name" => "Bambara",
"nativeName" => "Bamanankan"
],
[
"code" => "bn",
"name" => "Bengali",
"nativeName" => "বাংলা"
],
[
"code" => "bo",
"name" => "Tibetan",
"nativeName" => "བོད་ཡིག / Bod skad"
],
[
"code" => "br",
"name" => "Breton",
"nativeName" => "Brezhoneg"
],
[
"code" => "bs",
"name" => "Bosnian",
"nativeName" => "Bosanski"
],
[
"code" => "ca",
"name" => "Catalan",
"nativeName" => "Català"
],
[
"code" => "ce",
"name" => "Chechen",
"nativeName" => "Нохчийн"
],
[
"code" => "ch",
"name" => "Chamorro",
"nativeName" => "Chamoru"
],
[
"code" => "co",
"name" => "Corsican",
"nativeName" => "Corsu"
],
[
"code" => "cr",
"name" => "Cree",
"nativeName" => "Nehiyaw"
],
[
"code" => "cs",
"name" => "Czech",
"nativeName" => "Česky"
],
[
"code" => "cu",
"name" => "Old Church Slavonic / Old Bulgarian",
"nativeName" => "словѣньскъ / slověnĭskŭ"
],
[
"code" => "cv",
"name" => "Chuvash",
"nativeName" => "Чăваш"
],
[
"code" => "cy",
"name" => "Welsh",
"nativeName" => "Cymraeg"
],
[
"code" => "da",
"name" => "Danish",
"nativeName" => "Dansk"
],
[
"code" => "de",
"name" => "German",
"nativeName" => "Deutsch"
],
[
"code" => "dv",
"name" => "Divehi",
"nativeName" => "ދިވެހިބަސް"
],
[
"code" => "dz",
"name" => "Dzongkha",
"nativeName" => "ཇོང་ཁ"
],
[
"code" => "ee",
"name" => "Ewe",
"nativeName" => "Ɛʋɛ"
],
[
"code" => "el",
"name" => "Greek",
"nativeName" => "Ελληνικά"
],
[
"code" => "en",
"name" => "English",
"nativeName" => "English"
],
[
"code" => "eo",
"name" => "Esperanto",
"nativeName" => "Esperanto"
],
[
"code" => "es",
"name" => "Spanish",
"nativeName" => "Español"
],
[
"code" => "et",
"name" => "Estonian",
"nativeName" => "Eesti"
],
[
"code" => "eu",
"name" => "Basque",
"nativeName" => "Euskara"
],
[
"code" => "fa",
"name" => "Persian",
"nativeName" => "فارسی"
],
[
"code" => "ff",
"name" => "Peul",
"nativeName" => "Fulfulde"
],
[
"code" => "fi",
"name" => "Finnish",
"nativeName" => "Suomi"
],
[
"code" => "fj",
"name" => "Fijian",
"nativeName" => "Na Vosa Vakaviti"
],
[
"code" => "fo",
"name" => "Faroese",
"nativeName" => "Føroyskt"
],
[
"code" => "fr",
"name" => "French",
"nativeName" => "Français"
],
[
"code" => "fy",
"name" => "West Frisian",
"nativeName" => "Frysk"
],
[
"code" => "ga",
"name" => "Irish",
"nativeName" => "Gaeilge"
],
[
"code" => "gd",
"name" => "Scottish Gaelic",
"nativeName" => "Gàidhlig"
],
[
"code" => "gl",
"name" => "Galician",
"nativeName" => "Galego"
],
[
"code" => "gn",
"name" => "Guarani",
"nativeName" => "Avañe'ẽ"
],
[
"code" => "gu",
"name" => "Gujarati",
"nativeName" => "ગુજરાતી"
],
[
"code" => "gv",
"name" => "Manx",
"nativeName" => "Gaelg"
],
[
"code" => "ha",
"name" => "Hausa",
"nativeName" => "هَوُسَ"
],
[
"code" => "he",
"name" => "Hebrew",
"nativeName" => "עברית"
],
[
"code" => "hi",
"name" => "Hindi",
"nativeName" => "हिन्दी"
],
[
"code" => "ho",
"name" => "Hiri Motu",
"nativeName" => "Hiri Motu"
],
[
"code" => "hr",
"name" => "Croatian",
"nativeName" => "Hrvatski"
],
[
"code" => "ht",
"name" => "Haitian",
"nativeName" => "Krèyol ayisyen"
],
[
"code" => "hu",
"name" => "Hungarian",
"nativeName" => "Magyar"
],
[
"code" => "hy",
"name" => "Armenian",
"nativeName" => "Հայերեն"
],
[
"code" => "hz",
"name" => "Herero",
"nativeName" => "Otsiherero"
],
[
"code" => "ia",
"name" => "Interlingua",
"nativeName" => "Interlingua"
],
[
"code" => "id",
"name" => "Indonesian",
"nativeName" => "Bahasa Indonesia"
],
[
"code" => "ie",
"name" => "Interlingue",
"nativeName" => "Interlingue"
],
[
"code" => "ig",
"name" => "Igbo",
"nativeName" => "Igbo"
],
[
"code" => "ii",
"name" => "Sichuan Yi",
"nativeName" => "ꆇꉙ / 四川彝语"
],
[
"code" => "ik",
"name" => "Inupiak",
"nativeName" => "Iñupiak"
],
[
"code" => "io",
"name" => "Ido",
"nativeName" => "Ido"
],
[
"code" => "is",
"name" => "Icelandic",
"nativeName" => "Íslenska"
],
[
"code" => "it",
"name" => "Italian",
"nativeName" => "Italiano"
],
[
"code" => "iu",
"name" => "Inuktitut",
"nativeName" => "ᐃᓄᒃᑎᑐᑦ"
],
[
"code" => "ja",
"name" => "Japanese",
"nativeName" => "日本語"
],
[
"code" => "jv",
"name" => "Javanese",
"nativeName" => "Basa Jawa"
],
[
"code" => "ka",
"name" => "Georgian",
"nativeName" => "ქართული"
],
[
"code" => "kg",
"name" => "Kongo",
"nativeName" => "KiKongo"
],
[
"code" => "ki",
"name" => "Kikuyu",
"nativeName" => "Gĩkũyũ"
],
[
"code" => "kj",
"name" => "Kuanyama",
"nativeName" => "Kuanyama"
],
[
"code" => "kk",
"name" => "Kazakh",
"nativeName" => "Қазақша"
],
[
"code" => "kl",
"name" => "Greenlandic",
"nativeName" => "Kalaallisut"
],
[
"code" => "km",
"name" => "Cambodian",
"nativeName" => "ភាសាខ្មែរ"
],
[
"code" => "kn",
"name" => "Kannada",
"nativeName" => "ಕನ್ನಡ"
],
[
"code" => "ko",
"name" => "Korean",
"nativeName" => "한국어"
],
[
"code" => "kr",
"name" => "Kanuri",
"nativeName" => "Kanuri"
],
[
"code" => "ks",
"name" => "Kashmiri",
"nativeName" => "कश्मीरी / كشميري"
],
[
"code" => "ku",
"name" => "Kurdish",
"nativeName" => "Kurdî / كوردی"
],
[
"code" => "kv",
"name" => "Komi",
"nativeName" => "Коми"
],
[
"code" => "kw",
"name" => "Cornish",
"nativeName" => "Kernewek"
],
[
"code" => "ky",
"name" => "Kirghiz",
"nativeName" => "Kırgızca / Кыргызча"
],
[
"code" => "la",
"name" => "Latin",
"nativeName" => "Latina"
],
[
"code" => "lb",
"name" => "Luxembourgish",
"nativeName" => "Lëtzebuergesch"
],
[
"code" => "lg",
"name" => "Ganda",
"nativeName" => "Luganda"
],
[
"code" => "li",
"name" => "Limburgian",
"nativeName" => "Limburgs"
],
[
"code" => "ln",
"name" => "Lingala",
"nativeName" => "Lingála"
],
[
"code" => "lo",
"name" => "Laotian",
"nativeName" => "ລາວ / Pha xa lao"
],
[
"code" => "lt",
"name" => "Lithuanian",
"nativeName" => "Lietuvių"
],
[
"code" => "lu",
"name" => "Luba-Katanga",
"nativeName" => "Tshiluba"
],
[
"code" => "lv",
"name" => "Latvian",
"nativeName" => "Latviešu"
],
[
"code" => "mg",
"name" => "Malagasy",
"nativeName" => "Malagasy"
],
[
"code" => "mh",
"name" => "Marshallese",
"nativeName" => "Kajin Majel / Ebon"
],
[
"code" => "mi",
"name" => "Maori",
"nativeName" => "Māori"
],
[
"code" => "mk",
"name" => "Macedonian",
"nativeName" => "Македонски"
],
[
"code" => "ml",
"name" => "Malayalam",
"nativeName" => "മലയാളം"
],
[
"code" => "mn",
"name" => "Mongolian",
"nativeName" => "Монгол"
],
[
"code" => "mo",
"name" => "Moldovan",
"nativeName" => "Moldovenească"
],
[
"code" => "mr",
"name" => "Marathi",
"nativeName" => "मराठी"
],
[
"code" => "ms",
"name" => "Malay",
"nativeName" => "Bahasa Melayu"
],
[
"code" => "mt",
"name" => "Maltese",
"nativeName" => "bil-Malti"
],
[
"code" => "my",
"name" => "Burmese",
"nativeName" => "မြန်မာစာ"
],
[
"code" => "na",
"name" => "Nauruan",
"nativeName" => "Dorerin Naoero"
],
[
"code" => "nb",
"name" => "Norwegian Bokmål",
"nativeName" => "Norsk bokmål"
],
[
"code" => "nd",
"name" => "North Ndebele",
"nativeName" => "Sindebele"
],
[
"code" => "ne",
"name" => "Nepali",
"nativeName" => "नेपाली"
],
[
"code" => "ng",
"name" => "Ndonga",
"nativeName" => "Oshiwambo"
],
[
"code" => "nl",
"name" => "Dutch",
"nativeName" => "Nederlands"
],
[
"code" => "nn",
"name" => "Norwegian Nynorsk",
"nativeName" => "Norsk nynorsk"
],
[
"code" => "no",
"name" => "Norwegian",
"nativeName" => "Norsk"
],
[
"code" => "nr",
"name" => "South Ndebele",
"nativeName" => "isiNdebele"
],
[
"code" => "nv",
"name" => "Navajo",
"nativeName" => "Diné bizaad"
],
[
"code" => "ny",
"name" => "Chichewa",
"nativeName" => "Chi-Chewa"
],
[
"code" => "oc",
"name" => "Occitan",
"nativeName" => "Occitan"
],
[
"code" => "oj",
"name" => "Ojibwa",
"nativeName" => "ᐊᓂᔑᓈᐯᒧᐎᓐ / Anishinaabemowin"
],
[
"code" => "om",
"name" => "Oromo",
"nativeName" => "Oromoo"
],
[
"code" => "or",
"name" => "Oriya",
"nativeName" => "ଓଡ଼ିଆ"
],
[
"code" => "os",
"name" => "Ossetian / Ossetic",
"nativeName" => "Иронау"
],
[
"code" => "pa",
"name" => "Panjabi / Punjabi",
"nativeName" => "ਪੰਜਾਬੀ / पंजाबी / پنجابي"
],
[
"code" => "pi",
"name" => "Pali",
"nativeName" => "Pāli / पाऴि"
],
[
"code" => "pl",
"name" => "Polish",
"nativeName" => "Polski"
],
[
"code" => "ps",
"name" => "Pashto",
"nativeName" => "پښتو"
],
[
"code" => "pt",
"name" => "Portuguese",
"nativeName" => "Português"
],
[
"code" => "qu",
"name" => "Quechua",
"nativeName" => "Runa Simi"
],
[
"code" => "rm",
"name" => "Raeto Romance",
"nativeName" => "Rumantsch"
],
[
"code" => "rn",
"name" => "Kirundi",
"nativeName" => "Kirundi"
],
[
"code" => "ro",
"name" => "Romanian",
"nativeName" => "Română"
],
[
"code" => "ru",
"name" => "Russian",
"nativeName" => "Русский"
],
[
"code" => "rw",
"name" => "Rwandi",
"nativeName" => "Kinyarwandi"
],
[
"code" => "sa",
"name" => "Sanskrit",
"nativeName" => "संस्कृतम्"
],
[
"code" => "sc",
"name" => "Sardinian",
"nativeName" => "Sardu"
],
[
"code" => "sd",
"name" => "Sindhi",
"nativeName" => "सिनधि"
],
[
"code" => "se",
"name" => "Northern Sami",
"nativeName" => "Sámegiella"
],
[
"code" => "sg",
"name" => "Sango",
"nativeName" => "Sängö"
],
[
"code" => "sh",
"name" => "Serbo-Croatian",
"nativeName" => "Srpskohrvatski / Српскохрватски"
],
[
"code" => "si",
"name" => "Sinhalese",
"nativeName" => "සිංහල"
],
[
"code" => "sk",
"name" => "Slovak",
"nativeName" => "Slovenčina"
],
[
"code" => "sl",
"name" => "Slovenian",
"nativeName" => "Slovenščina"
],
[
"code" => "sm",
"name" => "Samoan",
"nativeName" => "Gagana Samoa"
],
[
"code" => "sn",
"name" => "Shona",
"nativeName" => "chiShona"
],
[
"code" => "so",
"name" => "Somalia",
"nativeName" => "Soomaaliga"
],
[
"code" => "sq",
"name" => "Albanian",
"nativeName" => "Shqip"
],
[
"code" => "sr",
"name" => "Serbian",
"nativeName" => "Српски"
],
[
"code" => "ss",
"name" => "Swati",
"nativeName" => "SiSwati"
],
[
"code" => "st",
"name" => "Southern Sotho",
"nativeName" => "Sesotho"
],
[
"code" => "su",
"name" => "Sundanese",
"nativeName" => "Basa Sunda"
],
[
"code" => "sv",
"name" => "Swedish",
"nativeName" => "Svenska"
],
[
"code" => "sw",
"name" => "Swahili",
"nativeName" => "Kiswahili"
],
[
"code" => "ta",
"name" => "Tamil",
"nativeName" => "தமிழ்"
],
[
"code" => "te",
"name" => "Telugu",
"nativeName" => "తెలుగు"
],
[
"code" => "tg",
"name" => "Tajik",
"nativeName" => "Тоҷикӣ"
],
[
"code" => "th",
"name" => "Thai",
"nativeName" => "ไทย / Phasa Thai"
],
[
"code" => "ti",
"name" => "Tigrinya",
"nativeName" => "ትግርኛ"
],
[
"code" => "tk",
"name" => "Turkmen",
"nativeName" => "Туркмен / تركمن"
],
[
"code" => "tl",
"name" => "Tagalog / Filipino",
"nativeName" => "Tagalog"
],
[
"code" => "tn",
"name" => "Tswana",
"nativeName" => "Setswana"
],
[
"code" => "to",
"name" => "Tonga",
"nativeName" => "Lea Faka-Tonga"
],
[
"code" => "tr",
"name" => "Turkish",
"nativeName" => "Türkçe"
],
[
"code" => "ts",
"name" => "Tsonga",
"nativeName" => "Xitsonga"
],
[
"code" => "tt",
"name" => "Tatar",
"nativeName" => "Tatarça"
],
[
"code" => "tw",
"name" => "Twi",
"nativeName" => "Twi"
],
[
"code" => "ty",
"name" => "Tahitian",
"nativeName" => "Reo Mā`ohi"
],
[
"code" => "ug",
"name" => "Uyghur",
"nativeName" => "Uyƣurqə / ئۇيغۇرچە"
],
[
"code" => "uk",
"name" => "Ukrainian",
"nativeName" => "Українська"
],
[
"code" => "ur",
"name" => "Urdu",
"nativeName" => "اردو"
],
[
"code" => "uz",
"name" => "Uzbek",
"nativeName" => "Ўзбек"
],
[
"code" => "ve",
"name" => "Venda",
"nativeName" => "Tshivenḓa"
],
[
"code" => "vi",
"name" => "Vietnamese",
"nativeName" => "Tiếng Việt"
],
[
"code" => "vo",
"name" => "Volapük",
"nativeName" => "Volapük"
],
[
"code" => "wa",
"name" => "Walloon",
"nativeName" => "Walon"
],
[
"code" => "wo",
"name" => "Wolof",
"nativeName" => "Wollof"
],
[
"code" => "xh",
"name" => "Xhosa",
"nativeName" => "isiXhosa"
],
[
"code" => "yi",
"name" => "Yiddish",
"nativeName" => "ייִדיש"
],
[
"code" => "yo",
"name" => "Yoruba",
"nativeName" => "Yorùbá"
],
[
"code" => "za",
"name" => "Zhuang",
"nativeName" => "Cuengh / Tôô / 壮语"
],
[
"code" => "zh",
"name" => "Chinese",
"nativeName" => "中文"
],
[
"code" => "zu",
"name" => "Zulu",
"nativeName" => "isiZulu"
]
];
+16 -2
View File
@@ -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,
@@ -139,6 +139,20 @@ return [
'gitRepoName' => 'sdk-for-node',
'gitUserName' => 'appwrite',
],
[
'key' => 'deno',
'name' => 'Deno',
'version' => '0.0.1',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'enabled' => false,
'beta' => true,
'family' => APP_PLATFORM_SERVER,
'prism' => 'typescript',
'source' => realpath(__DIR__ . '/../sdks/server-deno'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-deno.git',
'gitRepoName' => 'sdk-for-deno',
'gitUserName' => 'appwrite',
],
[
'key' => 'php',
'name' => 'PHP',
@@ -170,7 +184,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '1.0.10',
'version' => '1.0.11',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'enabled' => true,
'beta' => true,
+133 -95
View File
@@ -1,149 +1,187 @@
<?php
return [
return [ // Ordered by ABC.
'amazon' => [
'developers' => 'https://developer.amazon.com/apps-and-games/services-and-apis',
'icon' => 'icon-amazon',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'apple' => [
'developers' => 'https://developer.apple.com/',
'icon' => 'icon-apple',
'enabled' => true,
'form' => 'apple.phtml', // Perperation for adding ability to customized OAuth UI forms, currently handled hardcoded.
'beta' => true,
'mock' => false,
],
'bitbucket' => [
'developers' => 'https://developer.atlassian.com/bitbucket',
'icon' => 'icon-bitbucket',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'facebook' => [
'developers' => 'https://developers.facebook.com/',
'icon' => 'icon-facebook',
'bitly' => [
'developers' => 'https://dev.bitly.com/v4_documentation.html',
'icon' => 'icon-bitly',
'enabled' => true,
'mock' => false,
'form' => false,
'beta' => false,
'mock' => false
],
'github' => [
'developers' => 'https://developer.github.com/',
'icon' => 'icon-github-circled',
'enabled' => true,
'mock' => false,
],
'gitlab' => [
'developers' => 'https://docs.gitlab.com/ee/api/',
'icon' => 'icon-gitlab',
'enabled' => true,
'mock' => false,
],
'google' => [
'developers' => 'https://developers.google.com/',
'icon' => 'icon-google',
'enabled' => true,
'mock' => false,
],
// 'instagram' => [
// 'developers' => 'https://www.instagram.com/developer/',
// 'icon' => 'icon-instagram',
// 'enabled' => false,
// 'mock' => false,
// ],
'microsoft' => [
'developers' => 'https://developer.microsoft.com/en-us/',
'icon' => 'icon-windows',
'enabled' => true,
'mock' => false,
],
// 'twitter' => [
// 'developers' => 'https://developer.twitter.com/',
// 'icon' => 'icon-twitter',
// 'enabled' => false,
// 'mock' => false,
// ],
'linkedin' => [
'developers' => 'https://developer.linkedin.com/',
'icon' => 'icon-linkedin',
'enabled' => true,
'mock' => false,
],
'slack' => [
'developers' => 'https://api.slack.com/',
'icon' => 'icon-slack',
'discord' => [
'developers' => 'https://discordapp.com/developers/docs/topics/oauth2',
'icon' => 'icon-discord',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'dropbox' => [
'developers' => 'https://www.dropbox.com/developers/documentation',
'icon' => 'icon-dropbox',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'facebook' => [
'developers' => 'https://developers.facebook.com/',
'icon' => 'icon-facebook',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'github' => [
'developers' => 'https://developer.github.com/',
'icon' => 'icon-github-circled',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'gitlab' => [
'developers' => 'https://docs.gitlab.com/ee/api/',
'icon' => 'icon-gitlab',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'google' => [
'developers' => 'https://developers.google.com/',
'icon' => 'icon-google',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'linkedin' => [
'developers' => 'https://developer.linkedin.com/',
'icon' => 'icon-linkedin',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'microsoft' => [
'developers' => 'https://developer.microsoft.com/en-us/',
'icon' => 'icon-windows',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'paypal' => [
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false
],
'salesforce' => [
'developers' => 'https://developer.salesforce.com/docs/',
'icon' => 'icon-salesforce',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
// 'apple' => [
// 'developers' => 'https://developer.apple.com/',
// 'icon' => 'icon-apple',
// 'enabled' => false,
// 'mock' => false,
// ],
'amazon' => [
'developers' => 'https://developer.amazon.com/apps-and-games/services-and-apis',
'icon' => 'icon-amazon',
'enabled' => true,
'mock' => false,
],
'vk' => [
'developers' => 'https://vk.com/dev',
'icon' => 'icon-vk',
'enabled' => true,
'mock' => false,
],
'discord' => [
'developers' => 'https://discordapp.com/developers/docs/topics/oauth2',
'icon' => 'icon-discord',
'enabled' => true,
'mock' => false,
],
'twitch' => [
'developers' => 'https://dev.twitch.tv/docs/authentication',
'icon' => 'icon-twitch',
'slack' => [
'developers' => 'https://api.slack.com/',
'icon' => 'icon-slack',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'spotify' => [
'developers' => 'https://developer.spotify.com/documentation/general/guides/authorization-guide/',
'icon' => 'icon-spotify',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'twitch' => [
'developers' => 'https://dev.twitch.tv/docs/authentication',
'icon' => 'icon-twitch',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'vk' => [
'developers' => 'https://vk.com/dev',
'icon' => 'icon-vk',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'yahoo' => [
'developers' => 'https://developer.yahoo.com/oauth2/guide/flows_authcode/',
'icon' => 'icon-yahoo',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'yandex' => [
'developers' => 'https://tech.yandex.com/oauth/',
'icon' => 'icon-yandex',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false,
],
'twitter' => [
'developers' => 'https://developer.twitter.com/',
'icon' => 'icon-twitter',
'enabled' => false,
'mock' => false
],
'paypal' => [
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
'mock' => false
],
'bitly' => [
'developers' => 'https://dev.bitly.com/v4_documentation.html',
'icon' => 'icon-bitly',
'enabled' => true,
'mock' => false
],
// 'instagram' => [
// 'developers' => 'https://www.instagram.com/developer/',
// 'icon' => 'icon-instagram',
// 'enabled' => false,
// 'beta' => false,
// 'mock' => false,
// ],
// 'twitter' => [
// 'developers' => 'https://developer.twitter.com/',
// 'icon' => 'icon-twitter',
// 'enabled' => false,
// 'beta' => false,
// 'mock' => false,
// ],
// Keep Last
'mock' => [
'developers' => 'https://appwrite.io',
'icon' => 'icon-appwrite',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => true,
]
];
+1 -2
View File
@@ -24,7 +24,6 @@ $logged = [
'projects.write',
'locale.read',
'avatars.read',
'health.read',
];
$admins = [
@@ -60,10 +59,10 @@ return [
'public',
'home',
'console',
'documents.read',
'files.read',
'locale.read',
'avatars.read',
'health.read',
],
],
ROLE_MEMBER => [
+35 -11
View File
@@ -57,7 +57,7 @@ $utopia->post('/v1/account')
->label('sdk.description', '/docs/references/account/create.md')
->label('abuse-limit', 10)
->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password.')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->param('name', '', function () { return new Text(100); }, 'User name.', true)
->action(
function ($email, $password, $name) use ($register, $request, $response, $audit, $projectDB, $project, $webhook, $oauth2Keys) {
@@ -158,7 +158,7 @@ $utopia->post('/v1/account/sessions')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password.')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->action(
function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook) {
$protocol = Config::getParam('protocol');
@@ -251,8 +251,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->param('provider', '', function () { return new WhiteList(array_keys(Config::getParam('providers'))); }, 'OAuth2 Provider. Currently, supported providers are: ' . implode(', ', array_keys(array_filter(Config::getParam('providers'), function($node) {return (!$node['mock']);}))).'.')
->param('success', $oauthDefaultSuccess, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt.', true)
->param('failure', $oauthDefaultFailure, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt.', true)
->param('success', $oauthDefaultSuccess, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true)
->param('failure', $oauthDefaultFailure, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true)
->action(
function ($provider, $success, $failure) use ($response, $request, $project) {
$protocol = Config::getParam('protocol');
@@ -308,6 +308,29 @@ $utopia->get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
}
);
$utopia->post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->desc('OAuth2 Callback')
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('scope', 'public')
->label('origin', '*')
->label('docs', false)
->param('projectId', '', function () { return new Text(1024); }, 'Project unique ID.')
->param('provider', '', function () { return new WhiteList(array_keys(Config::getParam('providers'))); }, 'OAuth2 provider.')
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
->param('state', '', function () { return new Text(2048); }, 'Login state params.', true)
->action(
function ($projectId, $provider, $code, $state) use ($response) {
$domain = Config::getParam('domain');
$protocol = Config::getParam('protocol');
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
->redirect($protocol.'://'.$domain.'/v1/account/sessions/oauth2/'.$provider.'/redirect?'
.http_build_query(['project' => $projectId, 'code' => $code, 'state' => $state]));
}
);
$utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->desc('OAuth2 Redirect')
->label('error', __DIR__.'/../../views/general/error.phtml')
@@ -361,6 +384,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
if (!empty($state['failure']) && !$validateURL->isValid($state['failure'])) {
throw new Exception('Invalid redirect URL for failure login', 400);
}
$state['failure'] = null;
$accessToken = $oauth2->getAccessToken($code);
@@ -721,8 +745,8 @@ $utopia->patch('/v1/account/password')
->label('sdk.namespace', 'account')
->label('sdk.method', 'updatePassword')
->label('sdk.description', '/docs/references/account/update-password.md')
->param('password', '', function () { return new Password(); }, 'New user password.')
->param('oldPassword', '', function () { return new Password(); }, 'Old user password.')
->param('password', '', function () { return new Password(); }, 'New user password. Must be between 6 to 32 chars.')
->param('oldPassword', '', function () { return new Password(); }, 'Old user password. Must be between 6 to 32 chars.')
->action(
function ($password, $oldPassword) use ($response, $user, $projectDB, $audit, $oauth2Keys) {
if (!Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
@@ -764,7 +788,7 @@ $utopia->patch('/v1/account/email')
->label('sdk.method', 'updateEmail')
->label('sdk.description', '/docs/references/account/update-email.md')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password.')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->action(
function ($email, $password) use ($response, $user, $projectDB, $audit, $oauth2Keys) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
@@ -1027,7 +1051,7 @@ $utopia->post('/v1/account/recovery')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email.')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.')
->action(
function ($email, $url) use ($request, $response, $projectDB, $register, $audit, $project) {
$profile = $projectDB->getCollection([ // Get user by email address
@@ -1120,8 +1144,8 @@ $utopia->put('/v1/account/recovery')
->label('abuse-key', 'url:{url},userId:{param-userId}')
->param('userId', '', function () { return new UID(); }, 'User account UID address.')
->param('secret', '', function () { return new Text(256); }, 'Valid reset token.')
->param('password', '', function () { return new Password(); }, 'New password.')
->param('passwordAgain', '', function () {return new Password(); }, 'New password again.')
->param('password', '', function () { return new Password(); }, 'New password. Must be between 6 to 32 chars.')
->param('passwordAgain', '', function () {return new Password(); }, 'New password again. Must be between 6 to 32 chars.')
->action(
function ($userId, $secret, $password, $passwordAgain) use ($response, $projectDB, $audit) {
if ($password !== $passwordAgain) {
@@ -1188,7 +1212,7 @@ $utopia->post('/v1/account/verification')
->label('sdk.description', '/docs/references/account/create-verification.md')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the verification email.') // TODO add built-in confirm page
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add built-in confirm page
->action(
function ($url) use ($request, $response, $register, $user, $project, $projectDB, $audit) {
$verificationSecret = Auth::tokenGenerator();
+79 -1
View File
@@ -16,6 +16,7 @@ use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;
use Utopia\Config\Config;
use Utopia\Validator\HexColor;
include_once __DIR__ . '/../shared/api.php';
@@ -114,6 +115,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);
});
@@ -384,7 +386,83 @@ $utopia->get('/v1/avatars/qr')
$response
->addHeader('Expires', date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
->setContentType('image/png')
->send('', $writer->writeString($text))
->send($writer->writeString($text))
;
}
);
$utopia->get('/v1/avatars/initials')
->desc('Get User Initials')
->param('name', '', function () { return new Text(512); }, 'Full Name. When empty, current user name or email will be used.', true)
->param('width', 500, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 500, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('color', '', function () { return new HexColor(); }, 'Changes text color. By default a random color will be picked and stay will persistent to the given name.', true)
->param('background', '', function () { return new HexColor(); }, 'Changes background color. By default a random color will be picked and stay will persistent to the given name.', true)
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getInitials')
->label('sdk.methodType', 'location')
->label('sdk.description', '/docs/references/avatars/get-initials.md')
->action(
function ($name, $width, $height, $color, $background) use ($response, $user) {
$themes = [
['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET
['color' => '#5e2700', 'background' => '#f3d9c6'], // ORANGE
['color' => '#006128', 'background' => '#c9f3c6'], // GREEN
['color' => '#580061', 'background' => '#f2d1f5'], // FUSCHIA
['color' => '#00365d', 'background' => '#c6e1f3'], // BLUE
['color' => '#00075c', 'background' => '#d2d5f6'], // INDIGO
['color' => '#610038', 'background' => '#f5d1e6'], // PINK
['color' => '#386100', 'background' => '#dcf1bd'], // LIME
['color' => '#615800', 'background' => '#f1ecba'], // YELLOW
['color' => '#610008', 'background' => '#f6d2d5'] // RED
];
$rand = rand(0, count($themes)-1);
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
$words = explode(' ', strtoupper($name));
$initials = null;
$code = 0;
foreach ($words as $key => $w) {
$initials .= (isset($w[0])) ? $w[0] : '';
$code += (isset($w[0])) ? ord($w[0]) : 0;
if($key == 1) {
break;
}
}
$length = count($words);
$rand = substr($code,-1);
$background = (!empty($background)) ? '#'.$background : $themes[$rand]['background'];
$color = (!empty($color)) ? '#'.$color : $themes[$rand]['color'];
$image = new \Imagick();
$draw = new \ImagickDraw();
$fontSize = min($width, $height) / 2;
$draw->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
$image->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
$draw->setFillColor(new \ImagickPixel($color));
$draw->setFontSize($fontSize);
$draw->setTextAlignment(\Imagick::ALIGN_CENTER);
$draw->annotation($width / 1.97, ($height / 2) + ($fontSize / 3), $initials);
$image->newImage($width, $height, $background);
$image->setImageFormat("png");
$image->drawImage($draw);
//$image->setImageCompressionQuality(9 - round(($quality / 100) * 9));
$response
->addHeader('Expires', date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
->setContentType('image/png')
->send($image->getImageBlob())
;
}
);
+7 -3
View File
@@ -3,7 +3,7 @@
global $utopia, $request, $response, $register, $project;
use Utopia\Exception;
use Appwrite\Storage\Devices\Local;
use Appwrite\Storage\Device\Local;
use Appwrite\Storage\Storage;
use Appwrite\ClamAV\Network;
@@ -158,7 +158,7 @@ $utopia->get('/v1/health/queue/certificates')
->label('sdk.description', '/docs/references/health/get-queue-certificates.md')
->action(
function () use ($response) {
$response->json(['size' => Resque::size('v1-usage')]);
$response->json(['size' => Resque::size('v1-certificates')]);
}
);
@@ -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([
+16
View File
@@ -165,3 +165,19 @@ $utopia->get('/v1/locale/currencies')
$response->json($currencies);
}
);
$utopia->get('/v1/locale/languages')
->desc('List Languages')
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getLanguages')
->label('sdk.description', '/docs/references/locale/get-languages.md')
->action(
function () use ($response) {
$languages = include __DIR__.'/../../config/languages.php';
$response->json($languages);
}
);
+21 -16
View File
@@ -1,6 +1,6 @@
<?php
global $utopia, $request, $response, $register, $user, $consoleDB, $projectDB;
global $utopia, $request, $response, $register, $user, $consoleDB, $projectDB, $deletes;
use Utopia\Exception;
use Utopia\Response;
@@ -18,7 +18,7 @@ use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\UID;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\Network\Validators\CNAME;
use Appwrite\Network\Validator\CNAME;
use Cron\CronExpression;
include_once __DIR__ . '/../shared/api.php';
@@ -361,7 +361,7 @@ $utopia->patch('/v1/projects/:projectId/oauth2')
->param('projectId', '', function () { return new UID(); }, 'Project unique ID.')
->param('provider', '', function () { return new WhiteList(array_keys(Config::getParam('providers'))); }, 'Provider Name', false)
->param('appId', '', function () { return new Text(256); }, 'Provider app ID.', true)
->param('secret', '', function () { return new text(256); }, 'Provider secret key.', true)
->param('secret', '', function () { return new text(512); }, 'Provider secret key.', true)
->action(
function ($projectId, $provider, $appId, $secret) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
@@ -400,9 +400,9 @@ $utopia->delete('/v1/projects/:projectId')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'delete')
->param('projectId', '', function () { return new UID(); }, 'Project unique ID.')
->param('password', '', function () { return new UID(); }, 'Your user password for confirmation.')
->param('password', '', function () { return new UID(); }, 'Your user password for confirmation. Must be between 6 to 32 chars.')
->action(
function ($projectId, $password) use ($response, $consoleDB, $user) {
function ($projectId, $password) use ($response, $consoleDB, $user, $deletes) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401);
}
@@ -413,20 +413,26 @@ $utopia->delete('/v1/projects/:projectId')
throw new Exception('Project not found', 404);
}
// Delete all children (keys, webhooks, tasks [stop tasks?], platforms)
$deletes->setParam('document', $project->getArrayCopy());
foreach(['keys', 'webhooks', 'tasks', 'platforms', 'domains'] as $key) { // Delete all children (keys, webhooks, tasks [stop tasks?], platforms)
$list = $project->getAttribute('webhooks', []);
foreach ($list as $document) { /* @var $document Document */
if (!$consoleDB->deleteDocument($projectId)) {
throw new Exception('Failed to remove project document ('.$key.')] from DB', 500);
}
}
}
if (!$consoleDB->deleteDocument($project->getAttribute('teamId', null))) {
throw new Exception('Failed to remove project team from DB', 500);
}
if (!$consoleDB->deleteDocument($projectId)) {
throw new Exception('Failed to remove project from DB', 500);
}
// Delete all DBs
// $consoleDB->deleteNamespace($project->getId());
// Optimize DB?
// Delete all storage files
// Delete all storage cache
$response->noContent();
}
);
@@ -1229,9 +1235,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);
+52 -50
View File
@@ -15,10 +15,10 @@ use Appwrite\ClamAV\Network;
use Appwrite\Database\Database;
use Appwrite\Database\Validator\UID;
use Appwrite\Storage\Storage;
use Appwrite\Storage\Devices\Local;
use Appwrite\Storage\Validators\File;
use Appwrite\Storage\Validators\FileSize;
use Appwrite\Storage\Validators\Upload;
use Appwrite\Storage\Device\Local;
use Appwrite\Storage\Validator\File;
use Appwrite\Storage\Validator\FileSize;
use Appwrite\Storage\Validator\Upload;
use Appwrite\Storage\Compression\Algorithms\GZIP;
use Appwrite\Resize\Resize;
use Appwrite\OpenSSL\OpenSSL;
@@ -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()));
// }
// );
+32 -20
View File
@@ -213,9 +213,9 @@ $utopia->post('/v1/teams/:teamId/memberships')
->param('email', '', function () { return new Email(); }, 'New team member email.')
->param('name', '', function () { return new Text(100); }, 'New team member name.', true)
->param('roles', [], function () { return new ArrayList(new Text(128)); }, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions).')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email.') // TODO add our own built-in confirm page
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add our own built-in confirm page
->action(
function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB) {
function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB, $mode) {
$name = (empty($name)) ? $email : $name;
$team = $projectDB->getDocument($teamId);
@@ -285,7 +285,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
}
}
if (!$isOwner) {
if (!$isOwner && (APP_MODE_ADMIN !== $mode)) {
throw new Exception('User is not allowed to send invitations for this team', 401);
}
@@ -302,11 +302,18 @@ $utopia->post('/v1/teams/:teamId/memberships')
'roles' => $roles,
'invited' => time(),
'joined' => 0,
'confirm' => false,
'confirm' => (APP_MODE_ADMIN === $mode),
'secret' => Auth::hash($secret),
]);
$membership = $projectDB->createDocument($membership->getArrayCopy());
if(APP_MODE_ADMIN === $mode) { // Allow admin to create membership
Authorization::disable();
$membership = $projectDB->createDocument($membership->getArrayCopy());
Authorization::reset();
}
else {
$membership = $projectDB->createDocument($membership->getArrayCopy());
}
if (false === $membership) {
throw new Exception('Failed saving membership to DB', 500);
@@ -334,7 +341,9 @@ $utopia->post('/v1/teams/:teamId/memberships')
$mail->AltBody = strip_tags($body->render());
try {
$mail->send();
if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
$mail->send();
}
} catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
@@ -371,8 +380,12 @@ $utopia->get('/v1/teams/:teamId/memberships')
->label('sdk.method', 'getMemberships')
->label('sdk.description', '/docs/references/teams/get-team-members.md')
->param('teamId', '', function () { return new UID(); }, 'Team unique ID.')
->param('search', '', function () { return new Text(256); }, 'Search term to filter your list results.', true)
->param('limit', 25, function () { return new Range(0, 100); }, 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, function () { return new Range(0, 2000); }, 'Results offset. The default value is 0. Use this param to manage pagination.', true)
->param('orderType', 'ASC', function () { return new WhiteList(['ASC', 'DESC']); }, 'Order result by ASC or DESC order.', true)
->action(
function ($teamId) use ($response, $projectDB) {
function ($teamId, $search, $limit, $offset, $orderType) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId);
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
@@ -380,8 +393,12 @@ $utopia->get('/v1/teams/:teamId/memberships')
}
$memberships = $projectDB->getCollection([
'limit' => 50,
'offset' => 0,
'limit' => $limit,
'offset' => $offset,
'orderField' => 'joined',
'orderType' => $orderType,
'orderCast' => 'int',
'search' => $search,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'teamId='.$teamId,
@@ -408,15 +425,8 @@ $utopia->get('/v1/teams/:teamId/memberships')
]));
}
usort($users, function ($a, $b) {
if ($a['joined'] === 0 || $b['joined'] === 0) {
return $b['joined'] - $a['joined'];
}
$response->json(['sum' => $projectDB->getSum(), 'memberships' => $users]);
return $a['joined'] - $b['joined'];
});
$response->json($users);
}
);
@@ -583,9 +593,11 @@ $utopia->delete('/v1/teams/:teamId/memberships/:inviteId')
throw new Exception('Failed to remove membership from DB', 500);
}
$team = $projectDB->updateDocument(array_merge($team->getArrayCopy(), [
'sum' => $team->getAttribute('sum', 0) - 1,
]));
if ($membership->getAttribute('confirm')) { // Count only confirmed members
$team = $projectDB->updateDocument(array_merge($team->getArrayCopy(), [
'sum' => $team->getAttribute('sum', 0) - 1,
]));
}
if (false === $team) {
throw new Exception('Failed saving team to DB', 500);
+1 -1
View File
@@ -31,7 +31,7 @@ $utopia->post('/v1/users')
->label('sdk.method', 'create')
->label('sdk.description', '/docs/references/users/create-user.md')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password.')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->param('name', '', function () { return new Text(100); }, 'User name.', true)
->action(
function ($email, $password, $name) use ($response, $projectDB) {
+1 -1
View File
@@ -7,7 +7,7 @@ use Utopia\Validator\Text;
use Utopia\Validator\ArrayList;
use Utopia\Response;
use Utopia\Validator\Host;
use Appwrite\Storage\Validators\File;
use Appwrite\Storage\Validator\File;
$result = [];
+1 -1
View File
@@ -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'));
+24 -4
View File
@@ -137,7 +137,7 @@ $utopia->get('/console/webhooks')
$page
->setParam('events', Config::getParam('events', []))
;
$layout
->setParam('title', APP_NAME.' - Webhooks')
->setParam('body', $page);
@@ -187,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();
@@ -201,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')
@@ -281,6 +289,18 @@ $utopia->get('/console/users/user')
->setParam('body', $page);
});
$utopia->get('/console/users/teams/team')
->desc('Platform console project team')
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
$page = new View(__DIR__.'/../../views/console/users/team.phtml');
$layout
->setParam('title', APP_NAME.' - Team')
->setParam('body', $page);
});
$utopia->get('/console/functions')
->desc('Platform console project functions')
->label('permission', 'public')
+2 -1
View File
@@ -417,6 +417,7 @@ $utopia->get('/open-api-2.json')
'edit' => 'https://github.com/appwrite/appwrite/edit/master' . $route->getLabel('sdk.description', ''),
'rate-limit' => $route->getLabel('abuse-limit', 0),
'rate-time' => $route->getLabel('abuse-time', 3600),
'rate-key' => $route->getLabel('abuse-key', 'url:{url},ip:{ip}'),
'scope' => $route->getLabel('scope', ''),
'platforms' => $platformList,
];
@@ -474,7 +475,7 @@ $utopia->get('/open-api-2.json')
$node['x-example'] = '{}';
//$node['format'] = 'json';
break;
case 'Appwrite\Storage\Validators\File':
case 'Appwrite\Storage\Validator\File':
$consumes = ['multipart/form-data'];
$node['type'] = 'file';
break;
+6 -4
View File
@@ -34,7 +34,7 @@ const APP_USERAGENT = APP_NAME.'-Server v%s. Please report abuse at %s';
const APP_MODE_ADMIN = 'admin';
const APP_PAGING_LIMIT = 15;
const APP_CACHE_BUSTER = 125;
const APP_VERSION_STABLE = '0.6.1';
const APP_VERSION_STABLE = '0.6.2';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_CACHE = '/storage/cache';
const APP_STORAGE_CERTIFICATES = '/storage/certificates';
@@ -68,6 +68,7 @@ Config::setParam('domainVerification', false);
Config::setParam('version', $request->getServer('_APP_VERSION', 'UNKNOWN'));
Config::setParam('protocol', $request->getServer('HTTP_X_FORWARDED_PROTO', $request->getServer('REQUEST_SCHEME', 'https')));
Config::setParam('port', (string) parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_PORT));
Config::setParam('hostname', parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', null), PHP_URL_HOST));
$utopia = new App('Asia/Tel_Aviv', Config::getParam('env'));
@@ -78,10 +79,11 @@ define('COOKIE_DOMAIN',
(
$request->getServer('HTTP_HOST', null) === 'localhost' ||
$request->getServer('HTTP_HOST', null) === 'localhost:'.Config::getParam('port') ||
(filter_var($request->getServer('HTTP_HOST', null), FILTER_VALIDATE_IP) !== false)
(filter_var(Config::getParam('hostname'), FILTER_VALIDATE_IP) !== false)
)
? null
: '.'.parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_HOST));
: '.'.Config::getParam('hostname')
);
define('COOKIE_SAMESITE', Response::COOKIE_SAMESITE_NONE);
/*
@@ -295,7 +297,7 @@ if (APP_MODE_ADMIN === $mode) {
$session = Auth::decodeSession(
$request->getCookie(Auth::$cookieName, // Get sessions
$request->getCookie(Auth::$cookieName.'_legacy', // Get fallback session from old clients (no SameSite support)
$request->getHeader('X-Appwrite-Key', '')))); // Get API Key
$request->getHeader('X-Appwrite-Key', '')))); // Get API Key
// Get fallback session from clients who block 3rd-party cookies
$response->addHeader('X-Debug-Fallback', 'false');
+5
View File
@@ -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
+3 -3
View File
@@ -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:
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.createOAuth2Session(
Future result = account.createOAuth2Session(
provider: 'bitbucket',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.createRecovery(
Future result = account.createRecovery(
email: 'email@example.com',
url: 'https://example.com',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.createSession(
Future result = account.createSession(
email: 'email@example.com',
password: 'password',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.createVerification(
Future result = account.createVerification(
url: 'https://example.com',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.create(
Future result = account.create(
email: 'email@example.com',
password: 'password',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.deleteSession(
Future result = account.deleteSession(
sessionId: '[SESSION_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.deleteSessions();
Future result = account.deleteSessions( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.delete();
Future result = account.delete( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.getLogs();
Future result = account.getLogs( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.getPrefs();
Future result = account.getPrefs( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.getSessions();
Future result = account.getSessions( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.get();
Future result = account.get( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updateEmail(
Future result = account.updateEmail(
email: 'email@example.com',
password: 'password',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updateName(
Future result = account.updateName(
name: '[NAME]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updatePassword(
Future result = account.updatePassword(
password: 'password',
oldPassword: 'password',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updatePrefs(
Future result = account.updatePrefs(
prefs: {},
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,23 +1,25 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updateRecovery(
Future result = account.updateRecovery(
userId: '[USER_ID]',
secret: '[SECRET]',
password: 'password',
passwordAgain: 'password',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Account account = Account(client);
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = account.updateVerification(
Future result = account.updateVerification(
userId: '[USER_ID]',
secret: '[SECRET]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = avatars.getBrowser(
String result = avatars.getBrowser(
code: 'aa',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = avatars.getCreditCard(
String result = avatars.getCreditCard(
code: 'amex',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = avatars.getFavicon(
String result = avatars.getFavicon(
url: 'https://example.com',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = avatars.getFlag(
String result = avatars.getFlag(
code: 'af',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = avatars.getImage(
String result = avatars.getImage(
url: 'https://example.com',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
void main() { // Init SDK
Client client = Client();
Avatars avatars = Avatars(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = avatars.getQR(
String result = avatars.getQR(
text: '[TEXT]',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,23 +1,25 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Database database = Database(client);
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = database.createDocument(
Future result = database.createDocument(
collectionId: '[COLLECTION_ID]',
data: {},
read: [],
write: [],
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Database database = Database(client);
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = database.deleteDocument(
Future result = database.deleteDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Database database = Database(client);
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = database.getDocument(
Future result = database.getDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Database database = Database(client);
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = database.listDocuments(
Future result = database.listDocuments(
collectionId: '[COLLECTION_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,24 +1,26 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Database database = Database(client);
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = database.updateDocument(
Future result = database.updateDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
data: {},
read: [],
write: [],
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.getContinents();
Future result = locale.getContinents( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.getCountriesEU();
Future result = locale.getCountriesEU( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.getCountriesPhones();
Future result = locale.getCountriesPhones( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.getCountries();
Future result = locale.getCountries( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.getCurrencies();
Future result = locale.getCurrencies( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,18 +1,20 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Locale locale = Locale(client);
void main() { // Init SDK
Client client = Client();
Locale locale = Locale(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = locale.get();
Future result = locale.get( );
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,23 +1,25 @@
import 'dart:io';
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = storage.createFile(
Future result = storage.createFile(
file: await MultipartFile.fromFile('./path-to-files/image.jpg', 'image.jpg'),
read: [],
write: [],
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = storage.deleteFile(
Future result = storage.deleteFile(
fileId: '[FILE_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = storage.getFileDownload(
String result = storage.getFileDownload(
fileId: '[FILE_ID]',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = storage.getFilePreview(
String result = storage.getFilePreview(
fileId: '[FILE_ID]',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,15 +1,17 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
String result = storage.getFileView(
String result = storage.getFileView(
fileId: '[FILE_ID]',
);
);
print(result); // Resource URL string
print(result); // Resource URL string
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = storage.getFile(
Future result = storage.getFile(
fileId: '[FILE_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,19 +1,21 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = storage.listFiles(
);
Future result = storage.listFiles(
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,22 +1,24 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Storage storage = Storage(client);
void main() { // Init SDK
Client client = Client();
Storage storage = Storage(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = storage.updateFile(
Future result = storage.updateFile(
fileId: '[FILE_ID]',
read: [],
write: [],
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,23 +1,25 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.createMembership(
Future result = teams.createMembership(
teamId: '[TEAM_ID]',
email: 'email@example.com',
roles: [],
url: 'https://example.com',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.create(
Future result = teams.create(
name: '[NAME]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.deleteMembership(
Future result = teams.deleteMembership(
teamId: '[TEAM_ID]',
inviteId: '[INVITE_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.delete(
Future result = teams.delete(
teamId: '[TEAM_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.getMemberships(
Future result = teams.getMemberships(
teamId: '[TEAM_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,20 +1,22 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.get(
Future result = teams.get(
teamId: '[TEAM_ID]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,19 +1,21 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.list(
);
Future result = teams.list(
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,23 +1,25 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.updateMembershipStatus(
Future result = teams.updateMembershipStatus(
teamId: '[TEAM_ID]',
inviteId: '[INVITE_ID]',
userId: '[USER_ID]',
secret: '[SECRET]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -1,21 +1,23 @@
import 'package:appwrite/appwrite.dart';
// Init SDK
Client client = Client();
Teams teams = Teams(client);
void main() { // Init SDK
Client client = Client();
Teams teams = Teams(client);
client
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
;
Future result = teams.update(
Future result = teams.update(
teamId: '[TEAM_ID]',
name: '[NAME]',
);
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error);
});
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
+19 -17
View File
@@ -15,7 +15,7 @@ class Client {
Map<String, String> headers;
Map<String, String> 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<Response> call(HttpMethod method, {String path = '', Map<String, String> headers = const {}, Map<String, dynamic> 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(
@@ -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<Cookie> cookies = [new Cookie(url.queryParameters['key'], url.queryParameters['secret'])];
await client.init();
client.cookieJar.saveFromResponse(Uri.parse(client.endPoint), cookies);
});
}
@@ -17,20 +17,25 @@ class Avatars extends Service {
/// /account/sessions endpoint. Use width, height and quality arguments to
/// change the output settings.
///
Future<Response> getBrowser({@required String code, int width = 100, int height = 100, int quality = 100}) {
String getBrowser({@required String code, int width = 100, int height = 100, int quality = 100}) {
final String path = '/avatars/browsers/{code}'.replaceAll(RegExp('{code}'), code);
final Map<String, dynamic> params = {
'width': width,
'height': height,
'quality': quality,
'project': client.config['project'],
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
Uri endpoint = Uri.parse(client.endPoint);
Uri location = new Uri(scheme: endpoint.scheme,
host: endpoint.host,
port: endpoint.port,
path: endpoint.path + path,
queryParameters:params,
);
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
return location.toString();
}
/// Get Credit Card Icon
@@ -51,14 +56,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 +80,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 +107,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 +135,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 +162,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();
}
}
@@ -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();
}
}
+1 -1
View File
@@ -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
+1 -1
View File
@@ -1,7 +1,7 @@
# Appwrite Web SDK
![License](https://img.shields.io/github/license/appwrite/sdk-for-js.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.2-blue.svg?v=1)
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 Web SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.
@@ -1,10 +1,11 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.account.createOAuth2Session('bitbucket');
let promise = sdk.account.createOAuth2Session('amazon');
promise.then(function (response) {
console.log(response); // Success
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
@@ -1,6 +1,7 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;

Some files were not shown because too many files have changed in this diff Show More