diff --git a/CHANGES.md b/CHANGES.md index eba15ca01d..11f67a9ecd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,32 @@ # Version 0.7.1 (Not Released Yet) -- Updated missing storage env vars -- Added option to for Redis authentication -- Force adding a security email on setup +## Features + - Better error logs on appwrite cretificates 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 + +## Bug Fixes + +- Updated missing storage env vars + +## Security + +- Fixed an XSS vulnerability in the Appwrite console # Version 0.7.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a994337483..dd7217a9af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,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 @@ -157,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 diff --git a/Dockerfile b/Dockerfile index c7316bd1d4..7cd404b7ae 100755 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/README.md b/README.md index 681c8710ad..950c5a3010 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ docker run -it --rm , 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 @@ -133,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 diff --git a/app/config/variables.php b/app/config/variables.php index e842283c2c..14b29bc451 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -105,10 +105,10 @@ 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', - 'required' => false, + 'default' => '', + 'required' => true, 'question' => '', ], [ @@ -141,6 +141,22 @@ return [ 'required' => false, 'question' => '', ], + [ + 'name' => '_APP_REDIS_USER', + 'description' => 'Redis server user.', + 'introduction' => '0.7', + 'default' => '', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_REDIS_PASS', + 'description' => 'Redis server password.', + 'introduction' => '0.7', + 'default' => '', + 'required' => false, + 'question' => '', + ], ], ], [ @@ -239,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' => '', ], diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index fe2b53f71f..a094dc672a 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -1,28 +1,28 @@ 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()) ; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index e51fdd044f..7a6b11bcda 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -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(), [ diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index ed0d3a4435..63c99ffaee 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -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); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 98980fd6bd..d4500e95aa 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -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; @@ -332,17 +332,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 +353,7 @@ App::get('/v1/storage/files/:fileId/preview') ->send($data) ; - unset($resize); + unset($image); }); App::get('/v1/storage/files/:fileId/download') diff --git a/app/controllers/shared/web.php b/app/controllers/shared/web.php index 43eaf74d09..526a4dbb62 100644 --- a/app/controllers/shared/web.php +++ b/app/controllers/shared/web.php @@ -11,13 +11,18 @@ App::init(function ($utopia, $request, $response, $layout) { /* AJAX check */ if (!empty($request->getQuery('version', ''))) { - $layout->setPath(__DIR__.'/../../views/layouts/empty.phtml'); + $layout->setPath(__DIR__ . '/../../views/layouts/empty.phtml'); } - + + $port = $request->getPort(); + $protocol = $request->getProtocol(); + $domain = $request->getHostname(); + $layout ->setParam('title', APP_NAME) - ->setParam('protocol', $request->getProtocol()) - ->setParam('domain', $request->getHostname()) + ->setParam('protocol', $protocol) + ->setParam('domain', $domain) + ->setParam('endpoint', $protocol . '://' . $domain . ($port != 80 && $port != 443 ? ':' . $port : '')) ->setParam('home', App::getEnv('_APP_HOME')) ->setParam('setup', App::getEnv('_APP_SETUP')) ->setParam('class', 'unknown') @@ -34,10 +39,10 @@ App::init(function ($utopia, $request, $response, $layout) { $time = (60 * 60 * 24 * 45); // 45 days cache $response - ->addHeader('Cache-Control', 'public, max-age='.$time) - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $time).' GMT') // 45 days cache + ->addHeader('Cache-Control', 'public, max-age=' . $time) + ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $time) . ' GMT') // 45 days cache ->addHeader('X-Frame-Options', 'SAMEORIGIN') // Avoid console and homepage from showing in iframes - ->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url='.\urlencode($request->getURI())) + ->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url=' . \urlencode($request->getURI())) ->addHeader('X-UA-Compatible', 'IE=Edge') // Deny IE browsers from going into quirks mode ; diff --git a/app/controllers/web/console.php b/app/controllers/web/console.php index 6b3e105aa3..b41f1d1f86 100644 --- a/app/controllers/web/console.php +++ b/app/controllers/web/console.php @@ -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 diff --git a/app/controllers/web/home.php b/app/controllers/web/home.php index f302f0af33..1a25dc2ee6 100644 --- a/app/controllers/web/home.php +++ b/app/controllers/web/home.php @@ -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); }); \ No newline at end of file diff --git a/app/init.php b/app/init.php index ed2441d51b..a70ed1b88e 100644 --- a/app/init.php +++ b/app/init.php @@ -34,7 +34,7 @@ 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'; @@ -91,9 +91,13 @@ Config::load('storage-mimes', __DIR__.'/config/storage/mimes.php'); Config::load('storage-inputs', __DIR__.'/config/storage/inputs.php'); Config::load('storage-outputs', __DIR__.'/config/storage/outputs.php'); -Resque::setBackend(App::getEnv('_APP_REDIS_HOST', '') - .':'.App::getEnv('_APP_REDIS_PORT', '')); - +$user = App::getEnv('_APP_REDIS_USER',''); +$pass = App::getEnv('_APP_REDIS_PASS',''); +if(!empty($user) || !empty($pass)) { + Resque::setBackend('redis://'.$user.':'.$pass.'@'.App::getEnv('_APP_REDIS_HOST', '').':'.App::getEnv('_APP_REDIS_PORT', '')); +} else { + Resque::setBackend(App::getEnv('_APP_REDIS_HOST', '').':'.App::getEnv('_APP_REDIS_PORT', '')); +} /** * DB Filters */ @@ -176,6 +180,18 @@ $register->set('statsd', function () { // Register DB connection $register->set('cache', function () { // Register cache connection $redis = new Redis(); $redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', '')); + $user = App::getEnv('_APP_REDIS_USER',''); + $pass = App::getEnv('_APP_REDIS_PASS',''); + $auth = []; + if(!empty($user)) { + $auth["user"] = $user; + } + if(!empty($pass)) { + $auth["pass"] = $pass; + } + if(!empty($auth)) { + $redis->auth($auth); + } $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); return $redis; diff --git a/app/tasks/doctor.php b/app/tasks/doctor.php index 2918d4f1e4..0f601bb5b5 100644 --- a/app/tasks/doctor.php +++ b/app/tasks/doctor.php @@ -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'); diff --git a/app/views/console/database/collection.phtml b/app/views/console/database/collection.phtml index afe0365ee8..45d3287cf5 100644 --- a/app/views/console/database/collection.phtml +++ b/app/views/console/database/collection.phtml @@ -114,7 +114,7 @@ $maxCells = 10; - + {...} diff --git a/app/views/console/database/search/documents.phtml b/app/views/console/database/search/documents.phtml index 1b656dc4e4..6fb67feab1 100644 --- a/app/views/console/database/search/documents.phtml +++ b/app/views/console/database/search/documents.phtml @@ -72,7 +72,7 @@ $rules = $collection->getAttribute('rules', []); - + {...} diff --git a/app/views/console/database/search/files.phtml b/app/views/console/database/search/files.phtml index f8c39f4a87..0a1b4d739c 100644 --- a/app/views/console/database/search/files.phtml +++ b/app/views/console/database/search/files.phtml @@ -54,7 +54,7 @@ - + @@ -64,6 +64,7 @@ + diff --git a/app/views/console/functions/function.phtml b/app/views/console/functions/function.phtml index 49e2fffc41..4ae65f491e 100644 --- a/app/views/console/functions/function.phtml +++ b/app/views/console/functions/function.phtml @@ -117,7 +117,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);  
- +
getParam('usageStatsEnabled',true);

