1
0
Fork 0
mirror of synced 2024-06-02 02:44:47 +12:00

Merge branch 'dev' into feat-anon-login

This commit is contained in:
Torsten Dittmann 2021-02-23 23:44:59 +01:00 committed by GitHub
commit 6e5ce2c646
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 598 additions and 390 deletions

View file

@ -1,10 +1,34 @@
# Version DEV (NOT RELEASED YET)
# Version 0.8.0 (Not Released Yet)
## Features
- Added Anonymous Login ([RFC-010](https://github.com/appwrite/rfc/blob/main/010-anonymous-login.md))
- Added new Environment Variable to enable or disable Anonymous Login
# Version 0.7.1 (Not Released Yet)
## Features
- Added option for Redis authentication
- Force adding a security email on setup
- Better error logs on appwrite cretificates worker## Upgrades
- SMTP is now disabled by default, no dummy SMTP is included in setup
## 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
# Version 0.7.0
## Features

View file

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

View file

@ -301,7 +301,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '0.4.0',
'version' => '0.5.0',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://github.com/appwrite/sdk-for-cli',
'enabled' => true,

View file

@ -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' => '',
],
[
@ -149,6 +149,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' => '',
],
],
],
[
@ -247,17 +263,17 @@ return [
'variables' => [
[
'name' => '_APP_SMTP_HOST',
'description' => 'SMTP server host name address. Default value is: \'smtp\'. Pass an empty string to disable all mail sending from the server.',
'description' => 'SMTP server host name address. Use an empty string to disable all mail sending from the server. The default value for this variable is an empty string',
'introduction' => '',
'default' => 'smtp',
'default' => '',
'required' => false,
'question' => '',
],
[
'name' => '_APP_SMTP_PORT',
'description' => 'SMTP server TCP port. Default value is: \'25\'.',
'description' => 'SMTP server TCP port. Empty by default.',
'introduction' => '',
'default' => '25',
'default' => '',
'required' => false,
'question' => '',
],

View file

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

View file

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

View file

@ -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
;

View file

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

View file

@ -34,12 +34,12 @@ 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 = 143;
const APP_CACHE_BUSTER = 144;
const APP_VERSION_STABLE = '0.7.0';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
@ -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;

View file

@ -114,7 +114,7 @@ $maxCells = 10;
<?php if(!$array): ?>
<?php switch($type):
case 'fileId': ?>
<img data-ls-if="{{node.<?php echo $this->escape($key); ?>}} != ''" src="" data-ls-attrs="src=//{{env.DOMAIN}}/v1/storage/files/{{node.<?php echo $this->escape($key); ?>}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="avatar" width="30" height="30" loading="lazy" />
<img data-ls-if="{{node.<?php echo $this->escape($key); ?>}} != ''" src="" data-ls-attrs="src={{env.ENDPOINT}}/v1/storage/files/{{node.<?php echo $this->escape($key); ?>}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="avatar" width="30" height="30" loading="lazy" />
<?php break; ?>
<?php case 'document': ?>
{...}

View file

@ -72,7 +72,7 @@ $rules = $collection->getAttribute('rules', []);
<?php if(!$array): ?>
<?php switch($type):
case 'fileId': ?>
<img data-ls-if="{{node.<?php echo $this->escape($key); ?>}} != ''" src="" data-ls-attrs="src=//{{env.DOMAIN}}/v1/storage/files/{{node.<?php echo $this->escape($key); ?>}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="avatar" width="30" height="30" loading="lazy" />
<img data-ls-if="{{node.<?php echo $this->escape($key); ?>}} != ''" src="" data-ls-attrs="src={{env.ENDPOINT}}/v1/storage/files/{{node.<?php echo $this->escape($key); ?>}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="avatar" width="30" height="30" loading="lazy" />
<?php break; ?>
<?php case 'document': ?>
{...}

View file

@ -54,7 +54,7 @@
<input type="radio" name="selected" data-ls-attrs="value={{file.$id}}" data-ls-bind="{{search.selected}}" />
</td>
<td data-title="x" class="">
<img src="" data-ls-attrs="src=//{{env.DOMAIN}}/v1/storage/files/{{file.$id}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="pull-start avatar" width="30" height="30" loading="lazy" />
<img src="" data-ls-attrs="src={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="pull-start avatar" width="30" height="30" loading="lazy" />
</td>
<td data-title="Name: " class="text-one-liner">
<span data-ls-bind="{{file.name}}" data-ls-attrs="title={{file.name}}" class="text-fade text-size-small"></span>

View file

@ -596,9 +596,9 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<p><b>PowerShell</b></p>
<div class="margin-bottom">
<textarea type="hidden" data-ls-bind="appwrite functions createTag ,
--functionId={{project-function.$id}} ,
--command='mycommand' ,
<textarea type="hidden" data-ls-bind="appwrite functions createTag `
--functionId={{project-function.$id}} `
--command='mycommand' `
--code='/myrepo/myfunction'" data-forms-code="powershell" data-lang="powershell" data-lang-label="PowerShell"></textarea>
</div>

View file

@ -2,6 +2,7 @@
$customDomainsEnabled = $this->getParam('customDomainsEnabled', false);
$customDomainsTarget = $this->getParam('customDomainsTarget', false);
$smtpEnabled = $this->getParam('smtpEnabled', false);
?>
<div class="cover">
@ -135,7 +136,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
<label for="name">API Endpoint</label>
<div class="input-copy">
<input data-forms-copy type="text" disabled data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}/v1" />
<input data-forms-copy type="text" disabled data-ls-bind="{{env.ENDPOINT}}/v1" />
</div>
<ul class="margin-bottom-large text-fade text-size-small">
@ -453,7 +454,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
data-failure-param-alert-classname="error">
<input name="teamId" type="hidden" data-ls-bind="{{member.teamId}}">
<input name="url" type="hidden" data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}/auth/join?project={{router.params.project}}" />
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}/auth/join?project={{router.params.project}}" />
<input name="email" type="hidden" data-ls-bind="{{member.email}}">
<input name="name" type="hidden" data-ls-bind="{{member.name}}">
<input name="roles" type="hidden" data-ls-bind="{{member.roles}}" data-cast-to="json">
@ -493,7 +494,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
data-failure-param-alert-classname="error">
<input name="teamId" id="team-teamId" type="hidden" data-ls-bind="{{console-project.teamId}}">
<input name="url" type="hidden" data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}/auth/join?project={{router.params.project}}" />
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}/auth/join?project={{router.params.project}}" />
<label for="email">Email</label>
<input name="email" id="email" type="email" autocomplete="email" required>
@ -506,10 +507,16 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
<option data-ls-attrs="value={{role.type}}" data-ls-bind="{{role.label}}"></option>
</select>
<?php if(!$smtpEnabled): ?>
<div class="box note padding-tiny warning margin-bottom text-align-center">
<i class="icon-warning"></i> SMTP connection is disabled. <a href="https://appwrite.io/docs/email-delivery" target="_blank" rel="noopener">Learn more <i class="icon-link-ext"></i></a>
</div>
<?php endif; ?>
<hr />
<div class="clear">
<button>Send Invite</button>
<button<?php if(!$smtpEnabled): ?> disabled<?php endif; ?>>Send Invite</button>
&nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
</form>

