From 1fcc5eccb17bdb0021f66e2832541e9c87a6aeb4 Mon Sep 17 00:00:00 2001 From: Akshay Rana Date: Mon, 17 Oct 2022 12:44:44 +0530 Subject: [PATCH 01/16] updated timestamp format to ISO string in realtime payload --- app/realtime.php | 4 ++-- src/Appwrite/Messaging/Adapter/Realtime.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index be87c3d6e6..0b1d992922 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -237,7 +237,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, 'data' => [ 'events' => ['stats.connections'], 'channels' => ['project'], - 'timestamp' => DateTime::now(), + 'timestamp' => date('c'), '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' => date('c'), 'payload' => $payload ] ]; diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 9151a5c0b5..c595c394e4 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -149,7 +149,7 @@ class Realtime extends Adapter 'data' => [ 'events' => $events, 'channels' => $channels, - 'timestamp' => DateTime::now(), + 'timestamp' => date('c'), 'payload' => $payload ] ])); From c08f2e65e6e0fa201d8584483caa814ef5212f83 Mon Sep 17 00:00:00 2001 From: Akshay Rana Date: Tue, 18 Oct 2022 22:22:01 +0530 Subject: [PATCH 02/16] Updated timestamp format Co-authored-by: Steven <1477010+stnguyen90@users.noreply.github.com> --- src/Appwrite/Messaging/Adapter/Realtime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index c595c394e4..91b2e5e267 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -149,7 +149,7 @@ class Realtime extends Adapter 'data' => [ 'events' => $events, 'channels' => $channels, - 'timestamp' => date('c'), + 'timestamp' => DateTime::formatTz(DateTime::now()), 'payload' => $payload ] ])); From 641a4af8d460361cbda5d8ab9bda6246d1c152a2 Mon Sep 17 00:00:00 2001 From: Akshay Rana Date: Tue, 18 Oct 2022 22:40:50 +0530 Subject: [PATCH 03/16] upated the timestamp code --- app/realtime.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/realtime.php b/app/realtime.php index 0b1d992922..595f43b48f 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -237,7 +237,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, 'data' => [ 'events' => ['stats.connections'], 'channels' => ['project'], - 'timestamp' => date('c'), + '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' => date('c'), + 'timestamp' => DateTime::formatTz(DateTime::now()), 'payload' => $payload ] ]; From 29c30a361b06e9451a437aa1d8a3b7de80ebd849 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 9 Nov 2022 11:45:15 +0000 Subject: [PATCH 04/16] Fix null warnings - Fixed Avatars isset operator - Added isset operator to openSSL data in files - dns_get_record does not throw errors, instead it logs a warning and returns false. Altered code accordingly. PHP Bug Report: https://bugs.php.net/bug.php?id=73149 - --- app/controllers/api/avatars.php | 4 ++-- app/controllers/api/storage.php | 14 +++++++------- src/Appwrite/Network/Validator/CNAME.php | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index b7aef1505b..25c9fe8659 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -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; diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 530f174cd0..04ff10ca61 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -565,10 +565,10 @@ App::post('/v1/storage/buckets/:bucketId/files') 'comment' => '', 'chunksTotal' => $chunks, 'chunksUploaded' => $chunksUploaded, - 'openSSLVersion' => $openSSLVersion, - 'openSSLCipher' => $openSSLCipher, - 'openSSLTag' => $openSSLTag, - 'openSSLIV' => $openSSLIV, + 'openSSLVersion' => $openSSLVersion ?? null, + 'openSSLCipher' => $openSSLCipher ?? null, + 'openSSLTag' => $openSSLTag ?? null, + 'openSSLIV' => $openSSLIV ?? null, 'search' => implode(' ', [$fileId, $fileName]), 'metadata' => $metadata, ]); @@ -581,9 +581,9 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('mimeType', $mimeType) ->setAttribute('sizeActual', $sizeActual) ->setAttribute('algorithm', $algorithm) - ->setAttribute('openSSLVersion', $openSSLVersion) - ->setAttribute('openSSLCipher', $openSSLCipher) - ->setAttribute('openSSLTag', $openSSLTag) + ->setAttribute('openSSLVersion', $openSSLVersion ?? null) + ->setAttribute('openSSLCipher', $openSSLCipher ?? null) + ->setAttribute('openSSLTag', $openSSLTag ?? null) ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); diff --git a/src/Appwrite/Network/Validator/CNAME.php b/src/Appwrite/Network/Validator/CNAME.php index 93a302b962..678a57cecd 100644 --- a/src/Appwrite/Network/Validator/CNAME.php +++ b/src/Appwrite/Network/Validator/CNAME.php @@ -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; From a0ab93432845fd6e807bad4921d2c6063c574996 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 9 Nov 2022 13:23:14 +0000 Subject: [PATCH 05/16] Fix another null warning --- app/controllers/api/storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 04ff10ca61..837bb9e541 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -584,7 +584,7 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('openSSLVersion', $openSSLVersion ?? null) ->setAttribute('openSSLCipher', $openSSLCipher ?? null) ->setAttribute('openSSLTag', $openSSLTag ?? null) - ->setAttribute('openSSLIV', $openSSLIV) + ->setAttribute('openSSLIV', $openSSLIV ?? null) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); From bc915483ff96e74e9c06257e02ab76e9bb0add89 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Wed, 9 Nov 2022 13:52:46 +0000 Subject: [PATCH 06/16] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 2c649ab5f0..0230b0f840 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## Bugs - Fix license detection for Flutter and Dart SDKs [#4435](https://github.com/appwrite/appwrite/pull/4435) - Fix missing realtime event for create function deployment [#4574](https://github.com/appwrite/appwrite/pull/4574) +- Fix a few null safety warnings [#4654](https://github.com/appwrite/appwrite/pull/4654) # Version 1.0.3 ## Bugs From a19e668d790392fce616528931801ec509da7b3d Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Mon, 14 Nov 2022 13:11:43 +0000 Subject: [PATCH 07/16] Update storage.php --- app/controllers/api/storage.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 837bb9e541..690c0050ad 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -542,6 +542,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; @@ -565,10 +570,10 @@ App::post('/v1/storage/buckets/:bucketId/files') 'comment' => '', 'chunksTotal' => $chunks, 'chunksUploaded' => $chunksUploaded, - 'openSSLVersion' => $openSSLVersion ?? null, - 'openSSLCipher' => $openSSLCipher ?? null, - 'openSSLTag' => $openSSLTag ?? null, - 'openSSLIV' => $openSSLIV ?? null, + 'openSSLVersion' => $openSSLVersion, + 'openSSLCipher' => $openSSLCipher, + 'openSSLTag' => $openSSLTag, + 'openSSLIV' => $openSSLIV, 'search' => implode(' ', [$fileId, $fileName]), 'metadata' => $metadata, ]); @@ -581,10 +586,10 @@ App::post('/v1/storage/buckets/:bucketId/files') ->setAttribute('mimeType', $mimeType) ->setAttribute('sizeActual', $sizeActual) ->setAttribute('algorithm', $algorithm) - ->setAttribute('openSSLVersion', $openSSLVersion ?? null) - ->setAttribute('openSSLCipher', $openSSLCipher ?? null) - ->setAttribute('openSSLTag', $openSSLTag ?? null) - ->setAttribute('openSSLIV', $openSSLIV ?? null) + ->setAttribute('openSSLVersion', $openSSLVersion) + ->setAttribute('openSSLCipher', $openSSLCipher) + ->setAttribute('openSSLTag', $openSSLTag) + ->setAttribute('openSSLIV', $openSSLIV) ->setAttribute('metadata', $metadata) ->setAttribute('chunksUploaded', $chunksUploaded); From 42c855cb41a92e0ecc43bed4667ad3d29a86c5b1 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 14 Dec 2022 06:23:14 +0000 Subject: [PATCH 08/16] feat: make mails event and worker general --- app/workers/mails.php | 107 +----------------------------------- src/Appwrite/Event/Mail.php | 82 +++++++++------------------ 2 files changed, 30 insertions(+), 159 deletions(-) diff --git a/app/workers/mails.php b/app/workers/mails.php index 90e9e9a660..e850885ddc 100644 --- a/app/workers/mails.php +++ b/app/workers/mails.php @@ -1,11 +1,8 @@ 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; - } } diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index b3325c00be..1b7e218d69 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -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()) ]); } From 5741a960c75d4dd52e6d55564a55d63b9d4d22d0 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Wed, 14 Dec 2022 06:35:04 +0000 Subject: [PATCH 09/16] refactor: use refactored maile event and worker --- app/controllers/api/account.php | 63 +++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 45fb03062f..144bd1d2b2 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -713,11 +713,34 @@ 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) + ->setName('') + ->setSubject($subject) + ->setBody($body) + ->setFrom($from) ->setRecipient($user->getAttribute('email')) - ->setUrl($url) - ->setLocale($locale->default) ->trigger() ; @@ -2150,12 +2173,40 @@ App::post('/v1/account/verification') $url = Template::parseURL($url); $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]'); + + 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 = \sprintf($locale->getText("emails.verification.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.verification.hello")) + ->setParam('{{name}}', $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() ; From 5d195659bdcbb8fe62f0c462eb1a78b003cfc0b7 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 15 Dec 2022 09:22:05 +0000 Subject: [PATCH 10/16] refactor: mails refactor --- app/controllers/api/account.php | 42 +++++++++++++++++++++++---------- app/controllers/api/teams.php | 37 +++++++++++++++++++++++------ app/controllers/shared/api.php | 7 +----- app/workers/certificates.php | 38 ++++++++++++++++++++++------- 4 files changed, 90 insertions(+), 34 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 144bd1d2b2..ade0f4c89b 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -2014,12 +2014,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(); ; @@ -2173,22 +2196,15 @@ App::post('/v1/account/verification') $url = Template::parseURL($url); $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]'); - - 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 = \sprintf($locale->getText("emails.verification.subject"), $team->getAttribute('name'), $projectName); - $body->setParam('{{owner}}', $user->getAttribute('name')); - $body->setParam('{{team}}', $team->getAttribute('name')); - + $subject = $locale->getText("emails.verification.subject"); $body ->setParam('{{subject}}', $subject) ->setParam('{{hello}}', $locale->getText("emails.verification.hello")) - ->setParam('{{name}}', $name) + ->setParam('{{name}}', $user->getAttribute('name')) ->setParam('{{body}}', $locale->getText("emails.verification.body")) ->setParam('{{redirect}}', $url) ->setParam('{{footer}}', $locale->getText("emails.verification.footer")) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 567560c6a8..3b45450ba5 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -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($user->getAttribute('email')) + ->setName($user->getAttribute('name')) ->trigger() ; } diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 6a75025229..5aab0b723c 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -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('')) diff --git a/app/workers/certificates.php b/app/workers/certificates.php index e7885bc669..6de6445c48 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -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(); } From ea241ceaf5aedef07b8cf0c71d64138308545529 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 16 Dec 2022 11:33:16 +0545 Subject: [PATCH 11/16] Update app/workers/certificates.php Co-authored-by: Eldad A. Fux --- app/workers/certificates.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 6de6445c48..30137a007b 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -385,10 +385,10 @@ class CertificatesV1 extends Worker $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); + $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); + $body->setParam('{{domain}}', $domain); + $body->setParam('{{error}}', $errorMessage); + $body->setParam('{{attempt}}', $attempt); $body ->setParam('{{subject}}', $subject) From 495da1bfd4d2fda1afe9871ba791979b55f79267 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 16 Dec 2022 06:11:12 +0000 Subject: [PATCH 12/16] fix: template path --- app/controllers/api/account.php | 6 +++--- app/controllers/api/teams.php | 2 +- app/workers/certificates.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ade0f4c89b..6cbf4d130d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -715,7 +715,7 @@ App::post('/v1/account/sessions/magic-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'); + $body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl'); $subject = $locale->getText("emails.magicSession.subject"); $body @@ -2016,7 +2016,7 @@ App::post('/v1/account/recovery') $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'); + $body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl'); $subject = $locale->getText("emails.recovery.subject"); $body @@ -2199,7 +2199,7 @@ App::post('/v1/account/verification') $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'); + $body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl'); $subject = $locale->getText("emails.verification.subject"); $body ->setParam('{{subject}}', $subject) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 3b45450ba5..39b4cf678d 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -437,7 +437,7 @@ App::post('/v1/teams/:teamId/memberships') $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'); + $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')); diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 30137a007b..11f3439408 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -383,7 +383,7 @@ class CertificatesV1 extends Worker $locale->setDefault('en'); } - $body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl'); + $body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base.tpl'); $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); $body->setParam('{{domain}}', $domain); From b7d17e82dae58a85bd3f24f87b195880d3d8c1c7 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 16 Dec 2022 06:15:23 +0000 Subject: [PATCH 13/16] fix: membership invite email --- app/controllers/api/teams.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 39b4cf678d..9eba2d01d7 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -463,8 +463,8 @@ App::post('/v1/teams/:teamId/memberships') ->setSubject($subject) ->setBody($body) ->setFrom($from) - ->setRecipient($user->getAttribute('email')) - ->setName($user->getAttribute('name')) + ->setRecipient($invitee->getAttribute('email')) + ->setName($invitee->getAttribute('name')) ->trigger() ; } From 12302d5b3d8e88d65e0fbf7e0ed93547c60071cf Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Fri, 16 Dec 2022 06:34:03 +0000 Subject: [PATCH 14/16] refactor: remove empty param --- app/controllers/api/account.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 6cbf4d130d..a92067c63c 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -736,7 +736,6 @@ App::post('/v1/account/sessions/magic-url') $body = $body->render(); $mails - ->setName('') ->setSubject($subject) ->setBody($body) ->setFrom($from) From a1cb81abb6ff67ef88757edf4e2fd46b86135523 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Wed, 11 Jan 2023 21:49:15 +0000 Subject: [PATCH 15/16] Function default timeout example to 15s, so it doesn't look like a timestamp. --- src/Appwrite/Utopia/Response/Model/Func.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response/Model/Func.php b/src/Appwrite/Utopia/Response/Model/Func.php index c7e69fff88..74cfb1e844 100644 --- a/src/Appwrite/Utopia/Response/Model/Func.php +++ b/src/Appwrite/Utopia/Response/Model/Func.php @@ -97,7 +97,7 @@ class Func extends Model 'type' => self::TYPE_INTEGER, 'description' => 'Function execution timeout in seconds.', 'default' => 15, - 'example' => 1592981237, + 'example' => 15, ]) ; } From 58c4c3da1e6a0229b380f98188faa53587fd1590 Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Fri, 20 Jan 2023 09:52:11 +0000 Subject: [PATCH 16/16] feat: update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 5103e39a11..a6fa76fff7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # Version 1.2.1 ## 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) # Version 1.2.0 ## Features