Merge branch 'master' into feat-4803-flutter-web-platform-type

This commit is contained in:
Steven 2023-01-20 12:04:58 -08:00 committed by GitHub
commit e14f4404e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 183 additions and 195 deletions

View file

@ -4,6 +4,8 @@
## Changes
## Bugs
- Fix a few null safety warnings [#4654](https://github.com/appwrite/appwrite/pull/4654)
- Fix timestamp format in Realtime response [#4515](https://github.com/appwrite/appwrite/pull/4515)
- Add flutter-web as a platform type [#4992](https://github.com/appwrite/appwrite/pull/4992)
# Version 1.2.0

View file

@ -713,11 +713,33 @@ App::post('/v1/account/sessions/magic-url')
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $loginSecret, 'expire' => $expire, 'project' => $project->getId()]);
$url = Template::unParseURL($url);
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $project->getAttribute('name'));
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl');
$subject = $locale->getText("emails.magicSession.subject");
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("emails.magicSession.hello"))
->setParam('{{name}}', '')
->setParam('{{body}}', $locale->getText("emails.magicSession.body"))
->setParam('{{redirect}}', $url)
->setParam('{{footer}}', $locale->getText("emails.magicSession.footer"))
->setParam('{{thanks}}', $locale->getText("emails.magicSession.thanks"))
->setParam('{{signature}}', $locale->getText("emails.magicSession.signature"))
->setParam('{{project}}', $project->getAttribute('name'))
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$mails
->setType(MAIL_TYPE_MAGIC_SESSION)
->setSubject($subject)
->setBody($body)
->setFrom($from)
->setRecipient($user->getAttribute('email'))
->setUrl($url)
->setLocale($locale->default)
->trigger()
;
@ -1991,12 +2013,35 @@ App::post('/v1/account/recovery')
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret, 'expire' => $expire]);
$url = Template::unParseURL($url);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl');
$subject = $locale->getText("emails.recovery.subject");
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("emails.recovery.hello"))
->setParam('{{name}}', $profile->getAttribute('name'))
->setParam('{{body}}', $locale->getText("emails.recovery.body"))
->setParam('{{redirect}}', $url)
->setParam('{{footer}}', $locale->getText("emails.recovery.footer"))
->setParam('{{thanks}}', $locale->getText("emails.recovery.thanks"))
->setParam('{{signature}}', $locale->getText("emails.recovery.signature"))
->setParam('{{project}}', $projectName)
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$mails
->setType(MAIL_TYPE_RECOVERY)
->setRecipient($profile->getAttribute('email', ''))
->setUrl($url)
->setLocale($locale->default)
->setName($profile->getAttribute('name'))
->setBody($body)
->setFrom($from)
->setSubject($subject)
->trigger();
;
@ -2151,11 +2196,32 @@ App::post('/v1/account/verification')
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret, 'expire' => $expire]);
$url = Template::unParseURL($url);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl');
$subject = $locale->getText("emails.verification.subject");
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("emails.verification.hello"))
->setParam('{{name}}', $user->getAttribute('name'))
->setParam('{{body}}', $locale->getText("emails.verification.body"))
->setParam('{{redirect}}', $url)
->setParam('{{footer}}', $locale->getText("emails.verification.footer"))
->setParam('{{thanks}}', $locale->getText("emails.verification.thanks"))
->setParam('{{signature}}', $locale->getText("emails.verification.signature"))
->setParam('{{project}}', $projectName)
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$mails
->setType(MAIL_TYPE_VERIFICATION)
->setSubject($subject)
->setBody($body)
->setFrom($from)
->setRecipient($user->getAttribute('email'))
->setUrl($url)
->setLocale($locale->default)
->setName($user->getAttribute('name'))
->trigger()
;

View file