View file

@ -113,7 +113,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<tbody data-ls-loop="project-files.files" data-ls-as="file">
<tr>
<td class="hide">
<img src="" data-ls-attrs="src=//{{env.DOMAIN}}/v1/storage/files/{{file.$id}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="pull-start avatar" width="30" height="30" loading="lazy" />
<img src="" data-ls-attrs="src={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/preview?width=65&height=65&project={{router.params.project}}&mode=admin" class="pull-start avatar" width="30" height="30" loading="lazy" />
</td>
<td data-title="Name: " class="text-one-liner" data-ls-attrs="title={{file.name}}" >
<div data-ui-modal class="box modal sticky-footer width-large close" data-button-text="{{file.name}}" data-button-class="link" data-button-element="span">
@ -180,15 +180,15 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<div class="margin-bottom-small">File Preview</div>
<div class="margin-bottom-small">
<img src="" class="file-preview" data-ls-attrs="src=//{{env.DOMAIN}}/v1/storage/files/{{file.$id}}/preview?width=350&height=250&project={{router.params.project}}&mode=admin" loading="lazy" width="225" height="160" />
<img src="" class="file-preview" data-ls-attrs="src={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/preview?width=350&height=250&project={{router.params.project}}&mode=admin" loading="lazy" width="225" height="160" />
</div>
<div class="margin-bottom-tiny">
<a href="" data-ls-attrs="href=//{{env.DOMAIN}}/v1/storage/files/{{file.$id}}/view?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> New Window <i class="icon-link-ext"></i></a>
<a href="" data-ls-attrs="href={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/view?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> New Window <i class="icon-link-ext"></i></a>
</div>
<div class="margin-bottom">
<a href="" data-ls-attrs="href=//{{env.DOMAIN}}/v1/storage/files/{{file.$id}}/download?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Download <i class="icon-link-ext"></i></a>
<a href="" data-ls-attrs="href={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/download?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Download <i class="icon-link-ext"></i></a>
</div>
</div>
</div>

View file

@ -361,7 +361,7 @@ $providers = $this->getParam('providers', []);
<p>To complete set up, add this OAuth2 redirect URI to your <?php echo $this->escape(ucfirst($provider)); ?> app configuration.</p>
<div class="input-copy">
<input data-forms-copy type="text" disabled data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}/v1/account/sessions/oauth2/callback/<?php echo $this->escape($provider); ?>/{{router.params.project}}" class="margin-bottom-no" />
<input data-forms-copy type="text" disabled data-ls-bind="{{env.ENDPOINT}}/v1/account/sessions/oauth2/callback/<?php echo $this->escape($provider); ?>/{{router.params.project}}" class="margin-bottom-no" />
</div>
</div>
</div>

View file

@ -145,7 +145,7 @@
data-failure-param-alert-classname="error">
<input name="teamId" id="team-teamId" type="hidden" data-ls-bind="{{team.$id}}">
<input name="url" type="hidden" data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}" />
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}" />
<label for="email">Email</label>
<input name="email" id="email" type="email" autocomplete="email" required>

