1
0
Fork 0
mirror of synced 2024-05-21 05:02:37 +12:00

Merge pull request #960 from appwrite/dev

0.7.1 - Merge dev into release branch
This commit is contained in:
Eldad A. Fux 2021-03-13 00:20:15 +02:00 committed by GitHub
commit 232056898a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
114 changed files with 992 additions and 632 deletions

View file

@ -15,12 +15,7 @@ then
exit 1
fi
echo "Updating git repository $1 / $2"
git fetch origin
git reset --hard origin/master
if test $(find "./app/db/DBIP/dbip-country-lite-2020-01.mmdb" -mmin +259200)
if test $(find "./app/db/DBIP/dbip-country-lite-2021-02.mmdb" -mmin +259200)
then
printf "${RED}GEO country DB has not been updated for more than 6 months. Go to https://db-ip.com/db/download/ip-to-country-lite to download a newer version${NC}\n"
fi

View file

@ -1,3 +1,41 @@
# Version 0.8.0 (Not Released Yet)
- Anonymous login
# Version 0.7.1
## Features
- Better error logs on appwrite certificates worker
- Added option for Redis authentication
- Force adding a security email on setup
- SMTP is now disabled by default, no dummy SMTP is included in setup
- Added a new endpoint that returns the server and SDKs latest versions numbers #941
## Upgrades
- Upgraded redis extenstion lib to version 5.3.3
- Upgraded maxmind extenstion lib to version 1.10.0
- Upgraded utopia-php/cli lib to version 0.10.0
- Upgraded matomo/device-detector lib to version 4.1.0
- Upgraded dragonmantank/cron-expression lib to version 3.1.0
- Upgraded influxdb/influxdb-php lib to version 1.15.2
- Upgraded phpmailer/phpmailer lib to version 6.3.0
- Upgraded adhocore/jwt lib to version 1.1.2
- Upgraded domnikl/statsd to slickdeals/statsd version 3.0
## Bug Fixes
- Updated missing storage env vars
- Fixed a bug, that added a wrong timzone offset to user log timestamps
- Fixed a bug, that Response format header was not added in the access-control-allow-header list.
- Fixed a bug where countryName is unknown on sessions (#933)
- Added missing event users.update.prefs (#952)
## Security
- Fixed an XSS vulnerability in the Appwrite console
# Version 0.7.0
## Features

View file

@ -90,6 +90,35 @@ Appwrite uses an internal micro-framework called Litespeed.js to build simple UI
After finishing the installation process, you can start writing and editing code.
#### Advanced Topics
We love to create issues that are good for begginers and label them as `good for begginers` or `hacktoberfest`, but some more advanced topics might require extra knowledge. Below is a list of links you can use to learn more about some of the more advance topics that will help you master the Appwrite codebase.
##### Tools and Libs
- [Docker](https://www.docker.com/get-started)
- [PHP FIG](https://www.php-fig.org/) - [PSR-1](https://www.php-fig.org/psr/psr-1/) and [PSR-4](https://www.php-fig.org/psr/psr-4/)
- [PHP Swoole](https://www.swoole.co.uk/)
Learn more at our [Technology Stack](## Technology Stack) section.
##### Network and Protocols
- [OSI Model](https://en.wikipedia.org/wiki/OSI_model)
- [TCP vs UDP](https://www.guru99.com/tcp-vs-udp-understanding-the-difference.html#:~:text=TCP%20is%20a%20connection%2Doriented,speed%20of%20UDP%20is%20faster&text=TCP%20does%20error%20checking%20and,but%20it%20discards%20erroneous%20packets.)
- [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol)
- [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer)
- [GraphQL](https://en.wikipedia.org/wiki/GraphQL)
- [gRPC](https://en.wikipedia.org/wiki/GRPC)
##### Architecture
- [Microservices vs Monolithic](https://www.mulesoft.com/resources/api/microservices-vs-monolithic#:~:text=Microservices%20architecture%20vs%20monolithic%20architecture&text=A%20monolithic%20application%20is%20built%20as%20a%20single%20unit.&text=To%20make%20any%20alterations%20to,formally%20with%20business%2Doriented%20APIs.)
- [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) - Appwrite console architecture
##### Security
- [Appwrite Auth and ACL](https://github.com/appwrite/appwrite/blob/0.7.x/docs/specs/authentication.drawio.svg)
- [OAuth](https://en.wikipedia.org/wiki/OAuth)
- [Encryption](https://medium.com/searchencrypt/what-is-encryption-how-does-it-work-e8f20e340537#:~:text=Encryption%20is%20a%20process%20that,%2C%20or%20decrypt%2C%20the%20information.)
- [Hashing](https://searchsqlserver.techtarget.com/definition/hashing#:~:text=Hashing%20is%20the%20transformation%20of,it%20using%20the%20original%20value.)
## Architecture
Appwrite's current structure is a combination of both [Monolithic](https://en.wikipedia.org/wiki/Monolithic_application) and [Microservice](https://en.wikipedia.org/wiki/Microservices) architectures, but our final goal, as we grow, is to be using only microservices.
@ -114,7 +143,6 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
├── docs # Docs and tutorials
│ ├── examples
│ ├── references
│ ├── sdks
│ ├── services
│ ├── specs
│ └── tutorials
@ -128,11 +156,14 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
│ └── Appwrite
│ ├── Auth
│ ├── Database
│ ├── Detector
│ ├── Docker
│ ├── Event
│ ├── Extend
│ ├── Migration
│ ├── Network
│ ├── OpenSSL
│ ├── Specification
│ ├── Task
│ ├── Template
│ ├── URL

View file

@ -14,9 +14,9 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
FROM php:7.4-cli-alpine as step1
ENV PHP_REDIS_VERSION=5.3.0 \
ENV PHP_REDIS_VERSION=5.3.3 \
PHP_SWOOLE_VERSION=v4.5.8 \
PHP_MAXMINDDB_VERSION=v1.8.0 \
PHP_MAXMINDDB_VERSION=v1.10.0 \
PHP_XDEBUG_VERSION=sdebug_2_9-beta
RUN \
@ -90,8 +90,11 @@ ENV _APP_SERVER=swoole \
_APP_INFLUXDB_PORT=8086 \
_APP_STATSD_HOST=telegraf \
_APP_STATSD_PORT=8125 \
_APP_SMTP_HOST=smtp \
_APP_SMTP_PORT=25 \
_APP_SMTP_HOST= \
_APP_SMTP_PORT= \
_APP_SMTP_SECURE= \
_APP_SMTP_USERNAME= \
_APP_SMTP_PASSWORD= \
_APP_FUNCTIONS_TIMEOUT=900 \
_APP_FUNCTIONS_CONTAINERS=10 \
_APP_FUNCTIONS_CPUS=1 \
@ -106,9 +109,6 @@ ENV _APP_SERVER=swoole \
# 1 Day = 86400 s
_APP_MAINTENANCE_RETENTION_ABUSE=86400 \
_APP_MAINTENANCE_INTERVAL=86400
#ENV _APP_SMTP_SECURE ''
#ENV _APP_SMTP_USERNAME ''
#ENV _APP_SMTP_PASSWORD ''
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

View file

@ -53,7 +53,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:0.7.0
appwrite/appwrite:0.7.1
```
### Windows
@ -65,7 +65,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:0.7.0
appwrite/appwrite:0.7.1
```
#### PowerShell
@ -75,13 +75,13 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
appwrite/appwrite:0.7.0
appwrite/appwrite:0.7.1
```
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. You can also use our public [docker-compose.yml](https://appwrite.io/docker-compose.yml) file to manually set up and environment.
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 an environment.
### Upgrade from an Older Version
@ -94,6 +94,7 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
* [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 CLI](https://appwrite.io/docs/command-line)
* Getting Started for Android (Coming soon...)
* Getting Started for iOS (Coming soon...)
@ -132,13 +133,13 @@ Looking for more SDKs? - Help us by contributing a pull request to our [SDK Gene
## Contributing
All code contributions - including those of people having commit access - must go through a pull request and approved by a core developer before being merged. This is to ensure proper review of all the code.
All code contributions - including those of people having commit access - must go through a pull request and be approved by a core developer before being merged. This is to ensure a proper review of all the code.
We truly ❤️ pull requests! If you wish to help, you can learn more about how you can contribute to this project in the [contribution guide](CONTRIBUTING.md).
## Security
For security issues, kindly email us at [security@appwrite.io](mailto:security@appwrite.io) instead of posting a public issue in GitHub.
For security issues, kindly email us at [security@appwrite.io](mailto:security@appwrite.io) instead of posting a public issue on GitHub.
## Follow Us

View file

@ -117,6 +117,11 @@ return [
'model' => Response::MODEL_USER,
'note' => 'version >= 0.7',
],
'users.update.prefs' => [
'description' => 'This event triggers when a user preference is updated from the users API.',
'model' => Response::MODEL_ANY,
'note' => 'version >= 0.7',
],
'users.update.status' => [
'description' => 'This event triggers when a user status is updated from the users API.',
'model' => Response::MODEL_USER,

View file

@ -32,7 +32,7 @@ return [
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '0.3.0',
'version' => '0.4.0-dev.2',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@ -165,7 +165,7 @@ return [
[
'key' => 'deno',
'name' => 'Deno',
'version' => '0.1.0',
'version' => '0.1.1',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'package' => 'https://deno.land/x/appwrite',
'enabled' => true,
@ -199,7 +199,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '0.1.0',
'version' => '0.1.1',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@ -216,7 +216,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '2.0.0',
'version' => '2.0.2',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'package' => 'https://rubygems.org/gems/appwrite',
'enabled' => true,
@ -284,7 +284,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '0.2.0',
'version' => '0.3.1',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
@ -301,7 +301,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '0.5.0',
'version' => '0.6.0',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://github.com/appwrite/sdk-for-cli',
'enabled' => true,

View file

@ -105,9 +105,9 @@ return [
],
[
'name' => '_APP_SYSTEM_SECURITY_EMAIL_ADDRESS',
'description' => 'This is the email address used to issue SSL certificates for custom domains or the user agent in webhooks. The default value is \'security@localhost.test\'.',
'description' => 'This is the email address used to issue SSL certificates for custom domains or the user agent in your webhooks payload.',
'introduction' => '0.7.0',
'default' => 'security@localhost.test',
'default' => 'certs@appwrite.io',
'required' => false,
'question' => '',
],
@ -255,17 +255,17 @@ return [
'variables' => [
[
'name' => '_APP_SMTP_HOST',
'description' => 'SMTP server host name address. Default value is: \'smtp\'. Pass an empty string to disable all mail sending from the server.',
'description' => 'SMTP server host name address. Use an empty string to disable all mail sending from the server. The default value for this variable is an empty string',
'introduction' => '',
'default' => 'smtp',
'default' => '',
'required' => false,
'question' => '',
],
[
'name' => '_APP_SMTP_PORT',
'description' => 'SMTP server TCP port. Default value is: \'25\'.',
'description' => 'SMTP server TCP port. Empty by default.',
'introduction' => '',
'default' => '25',
'default' => '',
'required' => false,
'question' => '',
],

View file

@ -236,9 +236,11 @@ App::post('/v1/account/sessions')
->setStatusCode(Response::STATUS_CODE_CREATED)
;
$countries = $locale->getText('countries');
$session
->setAttribute('current', true)
->setAttribute('countryName', (isset($countries[$session->getAttribute('countryCode')])) ? $countries[$session->getAttribute('countryCode')] : $locale->getText('locale.country.unknown'))
->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'))
;
$response->dynamic($session, Response::MODEL_SESSION);
@ -679,8 +681,8 @@ App::get('/v1/account/sessions')
continue;
}
$token->setAttribute('countryName', (isset($countries[$token->getAttribute('contryCode')]))
? $countries[$token->getAttribute('contryCode')]
$token->setAttribute('countryName', (isset($countries[strtoupper($token->getAttribute('countryCode'))]))
? $countries[strtoupper($token->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown'));
$token->setAttribute('current', ($current == $token->getId()) ? true : false);

View file

@ -294,7 +294,7 @@ App::put('/v1/functions/:functionId')
}
$original = $function->getAttribute('schedule', '');
$cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? CronExpression::factory($schedule) : null;
$cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : null;
$function = $projectDB->updateDocument(array_merge($function->getArrayCopy(), [
@ -359,7 +359,7 @@ App::patch('/v1/functions/:functionId/tag')
}
$schedule = $function->getAttribute('schedule', '');
$cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? CronExpression::factory($schedule) : null;
$cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : null;
$function = $projectDB->updateDocument(array_merge($function->getArrayCopy(), [

View file

@ -943,7 +943,7 @@ App::post('/v1/projects/:projectId/tasks')
throw new Exception('Project not found', 404);
}
$cron = CronExpression::factory($schedule);
$cron = new CronExpression($schedule);
$next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null;
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
@ -1093,7 +1093,7 @@ App::put('/v1/projects/:projectId/tasks/:taskId')
throw new Exception('Task not found', 404);
}
$cron = CronExpression::factory($schedule);
$cron = new CronExpression($schedule);
$next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null;
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);

View file

@ -205,8 +205,8 @@ App::get('/v1/users/:userId/sessions')
continue;
}
$token->setAttribute('countryName', (isset($countries[$token->getAttribute('contryCode')]))
? $countries[$token->getAttribute('contryCode')]
$token->setAttribute('countryName', (isset($countries[strtoupper($token->getAttribute('countryCode'))]))
? $countries[strtoupper($token->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown'));
$token->setAttribute('current', false);
@ -373,6 +373,7 @@ App::patch('/v1/users/:userId/status')
App::patch('/v1/users/:userId/prefs')
->desc('Update User Preferences')
->groups(['api', 'users'])
->label('event', 'users.update.prefs')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.namespace', 'users')

View file

@ -117,7 +117,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
->addHeader('Server', 'Appwrite')
->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-Appwrite-JWT, X-SDK-Version, Cache-Control, Expires, Pragma')
->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-Appwrite-JWT, X-Appwrite-Response-Format, 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')
@ -237,7 +237,7 @@ App::options(function ($request, $response) {
$response
->addHeader('Server', 'Appwrite')
->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-Appwrite-JWT, X-SDK-Version, Cache-Control, Expires, Pragma, 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-Appwrite-JWT, X-Appwrite-Response-Format, 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')

View file

@ -144,6 +144,7 @@ App::get('/console/settings')
$page
->setParam('customDomainsEnabled', ($target->isKnown() && !$target->isTest()))
->setParam('customDomainsTarget', $target->get())
->setParam('smtpEnabled', (!empty(App::getEnv('_APP_SMTP_HOST'))))
;
$layout

View file

@ -375,4 +375,40 @@ App::get('/specs/:format')
$response
->json($specs->parse());
});
App::get('/versions')
->desc('Get Version')
->groups(['web', 'home'])
->label('scope', 'public')
->inject('response')
->action(function ($response) {
/** @var Appwrite\Utopia\Response $response */
$platforms = Config::getParam('platforms');
$versions = [
'server' => APP_VERSION_STABLE,
];
foreach($platforms as $platform) {
$languages = $platform['languages'] ?? [];
foreach ($languages as $key => $language) {
if(isset($language['dev']) && $language['dev']) {
continue;
}
if(isset($language['enabled']) && !$language['enabled']) {
continue;
}
$platformKey = $platform['key'] ?? '';
$languageKey = $language['key'] ?? '';
$version = $language['version'] ?? '';
$versions[$platformKey . '-' . $languageKey] = $version;
}
}
$response->json($versions);
});

View file

@ -94,7 +94,7 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
return;
}
$app = new App('America/New_York');
$app = new App('UTC');
try {
Authorization::cleanRoles();

View file

@ -34,13 +34,13 @@ use PDO as PDONative;
const APP_NAME = 'Appwrite';
const APP_DOMAIN = 'appwrite.io';
const APP_EMAIL_TEAM = 'team@localhost.test'; // Default email address
const APP_EMAIL_SECURITY = 'security@localhost.test'; // Default security email address
const APP_EMAIL_SECURITY = ''; // Default security email address
const APP_USERAGENT = APP_NAME.'-Server v%s. Please report abuse at %s';
const APP_MODE_DEFAULT = 'default';
const APP_MODE_ADMIN = 'admin';
const APP_PAGING_LIMIT = 12;
const APP_CACHE_BUSTER = 144;
const APP_VERSION_STABLE = '0.7.0';
const APP_VERSION_STABLE = '0.7.1';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache';

View file

@ -28,10 +28,9 @@ foreach ([
realpath(__DIR__ . '/../vendor/felixfbecker'),
realpath(__DIR__ . '/../vendor/twig/twig'),
realpath(__DIR__ . '/../vendor/guzzlehttp/guzzle'),
realpath(__DIR__ . '/../vendor/domnikl'),
realpath(__DIR__ . '/../vendor/domnikl'),
realpath(__DIR__ . '/../vendor/slickdeals'),
realpath(__DIR__ . '/../vendor/psr/log'),
realpath(__DIR__ . '/../vendor/piwik'),
realpath(__DIR__ . '/../vendor/matomo'),
realpath(__DIR__ . '/../vendor/symfony'),
] as $key => $value) {
if($value !== false) {

View file

@ -139,7 +139,6 @@ $cli
Console::success('SMTP................connected 👍');
} catch (\Throwable $th) {
Console::error('SMTP.............disconnected 👎');
var_dump($th);
}
$host = App::getEnv('_APP_STATSD_HOST', 'telegraf');

View file

@ -96,6 +96,15 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$config = new CLI();
$config->setComposerVendor('appwrite');
$config->setComposerPackage('cli');
$config->setExecutableName('appwrite');
$config->setLogo("
_ _ _ ___ __ _____
/_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
//_\\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
/ _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
\_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
|_| |_|
");
break;
case 'php':
$config = new PHP();

View file

@ -64,6 +64,7 @@
</td>
<td data-title="Size: ">
<span class="text-fade text-size-small" data-ls-bind="{{file.sizeOriginal|humanFileSize}}"></span>
<span class="text-fade text-size-small" data-ls-bind="{{file.sizeOriginal|humanFileUnit}}"></span>
</td>
<td data-title="Created: ">
<span class="text-fade text-size-small" data-ls-bind="{{file.dateCreated|dateText}}"></span>

View file

@ -117,7 +117,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<b data-ls-bind="{{tag.$id}}"></b> &nbsp;
<span class="text-fade" data-ls-bind="{{tag.command}}"></span>
<div class="text-size-small margin-top-small clear">
<span class="pull-start" data-ls-bind="Created {{tag.dateCreated|timeSince}} &nbsp; | &nbsp; {{tag.size|humanFileSize}}"></span>
<span class="pull-start" data-ls-bind="Created {{tag.dateCreated|timeSince}} &nbsp; | &nbsp; {{tag.size|humanFileSize}}{{tag.size|humanFileUnit}}"></span>
<form data-ls-if="{{tag.$id}} !== {{project-function.tag}}" name="functions.deleteTag" class="pull-start"
data-analytics

View file

@ -97,7 +97,10 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
</div>
</div>
<div class="col span-3">
<div class="value margin-bottom-small"><span class="sum" data-ls-bind="{{usage.network.total|humanFileSize}}" data-default="0">0</span></div>
<div class="value margin-bottom-small">
<span class="sum" data-ls-bind="{{usage.network.total|humanFileSize}}" data-default="0">0</span>
<span data-ls-bind="{{usage.network.total|humanFileUnit}}" class="text-size-small unit"></span>
</div>
<div class="metric margin-bottom-small">Bandwidth</div>
<div class="margin-top-large value small">
@ -117,7 +120,10 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<div class="margin-top-small"><b class="text-size-small unit">Documents</b></div>
</div>
<div class="col span-3">
<div class="value"><span class="sum" data-ls-bind="{{usage.storage.total|humanFileSize}}" data-default="0">0</span></div>
<div class="value">
<span class="sum" data-ls-bind="{{usage.storage.total|humanFileSize}}" data-default="0">0</span>
<span data-ls-bind="{{usage.storage.total|humanFileUnit}}" class="text-size-small unit"></span>
</div>
<div class="margin-top-small"><b class="text-size-small unit">Storage</b></div>
</div>
<div class="col span-3">

View file

@ -2,6 +2,7 @@
$customDomainsEnabled = $this->getParam('customDomainsEnabled', false);
$customDomainsTarget = $this->getParam('customDomainsTarget', false);
$smtpEnabled = $this->getParam('smtpEnabled', false);
?>
<div class="cover">
@ -506,10 +507,16 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
<option data-ls-attrs="value={{role.type}}" data-ls-bind="{{role.label}}"></option>
</select>
<?php if(!$smtpEnabled): ?>
<div class="box note padding-tiny warning margin-bottom text-align-center">
<i class="icon-warning"></i> SMTP connection is disabled. <a href="https://appwrite.io/docs/email-delivery" target="_blank" rel="noopener">Learn more <i class="icon-link-ext"></i></a>
</div>
<?php endif; ?>
<hr />
<div class="clear">
<button>Send Invite</button>
<button<?php if(!$smtpEnabled): ?> disabled<?php endif; ?>>Send Invite</button>
&nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
</form>

View file

@ -204,6 +204,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
</td>
<td data-title="Size: ">
<span class="text-fade text-size-small" data-ls-bind="{{file.sizeOriginal|humanFileSize}}"></span>
<span class="text-fade text-size-small" data-ls-bind="{{file.sizeOriginal|humanFileUnit}}"></span>
</td>
<td data-title="Created: ">
<span class="text-fade text-size-small" data-ls-bind="{{file.dateCreated|dateText}}"></span>

View file

@ -56,9 +56,12 @@ services:
- influxdb
environment:
- _APP_ENV
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_SYSTEM_RESPONSE_FORMAT
- _APP_OPTIONS_ABUSE
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
@ -273,7 +276,6 @@ services:
- appwrite
depends_on:
- redis
- smtp
environment:
- _APP_ENV
- _APP_SYSTEM_EMAIL_NAME
@ -340,16 +342,6 @@ services:
- MYSQL_PASSWORD=${_APP_DB_PASS}
command: 'mysqld --innodb-flush-method=fsync'
smtp:
image: appwrite/smtp:1.0.1
container_name: appwrite-smtp
restart: unless-stopped
networks:
- appwrite
environment:
- MAILNAME=appwrite
- RELAY_NETWORKS=:192.168.0.0/24:10.0.0.0/16
redis:
image: redis:6.0-alpine3.12
container_name: appwrite-redis

View file

@ -110,14 +110,22 @@ class CertificatesV1
}
$staging = (App::isProduction()) ? '' : ' --dry-run';
$email = App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS');
$response = \shell_exec("certbot certonly --webroot --noninteractive --agree-tos{$staging}"
." --email ".App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', 'security@localhost.test')
if(empty($email)) {
throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate');
}
$stdout = '';
$stderr = '';
$exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}"
." --email ".$email
." -w ".APP_STORAGE_CERTIFICATES
." -d {$domain->get()}");
." -d {$domain->get()}", '', $stdout, $stderr);
if(!$response) {
throw new Exception('Failed to issue a certificate');
if($stderr || $exit !== 0) {
throw new Exception('Failed to issue a certificate with message: '.$stderr);
}
$path = APP_STORAGE_CERTIFICATES.'/'.$domain->get();
@ -129,19 +137,19 @@ class CertificatesV1
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/cert.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/cert.pem')) {
throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($response));
throw new Exception('Failed to rename certificate cert.pem: '.\json_encode($stdout));
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/chain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/chain.pem')) {
throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($response));
throw new Exception('Failed to rename certificate chain.pem: '.\json_encode($stdout));
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/fullchain.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/fullchain.pem')) {
throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($response));
throw new Exception('Failed to rename certificate fullchain.pem: '.\json_encode($stdout));
}
if(!@\rename('/etc/letsencrypt/live/'.$domain->get().'/privkey.pem', APP_STORAGE_CERTIFICATES.'/'.$domain->get().'/privkey.pem')) {
throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($response));
throw new Exception('Failed to rename certificate privkey.pem: '.\json_encode($stdout));
}
$certificate = \array_merge($certificate, [
@ -154,7 +162,7 @@ class CertificatesV1
'issueDate' => \time(),
'renewDate' => $renew,
'attempts' => 0,
'log' => \json_encode($response),
'log' => \json_encode($stdout),
]);
$certificate = $consoleDB->createDocument($certificate);

View file

@ -227,7 +227,7 @@ class FunctionsV1
return;
}
$cron = CronExpression::factory($function->getAttribute('schedule'));
$cron = new CronExpression($function->getAttribute('schedule'));
$next = (int) $cron->getNextRunDate()->format('U');
$function

View file

@ -82,7 +82,7 @@ class TasksV1
// Reschedule
$cron = CronExpression::factory($task->getAttribute('schedule'));
$cron = new CronExpression($task->getAttribute('schedule'));
$next = (int) $cron->getNextRunDate()->format('U');
$headers = (\is_array($task->getAttribute('httpHeaders', []))) ? $task->getAttribute('httpHeaders', []) : [];

View file

@ -39,7 +39,7 @@
"utopia-php/analytics": "0.1.*",
"utopia-php/audit": "0.5.*",
"utopia-php/cache": "0.2.*",
"utopia-php/cli": "0.9.0",
"utopia-php/cli": "0.10.0",
"utopia-php/config": "0.2.*",
"utopia-php/locale": "0.3.*",
"utopia-php/registry": "0.2.*",
@ -51,16 +51,16 @@
"utopia-php/image": "0.1.*",
"resque/php-resque": "1.3.6",
"matomo/device-detector": "3.13.0",
"dragonmantank/cron-expression": "3.0.1",
"domnikl/statsd": "3.0.2",
"influxdb/influxdb-php": "1.15.1",
"phpmailer/phpmailer": "6.1.7",
"matomo/device-detector": "4.1.0",
"dragonmantank/cron-expression": "3.1.0",
"influxdb/influxdb-php": "1.15.2",
"phpmailer/phpmailer": "6.3.0",
"chillerlan/php-qrcode": "4.3.0",
"adhocore/jwt": "1.1.0"
"adhocore/jwt": "1.1.2",
"slickdeals/statsd": "~3.0"
},
"require-dev": {
"appwrite/sdk-generator": "0.5.5",
"appwrite/sdk-generator": "0.6.2",
"phpunit/phpunit": "9.4.2",
"swoole/ide-helper": "4.5.5",
"vimeo/psalm": "4.1.1"

723
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createOAuth2Session(
provider: 'amazon',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createRecovery(
email: 'email@example.com',
url: 'https://example.com',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createSession(
email: 'email@example.com',
password: 'password',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createVerification(
url: 'https://example.com',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.create(
email: 'email@example.com',
password: 'password',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.deleteSession(
sessionId: '[SESSION_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.deleteSessions();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.delete();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.getLogs();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.getPrefs();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.getSessions();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.get();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updateEmail(
email: 'email@example.com',
password: 'password',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updateName(
name: '[NAME]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updatePassword(
password: 'password',
oldPassword: 'password',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updatePrefs(
prefs: {},
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updateRecovery(
userId: '[USER_ID]',
secret: '[SECRET]',
@ -22,4 +21,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updateVerification(
userId: '[USER_ID]',
secret: '[SECRET]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getBrowser(
//displaying image
FutureBuilder(
future: avatars.getBrowser(
code: 'aa',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getCreditCard(
//displaying image
FutureBuilder(
future: avatars.getCreditCard(
code: 'amex',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getFavicon(
//displaying image
FutureBuilder(
future: avatars.getFavicon(
url: 'https://example.com',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getFlag(
//displaying image
FutureBuilder(
future: avatars.getFlag(
code: 'af',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getImage(
//displaying image
FutureBuilder(
future: avatars.getImage(
url: 'https://example.com',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,9 +8,17 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getInitials(
);
print(result); // Resource URL string
}
//displaying image
FutureBuilder(
future: avatars.getInitials(
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = avatars.getQR(
//displaying image
FutureBuilder(
future: avatars.getQR(
text: '[TEXT]',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.createDocument(
collectionId: '[COLLECTION_ID]',
data: {},
@ -22,4 +21,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.deleteDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.getDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.listDocuments(
collectionId: '[COLLECTION_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.updateDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
@ -23,4 +22,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = functions.createExecution(
functionId: '[FUNCTION_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = functions.getExecution(
functionId: '[FUNCTION_ID]',
executionId: '[EXECUTION_ID]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = functions.listExecutions(
functionId: '[FUNCTION_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getContinents();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getCountriesEU();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getCountriesPhones();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getCountries();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getCurrencies();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.getLanguages();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = locale.get();
result
@ -17,4 +16,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -9,7 +9,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = storage.createFile(
file: await MultipartFile.fromFile('./path-to-files/image.jpg', 'image.jpg'),
read: [],
@ -22,4 +21,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = storage.deleteFile(
fileId: '[FILE_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = storage.getFileDownload(
//displaying image
FutureBuilder(
future: storage.getFileDownload(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = storage.getFilePreview(
//displaying image
FutureBuilder(
future: storage.getFilePreview(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,10 +8,18 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
}
String result = storage.getFileView(
//displaying image
FutureBuilder(
future: storage.getFileView(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
}
), //works for both public file and private file, for private files you need to be logged in
builder: (context, snapshot) {
return snapshot.hasData && snapshot.data != null
? Image.memory(
snapshot.data.data,
)
: CircularProgressIndicator();
},
);

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = storage.getFile(
fileId: '[FILE_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = storage.listFiles(
);
@ -18,4 +17,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = storage.updateFile(
fileId: '[FILE_ID]',
read: [],
@ -21,4 +20,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.createMembership(
teamId: '[TEAM_ID]',
email: 'email@example.com',
@ -22,4 +21,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.create(
name: '[NAME]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.deleteMembership(
teamId: '[TEAM_ID]',
inviteId: '[INVITE_ID]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.delete(
teamId: '[TEAM_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.getMemberships(
teamId: '[TEAM_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.get(
teamId: '[TEAM_ID]',
);
@ -19,4 +18,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.list(
);
@ -18,4 +17,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.updateMembershipStatus(
teamId: '[TEAM_ID]',
inviteId: '[INVITE_ID]',
@ -22,4 +21,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -8,7 +8,6 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = teams.update(
teamId: '[TEAM_ID]',
name: '[NAME]',
@ -20,4 +19,4 @@ void main() { // Init SDK
}).catchError((error) {
print(error.response);
});
}
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getBrowser(
Future result = avatars.getBrowser(
code: 'aa',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getCreditCard(
Future result = avatars.getCreditCard(
code: 'amex',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getFavicon(
Future result = avatars.getFavicon(
url: 'https://example.com',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getFlag(
Future result = avatars.getFlag(
code: 'af',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getImage(
Future result = avatars.getImage(
url: 'https://example.com',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,8 +10,13 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getInitials(
Future result = avatars.getInitials(
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = avatars.getQR(
Future result = avatars.getQR(
text: '[TEXT]',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = storage.getFileDownload(
Future result = storage.getFileDownload(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = storage.getFilePreview(
Future result = storage.getFilePreview(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -10,9 +10,14 @@ void main() { // Init SDK
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
String result = storage.getFileView(
Future result = storage.getFileView(
fileId: '[FILE_ID]',
);
print(result); // Resource URL string
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}

View file

@ -1,3 +1,17 @@
## 0.3.1
- Minor fixes for custom exceptions
## 0.3.0
- Improved code quality
- Added a custom Appwrite exception
- Enabled access to private storage file
## 0.2.0
- Upgraded to work with Appwrite 0.7
## 0.1.0
- First release

View file

@ -1,3 +1,17 @@
## 0.4.0-dev.2
- Minor fixes for custom exceptions
## 0.4.0-dev.1
- Improved code quality
- Enabled access to private storage file
- Added easier integration for preview images and the Image widget
## 0.3.0
- Upgraded to work with Appwrite 0.7
## 0.3.0-dev.2
- Fix for an error when using a self-signed certificate for Web

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