@ -242,8 +242,8 @@ App::get('/v1/avatars/favicon')
case 'jpeg':
$size = \explode('x', \strtolower($sizes));
$sizeWidth = (int) $size[0] ?? 0;
$sizeHeight = (int) $size[1] ?? 0;
$sizeWidth = (int) ($size[0] ?? 0);
$sizeHeight = (int) ($size[1] ?? 0);
if (($sizeWidth * $sizeHeight) >= $space) {
$space = $sizeWidth * $sizeHeight;

View file

@ -549,6 +549,11 @@ App::post('/v1/storage/buckets/:bucketId/files')
$sizeActual = $deviceFiles->getFileSize($path);
$fileHash = $deviceFiles->getFileHash($path);
$openSSLVersion = null;
$openSSLCipher = null;
$openSSLTag = null;
$openSSLIV = null;
if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) {
$openSSLVersion = '1';
$openSSLCipher = OpenSSL::CIPHER_AES_128_GCM;

View file

@ -434,14 +434,37 @@ App::post('/v1/teams/:teamId/memberships')
$url = Template::unParseURL($url);
if (!$isPrivilegedUser && !$isAppUser) { // No need of confirmation when in admin or app mode
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl');
$subject = \sprintf($locale->getText("emails.invitation.subject"), $team->getAttribute('name'), $projectName);
$body->setParam('{{owner}}', $user->getAttribute('name'));
$body->setParam('{{team}}', $team->getAttribute('name'));
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("emails.invitation.hello"))
->setParam('{{name}}', $user->getAttribute('name'))
->setParam('{{body}}', $locale->getText("emails.invitation.body"))
->setParam('{{redirect}}', $url)
->setParam('{{footer}}', $locale->getText("emails.invitation.footer"))
->setParam('{{thanks}}', $locale->getText("emails.invitation.thanks"))
->setParam('{{signature}}', $locale->getText("emails.invitation.signature"))
->setParam('{{project}}', $projectName)
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$mails
->setType(MAIL_TYPE_INVITATION)
->setRecipient($email)
->setUrl($url)
->setName($name)
->setLocale($locale->default)
->setTeam($team)
->setUser($user)
->setSubject($subject)
->setBody($body)
->setFrom($from)
->setRecipient($invitee->getAttribute('email'))
->setName($invitee->getAttribute('name'))
->trigger()
;
}

View file

@ -98,13 +98,12 @@ App::init()
->inject('user')
->inject('events')
->inject('audits')
->inject('mails')
->inject('usage')
->inject('deletes')
->inject('database')
->inject('dbForProject')
->inject('mode')
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $events, Audit $audits, Mail $mails, Stats $usage, Delete $deletes, EventDatabase $database, Database $dbForProject, string $mode) use ($databaseListener) {
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, Database $dbForProject, string $mode) use ($databaseListener) {
$route = $utopia->match($request);
@ -178,10 +177,6 @@ App::init()
->setProject($project)
->setUser($user);
$mails
->setProject($project)
->setUser($user);
$audits
->setMode($mode)
->setUserAgent($request->getUserAgent(''))

View file

@ -237,7 +237,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
'data' => [
'events' => ['stats.connections'],
'channels' => ['project'],
'timestamp' => DateTime::now(),
'timestamp' => DateTime::formatTz(DateTime::now()),
'payload' => [
$projectId => $payload[$projectId]
]
@ -264,7 +264,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
'data' => [
'events' => ['test.event'],
'channels' => ['tests'],
'timestamp' => DateTime::now(),
'timestamp' => DateTime::formatTz(DateTime::now()),
'payload' => $payload
]
];

View file

@ -4,6 +4,7 @@ use Appwrite\Event\Event;
use Appwrite\Event\Mail;
use Appwrite\Network\Validator\CNAME;
use Appwrite\Resque\Worker;
use Appwrite\Template\Template;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Database\Database;
@ -12,6 +13,7 @@ use Utopia\Database\DateTime;
use Utopia\Database\ID;
use Utopia\Database\Query;
use Utopia\Domains\Domain;
use Utopia\Locale\Locale;
require_once __DIR__ . '/../init.php';
@ -375,18 +377,38 @@ class CertificatesV1 extends Worker
Console::warning('Cannot renew domain (' . $domain . ') on attempt no. ' . $attempt . ' certificate: ' . $errorMessage);
// Send mail to administratore mail
$locale = new Locale(App::getEnv('_APP_LOCALE', 'en'));
if (!$locale->getText('emails.sender') || !$locale->getText("emails.certificate.hello") || !$locale->getText("emails.certificate.subject") || !$locale->getText("emails.certificate.body") || !$locale->getText("emails.certificate.footer") || !$locale->getText("emails.certificate.thanks") || !$locale->getText("emails.certificate.signature")) {
$locale->setDefault('en');
}
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl');
$subject = \sprintf($locale->getText("emails.certificate.subject"), $domain);
$body->setParam('{{domain}}', $domain);
$body->setParam('{{error}}', $errorMessage);
$body->setParam('{{attempt}}', $attempt);
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("emails.certificate.hello"))
->setParam('{{body}}', $locale->getText("emails.certificate.body"))
->setParam('{{redirect}}', 'https://' . $domain)
->setParam('{{footer}}', $locale->getText("emails.certificate.footer"))
->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks"))
->setParam('{{signature}}', $locale->getText("emails.certificate.signature"))
->setParam('{{project}}', 'Console')
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$mail = new Mail();
$mail
->setType(MAIL_TYPE_CERTIFICATE)
->setRecipient(App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'))
->setUrl('https://' . $domain)
->setLocale(App::getEnv('_APP_LOCALE', 'en'))
->setName('Appwrite Administrator')
->setPayload([
'domain' => $domain,
'error' => $errorMessage,
'attempt' => $attempt
])
->trigger();
}

