From 4f67db160bf4d991e820741e8d3183b596fc80f1 Mon Sep 17 00:00:00 2001 From: achraf112ben Date: Sun, 28 Jan 2024 06:14:21 +0100 Subject: [PATCH 01/14] Adding Darija (Moroccan Arabic) translation file --- app/config/locale/translations/ar-ma.json | 238 ++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 app/config/locale/translations/ar-ma.json diff --git a/app/config/locale/translations/ar-ma.json b/app/config/locale/translations/ar-ma.json new file mode 100644 index 0000000000..18fcaa1ee0 --- /dev/null +++ b/app/config/locale/translations/ar-ma.json @@ -0,0 +1,238 @@ +{ + "settings.inspire": "\"الفن ديال الحكمة هو الفن ديال أنك تعرف أش تنخّل.\"", + "settings.locale": "ar-ma", + "settings.direction": "rtl", + "emails.sender": "فرقة %s", + "emails.verification.subject": "التيْقان ديال الحساب", + "emails.verification.hello": "السلام {{user}}", + "emails.verification.body": "تبّع هاد الوصلة باش تيقّن لادريسة تاع ليميل ديالك.", + "emails.verification.footer": "إلا ماشي نتا اللي طلبتي تيقّن هاد لادريسة تاع ليميل، ممكن تنخّل هاد البرية.", + "emails.verification.thanks": "شكرا", + "emails.verification.signature": "فرقة {{project}}", + "emails.magicSession.subject": "تكونيكطا", + "emails.magicSession.hello": "السلام,", + "emails.magicSession.body": "تبّع هاد الوصلة باش تتكونيكطا.", + "emails.magicSession.footer": "إلا ماشي نتا اللي طلبتي تتكونيكطا بهاد ليميل، ممكن تنخّل هاد البرية.", + "emails.magicSession.thanks": "شكرا", + "emails.magicSession.signature": "فرقة {{project}}", + "emails.recovery.subject": "تبدال كلمة السر", + "emails.recovery.hello": "السلام {{user}}", + "emails.recovery.body": "تبّع هاد الوصلة باش تبدّل كلمة السر تاع {{project}}.", + "emails.recovery.footer": "إلا ماشي نتا اللي طلبتي تبدّل كلمة السر، ممكن تنخّل هاد البرية.", + "emails.recovery.thanks": "شكرا", + "emails.recovery.signature": "فرقة {{project}}", + "emails.invitation.subject": "عراضة ل فرقة %s ف %s", + "emails.invitation.hello": "السلام", + "emails.invitation.body": "هاد البرية تصيفطات ليك حيت {{owner}} بغى يعرض عليك تولّي عضو ف فرقة {{team}} عند {{project}}.", + "emails.invitation.footer": "إلا كنتي ما مسوّقش, ممكن تنخّل هاد البرية.", + "emails.invitation.thanks": "شكرا", + "emails.invitation.signature": "فرقة {{project}}", + "emails.certificate.subject": "Certificate failure for %s", + "emails.certificate.hello": "Hello", + "emails.certificate.body": "السرتافيكة ديال ضومينك '{{domain}}' ما قدّاتش تجينيرا. هادي هي المحاولة نمرة {{attempt}}, السبب ديال هاد العطبة هو: {{error}}", + "emails.certificate.footer": "السرتافيكة الفايتة ديالك غاتبقى مزيانة لمدة 30 يوم من عند أول عطبة. كانشجعوك بزاف أنك تبقشش فهاد الموضوع, وا إلّا الضومين ديالك ما غايبقاش خدّام فيه الـ SSL.", + "emails.certificate.thanks": "شكرا", + "emails.certificate.signature": "فرقة {{project}}", + "locale.country.unknown": "ما معروفش", + "countries.af": "أفغانستان", + "countries.ao": "أنڭولا", + "countries.al": "ألبانيا", + "countries.ad": "أندورا", + "countries.ae": "الإمارات العربية المتّاحدة", + "countries.ar": "الأرجنتين", + "countries.am": "أرمينيا", + "countries.ag": "أنتيڭوا وبربودا", + "countries.au": "ؤسطراليا", + "countries.at": "النامسا", + "countries.az": "أديربيجان", + "countries.bi": "بوروندي", + "countries.be": "بلجيكا", + "countries.bj": "بينين", + "countries.bf": "بوركينا فاصو", + "countries.bd": "بنڭلاديش", + "countries.bg": "بلڭاريا", + "countries.bh": "البحرين", + "countries.bs": "دزيرات البهاما", + "countries.ba": "البوسنة ؤ الهرسك", + "countries.by": "بيلاروسيا", + "countries.bz": "بيليز", + "countries.bo": "بوليڤيا", + "countries.br": "البرازيل", + "countries.bb": "باربادوس", + "countries.bn": "بروناي", + "countries.bt": "بوتان", + "countries.bw": "بوتسوانا", + "countries.cf": "جمهورية إفريقيا الوسطانية", + "countries.ca": "كانادا", + "countries.ch": "سويسرا", + "countries.cl": "تشيلي", + "countries.cn": "الشينوا", + "countries.ci": "ساحل العاج", + "countries.cm": "الكاميرون", + "countries.cd": "جمهورية الكونڭو الديمقراطية", + "countries.cg": "جمهورية الكونڭو", + "countries.co": "كولومبيا", + "countries.km": "دزيرات القومور", + "countries.cv": "الراس الخضر", + "countries.cr": "كوسطاريكا", + "countries.cu": "كوبا", + "countries.cy": "قوبروص", + "countries.cz": "التشيك", + "countries.de": "ألمانيا", + "countries.dj": "دجيبوتي", + "countries.dm": "ضومينيكا", + "countries.dk": "الدنمارك", + "countries.do": "جمهورية الضومينيكان", + "countries.dz": "الدزاير", + "countries.ec": "إكوادور", + "countries.eg": "مصر", + "countries.er": "إريتريا", + "countries.es": "سبانيا", + "countries.ee": "إسطونيا", + "countries.et": "إتيوپيا", + "countries.fi": "فينلاندا", + "countries.fj": "فيدجي", + "countries.fr": "فرانسا", + "countries.fm": "ميكرونيزيا", + "countries.ga": "الڭابون", + "countries.gb": "المملكة المتّاحدة", + "countries.ge": "تجورجيا", + "countries.gh": "غانا", + "countries.gn": "غينيا", + "countries.gm": "ڭامبيا", + "countries.gw": "غينيا بيساو", + "countries.gq": "غينيا الستوائية", + "countries.gr": "اليونان", + "countries.gd": "ڭرينادا", + "countries.gt": "ڭواتيمالا", + "countries.gy": "ڭيانا", + "countries.hn": "هوندوراس", + "countries.hr": "كرواتيا", + "countries.ht": "هايتي", + "countries.hu": "الماجر", + "countries.id": "إندونيسيا", + "countries.in": "الهند", + "countries.ie": "إرلاندا", + "countries.ir": "إران", + "countries.iq": "العراق", + "countries.is": "إسلاندا", + "countries.il": "إسرائيل", + "countries.it": "الطاليان", + "countries.jm": "جامايكا", + "countries.jo": "الأردن", + "countries.jp": "الجاپون", + "countries.kz": "كازاخستان", + "countries.ke": "كينيا", + "countries.kg": "قيرغيزستان", + "countries.kh": "كمبوديا", + "countries.ki": "كيريباتي", + "countries.kn": "سانت كيتس ؤ نيفيس", + "countries.kr": "كوريا الجنوبية", + "countries.kw": "الكويت", + "countries.la": "لاوس", + "countries.lb": "لبنان", + "countries.lr": "ليبيريا", + "countries.ly": "ليبيا", + "countries.lc": "سانت لوسيا", + "countries.li": "ليختنشتاين", + "countries.lk": "سري لانكا", + "countries.ls": "ليسوتو", + "countries.lt": "ليتوانيا", + "countries.lu": "لوكسمبورڭ", + "countries.lv": "لاتفيا", + "countries.ma": "المغريب", + "countries.mc": "موناكو", + "countries.md": "مولضوڤا", + "countries.mg": "ماداغشقار", + "countries.mv": "دزيرات المالديڤ", + "countries.mx": "الميكسيك", + "countries.mh": "دزيرات مارشال", + "countries.mk": "مقدونيا", + "countries.ml": "مالي", + "countries.mt": "مالطا", + "countries.mm": "ميانمار", + "countries.me": "مونطينيڭرو", + "countries.mn": "منغوليا", + "countries.mz": "الموزمبيق", + "countries.mr": "موريتانيا", + "countries.mu": "موريشيوس", + "countries.mw": "مالاوي", + "countries.my": "ماليزيا", + "countries.na": "ناميبيا", + "countries.ne": "النيجر", + "countries.ng": "نيجيريا", + "countries.ni": "نيكاراڭوا", + "countries.nl": "هولاندا", + "countries.no": "النرويج", + "countries.np": "نيپال", + "countries.nr": "ناورو", + "countries.nz": "نيوزيلاندا", + "countries.om": "عمّان", + "countries.pk": "پاكيستان", + "countries.pa": "پاناما", + "countries.pe": "الپيرو", + "countries.ph": "الفيليپين", + "countries.pw": "پالاو", + "countries.pg": "پاپوا غينيا الجديدة", + "countries.pl": "پولاندا", + "countries.kp": "كوريا الشمالية", + "countries.pt": "البرطقيز", + "countries.py": "الپاراڭواي", + "countries.qa": "قطر", + "countries.ro": "رومانيا", + "countries.ru": "روسيا", + "countries.rw": "روّاندا", + "countries.sa": "المملكة العربية السعودية", + "countries.sd": "السودان", + "countries.sn": "السينيڭال", + "countries.sg": "سنغافورة", + "countries.sb": "دزيرات سليمان", + "countries.sl": "صييراليون", + "countries.sv": "السالڤاضور", + "countries.sm": "سان مارينو", + "countries.so": "الصومال", + "countries.rs": "صيربيا", + "countries.ss": "جنوب السودان", + "countries.st": "صاو طومي ؤ پرينسيپي", + "countries.sr": "سورينام", + "countries.sk": "صلوڤاكيا", + "countries.si": "صلوڤينيا", + "countries.se": "السويد", + "countries.sz": "سوازيلاند", + "countries.sc": "السيشيل", + "countries.sy": "سوريا", + "countries.td": "تشاد", + "countries.tg": "الطوڭو", + "countries.th": "الطايلوند", + "countries.tj": "طادجيكيستان", + "countries.tm": "تركمانيستان", + "countries.tl": "تيمور الشرقية", + "countries.to": "تونڭا", + "countries.tt": "ترينيداد ؤ طوباڭو", + "countries.tn": "تونس", + "countries.tr": "توركيا", + "countries.tv": "توڤالو", + "countries.tz": "طنزانيا", + "countries.ug": "ؤڭاندا", + "countries.ua": "ؤكرانيا", + "countries.uy": "ؤروڭواي", + "countries.us": "ميريكان", + "countries.uz": "ؤزباكيستان", + "countries.va": "مدينة الڤاتيكان", + "countries.vc": "سانت ڤانسون ؤ دزيرات ڭرينادين", + "countries.ve": "ڤينيزويلا", + "countries.vn": "ڤيطنام", + "countries.vu": "ڤانواتو", + "countries.ws": "ساموا", + "countries.ye": "اليمن", + "countries.za": "جنوب إفريقيا", + "countries.zm": "زامبيا", + "countries.zw": "زيمبابوي", + "continents.af": "أفريقيا", + "continents.an": "القارة القطبية الجنوبية", + "continents.as": "أسيا", + "continents.eu": "ؤروپا", + "continents.na": "ميريكان الشمالية", + "continents.oc": "ؤقيانوسيا", + "continents.sa": "ميريكان الجنوبية" +} From 3a35412bf8905abaf5a8912305f4820c1e05ec63 Mon Sep 17 00:00:00 2001 From: achraf112ben Date: Mon, 29 Jan 2024 04:21:14 +0100 Subject: [PATCH 02/14] fix some missed values --- app/config/locale/translations/ar-ma.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/config/locale/translations/ar-ma.json b/app/config/locale/translations/ar-ma.json index 18fcaa1ee0..453de25c80 100644 --- a/app/config/locale/translations/ar-ma.json +++ b/app/config/locale/translations/ar-ma.json @@ -27,10 +27,10 @@ "emails.invitation.footer": "إلا كنتي ما مسوّقش, ممكن تنخّل هاد البرية.", "emails.invitation.thanks": "شكرا", "emails.invitation.signature": "فرقة {{project}}", - "emails.certificate.subject": "Certificate failure for %s", - "emails.certificate.hello": "Hello", - "emails.certificate.body": "السرتافيكة ديال ضومينك '{{domain}}' ما قدّاتش تجينيرا. هادي هي المحاولة نمرة {{attempt}}, السبب ديال هاد العطبة هو: {{error}}", - "emails.certificate.footer": "السرتافيكة الفايتة ديالك غاتبقى مزيانة لمدة 30 يوم من عند أول عطبة. كانشجعوك بزاف أنك تبقشش فهاد الموضوع, وا إلّا الضومين ديالك ما غايبقاش خدّام فيه الـ SSL.", + "emails.certificate.subject": "السرتافيكة فشلات ل %s", + "emails.certificate.hello": "السلام", + "emails.certificate.body": "السرتافيكة ديال الضومين ديالك '{{domain}}' ما قدّاتش تجينيرا. هادي هي المحاولة نمرة {{attempt}}, السبب ديال هاد الفشل هو: {{error}}", + "emails.certificate.footer": "السرتافيكة الفايتة ديالك غاتبقى مزيانة لمدة 30 يوم من عند أول فشل. كانشجعوك بزاف أنك تبقشش فهاد الموضوع, وا إلّا الضومين ديالك ما غايبقاش خدّام فيه الـ SSL.", "emails.certificate.thanks": "شكرا", "emails.certificate.signature": "فرقة {{project}}", "locale.country.unknown": "ما معروفش", From 4fd94fd7b1e0bc6c652aa68a6703201b3342a257 Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Fri, 14 Jun 2024 15:37:30 +0530 Subject: [PATCH 03/14] fix: add `defaults` to collection attributes. --- src/Appwrite/Migration/Migration.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 15c14daf51..e3a2021c1a 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -239,7 +239,7 @@ abstract class Migration } /** - * Creates colletion from the config collection. + * Creates collection from the config collection. * * @param string $id * @param string|null $name @@ -266,6 +266,7 @@ abstract class Migration 'type' => $attribute['type'], 'size' => $attribute['size'], 'required' => $attribute['required'], + 'default' => $attribute['default'] ?? null, 'signed' => $attribute['signed'], 'array' => $attribute['array'], 'filters' => $attribute['filters'], From dbfae9455273433b9a090efcb9c1d43b2c2c4fd7 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 20 Jun 2024 17:28:21 +0900 Subject: [PATCH 04/14] Fix certificate emails --- .../templates/email-certificate-failed.tpl | 4 ++- app/config/locale/translations/en.json | 6 +++++ .../Platform/Workers/Certificates.php | 26 +++---------------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/app/config/locale/templates/email-certificate-failed.tpl b/app/config/locale/templates/email-certificate-failed.tpl index 18751ff412..0363fc6538 100644 --- a/app/config/locale/templates/email-certificate-failed.tpl +++ b/app/config/locale/templates/email-certificate-failed.tpl @@ -4,7 +4,9 @@
-

{{error}}

+

+ {{error}} +

diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index 72bb9c099e..8c908ae5ab 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -43,6 +43,12 @@ "emails.invitation.footer": "If you are not interested, you can ignore this message.", "emails.invitation.thanks": "Thanks", "emails.invitation.signature": "{{project}} team", + "emails.certificate.subject": "Certificate failure for %s", + "emails.certificate.hello": "Hello", + "emails.certificate.body": "Certificate for your domain '{{domain}}' could not be generated. This is attempt no. {{attempt}}, and the failure was caused by: {{error}}", + "emails.certificate.footer": "Your previous certificate will be valid for 30 days since the first failure. We highly recommend investigating this case, otherwise your domain will end up without a valid SSL communication.", + "emails.certificate.thanks": "Thanks", + "emails.certificate.signature": "{{project}} team", "sms.verification.body": "{{secret}}", "locale.country.unknown": "Unknown", "countries.af": "Afghanistan", diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index ad6cf09fa7..c7a4034a45 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -439,40 +439,22 @@ class Certificates extends Action $locale = new Locale(System::getEnv('_APP_LOCALE', 'en')); - // Send mail to administratore mail + // Send mail to administrator mail $template = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-certificate-failed.tpl'); $template->setParam('{{domain}}', $domain); $template->setParam('{{error}}', \nl2br($errorMessage)); $template->setParam('{{attempts}}', $attempt); - - // TODO: Use setbodyTemplate once #7307 is merged - $subject = 'Certificate failed to generate'; - $body = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl'); - - $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); - - $message = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-inner-base.tpl'); - $message - ->setParam('{{body}}', $locale->getText("emails.certificate.body"), escapeHtml: false) - ->setParam('{{hello}}', $locale->getText("emails.certificate.hello")) - ->setParam('{{footer}}', $locale->getText("emails.certificate.footer")) - ->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks")) - ->setParam('{{signature}}', $locale->getText("emails.certificate.signature")); - $body = $message->render(); + $body = $template->render(); $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - 'domain' => $domain, - 'error' => '
' . $errorMessage . '
', - 'attempt' => $attempt, - 'project' => 'Console', - 'redirect' => 'https://' . $domain, ]; $queueForMails - ->setSubject($subject) + ->setSubject('Certificate failed to generate') ->setBody($body) ->setName('Appwrite Administrator') + ->setbodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl') ->setVariables($emailVariables) ->setRecipient(System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'))) ->trigger(); From eb36ae5c6185f70199261f57dea15f72b88c8314 Mon Sep 17 00:00:00 2001 From: ItzNotABug Date: Thu, 20 Jun 2024 14:14:21 +0530 Subject: [PATCH 05/14] add: `default` to V20 migration. --- src/Appwrite/Migration/Version/V20.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Appwrite/Migration/Version/V20.php b/src/Appwrite/Migration/Version/V20.php index 1a599d32f2..5a0807cedf 100644 --- a/src/Appwrite/Migration/Version/V20.php +++ b/src/Appwrite/Migration/Version/V20.php @@ -336,6 +336,32 @@ class V20 extends Migration Console::warning("Purge cache from {$id}: {$th->getMessage()}"); } + break; + case 'topics': + try { + $this->projectDB->updateAttributeDefault($id, 'emailTotal', 0); + } catch (Throwable $th) { + Console::warning("'topics' from {$id}: {$th->getMessage()}"); + } + + try { + $this->projectDB->updateAttributeDefault($id, 'pushTotal', 0); + } catch (Throwable $th) { + Console::warning("'topics' from {$id}: {$th->getMessage()}"); + } + + try { + $this->projectDB->updateAttributeDefault($id, 'smsTotal', 0); + } catch (Throwable $th) { + Console::warning("'topics' from {$id}: {$th->getMessage()}"); + } + + try { + $this->projectDB->purgeCachedCollection($id); + } catch (Throwable $th) { + Console::warning("Purge cache from {$id}: {$th->getMessage()}"); + } + break; } From ea95e80cbfeeb3be73c181e83637d1be8dcbda61 Mon Sep 17 00:00:00 2001 From: Bradley Schofield Date: Thu, 20 Jun 2024 17:47:16 +0900 Subject: [PATCH 06/14] Use localised subject string --- src/Appwrite/Platform/Workers/Certificates.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index c7a4034a45..58dc1dd28a 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -450,8 +450,10 @@ class Certificates extends Action 'direction' => $locale->getText('settings.direction'), ]; + $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); + $queueForMails - ->setSubject('Certificate failed to generate') + ->setSubject($subject) ->setBody($body) ->setName('Appwrite Administrator') ->setbodyTemplate(__DIR__ . '/../../../../app/config/locale/templates/email-base-styled.tpl') From 01fc6a699a2619b928e941dcc5b833f29c97538f Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:02:44 +0000 Subject: [PATCH 07/14] fix(health): fix flaky certificate test There seems to be a load balancer in front of www.google.com that has either a certificate issuer of "Google Trust Services LLC" or "Google Trust Services". This causes the test to fail intermittently. This PR updates the test to check for the substring "Google Trust Services" instead of the exact string "Google Trust Services LLC". --- tests/e2e/Services/Health/HealthCustomServerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index 5fd7ab96da..8360af542e 100644 --- a/tests/e2e/Services/Health/HealthCustomServerTest.php +++ b/tests/e2e/Services/Health/HealthCustomServerTest.php @@ -455,7 +455,7 @@ class HealthCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('/CN=www.google.com', $response['body']['name']); $this->assertEquals('www.google.com', $response['body']['subjectSN']); - $this->assertEquals('Google Trust Services LLC', $response['body']['issuerOrganisation']); + $this->assertStringContainsString('Google Trust Services', $response['body']['issuerOrganisation']); $this->assertIsInt($response['body']['validFrom']); $this->assertIsInt($response['body']['validTo']); From 9ccf4991e38465edb36bfca1abe866b6694aa05d Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:15:41 +0000 Subject: [PATCH 08/14] fix(functions): fix flaky function test The execution is async so give the function a bit more time to execute. --- tests/e2e/Services/Functions/FunctionsCustomClientTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 5acc833fe2..6274f5ddae 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -166,7 +166,7 @@ class FunctionsCustomClientTest extends Scope $this->assertEquals(202, $execution['headers']['status-code']); // Wait for the first scheduled execution to be created - sleep(65); + sleep(90); $executions = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions', [ 'content-type' => 'application/json', From 34b2e152430493c42666f2c7ff8474b7099e4a11 Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Fri, 21 Jun 2024 22:25:27 +0000 Subject: [PATCH 09/14] fix(users): fix expire error when creating user session Before this, the Create session API call would throw: > Invalid document structure: Missing required attribute "expire" This is because the `expire` attribute is required, but it was omitted from the document. This PR ensures the `expire` attribute is set when creating the session document. --- app/controllers/api/users.php | 2 +- tests/e2e/Services/Users/UsersBase.php | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 193f3f095e..9e7ad94623 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1801,6 +1801,7 @@ App::post('/v1/users/:userId/sessions') 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => $expire, ], $detector->getOS(), $detector->getClient(), @@ -1812,7 +1813,6 @@ App::post('/v1/users/:userId/sessions') $session = $dbForProject->createDocument('sessions', $session); $session ->setAttribute('secret', $secret) - ->setAttribute('expire', $expire) ->setAttribute('countryName', $countryName); $queueForEvents diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 6b48470b6e..a24b6f8161 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -290,6 +290,28 @@ trait UsersBase $this->assertArrayNotHasKey('secret', $token['body']); } + /** + * @depends testCreateUser + */ + public function testCreateSession(array $data): void + { + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_POST, '/users/' . $data['userId'] . '/sessions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $response['headers']['status-code']); + + $session = $response['body']; + $this->assertEquals($data['userId'], $session['userId']); + $this->assertNotEmpty($session['secret']); + $this->assertNotEmpty($session['expire']); + $this->assertEquals('server', $session['provider']); + } + /** * Tests all optional parameters of createUser (email, phone, anonymous..) From 13027fac5bec966acf8b8512ac73597418886603 Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Fri, 21 Jun 2024 22:29:43 +0000 Subject: [PATCH 10/14] fix(users): update session secret to be longer The create session endpoint created a 6 character secret which is too short. This changes the secret to be 256 characters which is in line with the secret for `account.createEmailPasswordSession()`. --- app/controllers/api/users.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 9e7ad94623..dcc214972b 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1784,7 +1784,7 @@ App::post('/v1/users/:userId/sessions') throw new Exception(Exception::USER_NOT_FOUND); } - $secret = Auth::codeGenerator(); + $secret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION); $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); From c6489d172f359c4cdc3ac06d7ed920e70f9810bc Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Mon, 24 Jun 2024 18:47:28 +0000 Subject: [PATCH 11/14] chore: bump utopia-php/database and related packages utopia-php/database version 0.50.0 includes a new skipValidation() function we can use to skip validation when making queries. --- composer.json | 6 ++-- composer.lock | 98 +++++++++++++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/composer.json b/composer.json index 192b311822..6ec50f2987 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.13.*", "appwrite/php-clamav": "2.0.*", - "utopia-php/abuse": "0.37.*", + "utopia-php/abuse": "0.38.*", "utopia-php/analytics": "0.10.*", - "utopia-php/audit": "0.39.*", + "utopia-php/audit": "0.40.*", "utopia-php/cache": "0.10.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.49.*", + "utopia-php/database": "0.50.*", "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", diff --git a/composer.lock b/composer.lock index de23f2cbb0..0c6ee8d591 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e002600539435ca8eaaace6e73b4004d", + "content-hash": "89f2552eaa152516be5bf89628c0f86e", "packages": [ { "name": "adhocore/jwt", @@ -1128,16 +1128,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -1188,7 +1188,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -1204,20 +1204,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", "shasum": "" }, "require": { @@ -1268,7 +1268,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" }, "funding": [ { @@ -1284,7 +1284,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "thecodingmachine/safe", @@ -1427,23 +1427,23 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.1", + "version": "0.38.0", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" + "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", - "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/b7be9086c9d9b4561d810cbd42fdda798742f56c", + "reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c", "shasum": "" }, "require": { "ext-curl": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "0.50.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.1" + "source": "https://github.com/utopia-php/abuse/tree/0.38.0" }, - "time": "2024-06-05T18:03:59+00:00" + "time": "2024-06-24T00:52:02+00:00" }, { "name": "utopia-php/analytics", @@ -1522,21 +1522,21 @@ }, { "name": "utopia-php/audit", - "version": "0.39.1", + "version": "0.40.0", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" + "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", - "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/735ae211ce5fee5b52b736731571b4030b1d7cdc", + "reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "0.49.*" + "utopia-php/database": "0.50.*" }, "require-dev": { "laravel/pint": "1.5.*", @@ -1563,9 +1563,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.1" + "source": "https://github.com/utopia-php/audit/tree/0.40.0" }, - "time": "2024-06-05T19:28:22+00:00" + "time": "2024-06-24T00:52:17+00:00" }, { "name": "utopia-php/cache", @@ -1719,16 +1719,16 @@ }, { "name": "utopia-php/database", - "version": "0.49.13", + "version": "0.50.0", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860" + "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/fff42e0bd1db5a03d8c5df4302d72443bde3b860", - "reference": "fff42e0bd1db5a03d8c5df4302d72443bde3b860", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", + "reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", "shasum": "" }, "require": { @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.13" + "source": "https://github.com/utopia-php/database/tree/0.50.0" }, - "time": "2024-06-18T14:33:55+00:00" + "time": "2024-06-21T03:21:42+00:00" }, { "name": "utopia-php/domains", @@ -3156,16 +3156,16 @@ }, { "name": "laravel/pint", - "version": "v1.16.0", + "version": "v1.16.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98" + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", - "reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98", + "url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1", + "reference": "9266a47f1b9231b83e0cfd849009547329d871b1", "shasum": "" }, "require": { @@ -3176,13 +3176,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.57.1", - "illuminate/view": "^10.48.10", - "larastan/larastan": "^2.9.6", + "friendsofphp/php-cs-fixer": "^3.59.3", + "illuminate/view": "^10.48.12", + "larastan/larastan": "^2.9.7", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.34.7" + "pestphp/pest": "^2.34.8" }, "bin": [ "builds/pint" @@ -3218,7 +3218,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-05-21T18:08:25+00:00" + "time": "2024-06-18T16:50:05+00:00" }, { "name": "matthiasmullie/minify", @@ -5340,16 +5340,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -5399,7 +5399,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -5415,7 +5415,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "textalk/websocket", @@ -5615,5 +5615,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From 3a3a0594dc2ff481c40f7623d03d4ad9c76157e1 Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:34:08 +0000 Subject: [PATCH 12/14] fix(messaging): disable validation for subquery to prevent error If there are more than 100 targets, the validation throws an error. This change skips the validation so no error is thrown. --- app/init.php | 4 +- .../e2e/Services/Messaging/MessagingBase.php | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/init.php b/app/init.php index a86156c750..3582192a87 100644 --- a/app/init.php +++ b/app/init.php @@ -607,9 +607,9 @@ Database::addFilter( ]) )); if (\count($targetIds) > 0) { - return $database->find('targets', [ + return $database->skipValidation(fn () => $database->find('targets', [ Query::equal('$internalId', $targetIds) - ]); + ])); } return []; } diff --git a/tests/e2e/Services/Messaging/MessagingBase.php b/tests/e2e/Services/Messaging/MessagingBase.php index 0540479eb5..dc5ddb9d70 100644 --- a/tests/e2e/Services/Messaging/MessagingBase.php +++ b/tests/e2e/Services/Messaging/MessagingBase.php @@ -511,6 +511,55 @@ trait MessagingBase ]; } + public function testSubscriberTargetSubQuery() + { + $response = $this->client->call(Client::METHOD_POST, '/messaging/topics', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'topicId' => 'sub-query-test', + 'name' => 'sub-query-test', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $topic = $response['body']; + + $prefix = uniqid(); + + for ($i = 1; $i <= 101; $i++) { + $response = $this->client->call(Client::METHOD_POST, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'userId' => "$prefix-$i", + 'email' => "$prefix-$i@example.com", + 'password' => 'password', + 'name' => "User $prefix $i", + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $user = $response['body']; + $targets = $user['targets'] ?? []; + + $this->assertGreaterThan(0, count($targets)); + + $target = $targets[0]; + + $response = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['$id'] . '/subscribers', \array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'subscriberId' => $user['$id'], + 'targetId' => $target['$id'], + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + } + } + /** * @depends testCreateSubscriber */ From 827ad1446b14a9631d94877155b4003d220f0015 Mon Sep 17 00:00:00 2001 From: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com> Date: Tue, 25 Jun 2024 02:37:55 +0000 Subject: [PATCH 13/14] Bump console to version 4.3.14 --- .gitmodules | 2 +- app/console | 2 +- app/init.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index ffb7623bd7..653e6acbc0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "app/console"] path = app/console url = https://github.com/appwrite/console - branch = 4.3.5 + branch = 4.3.14 diff --git a/app/console b/app/console index 5169fe16d6..412bc33318 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 5169fe16d63066f64ab5013c78953aea04e24b53 +Subproject commit 412bc3331891c15ba7baf4f445e82ac3a678c6be diff --git a/app/init.php b/app/init.php index 3582192a87..44cd21d163 100644 --- a/app/init.php +++ b/app/init.php @@ -112,7 +112,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours -const APP_CACHE_BUSTER = 443; +const APP_CACHE_BUSTER = 4314; const APP_VERSION_STABLE = '1.5.7'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; From eacd965ae3a51ad510793b6ee884595d2852bd39 Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:13:34 -0400 Subject: [PATCH 14/14] feat: Adding profiler for debugging --- CONTRIBUTING.md | 12 ++++++++++++ Dockerfile | 3 ++- dev/xdebug.ini | 6 ++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e3e6fcd81..8d8ddadda6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -497,6 +497,18 @@ If you are in PHP Storm you don't need any plugin. Below are the settings requir 2. If needed edit the **dev/xdebug.ini** file to your needs. 3. Launch your Appwrite instance while your debugger is listening for connections. +## Profiling +Appwrite uses XDebug [Profiler](https://xdebug.org/docs/profiler) for generating **CacheGrind** files. The generated file would be located in each of the `appwrite` containers inside the `/tmp/xdebug` folder. + +To disable the profiler while debugging remove the `,profiler` mode from the `xdebug.ini` file +```diff +zend_extension=xdebug + +[xdebug] +-xdebug.mode=develop,debug,profile ++xdebug.mode=develop,debug +``` + ### VS Code Launch Configuration ```json diff --git a/Dockerfile b/Dockerfile index 1d82930c1d..7cc0403b84 100755 --- a/Dockerfile +++ b/Dockerfile @@ -108,9 +108,10 @@ RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/ # Enable Extensions RUN if [ "$DEBUG" == "true" ]; then cp /usr/src/code/dev/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini; fi +RUN if [ "$DEBUG" == "true" ]; then mkdir -p /tmp/xdebug; fi RUN if [ "$DEBUG" = "false" ]; then rm -rf /usr/src/code/dev; fi RUN if [ "$DEBUG" = "false" ]; then rm -f /usr/local/lib/php/extensions/no-debug-non-zts-20220829/xdebug.so; fi EXPOSE 80 -CMD [ "php", "app/http.php" ] \ No newline at end of file +CMD [ "php", "app/http.php" ] diff --git a/dev/xdebug.ini b/dev/xdebug.ini index e29c8bd46e..f9c535019f 100644 --- a/dev/xdebug.ini +++ b/dev/xdebug.ini @@ -1,6 +1,8 @@ zend_extension=xdebug [xdebug] -xdebug.mode=develop,debug +xdebug.mode=develop,debug,profile xdebug.client_host=host.docker.internal -xdebug.start_with_request=yes \ No newline at end of file +xdebug.start_with_request=yes +xdebug.output_dir=/tmp/xdebug +xdebug.use_compression=false