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..)