View file

@ -1,11 +1,8 @@
<?php
use Appwrite\Resque\Worker;
use Appwrite\Template\Template;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Database\Document;
use Utopia\Locale\Locale;
require_once __DIR__ . '/../init.php';
@ -32,67 +29,12 @@ class MailsV1 extends Worker
return;
}
$project = new Document($this->args['project'] ?? []);
$user = new Document($this->args['user'] ?? []);
$team = new Document($this->args['team'] ?? []);
$payload = $this->args['payload'] ?? [];
$recipient = $this->args['recipient'];
$url = $this->args['url'];
$subject = $this->args['subject'];
$name = $this->args['name'];
$type = $this->args['type'];
$prefix = $this->getPrefix($type);
$locale = new Locale($this->args['locale']);
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
if (!$this->doesLocaleExist($locale, $prefix)) {
$locale->setDefault('en');
}
$from = $project->isEmpty() || $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
$body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl');
$subject = '';
switch ($type) {
case MAIL_TYPE_CERTIFICATE:
$domain = $payload['domain'];
$error = $payload['error'];
$attempt = $payload['attempt'];
$subject = \sprintf($locale->getText("$prefix.subject"), $domain);
$body->setParam('{{domain}}', $domain);
$body->setParam('{{error}}', $error);
$body->setParam('{{attempt}}', $attempt);
break;
case MAIL_TYPE_INVITATION:
$subject = \sprintf($locale->getText("$prefix.subject"), $team->getAttribute('name'), $projectName);
$body->setParam('{{owner}}', $user->getAttribute('name'));
$body->setParam('{{team}}', $team->getAttribute('name'));
break;
case MAIL_TYPE_RECOVERY:
case MAIL_TYPE_VERIFICATION:
case MAIL_TYPE_MAGIC_SESSION:
$subject = $locale->getText("$prefix.subject");
break;
default:
throw new Exception('Undefined Mail Type : ' . $type, 500);
}
$body
->setParam('{{subject}}', $subject)
->setParam('{{hello}}', $locale->getText("$prefix.hello"))
->setParam('{{name}}', $name)
->setParam('{{body}}', $locale->getText("$prefix.body"))
->setParam('{{redirect}}', $url)
->setParam('{{footer}}', $locale->getText("$prefix.footer"))
->setParam('{{thanks}}', $locale->getText("$prefix.thanks"))
->setParam('{{signature}}', $locale->getText("$prefix.signature"))
->setParam('{{project}}', $projectName)
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{text-content}}', '#000000');
$body = $body->render();
$body = $this->args['body'];
$from = $this->args['from'];
/** @var \PHPMailer\PHPMailer\PHPMailer $mail */
$mail = $register->get('smtp');
@ -130,47 +72,4 @@ class MailsV1 extends Worker
public function shutdown(): void
{
}
/**
* Returns a prefix from a mail type
*
* @param $type
*
* @return string
*/
protected function getPrefix(string $type): string
{
switch ($type) {
case MAIL_TYPE_RECOVERY:
return 'emails.recovery';
case MAIL_TYPE_CERTIFICATE:
return 'emails.certificate';
case MAIL_TYPE_INVITATION:
return 'emails.invitation';
case MAIL_TYPE_VERIFICATION:
return 'emails.verification';
case MAIL_TYPE_MAGIC_SESSION:
return 'emails.magicSession';
default:
throw new Exception('Undefined Mail Type : ' . $type, 500);
}
}
/**
* Returns true if all the required terms in a locale exist. False otherwise
*
* @param $locale
* @param $prefix
*
* @return bool
*/
protected function doesLocaleExist(Locale $locale, string $prefix): bool
{
if (!$locale->getText('emails.sender') || !$locale->getText("$prefix.hello") || !$locale->getText("$prefix.subject") || !$locale->getText("$prefix.body") || !$locale->getText("$prefix.footer") || !$locale->getText("$prefix.thanks") || !$locale->getText("$prefix.signature")) {
return false;
}
return true;
}
}

