diff --git a/.env b/.env index b889ebb513..2283ceeb30 100644 --- a/.env +++ b/.env @@ -9,7 +9,8 @@ _APP_CONSOLE_COUNTRIES_DENYLIST=AQ _APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io _APP_SYSTEM_EMAIL_NAME=Appwrite _APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io -_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io +_APP_EMAIL_SECURITY=security@appwrite.io +_APP_EMAIL_CERTIFICATES=certificates@appwrite.io _APP_SYSTEM_RESPONSE_FORMAT= _APP_OPTIONS_ABUSE=disabled _APP_OPTIONS_ROUTER_PROTECTION=disabled diff --git a/app/cli.php b/app/cli.php index 60bf81b262..df4c82203f 100644 --- a/app/cli.php +++ b/app/cli.php @@ -119,3 +119,84 @@ $cli $cli ->setContainer($container) ->run(); +require_once __DIR__ . '/init2.php'; +use Swoole\Runtime; +use Utopia\CLI\Adapters\Swoole as SwooleCLI; +use Utopia\DI\Dependency; +global $global, $container; +Runtime::enableCoroutine(SWOOLE_HOOK_ALL); +/** + * @var Registry $global + * @var Container $container + */ +$register = new Dependency(); +$logError = new Dependency(); +$queueForDeletes = new Dependency(); +$queueForCertificates = new Dependency(); +$register + ->setName('register') + ->setCallback(function () use (&$global): Registry { + return $global; + }); +$queueForDeletes + ->setName('queueForDeletes') + ->inject('queue') + ->setCallback(function (Connection $queue) { + return new Delete($queue); + }); + +$queueForCertificates + ->setName('queueForCertificates') + ->inject('queue') + ->setCallback(function (Connection $queue) { + return new Certificate($queue); + }); + +$logError + ->setName('logError') + ->inject('register') + ->setCallback(function (Registry $register) { + return function (Throwable $error, string $namespace, string $action) use ($register) { + $logger = $register->get('logger'); + if ($logger) { + $version = System::getEnv('_APP_VERSION', 'UNKNOWN'); + $log = new Log(); + $log->setNamespace($namespace); + $log->setServer(\gethostname()); + $log->setVersion($version); + $log->setType(Log::TYPE_ERROR); + $log->setMessage($error->getMessage()); + $log->addTag('code', $error->getCode()); + $log->addTag('verboseType', get_class($error)); + $log->addExtra('file', $error->getFile()); + $log->addExtra('line', $error->getLine()); + $log->addExtra('trace', $error->getTraceAsString()); + $log->addExtra('detailedTrace', $error->getTrace()); + $log->setAction($action); + $isProduction = System::getEnv('_APP_ENV', 'development') === 'production'; + + $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); + $responseCode = $logger->addLog($log); + Console::info('Usage stats log pushed with status code: ' . $responseCode); + } + Console::warning("Failed: {$error->getMessage()}"); + Console::warning($error->getTraceAsString()); + }; + }); + + +$container->set($logError); +$container->set($register); +$container->set($queueForDeletes); +$container->set($queueForCertificates); +$platform->init(Service::TYPE_CLI, ['adapter' => new SwooleCLI(1)]); +$cli + ->init() + ->inject('authorization') + ->action(function (Authorization $authorization) { + $authorization->disable(); + }); + +$cli + ->setContainer($container) + ->run(); diff --git a/app/config/locale/translations/af.json b/app/config/locale/translations/af.json index f8c8123979..238c6777bd 100644 --- a/app/config/locale/translations/af.json +++ b/app/config/locale/translations/af.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroasië", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ar.json b/app/config/locale/translations/ar.json index b2659a97be..cd45b32e02 100644 --- a/app/config/locale/translations/ar.json +++ b/app/config/locale/translations/ar.json @@ -100,6 +100,7 @@ "countries.gd": "غرينادا", "countries.gt": "غواتيمالا", "countries.gy": "غيانا", + "countries.hk": "هونغ كونغ", "countries.hn": "هندوراس", "countries.hr": "كرواتيا", "countries.ht": "هايتي", diff --git a/app/config/locale/translations/as.json b/app/config/locale/translations/as.json index 81a3c9aaa0..aa42483dde 100644 --- a/app/config/locale/translations/as.json +++ b/app/config/locale/translations/as.json @@ -100,6 +100,7 @@ "countries.gd": "গ্ৰেনাডা", "countries.gt": "গুয়াতেমালা", "countries.gy": "গায়ানা", + "countries.hk": "হং কং", "countries.hn": "হণ্ডুৰাছ", "countries.hr": "ক্ৰোৱেছিয়া", "countries.ht": "হাইতি", diff --git a/app/config/locale/translations/az.json b/app/config/locale/translations/az.json index c6a5c1301c..df1264fe8d 100644 --- a/app/config/locale/translations/az.json +++ b/app/config/locale/translations/az.json @@ -100,6 +100,7 @@ "countries.gd": "Qrenada", "countries.gt": "Qvatemala", "countries.gy": "Guyana", + "countries.hk": "Honq Konq", "countries.hn": "Honduras", "countries.hr": "Xorvatiya", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/be.json b/app/config/locale/translations/be.json index a5c03d0e29..a33916f623 100644 --- a/app/config/locale/translations/be.json +++ b/app/config/locale/translations/be.json @@ -100,6 +100,7 @@ "countries.gd": "Грэнада", "countries.gt": "Гватэмала", "countries.gy": "Гаяна", + "countries.hk": "Гонконг", "countries.hn": "Гандурас", "countries.hr": "Харватыя", "countries.ht": "Гаіці", diff --git a/app/config/locale/translations/bg.json b/app/config/locale/translations/bg.json index a3ed69f4c6..2dad3aecbe 100644 --- a/app/config/locale/translations/bg.json +++ b/app/config/locale/translations/bg.json @@ -100,6 +100,7 @@ "countries.gd": "Гренада", "countries.gt": "Гватемала", "countries.gy": "Гвиана", + "countries.hk": "Хонг Конг", "countries.hn": "Хондурас", "countries.hr": "Хърватия", "countries.ht": "Хаити", diff --git a/app/config/locale/translations/bh.json b/app/config/locale/translations/bh.json index eb6de0f12d..347f6f5d31 100644 --- a/app/config/locale/translations/bh.json +++ b/app/config/locale/translations/bh.json @@ -100,6 +100,7 @@ "countries.gd": "ग्रेनाडा", "countries.gt": "ग्वाटेमाला", "countries.gy": "गयाना", + "countries.hk": "हांगकांग", "countries.hn": "होंडुरस", "countries.hr": "क्रोएशिया", "countries.ht": "हैती", diff --git a/app/config/locale/translations/bn.json b/app/config/locale/translations/bn.json index 3e67c466d0..897faea7c1 100644 --- a/app/config/locale/translations/bn.json +++ b/app/config/locale/translations/bn.json @@ -100,6 +100,7 @@ "countries.gd": "গ্রেনাডা", "countries.gt": "গুয়াতেমালা", "countries.gy": "গায়ানা", + "countries.hk": "হংকং", "countries.hn": "হন্ডুরাস", "countries.hr": "ক্রোয়েশিয়া", "countries.ht": "হাইতি", diff --git a/app/config/locale/translations/bs.json b/app/config/locale/translations/bs.json index bdf6fe5be4..1ce2d57a3e 100644 --- a/app/config/locale/translations/bs.json +++ b/app/config/locale/translations/bs.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Gvajana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Hrvatska", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ca.json b/app/config/locale/translations/ca.json index 34c4b949cb..94e3ae24c5 100644 --- a/app/config/locale/translations/ca.json +++ b/app/config/locale/translations/ca.json @@ -100,6 +100,7 @@ "countries.gd": "Granada", "countries.gt": "Guatemala", "countries.gy": "Guaiana", + "countries.hk": "Hong Kong", "countries.hn": "Hondures", "countries.hr": "Croàcia", "countries.ht": "Haití", diff --git a/app/config/locale/translations/cs.json b/app/config/locale/translations/cs.json index 4156059080..4e3c533c77 100644 --- a/app/config/locale/translations/cs.json +++ b/app/config/locale/translations/cs.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Chorvatsko", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/da.json b/app/config/locale/translations/da.json index b5a2bcaa9d..d50d9c46c6 100644 --- a/app/config/locale/translations/da.json +++ b/app/config/locale/translations/da.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatien", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/de.json b/app/config/locale/translations/de.json index 61f4ad4d42..2279fcf4c0 100644 --- a/app/config/locale/translations/de.json +++ b/app/config/locale/translations/de.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatien", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/el.json b/app/config/locale/translations/el.json index de64b5738a..16c165ea39 100644 --- a/app/config/locale/translations/el.json +++ b/app/config/locale/translations/el.json @@ -100,6 +100,7 @@ "countries.gd": "Γρενάδα", "countries.gt": "Γουατεμάλα", "countries.gy": "Γουιάνα", + "countries.hk": "Χονγκ Κονγκ", "countries.hn": "Ονδούρα", "countries.hr": "Κροατία", "countries.ht": "Αϊτή", diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index f93dfcc0fd..72bb9c099e 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -117,6 +117,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/eo.json b/app/config/locale/translations/eo.json index ac54562128..406bd4f52c 100644 --- a/app/config/locale/translations/eo.json +++ b/app/config/locale/translations/eo.json @@ -99,6 +99,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/es.json b/app/config/locale/translations/es.json index 69abecfc52..0e02f816fe 100644 --- a/app/config/locale/translations/es.json +++ b/app/config/locale/translations/es.json @@ -100,6 +100,7 @@ "countries.gd": "Granada", "countries.gt": "Guatemala", "countries.gy": "Guayana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croacia", "countries.ht": "Haití", diff --git a/app/config/locale/translations/fa.json b/app/config/locale/translations/fa.json index 8a82b51e8c..9620b2c3f0 100644 --- a/app/config/locale/translations/fa.json +++ b/app/config/locale/translations/fa.json @@ -100,6 +100,7 @@ "countries.gd": "گرنادا", "countries.gt": "گواتمالا", "countries.gy": "گویان", + "countries.hk": "هنگ کنگ", "countries.hn": "هندوراس", "countries.hr": "کرواسی", "countries.ht": "هائیتی", diff --git a/app/config/locale/translations/fi.json b/app/config/locale/translations/fi.json index c7bea9a077..d86810d925 100644 --- a/app/config/locale/translations/fi.json +++ b/app/config/locale/translations/fi.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/fo.json b/app/config/locale/translations/fo.json index 2c6110f7f0..3853dbab9f 100644 --- a/app/config/locale/translations/fo.json +++ b/app/config/locale/translations/fo.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Gujana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/fr.json b/app/config/locale/translations/fr.json index 8ee459c9a9..d73f4e7c81 100644 --- a/app/config/locale/translations/fr.json +++ b/app/config/locale/translations/fr.json @@ -100,6 +100,7 @@ "countries.gd": "Grenade", "countries.gt": "Guatemala", "countries.gy": "Guyane", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatie", "countries.ht": "Haïti", diff --git a/app/config/locale/translations/ga.json b/app/config/locale/translations/ga.json index 8217dbe042..b7a641ac01 100644 --- a/app/config/locale/translations/ga.json +++ b/app/config/locale/translations/ga.json @@ -100,6 +100,7 @@ "countries.gd": "Greanáda", "countries.gt": "Guatamala", "countries.gy": "An Ghuáin", + "countries.hk": "Hong Kong", "countries.hn": "Hondúras", "countries.hr": "An Chróit", "countries.ht": "Háítí", diff --git a/app/config/locale/translations/gu.json b/app/config/locale/translations/gu.json index dc526cda61..8c41c76c54 100644 --- a/app/config/locale/translations/gu.json +++ b/app/config/locale/translations/gu.json @@ -100,6 +100,7 @@ "countries.gd": "ગ્રેનાડા", "countries.gt": "ગ્વાટેમાલા", "countries.gy": "ગુયાના", + "countries.hk": "હોંગ કોંગ", "countries.hn": "હોન્ડુરાસ", "countries.hr": "ક્રોએશિયા", "countries.ht": "હૈતી", diff --git a/app/config/locale/translations/he.json b/app/config/locale/translations/he.json index 96e8c32cc7..81705d3492 100644 --- a/app/config/locale/translations/he.json +++ b/app/config/locale/translations/he.json @@ -100,6 +100,7 @@ "countries.gd": "גרנדה", "countries.gt": "גואטמלה", "countries.gy": "גיאנה", + "countries.hk": "הונג קונג", "countries.hn": "הונדורס", "countries.hr": "קרואטיה", "countries.ht": "האיטי", diff --git a/app/config/locale/translations/hi.json b/app/config/locale/translations/hi.json index f3f1adf579..d764205ad6 100644 --- a/app/config/locale/translations/hi.json +++ b/app/config/locale/translations/hi.json @@ -100,6 +100,7 @@ "countries.gd": "ग्रेनाडा", "countries.gt": "ग्वाटेमाला", "countries.gy": "गयाना", + "countries.hk": "हांग कांग", "countries.hn": "होंडुरस", "countries.hr": "क्रोएशिया", "countries.ht": "हैती", diff --git a/app/config/locale/translations/hr.json b/app/config/locale/translations/hr.json index 12d7fe846c..8e537f12ec 100644 --- a/app/config/locale/translations/hr.json +++ b/app/config/locale/translations/hr.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gvatemala", "countries.gy": "Gvajana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Hrvatska", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/hu.json b/app/config/locale/translations/hu.json index d266c3ae1f..fded03aee1 100644 --- a/app/config/locale/translations/hu.json +++ b/app/config/locale/translations/hu.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Horvátország", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/hy.json b/app/config/locale/translations/hy.json index f951686961..2c4e72ebe3 100644 --- a/app/config/locale/translations/hy.json +++ b/app/config/locale/translations/hy.json @@ -100,6 +100,7 @@ "countries.gd": "Գրենադա", "countries.gt": "Գվատեմալա", "countries.gy": "Գայանա", + "countries.hk": "Հոնգ Կոնգ", "countries.hn": "Գոնդուրաս", "countries.hr": "Խորվաթիա", "countries.ht": "Հաիթի", diff --git a/app/config/locale/translations/id.json b/app/config/locale/translations/id.json index fae0246ca0..90b096e39e 100644 --- a/app/config/locale/translations/id.json +++ b/app/config/locale/translations/id.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroasia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/is.json b/app/config/locale/translations/is.json index 5b01dec76b..039d6849b7 100644 --- a/app/config/locale/translations/is.json +++ b/app/config/locale/translations/is.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gvatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Hondúras", "countries.hr": "Króatía", "countries.ht": "Haítí", diff --git a/app/config/locale/translations/it.json b/app/config/locale/translations/it.json index 5adf410708..d0716dd1e2 100644 --- a/app/config/locale/translations/it.json +++ b/app/config/locale/translations/it.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croazia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ja.json b/app/config/locale/translations/ja.json index 124f014bd6..6482488cf5 100644 --- a/app/config/locale/translations/ja.json +++ b/app/config/locale/translations/ja.json @@ -100,6 +100,7 @@ "countries.gd": "グレナダ", "countries.gt": "グアテマラ", "countries.gy": "ガイアナ", + "countries.hk": "香港", "countries.hn": "ホンジュラス", "countries.hr": "クロアチア", "countries.ht": "ハイチ", diff --git a/app/config/locale/translations/jv.json b/app/config/locale/translations/jv.json index 9e21d766f6..7f91a8dcef 100644 --- a/app/config/locale/translations/jv.json +++ b/app/config/locale/translations/jv.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/km.json b/app/config/locale/translations/km.json index 9088c7328a..72c362a77c 100644 --- a/app/config/locale/translations/km.json +++ b/app/config/locale/translations/km.json @@ -100,6 +100,7 @@ "countries.gd": "ហ្គ្រេណាដា", "countries.gt": "ហ្គាតេម៉ាឡា", "countries.gy": "ហ្គីយ៉ាណា", + "countries.hk": "ហុងកុង", "countries.hn": "ហុងឌូរ៉ាស", "countries.hr": "ក្រូអាត", "countries.ht": "ហៃទី", diff --git a/app/config/locale/translations/kn.json b/app/config/locale/translations/kn.json index 2b1424aba7..429958fc1a 100644 --- a/app/config/locale/translations/kn.json +++ b/app/config/locale/translations/kn.json @@ -100,6 +100,7 @@ "countries.gd": "ಗ್ರೆನಡಾ", "countries.gt": "ಗ್ವಾಟೆಮಾಲಾ", "countries.gy": "ಗಯಾನಾ", + "countries.hk": "ಹಾಂಗ್ ಕಾಂಗ್", "countries.hn": "ಹೊಂಡುರಾಸ್", "countries.hr": "ಕ್ರೊಯೇಷಿಯಾ", "countries.ht": "ಹೈಟಿ", diff --git a/app/config/locale/translations/ko.json b/app/config/locale/translations/ko.json index efca39eb72..372b7f1664 100644 --- a/app/config/locale/translations/ko.json +++ b/app/config/locale/translations/ko.json @@ -100,6 +100,7 @@ "countries.gd": "그레나다", "countries.gt": "과테말라", "countries.gy": "기아나", + "countries.hk": "홍콩", "countries.hn": "온두라스", "countries.hr": "크로아티아", "countries.ht": "아이티", diff --git a/app/config/locale/translations/la.json b/app/config/locale/translations/la.json index 2fcfb92b49..9ccbaba86e 100644 --- a/app/config/locale/translations/la.json +++ b/app/config/locale/translations/la.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", @@ -250,4 +251,4 @@ "emails.certificate.thanks": "Gratias", "emails.certificate.signature": "team {{project}}", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/lt.json b/app/config/locale/translations/lt.json index d026ee50e1..f72250c98e 100644 --- a/app/config/locale/translations/lt.json +++ b/app/config/locale/translations/lt.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gvatemala", "countries.gy": "Gajana", + "countries.hk": "Honkongas", "countries.hn": "Hondūras", "countries.hr": "Kroatija", "countries.ht": "Haitis", diff --git a/app/config/locale/translations/lv.json b/app/config/locale/translations/lv.json index d36e41f5b7..66604a0e3e 100644 --- a/app/config/locale/translations/lv.json +++ b/app/config/locale/translations/lv.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gvatemala", "countries.gy": "Gajāna", + "countries.hk": "Honkonga", "countries.hn": "Hondurasa", "countries.hr": "Horvātija", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ml.json b/app/config/locale/translations/ml.json index 8535aa9bb3..60e84e2a92 100644 --- a/app/config/locale/translations/ml.json +++ b/app/config/locale/translations/ml.json @@ -100,6 +100,7 @@ "countries.gd": "ഗ്രെനാഡ", "countries.gt": "ഗ്വാട്ടിമാല", "countries.gy": "ഗയാന", + "countries.hk": "ഹോങ്കോങ്", "countries.hn": "ഹോണ്ടുറാസ്", "countries.hr": "ക്രോയേഷ്യ", "countries.ht": "ഹെയ്തി", diff --git a/app/config/locale/translations/mr.json b/app/config/locale/translations/mr.json index d504755c70..4edd6bf617 100644 --- a/app/config/locale/translations/mr.json +++ b/app/config/locale/translations/mr.json @@ -100,6 +100,7 @@ "countries.gd": "ग्रेनाडा", "countries.gt": "ग्वाटेमाला", "countries.gy": "गुयाना", + "countries.hk": "हाँगकांग", "countries.hn": "होंडुरास", "countries.hr": "क्रोएशिया", "countries.ht": "हैती", diff --git a/app/config/locale/translations/ms.json b/app/config/locale/translations/ms.json index 1453a261a3..ded7587d34 100644 --- a/app/config/locale/translations/ms.json +++ b/app/config/locale/translations/ms.json @@ -100,6 +100,7 @@ "countries.gd": "Granada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/nb.json b/app/config/locale/translations/nb.json index 3419d7842a..f8680e8993 100644 --- a/app/config/locale/translations/nb.json +++ b/app/config/locale/translations/nb.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ne.json b/app/config/locale/translations/ne.json index 99888c64d4..f31609eafc 100644 --- a/app/config/locale/translations/ne.json +++ b/app/config/locale/translations/ne.json @@ -100,6 +100,7 @@ "countries.gd": "ग्रेनेडा", "countries.gt": "ग्वाटेमाला", "countries.gy": "गुयाना", + "countries.hk": "हाँगकाँग", "countries.hn": "होन्डुरस", "countries.hr": "क्रोएशिया", "countries.ht": "हैती", diff --git a/app/config/locale/translations/nl.json b/app/config/locale/translations/nl.json index 7ef9e776fd..55e48fa753 100644 --- a/app/config/locale/translations/nl.json +++ b/app/config/locale/translations/nl.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hongkong", "countries.hn": "Honduras", "countries.hr": "Croatië", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/nn.json b/app/config/locale/translations/nn.json index a77ac1b173..6ab037466f 100644 --- a/app/config/locale/translations/nn.json +++ b/app/config/locale/translations/nn.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/or.json b/app/config/locale/translations/or.json index 72c9888c4a..08b150fbb7 100644 --- a/app/config/locale/translations/or.json +++ b/app/config/locale/translations/or.json @@ -100,6 +100,7 @@ "countries.gd": "ଗ୍ରେନାଡା", "countries.gt": "ଗୁଆଟେମାଲା", "countries.gy": "ଗୁଇନ୍ଦା", + "countries.hk": "ହଂ କଙ୍ଗ", "countries.hn": "ହୋଣ୍ଡୁରାସ୍", "countries.hr": "କ୍ରୋଏସିଆ", "countries.ht": "ହାଇତି", diff --git a/app/config/locale/translations/pa.json b/app/config/locale/translations/pa.json index aaa260cbaa..76efde346b 100644 --- a/app/config/locale/translations/pa.json +++ b/app/config/locale/translations/pa.json @@ -100,6 +100,7 @@ "countries.gd": "ਗ੍ਰੇਨਾਡਾ", "countries.gt": "ਗੁਆਟੇਮਾਲਾ", "countries.gy": "ਗੇਆਨਾ", + "countries.hk": "ਹਾਂਗ ਕਾਂਗ", "countries.hn": "ਹੌਂਡੂਰਸ", "countries.hr": "ਕਰੋਸ਼ੀਆ", "countries.ht": "ਹੈਤੀ", diff --git a/app/config/locale/translations/pl.json b/app/config/locale/translations/pl.json index 05cad39be8..e596d2c04b 100644 --- a/app/config/locale/translations/pl.json +++ b/app/config/locale/translations/pl.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gwatemala", "countries.gy": "Gujana", + "countries.hk": "Hongkong", "countries.hn": "Honduras", "countries.hr": "Chorwacja", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/pt-br.json b/app/config/locale/translations/pt-br.json index 2094b053f0..b2c4931011 100644 --- a/app/config/locale/translations/pt-br.json +++ b/app/config/locale/translations/pt-br.json @@ -100,6 +100,7 @@ "countries.gd": "Granada", "countries.gt": "Guatemala", "countries.gy": "Guiana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croácia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/pt-pt.json b/app/config/locale/translations/pt-pt.json index 173a7b3a3a..2dab03c9dd 100644 --- a/app/config/locale/translations/pt-pt.json +++ b/app/config/locale/translations/pt-pt.json @@ -100,6 +100,7 @@ "countries.gd": "Granada", "countries.gt": "Guatemala", "countries.gy": "Guiana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croácia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ro.json b/app/config/locale/translations/ro.json index e8cb94b2d6..45fb71d190 100644 --- a/app/config/locale/translations/ro.json +++ b/app/config/locale/translations/ro.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croația", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ru.json b/app/config/locale/translations/ru.json index fa60ff83c6..a1d740bea2 100644 --- a/app/config/locale/translations/ru.json +++ b/app/config/locale/translations/ru.json @@ -100,6 +100,7 @@ "countries.gd": "Гренада", "countries.gt": "Гватемала", "countries.gy": "Гайана", + "countries.hk": "Гонконг", "countries.hn": "Гондурас", "countries.hr": "Хорватия", "countries.ht": "Гаити", diff --git a/app/config/locale/translations/sa.json b/app/config/locale/translations/sa.json index b05ff33e6a..b82a3ed9ba 100644 --- a/app/config/locale/translations/sa.json +++ b/app/config/locale/translations/sa.json @@ -100,6 +100,7 @@ "countries.gd": "ग्रेनेडा", "countries.gt": "ग्वाटेमाला", "countries.gy": "गुयाना", + "countries.hk": "हांगकांग", "countries.hn": "होंडुरस्‌", "countries.hr": "क्रोएशिया", "countries.ht": "हैती", diff --git a/app/config/locale/translations/sd.json b/app/config/locale/translations/sd.json index c6ba578f15..69cad52549 100644 --- a/app/config/locale/translations/sd.json +++ b/app/config/locale/translations/sd.json @@ -100,6 +100,7 @@ "countries.gd": "گرينڊا", "countries.gt": "گٽيمالا", "countries.gy": "گيانا", + "countries.hk": "هانگ کانگ", "countries.hn": "هونڊرس", "countries.hr": "ڪوريٽيا", "countries.ht": "هيٽي", diff --git a/app/config/locale/translations/si.json b/app/config/locale/translations/si.json index e95f993438..f1c4b7c86b 100644 --- a/app/config/locale/translations/si.json +++ b/app/config/locale/translations/si.json @@ -100,6 +100,7 @@ "countries.gd": "ග්‍රෙනාඩා", "countries.gt": "ග්වාතමාලාව", "countries.gy": "ගයනා", + "countries.hk": "හොංකොං", "countries.hn": "හොන්ඩුරාස්", "countries.hr": "ක්‍රොඒෂියාව", "countries.ht": "හයිටි", diff --git a/app/config/locale/translations/sk.json b/app/config/locale/translations/sk.json index 61405df84d..457e756c9a 100644 --- a/app/config/locale/translations/sk.json +++ b/app/config/locale/translations/sk.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hongkong", "countries.hn": "Honduras", "countries.hr": "Chorvátsko", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/sl.json b/app/config/locale/translations/sl.json index ffd7ee8902..ec7b4c1ebf 100644 --- a/app/config/locale/translations/sl.json +++ b/app/config/locale/translations/sl.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Gvatemala", "countries.gy": "Gvajana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Hrvaška", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/sn.json b/app/config/locale/translations/sn.json index 62b97c4237..d8b2f2c682 100644 --- a/app/config/locale/translations/sn.json +++ b/app/config/locale/translations/sn.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/sq.json b/app/config/locale/translations/sq.json index 9a54e45d25..0fb066a8ea 100644 --- a/app/config/locale/translations/sq.json +++ b/app/config/locale/translations/sq.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guajana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroacia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/sv.json b/app/config/locale/translations/sv.json index 3ee4c1d0e3..b838c05084 100644 --- a/app/config/locale/translations/sv.json +++ b/app/config/locale/translations/sv.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroatien", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/ta.json b/app/config/locale/translations/ta.json index 252f91a579..659306c977 100644 --- a/app/config/locale/translations/ta.json +++ b/app/config/locale/translations/ta.json @@ -100,6 +100,7 @@ "countries.gd": "கிரெனடா", "countries.gt": "குவாத்தமாலா", "countries.gy": "கயானா", + "countries.hk": "ஹாங்காங்", "countries.hn": "ஹொண்டூராஸ்", "countries.hr": "குரோவாசியா", "countries.ht": "ஹைத்தி", diff --git a/app/config/locale/translations/te.json b/app/config/locale/translations/te.json index 86ffbeca43..019b4581ca 100644 --- a/app/config/locale/translations/te.json +++ b/app/config/locale/translations/te.json @@ -100,6 +100,7 @@ "countries.gd": "గ్రెనడా", "countries.gt": "గ్వాటెమాల", "countries.gy": "గయానా", + "countries.hk": "హాంగ్ కొంగ", "countries.hn": "హోండురాస్", "countries.hr": "క్రొయేషియా", "countries.ht": "హైతీ", diff --git a/app/config/locale/translations/th.json b/app/config/locale/translations/th.json index 95552f624b..97d224de1f 100644 --- a/app/config/locale/translations/th.json +++ b/app/config/locale/translations/th.json @@ -100,6 +100,7 @@ "countries.gd": "เกรเนดา", "countries.gt": "กัวเตมาลา", "countries.gy": "กายอานา", + "countries.hk": "ฮ่องกง", "countries.hn": "ฮอนดูรัส", "countries.hr": "โครเอเชีย", "countries.ht": "ไฮติ", diff --git a/app/config/locale/translations/tl.json b/app/config/locale/translations/tl.json index 1da537230d..e6df9f8aef 100644 --- a/app/config/locale/translations/tl.json +++ b/app/config/locale/translations/tl.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guwatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Kroasya", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/tr.json b/app/config/locale/translations/tr.json index 54007fc723..808a20576c 100644 --- a/app/config/locale/translations/tr.json +++ b/app/config/locale/translations/tr.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Hırvatistan", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/uk.json b/app/config/locale/translations/uk.json index a7a0d7a78d..78e3a6c556 100644 --- a/app/config/locale/translations/uk.json +++ b/app/config/locale/translations/uk.json @@ -100,6 +100,7 @@ "countries.gd": "Гренада", "countries.gt": "Гватемала", "countries.gy": "Гайана", + "countries.hk": "Гонконг", "countries.hn": "Гондурас", "countries.hr": "Хорватія", "countries.ht": "Гаїті", diff --git a/app/config/locale/translations/ur.json b/app/config/locale/translations/ur.json index de9a2768c3..060cea0736 100644 --- a/app/config/locale/translations/ur.json +++ b/app/config/locale/translations/ur.json @@ -100,6 +100,7 @@ "countries.gd": "گریناڈا", "countries.gt": "گوئٹے مالا", "countries.gy": "گیانا", + "countries.hk": "ہانگ کانگ", "countries.hn": "ہونڈوراس", "countries.hr": "کروشیا", "countries.ht": "ہیٹی", diff --git a/app/config/locale/translations/vi.json b/app/config/locale/translations/vi.json index 400c8c09d1..cf04a5b737 100644 --- a/app/config/locale/translations/vi.json +++ b/app/config/locale/translations/vi.json @@ -100,6 +100,7 @@ "countries.gd": "Grenada", "countries.gt": "Guatemala", "countries.gy": "Guyana", + "countries.hk": "Hong Kong", "countries.hn": "Honduras", "countries.hr": "Croatia", "countries.ht": "Haiti", diff --git a/app/config/locale/translations/zh-cn.json b/app/config/locale/translations/zh-cn.json index 5b634d990f..0bfbc54e0e 100644 --- a/app/config/locale/translations/zh-cn.json +++ b/app/config/locale/translations/zh-cn.json @@ -100,6 +100,7 @@ "countries.gd": "格林纳达", "countries.gt": "危地马拉", "countries.gy": "圭亚那", + "countries.hk": "香港", "countries.hn": "洪都拉斯", "countries.hr": "克罗地亚", "countries.ht": "海地", diff --git a/app/config/locale/translations/zh-tw.json b/app/config/locale/translations/zh-tw.json index 61600da08e..24729de6b3 100644 --- a/app/config/locale/translations/zh-tw.json +++ b/app/config/locale/translations/zh-tw.json @@ -100,6 +100,7 @@ "countries.gd": "格瑞那達", "countries.gt": "瓜地馬拉", "countries.gy": "蓋亞那", + "countries.hk": "香港", "countries.hn": "宏都拉斯", "countries.hr": "克羅埃西亞", "countries.ht": "海地", diff --git a/app/config/variables.php b/app/config/variables.php index b61a267785..f7cd34b1e1 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -162,13 +162,31 @@ return [ ], [ 'name' => '_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', - 'description' => 'This is the email address used to issue SSL certificates for custom domains or the user agent in your webhooks payload.', + 'description' => 'Deprecated since 1.5.1 use _APP_EMAIL_SECURITY and _APP_EMAIL_CERTIFICATES instead', 'introduction' => '0.7.0', 'default' => 'certs@appwrite.io', 'required' => false, 'question' => '', 'filter' => '' ], + [ + 'name' => '_APP_EMAIL_SECURITY', + 'description' => 'This is the email address used as the user agent in your webhooks payload.', + 'introduction' => '1.5.1', + 'default' => '', + 'required' => false, + 'question' => '', + 'filter' => '' + ], + [ + 'name' => '_APP_EMAIL_CERTIFICATES', + 'description' => 'This is the email address used to issue SSL certificates for custom domains', + 'introduction' => '1.5.1', + 'default' => '', + 'required' => true, + 'question' => '', + 'filter' => '' + ], [ 'name' => '_APP_USAGE_STATS', 'description' => 'This variable allows you to disable the collection and displaying of usage stats. This value is set to \'enabled\' by default, to disable the usage stats set the value to \'disabled\'. When disabled, it\'s recommended to turn off the Worker Usage container to reduce resource usage.', diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ee8368a102..05bf87829e 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -291,7 +291,9 @@ Http::post('/v1/account') $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); + } } $dbForProject->purgeCachedDocument('users', $user->getId()); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index b54413f457..54ba096c5d 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -354,7 +354,7 @@ Http::get('/v1/avatars/favicon') ->setUserAgent(\sprintf( APP_USERAGENT, System::getEnv('_APP_VERSION', 'UNKNOWN'), - System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + System::getEnv('_APP_EMAIL_SECURITY', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)) )) ->fetch($url); } catch (\Throwable) { diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index bfd98dd636..564c9314a0 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -352,7 +352,7 @@ Http::post('/v1/storage/buckets/:bucketId/files') ->label('sdk.response.model', Response::MODEL_FILE) ->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).') ->param('fileId', '', new CustomId(), 'File ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') - ->param('file', [], new File(), 'Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/storage#file-input).', skipValidation: true) + ->param('file', [], new File(), 'Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/products/storage/upload-download#input-file).', skipValidation: true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->inject('request') ->inject('response') diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index e3cd21fdb7..2bab10d0f1 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -388,7 +388,7 @@ Http::post('/v1/teams/:teamId/memberships') ->param('userId', '', new UID(), 'ID of the user to be added to a team.', true) ->param('phone', '', new Phone(), 'Phone number. Format this number with a leading \'+\' and a country code, e.g., +16175551212.', true) ->param('roles', [], new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.') - ->param('url', '', fn ($clients) => new Host($clients), 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients']) // TODO add our own built-in confirm page + ->param('url', '', fn ($clients) => new Host($clients), 'URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients']) // TODO add our own built-in confirm page ->param('name', '', new Text(128), 'Name of the new team member. Max length: 128 chars.', true) ->inject('response') ->inject('project') diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 27f605e571..439da24ff4 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -138,7 +138,9 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); + } } } @@ -160,7 +162,9 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + if($existingTarget) { + $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); + } } } diff --git a/app/init.php b/app/init.php index 5e11f96e5d..c31c83864a 100644 --- a/app/init.php +++ b/app/init.php @@ -1013,7 +1013,7 @@ foreach ($locales as $locale) { 'user_agent' => \sprintf( APP_USERAGENT, System::getEnv('_APP_VERSION', 'UNKNOWN'), - System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + System::getEnv('_APP_EMAIL_SECURITY', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)) ), 'timeout' => 2, ], diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 2667b43f6b..5dbd860c0a 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -80,7 +80,7 @@ services: - _APP_CONSOLE_HOSTNAMES - _APP_SYSTEM_EMAIL_NAME - _APP_SYSTEM_EMAIL_ADDRESS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_SYSTEM_RESPONSE_FORMAT - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION @@ -250,6 +250,7 @@ services: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 + - _APP_EMAIL_SECURITY - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS - _APP_DB_HOST - _APP_DB_PORT @@ -431,7 +432,7 @@ services: - _APP_DOMAIN - _APP_DOMAIN_TARGET - _APP_DOMAIN_FUNCTIONS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_CERTIFICATES - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER @@ -581,7 +582,7 @@ services: - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - _APP_DOMAIN_TARGET - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER diff --git a/app/worker.php b/app/worker.php index 39cb69fd6f..3ce0281fe7 100644 --- a/app/worker.php +++ b/app/worker.php @@ -113,11 +113,6 @@ if (!isset($args[1])) { \array_shift($args); $workerName = $args[0]; -$workerIndex = $args[1] ?? ''; - -if (!empty($workerIndex)) { - $workerName .= '_' . $workerIndex; -} if (\str_starts_with($workerName, 'databases')) { $queueName = System::getEnv('_APP_QUEUE_NAME', 'db_main'); diff --git a/composer.json b/composer.json index 2ac000424f..b06b27d75c 100644 --- a/composer.json +++ b/composer.json @@ -70,6 +70,7 @@ "utopia-php/queue": "dev-feat-coroutine-and-di as 0.7.99", "utopia-php/registry": "0.5.*", "utopia-php/storage": "dev-feat-framework-v2-v2 as 0.18.99", + "utopia-php/swoole": "0.8.*", "utopia-php/system": "0.8.*", "utopia-php/vcs": "0.6.*", "utopia-php/websocket": "0.1.*", diff --git a/docker-compose.yml b/docker-compose.yml index 69c2832b46..3b2f7da5e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -101,7 +101,7 @@ services: - _APP_CONSOLE_HOSTNAMES - _APP_SYSTEM_EMAIL_NAME - _APP_SYSTEM_EMAIL_ADDRESS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_SYSTEM_RESPONSE_FORMAT - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION @@ -286,7 +286,7 @@ services: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_DB_HOST - _APP_DB_PORT - _APP_DB_SCHEMA @@ -475,7 +475,7 @@ services: - _APP_DOMAIN - _APP_DOMAIN_TARGET - _APP_DOMAIN_FUNCTIONS - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_CERTIFICATES - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER @@ -635,7 +635,7 @@ services: - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - _APP_DOMAIN_TARGET - - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT - _APP_REDIS_USER diff --git a/src/Appwrite/Platform/Appwrite.php b/src/Appwrite/Platform/Appwrite.php index 05224799f3..6b3eb077fa 100644 --- a/src/Appwrite/Platform/Appwrite.php +++ b/src/Appwrite/Platform/Appwrite.php @@ -2,15 +2,13 @@ namespace Appwrite\Platform; -use Appwrite\Platform\Services\Tasks; -use Appwrite\Platform\Services\Workers; +use Appwrite\Platform\Modules\Core; use Utopia\Platform\Platform; class Appwrite extends Platform { public function __construct() { - $this->addService('tasks', new Tasks()); - $this->addService('workers', new Workers()); + parent::__construct(new Core()); } } diff --git a/src/Appwrite/Platform/Modules/Core.php b/src/Appwrite/Platform/Modules/Core.php new file mode 100644 index 0000000000..859ca3b529 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Core.php @@ -0,0 +1,17 @@ +addService('tasks', new Tasks()); + $this->addService('workers', new Workers()); + } + +} diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index ac1f99eec3..31465d2f26 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -22,7 +22,7 @@ class Tasks extends Service { public function __construct() { - $this->type = self::TYPE_CLI; + $this->type = Service::TYPE_TASK; $this ->addAction(Doctor::getName(), new Doctor()) ->addAction(Install::getName(), new Install()) diff --git a/src/Appwrite/Platform/Services/Workers.php b/src/Appwrite/Platform/Services/Workers.php index 62a7fcf3fb..0e79f4257c 100644 --- a/src/Appwrite/Platform/Services/Workers.php +++ b/src/Appwrite/Platform/Services/Workers.php @@ -20,7 +20,7 @@ class Workers extends Service { public function __construct() { - $this->type = self::TYPE_WORKER; + $this->type = Service::TYPE_WORKER; $this ->addAction(Audits::getName(), new Audits()) ->addAction(Builds::getName(), new Builds()) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index cfbc4b200a..1da8a58ebe 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -49,6 +49,7 @@ class Maintenance extends Action $this->foreachProject($dbForConsole, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) { $queueForDeletes->setProject($project); + $this->notifyDeleteTargets($queueForDeletes); $this->notifyDeleteExecutionLogs($queueForDeletes); $this->notifyDeleteAbuseLogs($queueForDeletes); $this->notifyDeleteAuditLogs($queueForDeletes); @@ -60,7 +61,6 @@ class Maintenance extends Action $this->renewCertificates($dbForConsole, $queueForCertificates); $this->notifyDeleteCache($cacheRetention, $queueForDeletes); $this->notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes); - $this->notifyDeleteTargets($queueForDeletes); }, $interval, $delay); } diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index c4a6cd7a04..5b89334520 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -135,9 +135,9 @@ class Certificates extends Action try { // Email for alerts is required by LetsEncrypt - $email = System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'); + $email = System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')); if (empty($email)) { - throw new Exception('You must set a valid security email address (_APP_SYSTEM_SECURITY_EMAIL_ADDRESS) to issue an SSL certificate.'); + throw new Exception('You must set a valid security email address (_APP_EMAIL_CERTIFICATES) to issue an SSL certificate.'); } // Validate domain and DNS records. Skip if job is forced @@ -470,7 +470,7 @@ class Certificates extends Action ->setBody($body) ->setName('Appwrite Administrator') ->setVariables($emailVariables) - ->setRecipient(System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')) + ->setRecipient(System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'))) ->trigger(); } diff --git a/src/Appwrite/Platform/Workers/Webhooks.php b/src/Appwrite/Platform/Workers/Webhooks.php index d60946f709..88ca7871f2 100644 --- a/src/Appwrite/Platform/Workers/Webhooks.php +++ b/src/Appwrite/Platform/Workers/Webhooks.php @@ -104,7 +104,7 @@ class Webhooks extends Action \curl_setopt($ch, CURLOPT_USERAGENT, \sprintf( APP_USERAGENT, System::getEnv('_APP_VERSION', 'UNKNOWN'), - System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + System::getEnv('_APP_EMAIL_SECURITY', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)) )); \curl_setopt( $ch, diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 23771712e8..b1f7c85cd9 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -150,7 +150,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertEquals($response['body']['name'], $name); $this->assertArrayHasKey('accessedAt', $response['body']); @@ -294,7 +294,7 @@ class AccountCustomClientTest extends Scope $this->assertIsNumeric($response['body']['total']); $this->assertEquals("user.create", $response['body']['logs'][2]['event']); $this->assertEquals(filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP), $response['body']['logs'][2]['ip']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['logs'][2]['time'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['logs'][2]['time'])); $this->assertEquals('Windows', $response['body']['logs'][1]['osName']); $this->assertEquals('WIN', $response['body']['logs'][1]['osCode']); @@ -327,7 +327,6 @@ class AccountCustomClientTest extends Scope $this->assertEquals('desktop', $response['body']['logs'][2]['deviceName']); $this->assertEquals('', $response['body']['logs'][2]['deviceBrand']); $this->assertEquals('', $response['body']['logs'][2]['deviceModel']); - $this->assertEquals($response['body']['logs'][2]['ip'], filter_var($response['body']['logs'][2]['ip'], FILTER_VALIDATE_IP)); $this->assertEquals('--', $response['body']['logs'][2]['countryCode']); $this->assertEquals('Unknown', $response['body']['logs'][2]['countryName']); @@ -343,7 +342,7 @@ class AccountCustomClientTest extends Scope ] ]); - $this->assertEquals($responseLimit['headers']['status-code'], 200); + $this->assertEquals(200, $responseLimit['headers']['status-code']); $this->assertIsArray($responseLimit['body']['logs']); $this->assertNotEmpty($responseLimit['body']['logs']); $this->assertCount(1, $responseLimit['body']['logs']); @@ -382,7 +381,7 @@ class AccountCustomClientTest extends Scope ] ]); - $this->assertEquals($responseLimitOffset['headers']['status-code'], 200); + $this->assertEquals(200, $responseLimitOffset['headers']['status-code']); $this->assertIsArray($responseLimitOffset['body']['logs']); $this->assertNotEmpty($responseLimitOffset['body']['logs']); $this->assertCount(1, $responseLimitOffset['body']['logs']); @@ -430,7 +429,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertEquals($response['body']['name'], $newName); @@ -497,7 +496,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -587,7 +586,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $newEmail); /** @@ -629,7 +628,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $data['email']); $this->assertEquals($response['body']['name'], $data['name']); @@ -771,7 +770,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $lastEmail = $this->getLastEmail(); @@ -1073,7 +1072,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $lastEmail = $this->getLastEmail(); @@ -1668,7 +1667,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -1756,13 +1755,11 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals($response['body']['$id'], $userId); - $this->assertEquals($response['body']['name'], 'User Name'); - $this->assertEquals($response['body']['email'], 'useroauth@localhost.test'); + $this->assertEquals('User Name', $response['body']['name']); + $this->assertEquals('useroauth@localhost.test', $response['body']['email']); // Since we only support one oauth user, let's also check updateSession here - $this->assertEquals(200, $response['headers']['status-code']); - $response = $this->client->call(Client::METHOD_GET, '/account/sessions/current', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -1808,7 +1805,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals($response['body']['provider'], 'anonymous'); + $this->assertEquals('anonymous', $response['body']['provider']); $sessionID = $response['body']['$id']; @@ -1821,7 +1818,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals($response['body']['provider'], 'anonymous'); + $this->assertEquals('anonymous', $response['body']['provider']); $response = $this->client->call(Client::METHOD_GET, '/account/sessions/97823askjdkasd80921371980', array_merge([ 'origin' => 'http://localhost', @@ -1934,7 +1931,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $userId = $response['body']['userId']; @@ -2085,7 +2082,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ @@ -2127,7 +2124,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['phone'], $newPhone); /** @@ -2240,7 +2237,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $smsRequest = $this->getLastRequest(); @@ -2327,7 +2324,7 @@ class AccountCustomClientTest extends Scope $this->assertNotEmpty($response['body']['$id']); $this->assertEmpty($response['body']['secret']); $this->assertEmpty($response['body']['phrase']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['expire'])); $userId = $response['body']['userId']; @@ -2452,7 +2449,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $this->assertTrue($response['body']['emailVerification']); @@ -2512,7 +2509,7 @@ class AccountCustomClientTest extends Scope $this->assertIsArray($response['body']); $this->assertNotEmpty($response['body']); $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['registration'])); + $this->assertTrue((new DatetimeValidator())->isValid($response['body']['registration'])); $this->assertEquals($response['body']['email'], $email); $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ diff --git a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php index 119c1a2223..0b8ea71aad 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomClientTest.php @@ -716,4 +716,94 @@ class FunctionsCustomClientTest extends Scope return []; } + + public function testNonOverrideOfHeaders(): array + { + /** + * Test for SUCCESS + */ + $projectId = $this->getProject()['$id']; + $apikey = $this->getProject()['apiKey']; + + $function = $this->client->call(Client::METHOD_POST, '/functions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ], [ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::any()->toString()], + 'runtime' => 'node-18.0', + 'entrypoint' => 'index.js' + ]); + + $functionId = $function['body']['$id'] ?? ''; + + $this->assertEquals(201, $function['headers']['status-code']); + + $folder = 'node'; + $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + $this->packageCode($folder); + + $deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $apikey, + ], [ + 'entrypoint' => 'index.js', + 'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional + 'activate' => true + ]); + + $deploymentId = $deployment['body']['$id'] ?? ''; + + $this->assertEquals(202, $deployment['headers']['status-code']); + + // Poll until deployment is built + while (true) { + $deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/deployments/' . $deploymentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + if ( + $deployment['headers']['status-code'] >= 400 + || \in_array($deployment['body']['status'], ['ready', 'failed']) + ) { + break; + } + + \sleep(1); + } + + $this->assertEquals('ready', $deployment['body']['status']); + + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'x-appwrite-event' => "OVERRIDDEN", + 'x-appwrite-trigger' => "OVERRIDDEN", + 'x-appwrite-user-id' => "OVERRIDDEN", + 'x-appwrite-user-jwt' => "OVERRIDDEN", + ]); + + $output = json_decode($execution['body']['responseBody'], true); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_JWT']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_EVENT']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_TRIGGER']); + $this->assertNotEquals('OVERRIDDEN', $output['APPWRITE_FUNCTION_USER_ID']); + + // Cleanup : Delete function + $response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], []); + + $this->assertEquals(204, $response['headers']['status-code']); + + return []; + } }