diff --git a/CHANGES.md b/CHANGES.md index 2ba4e152e..e680482ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,8 @@ - Added option to delete team from the console - Added option to view team members from the console - Added option to join a user to any team from the console +- Added support for Brotli compression +- UI performance & accessibility improvments ## Bug Fixes @@ -17,6 +19,7 @@ - Fixed network calculation for uploaded files - Fixed a UI bug preventing float values in numeric fields - Fixed scroll positioning when moving rules order up & down +- Fixed missing validation for database documents key length (32 chars) ## Security diff --git a/Dockerfile b/Dockerfile index efd1344c5..1f41c3e33 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ENV TZ=Asia/Tel_Aviv \ RUN \ apt-get update && \ - apt-get install -y --no-install-recommends --no-install-suggests ca-certificates software-properties-common wget curl git openssl && \ + apt-get install -y --no-install-recommends --no-install-suggests ca-certificates software-properties-common wget git openssl && \ LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \ apt-get update && \ apt-get install -y --no-install-recommends --no-install-suggests make php$PHP_VERSION php$PHP_VERSION-dev zip unzip php$PHP_VERSION-zip && \ @@ -23,7 +23,13 @@ RUN \ ./configure && \ make && \ # Composer - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer + wget https://getcomposer.org/composer.phar && \ + chmod +x ./composer.phar && \ + mv ./composer.phar /usr/bin/composer && \ + #Brotli + cd / && \ + git clone https://github.com/eustas/ngx_brotli.git && \ + cd ngx_brotli && git submodule update --init && cd .. WORKDIR /usr/local/src/ @@ -75,31 +81,50 @@ ENV TZ=Asia/Tel_Aviv \ #ENV _APP_SMTP_PASSWORD '' COPY --from=builder /phpredis-5.2.1/modules/redis.so /usr/lib/php/20190902/ +COPY --from=builder /phpredis-5.2.1/modules/redis.so /usr/lib/php/20190902/ +COPY --from=builder /ngx_brotli /ngx_brotli RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN \ apt-get update && \ - apt-get install -y --no-install-recommends --no-install-suggests wget curl ca-certificates software-properties-common openssl gnupg && \ + apt-get install -y --no-install-recommends --no-install-suggests wget ca-certificates software-properties-common build-essential libpcre3-dev zlib1g-dev libssl-dev openssl gnupg htop supervisor && \ LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \ add-apt-repository universe && \ add-apt-repository ppa:certbot/certbot && \ apt-get update && \ - apt-get install -y --no-install-recommends --no-install-suggests htop supervisor php$PHP_VERSION php$PHP_VERSION-fpm \ + apt-get install -y --no-install-recommends --no-install-suggests php$PHP_VERSION php$PHP_VERSION-fpm \ php$PHP_VERSION-mysqlnd php$PHP_VERSION-curl php$PHP_VERSION-imagick php$PHP_VERSION-mbstring php$PHP_VERSION-dom webp certbot && \ # Nginx - echo "deb http://nginx.org/packages/mainline/ubuntu/ bionic nginx" >> /etc/apt/sources.list.d/nginx.list && \ - wget -q http://nginx.org/keys/nginx_signing.key && \ - apt-key add nginx_signing.key && \ - apt-get update && \ - apt-get install -y --no-install-recommends --no-install-suggests nginx && \ + wget http://nginx.org/download/nginx-1.19.0.tar.gz && \ + tar -xzvf nginx-1.19.0.tar.gz && rm nginx-1.19.0.tar.gz && \ + cd nginx-1.19.0 && \ + ./configure --prefix=/usr/share/nginx \ + --sbin-path=/usr/sbin/nginx \ + --modules-path=/usr/lib/nginx/modules \ + --conf-path=/etc/nginx/nginx.conf \ + --error-log-path=/var/log/nginx/error.log \ + --http-log-path=/var/log/nginx/access.log \ + --pid-path=/run/nginx.pid \ + --lock-path=/var/lock/nginx.lock \ + --user=www-data \ + --group=www-data \ + --build=Ubuntu \ + --with-http_gzip_static_module \ + --with-http_ssl_module \ + --with-http_v2_module \ + --add-module=/ngx_brotli && \ + make && \ + make install && \ + rm -rf ../nginx-1.19.0 && \ # Redis Extension echo extension=redis.so >> /etc/php/$PHP_VERSION/fpm/conf.d/redis.ini && \ echo extension=redis.so >> /etc/php/$PHP_VERSION/cli/conf.d/redis.ini && \ # Cleanup cd ../ && \ - apt-get purge -y --auto-remove software-properties-common gnupg curl && \ + apt-get purge -y --auto-remove wget software-properties-common build-essential libpcre3-dev zlib1g-dev libssl-dev gnupg && \ apt-get clean && \ + rm -rf /ngx_brotli && \ rm -rf /var/lib/apt/lists/* # Set Upload Limit (default to 100MB) diff --git a/app/app.php b/app/app.php index 35f208b33..dcab392a7 100644 --- a/app/app.php +++ b/app/app.php @@ -27,6 +27,7 @@ $services = include __DIR__.'/config/services.php'; // List of services $webhook = new Event('v1-webhooks', 'WebhooksV1'); $audit = new Event('v1-audits', 'AuditsV1'); $usage = new Event('v1-usage', 'UsageV1'); +$mail = new Event('v1-mails', 'MailsV1'); $deletes = new Event('v1-deletes', 'DeletesV1'); /** @@ -53,7 +54,7 @@ $clients = array_unique(array_merge($clientsConsole, array_map(function ($node) return false; })))); -$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $console, $roles, $webhook, $audit, $usage, $clients) { +$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $console, $roles, $webhook, $mail, $audit, $usage, $clients) { $route = $utopia->match($request); diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 282a5d9a2..17369b0c3 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1,7 +1,7 @@ post('/v1/account') ->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.') ->param('name', '', function () { return new Text(100); }, 'User name.', true) ->action( - function ($email, $password, $name) use ($register, $request, $response, $audit, $projectDB, $project, $webhook, $oauth2Keys) { + function ($email, $password, $name) use ($request, $response, $audit, $projectDB, $project, $webhook, $oauth2Keys) { if ('console' === $project->getId()) { $whitlistEmails = $project->getAttribute('authWhitelistEmails'); $whitlistIPs = $project->getAttribute('authWhitelistIPs'); @@ -1053,7 +1053,7 @@ $utopia->post('/v1/account/recovery') ->param('email', '', function () { return new Email(); }, 'User email.') ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') ->action( - function ($email, $url) use ($request, $response, $projectDB, $register, $audit, $project) { + function ($email, $url) use ($request, $response, $projectDB, $mail, $audit, $project) { $profile = $projectDB->getCollection([ // Get user by email address 'limit' => 1, 'first' => true, @@ -1106,19 +1106,14 @@ $utopia->post('/v1/account/recovery') ->setParam('{{redirect}}', $url) ; - $mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */ - - $mail->addAddress($profile->getAttribute('email', ''), $profile->getAttribute('name', '')); - - $mail->Subject = Locale::getText('account.emails.recovery.title'); - $mail->Body = $body->render(); - $mail->AltBody = strip_tags($body->render()); - - try { - $mail->send(); - } catch (\Exception $error) { - throw new Exception('Error sending mail: ' . $error->getMessage(), 500); - } + $mail + ->setParam('event', 'account.recovery.create') + ->setParam('recipient', $profile->getAttribute('email', '')) + ->setParam('name', $profile->getAttribute('name', '')) + ->setParam('subject', Locale::getText('account.emails.recovery.title')) + ->setParam('body', $body->render()) + ->trigger(); + ; $audit ->setParam('userId', $profile->getId()) @@ -1214,7 +1209,7 @@ $utopia->post('/v1/account/verification') ->label('abuse-key', 'url:{url},email:{param-email}') ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add built-in confirm page ->action( - function ($url) use ($request, $response, $register, $user, $project, $projectDB, $audit) { + function ($url) use ($request, $response, $mail, $user, $project, $projectDB, $audit) { $verificationSecret = Auth::tokenGenerator(); $verification = new Document([ @@ -1255,19 +1250,14 @@ $utopia->post('/v1/account/verification') ->setParam('{{redirect}}', $url) ; - $mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */ - - $mail->addAddress($user->getAttribute('email'), $user->getAttribute('name')); - - $mail->Subject = Locale::getText('account.emails.verification.title'); - $mail->Body = $body->render(); - $mail->AltBody = strip_tags($body->render()); - - try { - $mail->send(); - } catch (\Exception $error) { - throw new Exception('Problem sending mail: ' . $error->getMessage(), 500); - } + $mail + ->setParam('event', 'account.verification.create') + ->setParam('recipient', $user->getAttribute('email')) + ->setParam('name', $user->getAttribute('name')) + ->setParam('subject', Locale::getText('account.emails.verification.title')) + ->setParam('body', $body->render()) + ->trigger() + ; $audit ->setParam('userId', $user->getId()) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index ded2445fa..54ff361a5 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -1,6 +1,6 @@ post('/v1/teams/:teamId/memberships') ->param('roles', [], function () { return new ArrayList(new Text(128)); }, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions).') ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add our own built-in confirm page ->action( - function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB, $mode) { + function ($teamId, $email, $name, $roles, $url) use ($response, $mail, $project, $user, $audit, $projectDB, $mode) { $name = (empty($name)) ? $email : $name; $team = $projectDB->getDocument($teamId); @@ -332,20 +332,15 @@ $utopia->post('/v1/teams/:teamId/memberships') ->setParam('{{redirect}}', $url) ; - $mail = $register->get('smtp'); /* @var $mail \PHPMailer\PHPMailer\PHPMailer */ - - $mail->addAddress($email, $name); - - $mail->Subject = sprintf(Locale::getText('account.emails.invitation.title'), $team->getAttribute('name', '[TEAM-NAME]'), $project->getAttribute('name', ['[APP-NAME]'])); - $mail->Body = $body->render(); - $mail->AltBody = strip_tags($body->render()); - - try { - if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode - $mail->send(); - } - } catch (\Exception $error) { - throw new Exception('Error sending mail: ' . $error->getMessage(), 500); + if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode + $mail + ->setParam('event', 'teams.membership.create') + ->setParam('recipient', $email) + ->setParam('name', $name) + ->setParam('subject', sprintf(Locale::getText('account.emails.invitation.title'), $team->getAttribute('name', '[TEAM-NAME]'), $project->getAttribute('name', ['[APP-NAME]']))) + ->setParam('body', $body->render()) + ->trigger(); + ; } $audit diff --git a/app/controllers/web/console.php b/app/controllers/web/console.php index d90966ba7..ff59b0307 100644 --- a/app/controllers/web/console.php +++ b/app/controllers/web/console.php @@ -14,6 +14,7 @@ use Appwrite\Storage\Storage; $utopia->init(function () use ($layout) { $layout + ->setParam('description', 'Appwrite Console allows you to easily manage, monitor, and control your entire backend API and tools.') ->setParam('analytics', 'UA-26264668-5') ; }); diff --git a/app/views/console/comps/footer.phtml b/app/views/console/comps/footer.phtml index e8f7770d6..c96683939 100644 --- a/app/views/console/comps/footer.phtml +++ b/app/views/console/comps/footer.phtml @@ -9,21 +9,21 @@ $version = $this->getParam('version', '').'.'.APP_CACHE_BUSTER; data-analytics-event="click" data-analytics-category="console/footer" data-analytics-label="GitHub Link" - href="https://github.com/appwrite/appwrite" target="_blank"> GitHub + href="https://github.com/appwrite/appwrite" target="_blank" rel="noopener"> GitHub
  • Open an Issue + href="https://github.com/appwrite/appwrite/issues/new?body=%0A%0A%0A---%0AAppwrite Version:%20" target="_blank" rel="noopener">Open an Issue
  • Docs + href="/docs" target="_blank" rel="noopener">Docs
  • v: diff --git a/app/views/console/comps/header.phtml b/app/views/console/comps/header.phtml index 6588adf4e..4a8d58643 100644 --- a/app/views/console/comps/header.phtml +++ b/app/views/console/comps/header.phtml @@ -42,7 +42,7 @@ -
    +
    -