View file

@ -8,11 +8,10 @@ use Utopia\Database\Document;
class Mail extends Event
{
protected string $recipient = '';
protected string $url = '';
protected string $type = '';
protected string $from = '';
protected string $name = '';
protected string $locale = '';
protected ?Document $team = null;
protected string $subject = '';
protected string $body = '';
public function __construct()
{
@ -20,14 +19,14 @@ class Mail extends Event
}
/**
* Sets team for the mail event.
* Sets subject for the mail event.
*
* @param Document $team
* @param string $subject
* @return self
*/
public function setTeam(Document $team): self
public function setSubject(string $subject): self
{
$this->team = $team;
$this->subject = $subject;
return $this;
}
@ -35,11 +34,11 @@ class Mail extends Event
/**
* Returns set team for the mail event.
*
* @return null|Document
* @return string
*/
public function getTeam(): ?Document
public function getSubject(): string
{
return $this->team;
return $this->subject;
}
/**
@ -66,49 +65,49 @@ class Mail extends Event
}
/**
* Sets url for the mail event.
* Sets from for the mail event.
*
* @param string $url
* @param string $from
* @return self
*/
public function setUrl(string $url): self
public function setFrom(string $from): self
{
$this->url = $url;
$this->from = $from;
return $this;
}
/**
* Returns set url for the mail event.
* Returns from for mail event.
*
* @return string
*/
public function getURL(): string
public function getFrom(): string
{
return $this->url;
return $this->from;
}
/**
* Sets type for the mail event (use the constants starting with MAIL_TYPE_*).
* Sets body for the mail event.
*
* @param string $type
* @param string $body
* @return self
*/
public function setType(string $type): self
public function setBody(string $body): self
{
$this->type = $type;
$this->body = $body;
return $this;
}
/**
* Returns set type for the mail event.
* Returns body for the mail event.
*
* @return string
*/
public function getType(): string
public function getBody(): string
{
return $this->type;
return $this->body;
}
/**
@ -134,29 +133,6 @@ class Mail extends Event
return $this->name;
}
/**
* Sets locale for the mail event.
*
* @param string $locale
* @return self
*/
public function setLocale(string $locale): self
{
$this->locale = $locale;
return $this;
}
/**
* Returns set locale for the mail event.
*
* @return string
*/
public function getLocale(): string
{
return $this->locale;
}
/**
* Executes the event and sends it to the mails worker.
*
@ -166,15 +142,11 @@ class Mail extends Event
public function trigger(): string|bool
{
return Resque::enqueue($this->queue, $this->class, [
'project' => $this->project,
'user' => $this->user,
'payload' => $this->payload,
'from' => $this->from,
'recipient' => $this->recipient,
'url' => $this->url,
'locale' => $this->locale,
'type' => $this->type,
'name' => $this->name,
'team' => $this->team,
'subject' => $this->subject,
'body' => $this->body,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
]);
}

View file

@ -149,7 +149,7 @@ class Realtime extends Adapter
'data' => [
'events' => $events,
'channels' => $channels,
'timestamp' => DateTime::now(),
'timestamp' => DateTime::formatTz(DateTime::now()),
'payload' => $payload
]
]));

View file

@ -46,6 +46,10 @@ class CNAME extends Validator
return false;
}
if (!$records) {
return false;
}
foreach ($records as $record) {
if (isset($record['target']) && $record['target'] === $this->target) {
return true;

View file

@ -97,7 +97,7 @@ class Func extends Model
'type' => self::TYPE_INTEGER,
'description' => 'Function execution timeout in seconds.',
'default' => 15,
'example' => 1592981237,
'example' => 15,
])
;
}