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 56c22fe679..cf15d4c6c1 100755 --- a/Dockerfile +++ b/Dockerfile @@ -109,9 +109,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/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/ar-ma.json b/app/config/locale/translations/ar-ma.json new file mode 100644 index 0000000000..453de25c80 --- /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": "السرتافيكة فشلات ل %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": "ما معروفش", + "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": "ميريكان الجنوبية" +} diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index 953888013a..3a4a199e38 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -52,6 +52,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/app/controllers/api/users.php b/app/controllers/api/users.php index 7cab92da09..8b32349957 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1786,7 +1786,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()); @@ -1803,6 +1803,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(), @@ -1814,7 +1815,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/app/init.php b/app/init.php index b75e1bdd99..1ddb3ecdea 100644 --- a/app/init.php +++ b/app/init.php @@ -116,7 +116,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'; @@ -622,9 +622,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/composer.json b/composer.json index 9bdf194f73..d7b3e97c62 100644 --- a/composer.json +++ b/composer.json @@ -44,13 +44,13 @@ "ext-sockets": "*", "appwrite/php-runtimes": "0.14.*", "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 e18350a15a..a32159f79a 100644 --- a/composer.lock +++ b/composer.lock @@ -1428,23 +1428,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.*", @@ -1471,9 +1471,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", @@ -1523,21 +1523,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.*", @@ -1564,9 +1564,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", 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 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'], 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; } diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index ad6cf09fa7..58dc1dd28a 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -439,40 +439,24 @@ 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, ]; + $subject = \sprintf($locale->getText("emails.certificate.subject"), $domain); + $queueForMails ->setSubject($subject) ->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(); diff --git a/tests/e2e/Services/Health/HealthCustomServerTest.php b/tests/e2e/Services/Health/HealthCustomServerTest.php index 335e44be1b..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', $response['body']['issuerOrganisation']); + $this->assertStringContainsString('Google Trust Services', $response['body']['issuerOrganisation']); $this->assertIsInt($response['body']['validFrom']); $this->assertIsInt($response['body']['validTo']); 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 */ diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index 5af4aa751a..c34227e4de 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..)