View file

@ -23,7 +23,7 @@
<label>Email</label>
<input name="email" type="email" class="full-width" autocomplete="email" placeholder="me@example.com" required>
<input name="url" type="hidden" data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}/auth/recovery/reset" />
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}/auth/recovery/reset" />
<button type="submit" class="btn btn-primary"><i class="fa fa-sign-in"></i> Recover</button>
</form>

View file

@ -56,9 +56,12 @@ services:
- influxdb
environment:
- _APP_ENV
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_SYSTEM_RESPONSE_FORMAT
- _APP_OPTIONS_ABUSE
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
@ -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
@ -105,6 +110,8 @@ services:
- _APP_ENV
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_STATSD_HOST
- _APP_STATSD_PORT
@ -122,6 +129,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
@ -143,6 +152,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
@ -164,6 +175,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
@ -188,6 +201,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
@ -212,6 +227,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
@ -237,6 +254,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
@ -258,13 +277,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
@ -284,6 +304,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
@ -303,6 +325,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
@ -319,16 +343,6 @@ services:
- MYSQL_PASSWORD=${_APP_DB_PASS}
command: 'mysqld --innodb-flush-method=fsync'
smtp:
image: appwrite/smtp:1.0.1
container_name: appwrite-smtp
restart: unless-stopped
networks:
- appwrite
environment:
- MAILNAME=appwrite
- RELAY_NETWORKS=:192.168.0.0/24:10.0.0.0/16
redis:
image: redis:6.0-alpine3.12
container_name: appwrite-redis

View file

@ -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)) {
<?php if (!empty($canonical)): ?>
<meta property="og:url" content="<?php echo $canonical; ?>" />
<?php endif; ?>
<meta property="og:image" content="<?php echo $protocol; ?>://<?php echo $domain; ?>/images/logo.png?v=<?php echo APP_CACHE_BUSTER; ?>" />
<meta property="og:image" content="<?php echo $endpoint; ?>/images/logo.png?v=<?php echo APP_CACHE_BUSTER; ?>" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
@ -71,6 +72,7 @@ if(!empty($platforms)) {
VERSION: '<?php echo $version; ?>',
CACHEBUSTER: '<?php echo $version; ?>/<?php echo APP_CACHE_BUSTER; ?>',
PROTOCOL: '<?php echo $protocol; ?>',
ENDPOINT: '<?php echo $endpoint; ?>',
DOMAIN: '<?php echo $domain; ?>',
HOME: '<?php echo $this->escape($this->getParam('home')); ?>',
SETUP: '<?php echo $this->escape($this->getParam('setup')); ?>',
@ -142,4 +144,4 @@ if(!empty($platforms)) {
<!-- Version <?php echo $version; ?> -->
</body>
</html>
</html>

View file

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

View file

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

View file

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

View file

@ -1,3 +1,10 @@
#!/bin/sh
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
REDIS_BACKEND=$REDIS_BACKEND RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

9
bin/worker-certificates Normal file → Executable file
View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-certificates' APP_INCLUDE='/usr/src/code/app/workers/certificates.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-certificates' APP_INCLUDE='/usr/src/code/app/workers/certificates.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-deletes' APP_INCLUDE='/usr/src/code/app/workers/deletes.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-deletes' APP_INCLUDE='/usr/src/code/app/workers/deletes.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

@ -1,3 +1,10 @@
#!/bin/sh
QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php

View file

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

604
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -86,6 +86,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
@ -128,6 +130,8 @@ services:
- _APP_ENV
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_STATSD_HOST
- _APP_STATSD_PORT
@ -148,6 +152,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
@ -173,6 +179,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
@ -197,6 +205,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
@ -224,6 +234,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
@ -250,6 +262,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
@ -277,6 +291,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
@ -311,6 +327,8 @@ services:
- _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
@ -333,6 +351,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
@ -354,6 +374,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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,14 @@
display: block;
border-bottom: none;
&.padding-tiny {
padding: 5px;
}
&.padding-xs {
padding: 10px;
}
&.padding-small {
padding: 15px;
}
@ -53,7 +61,7 @@
}
&.warning {
background: var(--config-color-success);
background: var(--config-color-warning);
color: #2d2d2d;
button,

View file

@ -53,6 +53,14 @@
}
}
&.padding-tiny {
padding: 5px;
}
&.padding-xs {
padding: 10px;
}
&.padding-small {
padding: 15px;
}

View file

@ -27,7 +27,7 @@
--config-color-fade-super: #f1f3f5;
--config-color-danger: #f53d3d;
--config-color-success: #1bbf61;
--config-color-warning: #ffed4d;
--config-color-warning: #fffbdd;
--config-color-info: #386fd2;
--config-border-color: #f3f3f3;
--config-border-fade: #e0e3e4;

View file

@ -38,7 +38,7 @@ class DetectorTest extends TestCase
'clientName' => 'Firefox',
'clientVersion' => '47.0',
'clientEngine' => 'Gecko',
'clientEngineVersion' => '',
'clientEngineVersion' => '47.0',
]);
}