mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '0.7.x' into feat-upgrade-php-version
This commit is contained in:
+1
-6
@@ -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
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ script:
|
||||
- docker-compose logs appwrite-worker-functions
|
||||
- docker-compose exec appwrite doctor
|
||||
- docker-compose exec appwrite vars
|
||||
- docker-compose exec appwrite test
|
||||
- docker-compose exec appwrite test --debug
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
|
||||
+59
@@ -1,3 +1,62 @@
|
||||
# Version 0.8.0 (Not Released Yet)
|
||||
|
||||
- Anonymous login
|
||||
|
||||
# Version 0.7.2 (Not Released Yet)
|
||||
|
||||
## Features
|
||||
|
||||
- When creating new resources from the client API, the current user gets both read & write permissions by default. (#1007)
|
||||
- Added timestamp to errors logs on the HTTP API container (#1002)
|
||||
- Added verbose tests output on the terminal and CI (#1006)
|
||||
|
||||
## Upgrades
|
||||
|
||||
- Upgraded utopia-php/abuse to version 0.4.0
|
||||
- Upgraded utopia-php/analytics to version 0.2.0
|
||||
|
||||
## Bugs
|
||||
|
||||
- Fixed certificates worker error on successful operations (#1010)
|
||||
- Fixed head requests not responding (#998)
|
||||
- Fixed bug when using auth credential for the Redis container (#993)
|
||||
- Fixed server warning logs on 3** redirect endpoints (#1013)
|
||||
|
||||
# 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)
|
||||
- Fixed bug not allowing to reset document permissions (#977)
|
||||
|
||||
## Security
|
||||
|
||||
- Fixed an XSS vulnerability in the Appwrite console
|
||||
|
||||
# Version 0.7.0
|
||||
|
||||
## Features
|
||||
|
||||
+32
-4
@@ -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,13 +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
|
||||
│ ├── Resize
|
||||
│ ├── Storage
|
||||
│ ├── Specification
|
||||
│ ├── Task
|
||||
│ ├── Template
|
||||
│ ├── URL
|
||||
@@ -337,7 +366,6 @@ From time to time, our team will add tutorials that will help contributors find
|
||||
* [Appwrite Environment Variables](./docs/tutorials/environment-variables.md)
|
||||
* [Running in Production](./docs/tutorials/running-in-production.md)
|
||||
|
||||
|
||||
## Other Ways to Help
|
||||
|
||||
Pull requests are great, but there are many other areas where you can help Appwrite.
|
||||
|
||||
+7
-7
@@ -14,11 +14,11 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
|
||||
|
||||
FROM php:8.0-cli-alpine as step1
|
||||
|
||||
ENV PHP_REDIS_VERSION=5.3.2 \
|
||||
ENV PHP_REDIS_VERSION=5.3.3 \
|
||||
PHP_SWOOLE_VERSION=v4.6.3 \
|
||||
PHP_IMAGICK_VERSION=master \
|
||||
PHP_YAML_VERSION=2.2.1 \
|
||||
PHP_MAXMINDDB_VERSION=v1.9.0
|
||||
PHP_MAXMINDDB_VERSION=v1.10.0
|
||||
|
||||
RUN \
|
||||
apk add --no-cache --virtual .deps \
|
||||
@@ -110,8 +110,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 \
|
||||
@@ -126,9 +129,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
|
||||
|
||||
|
||||
@@ -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.2
|
||||
```
|
||||
|
||||
### 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.2
|
||||
```
|
||||
|
||||
#### 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.2
|
||||
```
|
||||
|
||||
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes.
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -32,7 +32,7 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '0.3.0',
|
||||
'version' => '0.4.0-dev.3',
|
||||
'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,12 +284,12 @@ return [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '0.2.0',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'dev' => true,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
'prism' => 'dart',
|
||||
@@ -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,
|
||||
|
||||
@@ -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' => '',
|
||||
],
|
||||
@@ -143,7 +143,7 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_REDIS_USER',
|
||||
'description' => 'Redis server user.',
|
||||
'description' => 'Redis server user. This is an optional variable. Default value is an empty string.',
|
||||
'introduction' => '0.7',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
@@ -151,7 +151,7 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_REDIS_PASS',
|
||||
'description' => 'Redis server password.',
|
||||
'description' => 'Redis server password. This is an optional variable. Default value is an empty string.',
|
||||
'introduction' => '0.7',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
@@ -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' => '',
|
||||
],
|
||||
|
||||
@@ -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);
|
||||
@@ -253,8 +255,8 @@ App::get('/v1/account/sessions/oauth2/:provider')
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'createOAuth2Session')
|
||||
->label('sdk.description', '/docs/references/account/create-session-oauth2.md')
|
||||
->label('sdk.response.code', 301)
|
||||
->label('sdk.response.type', 'text/html')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_MOVED_PERMANENTLY)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_HTML)
|
||||
->label('sdk.methodType', 'webAuth')
|
||||
->label('abuse-limit', 50)
|
||||
->label('abuse-key', 'ip:{ip}')
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Appwrite\Resize\Resize;
|
||||
use Appwrite\URL\URL as URLParse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Validator\HexColor;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\HexColor;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
$avatarCallback = function ($type, $code, $width, $height, $quality, $response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$code = \strtolower($code);
|
||||
$type = \strtolower($type);
|
||||
$set = Config::getParam('avatar-'.$type, []);
|
||||
$set = Config::getParam('avatar-' . $type, []);
|
||||
|
||||
if (empty($set)) {
|
||||
throw new Exception('Avatar set not found', 404);
|
||||
@@ -37,17 +37,17 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
||||
}
|
||||
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v1/avatars/:type/:code-'.$code.$width.$height.$quality.$output);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v1/avatars/:type/:code-' . $code . $width . $height . $quality . $output);
|
||||
$path = $set[$code];
|
||||
$type = 'png';
|
||||
|
||||
if (!\is_readable($path)) {
|
||||
throw new Exception('File not readable in '.$path, 500);
|
||||
throw new Exception('File not readable in ' . $path, 500);
|
||||
}
|
||||
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
//$output = (empty($output)) ? $type : $output;
|
||||
@@ -60,24 +60,23 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
||||
;
|
||||
}
|
||||
|
||||
$resize = new Resize(\file_get_contents($path));
|
||||
$image = new Image(\file_get_contents($path));
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
|
||||
$response
|
||||
->setContentType('image/png')
|
||||
->addHeader('Expires', $date)
|
||||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send($data, null);
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
};
|
||||
|
||||
App::get('/v1/avatars/credit-cards/:code')
|
||||
@@ -91,7 +90,7 @@ App::get('/v1/avatars/credit-cards/:code')
|
||||
->label('sdk.description', '/docs/references/avatars/get-credit-card.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_IMAGE_PNG)
|
||||
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: '.\implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))).'.')
|
||||
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: ' . \implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))) . '.')
|
||||
->param('width', 100, new Range(0, 2000), 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
@@ -160,11 +159,11 @@ App::get('/v1/avatars/image')
|
||||
|
||||
$quality = 80;
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/images-'.$url.'-'.$width.'/'.$height.'/'.$quality);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/images-' . $url . '-' . $width . '/' . $height . '/' . $quality);
|
||||
$type = 'png';
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 7 /* 1 week */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 7/* 1 week */);
|
||||
|
||||
if ($data) {
|
||||
return $response
|
||||
@@ -186,17 +185,17 @@ App::get('/v1/avatars/image')
|
||||
}
|
||||
|
||||
try {
|
||||
$resize = new Resize($fetch);
|
||||
} catch (\Exception $exception) {
|
||||
$image = new Image($fetch);
|
||||
} catch (\Exception$exception) {
|
||||
throw new Exception('Unable to parse image', 500);
|
||||
}
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
|
||||
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
$response
|
||||
@@ -206,7 +205,7 @@ App::get('/v1/avatars/image')
|
||||
->send($data);
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/avatars/favicon')
|
||||
@@ -229,11 +228,11 @@ App::get('/v1/avatars/favicon')
|
||||
$height = 56;
|
||||
$quality = 80;
|
||||
$output = 'png';
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/favicon-'.$url);
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
|
||||
$key = \md5('/v2/avatars/favicon-' . $url);
|
||||
$type = 'png';
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
|
||||
|
||||
if ($data) {
|
||||
return $response
|
||||
@@ -316,7 +315,7 @@ App::get('/v1/avatars/favicon')
|
||||
if (empty($outputHref) || empty($outputExt)) {
|
||||
$default = \parse_url($url);
|
||||
|
||||
$outputHref = $default['scheme'].'://'.$default['host'].'/favicon.ico';
|
||||
$outputHref = $default['scheme'] . '://' . $default['host'] . '/favicon.ico';
|
||||
$outputExt = 'ico';
|
||||
}
|
||||
|
||||
@@ -343,13 +342,13 @@ App::get('/v1/avatars/favicon')
|
||||
throw new Exception('Icon not found', 404);
|
||||
}
|
||||
|
||||
$resize = new Resize($fetch);
|
||||
$image = new Image($fetch);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
@@ -359,7 +358,7 @@ App::get('/v1/avatars/favicon')
|
||||
->addHeader('X-Appwrite-Cache', 'miss')
|
||||
->send($data);
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/avatars/qr')
|
||||
@@ -394,14 +393,14 @@ App::get('/v1/avatars/qr')
|
||||
$response->addHeader('Content-Disposition', 'attachment; filename="qr.png"');
|
||||
}
|
||||
|
||||
$resize = new Resize($qrcode->render($text));
|
||||
$image = new Image($qrcode->render($text));
|
||||
|
||||
$resize->crop((int) $size, (int) $size);
|
||||
$image->crop((int) $size, (int) $size);
|
||||
|
||||
$response
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
|
||||
->setContentType('image/png')
|
||||
->send($resize->output('png', 9))
|
||||
->send($image->output('png', 9))
|
||||
;
|
||||
});
|
||||
|
||||
@@ -437,10 +436,10 @@ App::get('/v1/avatars/initials')
|
||||
['color' => '#610038', 'background' => '#f5d1e6'], // PINK
|
||||
['color' => '#386100', 'background' => '#dcf1bd'], // LIME
|
||||
['color' => '#615800', 'background' => '#f1ecba'], // YELLOW
|
||||
['color' => '#610008', 'background' => '#f6d2d5'] // RED
|
||||
['color' => '#610008', 'background' => '#f6d2d5'], // RED
|
||||
];
|
||||
|
||||
$rand = \rand(0, \count($themes)-1);
|
||||
$rand = \rand(0, \count($themes) - 1);
|
||||
|
||||
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
|
||||
$words = \explode(' ', \strtoupper($name));
|
||||
@@ -457,23 +456,23 @@ App::get('/v1/avatars/initials')
|
||||
}
|
||||
|
||||
$length = \count($words);
|
||||
$rand = \substr($code,-1);
|
||||
$background = (!empty($background)) ? '#'.$background : $themes[$rand]['background'];
|
||||
$color = (!empty($color)) ? '#'.$color : $themes[$rand]['color'];
|
||||
$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->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);
|
||||
@@ -481,7 +480,7 @@ App::get('/v1/avatars/initials')
|
||||
//$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
|
||||
->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())
|
||||
;
|
||||
|
||||
@@ -169,8 +169,8 @@ App::put('/v1/database/collections/:collectionId')
|
||||
->label('sdk.response.model', Response::MODEL_COLLECTION)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID.')
|
||||
->param('name', null, new Text(128), 'Collection name. Max length: 128 chars.')
|
||||
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions(/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('rules', [], function ($projectDB) { return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]])); }, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation.', true, ['projectDB'])
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
@@ -187,6 +187,8 @@ App::put('/v1/database/collections/:collectionId')
|
||||
}
|
||||
|
||||
$parsedRules = [];
|
||||
$read = (is_null($read)) ? ($collection->getPermissions()['read'] ?? []) : $read; // By default inherit read permissions
|
||||
$write = (is_null($write)) ? ($collection->getPermissions()['write'] ?? []) : $write; // By default inherit write permissions
|
||||
|
||||
foreach ($rules as &$rule) {
|
||||
$parsedRules[] = \array_merge([
|
||||
@@ -295,17 +297,19 @@ App::post('/v1/database/collections/:collectionId/documents')
|
||||
->label('sdk.response.model', Response::MODEL_ANY)
|
||||
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('data', [], new JSON(), 'Document data as JSON object.')
|
||||
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('parentDocument', '', new UID(), 'Parent document unique ID. Use when you want your new document to be a child of a parent document.', true)
|
||||
->param('parentProperty', '', new Key(), 'Parent document property name. Use when you want your new document to be a child of a parent document.', true)
|
||||
->param('parentPropertyType', Document::SET_TYPE_ASSIGN, new WhiteList([Document::SET_TYPE_ASSIGN, Document::SET_TYPE_APPEND, Document::SET_TYPE_PREPEND], true), 'Parent document property connection type. You can set this value to **assign**, **append** or **prepend**, default value is assign. Use when you want your new document to be a child of a parent document.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('user')
|
||||
->inject('audits')
|
||||
->action(function ($collectionId, $data, $read, $write, $parentDocument, $parentProperty, $parentPropertyType, $response, $projectDB, $audits) {
|
||||
->action(function ($collectionId, $data, $read, $write, $parentDocument, $parentProperty, $parentPropertyType, $response, $projectDB, $user, $audits) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
|
||||
@@ -326,8 +330,8 @@ App::post('/v1/database/collections/:collectionId/documents')
|
||||
|
||||
$data['$collection'] = $collectionId; // Adding this param to make API easier for developers
|
||||
$data['$permissions'] = [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
'read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
|
||||
'write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
|
||||
];
|
||||
|
||||
// Read parent document + validate not 404 + validate read / write permission like patch method
|
||||
@@ -508,8 +512,8 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
||||
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('documentId', null, new UID(), 'Document unique ID.')
|
||||
->param('data', [], new JSON(), 'Document data as JSON object.')
|
||||
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('audits')
|
||||
@@ -522,7 +526,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
||||
$document = $projectDB->getDocument($documentId, false);
|
||||
|
||||
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
|
||||
|
||||
|
||||
if (!\is_array($data)) {
|
||||
throw new Exception('Data param should be a valid JSON object', 400);
|
||||
}
|
||||
@@ -535,20 +539,12 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
||||
throw new Exception('No document found', 404);
|
||||
}
|
||||
|
||||
//TODO check merge read write permissions
|
||||
|
||||
if (!empty($read)) { // Overwrite permissions only when passed
|
||||
$data['$permissions']['read'] = $read;
|
||||
}
|
||||
|
||||
if (!empty($write)) { // Overwrite permissions only when passed
|
||||
$data['$permissions']['write'] = $write;
|
||||
}
|
||||
|
||||
$data = \array_merge($document->getArrayCopy(), $data);
|
||||
|
||||
$data['$collection'] = $collection->getId(); // Make sure user don't switch collectionID
|
||||
$data['$id'] = $document->getId(); // Make sure user don't switch document unique ID
|
||||
$data['$permissions']['read'] = (is_null($read)) ? ($document->getPermissions()['read'] ?? []) : $read; // By default inherit read permissions
|
||||
$data['$permissions']['write'] = (is_null($write)) ? ($document->getPermissions()['write'] ?? []) : $write; // By default inherit write permissions
|
||||
|
||||
if (empty($data)) {
|
||||
throw new Exception('Missing payload', 400);
|
||||
|
||||
@@ -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(), [
|
||||
@@ -435,7 +435,7 @@ App::post('/v1/functions/:functionId/tags')
|
||||
->label('sdk.response.model', Response::MODEL_TAG)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('command', '', new Text('1028'), 'Code execution command.')
|
||||
->param('code', null, new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
|
||||
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
|
||||
@@ -254,7 +254,10 @@ App::get('/v1/health/anti-virus')
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
if (App::getEnv('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
|
||||
throw new Exception('Anitvirus is disabled');
|
||||
return $response->json([
|
||||
'status' => 'disabled',
|
||||
'version' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
$antiVirus = new Network(App::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,7 +18,7 @@ use Utopia\Storage\Validator\File;
|
||||
use Utopia\Storage\Validator\FileSize;
|
||||
use Utopia\Storage\Validator\Upload;
|
||||
use Utopia\Storage\Compression\Algorithms\GZIP;
|
||||
use Appwrite\Resize\Resize;
|
||||
use Utopia\Image\Image;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
@@ -38,17 +38,19 @@ App::post('/v1/storage/files')
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_FILE)
|
||||
->param('file', [], new File(), 'Binary file.', false)
|
||||
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('user')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($file, $read, $write, $request, $response, $projectDB, $audits, $usage) {
|
||||
->action(function ($file, $read, $write, $request, $response, $projectDB, $user, $audits, $usage) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
|
||||
@@ -122,8 +124,8 @@ App::post('/v1/storage/files')
|
||||
$file = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_FILES,
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
'read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
|
||||
'write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
|
||||
],
|
||||
'dateCreated' => \time(),
|
||||
'folderId' => '',
|
||||
@@ -332,17 +334,17 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
$source = $compressor->decompress($source);
|
||||
}
|
||||
|
||||
$resize = new Resize($source);
|
||||
$image = new Image($source);
|
||||
|
||||
$resize->crop((int) $width, (int) $height);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
|
||||
if (!empty($background)) {
|
||||
$resize->setBackground('#'.$background);
|
||||
$image->setBackground('#'.$background);
|
||||
}
|
||||
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
|
||||
$data = $resize->output($output, $quality);
|
||||
$data = $image->output($output, $quality);
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
@@ -353,7 +355,7 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
->send($data)
|
||||
;
|
||||
|
||||
unset($resize);
|
||||
unset($image);
|
||||
});
|
||||
|
||||
App::get('/v1/storage/files/:fileId/download')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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')
|
||||
@@ -256,6 +256,8 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
$template = ($route) ? $route->getLabel('error', null) : null;
|
||||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
Console::error('[Error] Timestamp: '.date('c', time()));
|
||||
|
||||
if($route) {
|
||||
Console::error('[Error] Method: '.$route->getMethod());
|
||||
Console::error('[Error] URL: '.$route->getURL());
|
||||
|
||||
+119
-38
@@ -2,8 +2,9 @@
|
||||
|
||||
global $utopia, $request, $response;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Response;
|
||||
use Utopia\Validator\Numeric;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\ArrayList;
|
||||
@@ -11,13 +12,16 @@ use Utopia\Validator\Host;
|
||||
use Utopia\Storage\Validator\File;
|
||||
|
||||
App::get('/v1/mock/tests/foo')
|
||||
->desc('Mock a get request for SDK tests')
|
||||
->desc('Get Foo')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'foo')
|
||||
->label('sdk.method', 'get')
|
||||
->label('sdk.description', 'Mock a get request for SDK tests')
|
||||
->label('sdk.description', 'Mock a get request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -26,13 +30,16 @@ App::get('/v1/mock/tests/foo')
|
||||
});
|
||||
|
||||
App::post('/v1/mock/tests/foo')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Post Foo')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'foo')
|
||||
->label('sdk.method', 'post')
|
||||
->label('sdk.description', 'Mock a post request for SDK tests')
|
||||
->label('sdk.description', 'Mock a post request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -41,13 +48,16 @@ App::post('/v1/mock/tests/foo')
|
||||
});
|
||||
|
||||
App::patch('/v1/mock/tests/foo')
|
||||
->desc('Mock a patch request for SDK tests')
|
||||
->desc('Patch Foo')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'foo')
|
||||
->label('sdk.method', 'patch')
|
||||
->label('sdk.description', 'Mock a get request for SDK tests')
|
||||
->label('sdk.description', 'Mock a patch request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -56,13 +66,16 @@ App::patch('/v1/mock/tests/foo')
|
||||
});
|
||||
|
||||
App::put('/v1/mock/tests/foo')
|
||||
->desc('Mock a put request for SDK tests')
|
||||
->desc('Put Foo')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'foo')
|
||||
->label('sdk.method', 'put')
|
||||
->label('sdk.description', 'Mock a put request for SDK tests')
|
||||
->label('sdk.description', 'Mock a put request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -71,13 +84,16 @@ App::put('/v1/mock/tests/foo')
|
||||
});
|
||||
|
||||
App::delete('/v1/mock/tests/foo')
|
||||
->desc('Mock a delete request for SDK tests')
|
||||
->desc('Delete Foo')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'foo')
|
||||
->label('sdk.method', 'delete')
|
||||
->label('sdk.description', 'Mock a delete request for SDK tests')
|
||||
->label('sdk.description', 'Mock a delete request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -86,13 +102,16 @@ App::delete('/v1/mock/tests/foo')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/bar')
|
||||
->desc('Mock a get request for SDK tests')
|
||||
->desc('Get Bar')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'bar')
|
||||
->label('sdk.method', 'get')
|
||||
->label('sdk.description', 'Mock a get request for SDK tests')
|
||||
->label('sdk.description', 'Mock a get request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -101,13 +120,16 @@ App::get('/v1/mock/tests/bar')
|
||||
});
|
||||
|
||||
App::post('/v1/mock/tests/bar')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Post Bar')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'bar')
|
||||
->label('sdk.method', 'post')
|
||||
->label('sdk.description', 'Mock a post request for SDK tests')
|
||||
->label('sdk.description', 'Mock a post request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -116,13 +138,16 @@ App::post('/v1/mock/tests/bar')
|
||||
});
|
||||
|
||||
App::patch('/v1/mock/tests/bar')
|
||||
->desc('Mock a patch request for SDK tests')
|
||||
->desc('Patch Bar')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'bar')
|
||||
->label('sdk.method', 'patch')
|
||||
->label('sdk.description', 'Mock a get request for SDK tests')
|
||||
->label('sdk.description', 'Mock a patch request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -131,13 +156,16 @@ App::patch('/v1/mock/tests/bar')
|
||||
});
|
||||
|
||||
App::put('/v1/mock/tests/bar')
|
||||
->desc('Mock a put request for SDK tests')
|
||||
->desc('Put Bar')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'bar')
|
||||
->label('sdk.method', 'put')
|
||||
->label('sdk.description', 'Mock a put request for SDK tests')
|
||||
->label('sdk.description', 'Mock a put request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -146,13 +174,16 @@ App::put('/v1/mock/tests/bar')
|
||||
});
|
||||
|
||||
App::delete('/v1/mock/tests/bar')
|
||||
->desc('Mock a delete request for SDK tests')
|
||||
->desc('Delete Bar')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'bar')
|
||||
->label('sdk.method', 'delete')
|
||||
->label('sdk.description', 'Mock a delete request for SDK tests')
|
||||
->label('sdk.description', 'Mock a delete request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -161,14 +192,17 @@ App::delete('/v1/mock/tests/bar')
|
||||
});
|
||||
|
||||
App::post('/v1/mock/tests/general/upload')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Upload File')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'upload')
|
||||
->label('sdk.description', 'Mock a delete request for SDK tests')
|
||||
->label('sdk.description', 'Mock a file upload request.')
|
||||
->label('sdk.request.type', 'multipart/form-data')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->param('x', '', new Text(100), 'Sample string param')
|
||||
->param('y', '', new Numeric(), 'Sample numeric param')
|
||||
@@ -203,13 +237,15 @@ App::post('/v1/mock/tests/general/upload')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/redirect')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Redirect')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'redirect')
|
||||
->label('sdk.description', 'Mock a redirect request for SDK tests')
|
||||
->label('sdk.description', 'Mock a redirect request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_MOVED_PERMANENTLY)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_HTML)
|
||||
->label('sdk.mock', true)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
@@ -219,25 +255,31 @@ App::get('/v1/mock/tests/general/redirect')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/redirect/done')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Redirected')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'redirected')
|
||||
->label('sdk.description', 'Mock a redirected request for SDK tests')
|
||||
->label('sdk.description', 'Mock a redirected request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->action(function () {
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/set-cookie')
|
||||
->desc('Mock a cookie request for SDK tests')
|
||||
->desc('Set Cookie')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'setCookie')
|
||||
->label('sdk.description', 'Mock a set cookie request for SDK tests')
|
||||
->label('sdk.description', 'Mock a set cookie request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
@@ -247,13 +289,16 @@ App::get('/v1/mock/tests/general/set-cookie')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/get-cookie')
|
||||
->desc('Mock a cookie request for SDK tests')
|
||||
->desc('Get Cookie')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'getCookie')
|
||||
->label('sdk.description', 'Mock a get cookie request for SDK tests')
|
||||
->label('sdk.description', 'Mock a cookie response.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->inject('request')
|
||||
->action(function ($request) {
|
||||
@@ -265,13 +310,15 @@ App::get('/v1/mock/tests/general/get-cookie')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/empty')
|
||||
->desc('Mock a post request for SDK tests')
|
||||
->desc('Empty Response')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'empty')
|
||||
->label('sdk.description', 'Mock a redirected request for SDK tests')
|
||||
->label('sdk.description', 'Mock a an empty response.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->label('sdk.mock', true)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
@@ -280,8 +327,40 @@ App::get('/v1/mock/tests/general/empty')
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/400-error')
|
||||
->desc('400 Error')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'error400')
|
||||
->label('sdk.description', 'Mock a an 400 failed request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_BAD_REQUEST)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ERROR)
|
||||
->label('sdk.mock', true)
|
||||
->action(function () {
|
||||
throw new Exception('Mock 400 error', 400);
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/500-error')
|
||||
->desc('500 Error')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'general')
|
||||
->label('sdk.method', 'error500')
|
||||
->label('sdk.description', 'Mock a an 500 failed request.')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_INTERNAL_SERVER_ERROR)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ERROR)
|
||||
->label('sdk.mock', true)
|
||||
->action(function () {
|
||||
throw new Exception('Mock 500 error', 500);
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2')
|
||||
->desc('Mock an OAuth2 login route')
|
||||
->desc('OAuth Login')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
@@ -298,7 +377,7 @@ App::get('/v1/mock/tests/general/oauth2')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2/token')
|
||||
->desc('Mock an OAuth2 login route')
|
||||
->desc('OAuth2 Token')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
@@ -327,7 +406,7 @@ App::get('/v1/mock/tests/general/oauth2/token')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2/user')
|
||||
->desc('Mock an OAuth2 user route')
|
||||
->desc('OAuth2 User')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
@@ -348,8 +427,9 @@ App::get('/v1/mock/tests/general/oauth2/user')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2/success')
|
||||
->label('scope', 'public')
|
||||
->desc('OAuth2 Success')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
@@ -361,6 +441,7 @@ App::get('/v1/mock/tests/general/oauth2/success')
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2/failure')
|
||||
->desc('OAuth2 Failure')
|
||||
->groups(['mock'])
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
@@ -397,5 +478,5 @@ App::shutdown(function($utopia, $response, $request) {
|
||||
throw new Exception('Failed to save resutls', 500);
|
||||
}
|
||||
|
||||
$response->json(['result' => $route->getMethod() . ':' . $route->getURL() . ':passed']);
|
||||
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getURL() . ':passed']), Response::MODEL_MOCK);
|
||||
}, ['utopia', 'response', 'request'], 'mock');
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+3
-3
@@ -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_CACHE_BUSTER = 145;
|
||||
const APP_VERSION_STABLE = '0.7.2';
|
||||
const APP_STORAGE_UPLOADS = '/storage/uploads';
|
||||
const APP_STORAGE_FUNCTIONS = '/storage/functions';
|
||||
const APP_STORAGE_CACHE = '/storage/cache';
|
||||
|
||||
+2
-3
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -124,7 +124,7 @@ $cli
|
||||
|
||||
$input[$var['name']] = Console::confirm($var['question'].' (default: \''.$var['default'].'\')');
|
||||
|
||||
if(empty($input[$key])) {
|
||||
if(empty($input[$var['name']])) {
|
||||
$input[$var['name']] = $var['default'];
|
||||
}
|
||||
}
|
||||
@@ -181,4 +181,4 @@ $cli
|
||||
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE.' - '.$message);
|
||||
Console::success($message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
+13
-1
@@ -42,7 +42,7 @@ $cli
|
||||
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
|
||||
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
|
||||
|
||||
if(!in_array($version, ['0.6.2', '0.7.0'])) {
|
||||
if(!in_array($version, ['0.6.x', '0.7.x'])) {
|
||||
throw new Exception('Unknown version given');
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ $cli
|
||||
$target = \realpath(__DIR__.'/..').'/sdks/git/'.$language['key'].'/';
|
||||
$readme = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/README.md');
|
||||
$readme = ($readme) ? \file_get_contents($readme) : '';
|
||||
$gettingStarted = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/GETTING_STARTED.md');
|
||||
$gettingStarted = ($gettingStarted) ? \file_get_contents($gettingStarted) : '';
|
||||
$examples = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/EXAMPLES.md');
|
||||
$examples = ($examples) ? \file_get_contents($examples) : '';
|
||||
$changelog = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/CHANGELOG.md');
|
||||
@@ -96,6 +98,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();
|
||||
@@ -178,6 +189,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
->setShareVia('appwrite_io')
|
||||
->setWarning($warning)
|
||||
->setReadme($readme)
|
||||
->setGettingStarted($gettingStarted)
|
||||
->setChangelog($changelog)
|
||||
->setExamples($examples)
|
||||
;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -117,7 +117,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
|
||||
<b data-ls-bind="{{tag.$id}}"></b>
|
||||
<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}} | {{tag.size|humanFileSize}}"></span>
|
||||
<span class="pull-start" data-ls-bind="Created {{tag.dateCreated|timeSince}} | {{tag.size|humanFileSize}}{{tag.size|humanFileUnit}}"></span>
|
||||
|
||||
<form data-ls-if="{{tag.$id}} !== {{project-function.tag}}" name="functions.deleteTag" class="pull-start"
|
||||
data-analytics
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
<button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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($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);
|
||||
|
||||
@@ -225,7 +225,7 @@ class FunctionsV1
|
||||
return;
|
||||
}
|
||||
|
||||
$cron = CronExpression::factory($function->getAttribute('schedule'));
|
||||
$cron = new CronExpression($function->getAttribute('schedule'));
|
||||
$next = (int) $cron->getNextRunDate()->format('U');
|
||||
|
||||
$function
|
||||
|
||||
@@ -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', []) : [];
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
/usr/src/code/vendor/bin/phpunit --verbose --configuration /usr/src/code/phpunit.xml $@
|
||||
/usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml $@
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
|
||||
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
|
||||
then
|
||||
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
else
|
||||
|
||||
+16
-12
@@ -15,7 +15,10 @@
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {"Tests\\E2E\\": "tests/e2e"}
|
||||
"psr-4": {
|
||||
"Tests\\E2E\\": "tests/e2e",
|
||||
"Appwrite\\Tests\\": "tests/extensions"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4.0",
|
||||
@@ -34,12 +37,12 @@
|
||||
|
||||
"appwrite/php-clamav": "1.0.*",
|
||||
|
||||
"utopia-php/framework": "0.10.0",
|
||||
"utopia-php/abuse": "0.3.*",
|
||||
"utopia-php/analytics": "0.1.*",
|
||||
"utopia-php/framework": "0.12.*",
|
||||
"utopia-php/abuse": "0.4.*",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"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.*",
|
||||
@@ -47,20 +50,21 @@
|
||||
"utopia-php/domains": "0.2.*",
|
||||
"utopia-php/swoole": "0.2.*",
|
||||
"utopia-php/system": "0.4.*",
|
||||
"utopia-php/storage": "0.2.*",
|
||||
"utopia-php/storage": "0.4.*",
|
||||
"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",
|
||||
"matomo/device-detector": "4.1.0",
|
||||
"dragonmantank/cron-expression": "3.1.0",
|
||||
"influxdb/influxdb-php": "1.15.2",
|
||||
"phpmailer/phpmailer": "6.1.7",
|
||||
"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": {
|
||||
"swoole/ide-helper": "4.6.2",
|
||||
"appwrite/sdk-generator": "0.5.5",
|
||||
"appwrite/sdk-generator": "0.6.3",
|
||||
"phpunit/phpunit": "9.4.2",
|
||||
"vimeo/psalm": "4.1.1"
|
||||
},
|
||||
|
||||
Generated
+552
-365
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user