PowerShell

-
diff --git a/app/views/console/home/index.phtml b/app/views/console/home/index.phtml index e7164ebfde..1f3e95f1d9 100644 --- a/app/views/console/home/index.phtml +++ b/app/views/console/home/index.phtml @@ -97,7 +97,10 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
-
0
+
+ 0 + +
Bandwidth
@@ -117,7 +120,10 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
Documents
-
0
+
+ 0 + +
Storage
diff --git a/app/views/console/settings/index.phtml b/app/views/console/settings/index.phtml index 5eedb6388a..8cefd580cd 100644 --- a/app/views/console/settings/index.phtml +++ b/app/views/console/settings/index.phtml @@ -2,6 +2,7 @@ $customDomainsEnabled = $this->getParam('customDomainsEnabled', false); $customDomainsTarget = $this->getParam('customDomainsTarget', false); +$smtpEnabled = $this->getParam('smtpEnabled', false); ?>
@@ -135,7 +136,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
- +
    @@ -453,7 +454,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false); data-failure-param-alert-classname="error"> - + @@ -493,7 +494,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false); data-failure-param-alert-classname="error"> - + @@ -506,10 +507,16 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false); + +
    + SMTP connection is disabled. Learn more +
    + +
    - + disabled>Send Invite  
    diff --git a/app/views/console/storage/index.phtml b/app/views/console/storage/index.phtml index 934189f93c..6b03814ae2 100644 --- a/app/views/console/storage/index.phtml +++ b/app/views/console/storage/index.phtml @@ -113,7 +113,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0); - +
@@ -204,6 +204,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0); + diff --git a/app/views/console/users/index.phtml b/app/views/console/users/index.phtml index 8debcd9b4c..b41730baf9 100644 --- a/app/views/console/users/index.phtml +++ b/app/views/console/users/index.phtml @@ -361,7 +361,7 @@ $providers = $this->getParam('providers', []);

To complete set up, add this OAuth2 redirect URI to your escape(ucfirst($provider)); ?> app configuration.

- +
diff --git a/app/views/console/users/team.phtml b/app/views/console/users/team.phtml index 659fe3bd5a..ad6d263fac 100644 --- a/app/views/console/users/team.phtml +++ b/app/views/console/users/team.phtml @@ -145,7 +145,7 @@ data-failure-param-alert-classname="error"> - + diff --git a/app/views/home/auth/recovery.phtml b/app/views/home/auth/recovery.phtml index 575227a158..6f633b9a0c 100644 --- a/app/views/home/auth/recovery.phtml +++ b/app/views/home/auth/recovery.phtml @@ -23,7 +23,7 @@ - + diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index b98642fb94..1c0c98108f 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -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 @@ -66,6 +69,8 @@ services: - _APP_DOMAIN_TARGET - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -104,6 +109,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_STATSD_HOST - _APP_STATSD_PORT @@ -121,6 +128,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -142,6 +151,8 @@ services: - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -163,6 +174,8 @@ services: - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -187,6 +200,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -211,6 +226,8 @@ services: - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DOMAIN_TARGET - _APP_DB_HOST - _APP_DB_PORT @@ -236,6 +253,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -257,13 +276,14 @@ services: - appwrite depends_on: - redis - - smtp environment: - _APP_ENV - _APP_SYSTEM_EMAIL_NAME - _APP_SYSTEM_EMAIL_ADDRESS - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_SMTP_HOST - _APP_SMTP_PORT - _APP_SMTP_SECURE @@ -283,6 +303,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_ABUSE @@ -302,6 +324,8 @@ services: - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS mariadb: image: appwrite/mariadb:1.2.0 # fix issues when upgrading using: mysql_upgrade -u root -p @@ -318,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 diff --git a/app/views/layouts/default.phtml b/app/views/layouts/default.phtml index 1f0c686494..b019baa0df 100644 --- a/app/views/layouts/default.phtml +++ b/app/views/layouts/default.phtml @@ -2,6 +2,7 @@ $protocol = $this->getParam('protocol', ''); $domain = $this->getParam('domain', ''); +$endpoint = $this->getParam('endpoint', ''); $platforms = $this->getParam('platforms', []); $version = $this->getParam('version', '0.0.0'); $isDev = $this->getParam('isDev', false); @@ -56,7 +57,7 @@ if(!empty($platforms)) { - +