diff --git a/.env b/.env index f6a6a7f642..8ff8164a21 100644 --- a/.env +++ b/.env @@ -2,6 +2,7 @@ _APP_ENV=development _APP_EDITION=self-hosted _APP_LOCALE=en _APP_WORKER_PER_CORE=6 +_APP_COMPRESSION_MIN_SIZE_BYTES=1024 _APP_CONSOLE_WHITELIST_ROOT=disabled _APP_CONSOLE_WHITELIST_EMAILS= _APP_CONSOLE_SESSION_ALERTS=enabled diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7c53b03b52..29aa9b0581 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -125,6 +125,7 @@ jobs: Webhooks, VCS, Messaging, + Migrations ] steps: diff --git a/.gitignore b/.gitignore index 5ae03e2a56..0d2b4b51ff 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ dev/yasd_init.php .phpunit.result.cache Makefile appwrite.json +.zed/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 13b018df0f..07295f4afb 100755 --- a/Dockerfile +++ b/Dockerfile @@ -92,10 +92,10 @@ RUN chmod +x /usr/local/bin/doctor && \ 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" = "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 +RUN if [ "$DEBUG" = "false" ]; then rm -f /usr/local/lib/php/extensions/no-debug-non-zts-20230831/xdebug.so; fi EXPOSE 80 diff --git a/SECURITY.md b/SECURITY.md index a17a55e368..d5901533fb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,6 +11,7 @@ | 1.3.x | :white_check_mark: | | 1.4.x | :white_check_mark: | | 1.5.x | :white_check_mark: | +| 1.6.x | :white_check_mark: | ## Reporting a Vulnerability diff --git a/app/config/errors.php b/app/config/errors.php index fc79599b12..3afec4faaf 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -24,6 +24,11 @@ return [ 'description' => 'Access to this API is forbidden.', 'code' => 401, ], + Exception::GENERAL_RESOURCE_BLOCKED => [ + 'name' => Exception::GENERAL_RESOURCE_BLOCKED, + 'description' => 'Access to this resource is blocked.', + 'code' => 401, + ], Exception::GENERAL_UNKNOWN_ORIGIN => [ 'name' => Exception::GENERAL_UNKNOWN_ORIGIN, 'description' => 'The request originated from an unknown origin. If you trust this domain, please list it as a trusted platform in the Appwrite console.', diff --git a/app/config/locale/templates/email-inner-base.tpl b/app/config/locale/templates/email-inner-base.tpl index 52e1093ffb..8cef391d2f 100644 --- a/app/config/locale/templates/email-inner-base.tpl +++ b/app/config/locale/templates/email-inner-base.tpl @@ -1,9 +1,9 @@ -

{{hello}},

+

{{hello}}

{{body}}

{{redirect}}

{{footer}}

- {{thanks}}, + {{thanks}}
{{signature}}

\ No newline at end of file diff --git a/app/config/locale/templates/email-magic-url.tpl b/app/config/locale/templates/email-magic-url.tpl index def1ea2395..21988c5bc1 100644 --- a/app/config/locale/templates/email-magic-url.tpl +++ b/app/config/locale/templates/email-magic-url.tpl @@ -1,4 +1,4 @@ -

{{hello}},

+

{{hello}}

{{optionButton}}

diff --git a/app/config/locale/templates/email-mfa-challenge.tpl b/app/config/locale/templates/email-mfa-challenge.tpl index e3cb6b444d..3e55227055 100644 --- a/app/config/locale/templates/email-mfa-challenge.tpl +++ b/app/config/locale/templates/email-mfa-challenge.tpl @@ -1,4 +1,4 @@ -

{{hello}},

+

{{hello}}

{{description}}

diff --git a/app/config/locale/templates/email-otp.tpl b/app/config/locale/templates/email-otp.tpl index 9552185f84..84802c1603 100644 --- a/app/config/locale/templates/email-otp.tpl +++ b/app/config/locale/templates/email-otp.tpl @@ -1,4 +1,4 @@ -

{{hello}},

+

{{hello}}

{{description}}

diff --git a/app/config/locale/templates/email-session-alert.tpl b/app/config/locale/templates/email-session-alert.tpl index 20cecf212d..bd2f52af79 100644 --- a/app/config/locale/templates/email-session-alert.tpl +++ b/app/config/locale/templates/email-session-alert.tpl @@ -1,4 +1,4 @@ -

{{hello}},

+

{{hello}}

{{body}}

diff --git a/app/config/locale/translations/af.json b/app/config/locale/translations/af.json index 238c6777bd..e68fda2c75 100644 --- a/app/config/locale/translations/af.json +++ b/app/config/locale/translations/af.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s span", "emails.verification.subject": "Rekening Bevestiging", - "emails.verification.hello": "Goeie dag {{user}}", + "emails.verification.hello": "Goeie dag {{user}},", "emails.verification.body": "Volg hierdie skakel om u e-pos adres te bevestig.", "emails.verification.footer": "Ignoreer gerus hierdie boodskap as u nie die versoek gestuur het om u adres te bevestig nie.", - "emails.verification.thanks": "Baie dankie", + "emails.verification.thanks": "Baie dankie,", "emails.verification.signature": "Die {{project}} span", "emails.magicSession.subject": "Teken aan", - "emails.magicSession.hello": "Goeie dag", + "emails.magicSession.hello": "Goeie dag,", "emails.magicSession.body": "Volg hierdie skakel om in te teken.", "emails.magicSession.footer": "Ignoreer gerus hierdie boodskap as u nie die versoek gestuur het om met die' adres in te teken nie.", - "emails.magicSession.thanks": "Baie dankie", + "emails.magicSession.thanks": "Baie dankie,", "emails.magicSession.signature": "Die {{project}} span", "emails.recovery.subject": "Herstel Wagwoord", - "emails.recovery.hello": "Goeie dag {{user}}", + "emails.recovery.hello": "Goeie dag {{user}},", "emails.recovery.body": "Volg hierdie skakel om u {{project}} wagwoord te herstel.", "emails.recovery.footer": "Ignoreer gerus hierdie boodskap as u nie die versoek gestuur het om u wagwoord te herstel nie.", - "emails.recovery.thanks": "Baie dankie", + "emails.recovery.thanks": "Baie dankie,", "emails.recovery.signature": "Die {{project}} span", "emails.invitation.subject": "Uitnodiging om by die %s span aan te sluit by %s", "emails.invitation.hello": "Goeie dag,", "emails.invitation.body": "Hierdie boodskap is aan u gestuur omdat {{owner}} u uitnooi om 'n lid van die {{team}} groep by die {{project}} projek te wees.", "emails.invitation.footer": "As u nie belang stel nie, kan u gerus hierdie boodskap ignoreer.", - "emails.invitation.thanks": "Baie dankie", + "emails.invitation.thanks": "Baie dankie,", "emails.invitation.signature": "Die {{project}} span", "locale.country.unknown": "Onbekend", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Die veiligheidsfrase vir hierdie e-pos is {{phrase}}. Jy kan hierdie e-pos vertrou as hierdie frase ooreenstem met die frase wat gewys is tydens aanmelding.", "emails.otpSession.thanks": "Dankie,", "emails.otpSession.signature": "{{project}} span" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ar-ma.json b/app/config/locale/translations/ar-ma.json index 453de25c80..efd2e95c31 100644 --- a/app/config/locale/translations/ar-ma.json +++ b/app/config/locale/translations/ar-ma.json @@ -4,34 +4,34 @@ "settings.direction": "rtl", "emails.sender": "فرقة %s", "emails.verification.subject": "التيْقان ديال الحساب", - "emails.verification.hello": "السلام {{user}}", + "emails.verification.hello": "السلام {{user}}،", "emails.verification.body": "تبّع هاد الوصلة باش تيقّن لادريسة تاع ليميل ديالك.", "emails.verification.footer": "إلا ماشي نتا اللي طلبتي تيقّن هاد لادريسة تاع ليميل، ممكن تنخّل هاد البرية.", - "emails.verification.thanks": "شكرا", + "emails.verification.thanks": "شكرا،", "emails.verification.signature": "فرقة {{project}}", "emails.magicSession.subject": "تكونيكطا", - "emails.magicSession.hello": "السلام,", + "emails.magicSession.hello": "السلام،", "emails.magicSession.body": "تبّع هاد الوصلة باش تتكونيكطا.", "emails.magicSession.footer": "إلا ماشي نتا اللي طلبتي تتكونيكطا بهاد ليميل، ممكن تنخّل هاد البرية.", - "emails.magicSession.thanks": "شكرا", + "emails.magicSession.thanks": "شكرا،", "emails.magicSession.signature": "فرقة {{project}}", "emails.recovery.subject": "تبدال كلمة السر", - "emails.recovery.hello": "السلام {{user}}", + "emails.recovery.hello": "السلام {{user}}،", "emails.recovery.body": "تبّع هاد الوصلة باش تبدّل كلمة السر تاع {{project}}.", "emails.recovery.footer": "إلا ماشي نتا اللي طلبتي تبدّل كلمة السر، ممكن تنخّل هاد البرية.", - "emails.recovery.thanks": "شكرا", + "emails.recovery.thanks": "شكرا،", "emails.recovery.signature": "فرقة {{project}}", "emails.invitation.subject": "عراضة ل فرقة %s ف %s", - "emails.invitation.hello": "السلام", + "emails.invitation.hello": "السلام،", "emails.invitation.body": "هاد البرية تصيفطات ليك حيت {{owner}} بغى يعرض عليك تولّي عضو ف فرقة {{team}} عند {{project}}.", "emails.invitation.footer": "إلا كنتي ما مسوّقش, ممكن تنخّل هاد البرية.", - "emails.invitation.thanks": "شكرا", + "emails.invitation.thanks": "شكرا،", "emails.invitation.signature": "فرقة {{project}}", "emails.certificate.subject": "السرتافيكة فشلات ل %s", - "emails.certificate.hello": "السلام", + "emails.certificate.hello": "السلام،", "emails.certificate.body": "السرتافيكة ديال الضومين ديالك '{{domain}}' ما قدّاتش تجينيرا. هادي هي المحاولة نمرة {{attempt}}, السبب ديال هاد الفشل هو: {{error}}", "emails.certificate.footer": "السرتافيكة الفايتة ديالك غاتبقى مزيانة لمدة 30 يوم من عند أول فشل. كانشجعوك بزاف أنك تبقشش فهاد الموضوع, وا إلّا الضومين ديالك ما غايبقاش خدّام فيه الـ SSL.", - "emails.certificate.thanks": "شكرا", + "emails.certificate.thanks": "شكرا،", "emails.certificate.signature": "فرقة {{project}}", "locale.country.unknown": "ما معروفش", "countries.af": "أفغانستان", diff --git a/app/config/locale/translations/ar.json b/app/config/locale/translations/ar.json index cd45b32e02..1d67c2ecf7 100644 --- a/app/config/locale/translations/ar.json +++ b/app/config/locale/translations/ar.json @@ -4,28 +4,28 @@ "settings.direction": "rtl", "emails.sender": "فريق %s", "emails.verification.subject": "تأكيد الحساب", - "emails.verification.hello": "مرحبا {{user}}", + "emails.verification.hello": "مرحبا {{user}}،", "emails.verification.body": "برجاء اتباع الرابط التالي لتأكيد بريدك الإلكتروني", "emails.verification.footer": "لو لم تطلب تأكيد هذا البريد الإلكتروني، يمكنك تجاهل هذه الرسالة", - "emails.verification.thanks": "شكرا", + "emails.verification.thanks": "شكرا،", "emails.verification.signature": "فريق {{project}}", "emails.magicSession.subject": "تسجيل الدخول", - "emails.magicSession.hello": "أهلا", + "emails.magicSession.hello": "أهلا،", "emails.magicSession.body": "اتبع هذا الرابط لتسجيل الدخول", "emails.magicSession.footer": "لو لم تطلب تسجيل الدخول بهذا البريد الاكتروني ، يمكنك تجاهل هذه الرسالة", - "emails.magicSession.thanks": "شكرا", + "emails.magicSession.thanks": "شكرا،", "emails.magicSession.signature": "فريق {{project}}", "emails.recovery.subject": "تغيير كلمة السر", - "emails.recovery.hello": "أهلا {{user}}", + "emails.recovery.hello": "أهلا {{user}}،", "emails.recovery.body": "برجاء اتباع الراط التالي لتغيير كلمة السر الخاصة بـ{{project}}", "emails.recovery.footer": "لولم تطلب تغيير كلمة السر، يمكنك تجاهل هذه الرسالة", - "emails.recovery.thanks": "شكرا", + "emails.recovery.thanks": "شكرا،", "emails.recovery.signature": "فريق {{project}}", "emails.invitation.subject": "دعوة لفريق %s في %s", - "emails.invitation.hello": "أهلا", + "emails.invitation.hello": "أهلا،", "emails.invitation.body": "هذة الرسالة تم ارسالها لك لأن {{owner}} ارسل لك دعوة لتكون عضوا بفريق {{team}} في {{project}}", "emails.invitation.footer": "اذا كنت غير مهتم، يمكنك تجاهل هذه الرسالة", - "emails.invitation.thanks": "شكرا", + "emails.invitation.thanks": "شكرا،", "emails.invitation.signature": "فريق {{project}}", "locale.country.unknown": "مجهول", "countries.af": "أفغانستان", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "عبارة الأمان لهذا البريد الإلكتروني هي {{phrase}}. يمكنك الوثوق بهذا البريد الإلكتروني إذا كانت هذه العبارة تتطابق مع العبارة المعروضة أثناء تسجيل الدخول.", "emails.otpSession.thanks": "شكرًا،", "emails.otpSession.signature": "فريق {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/as.json b/app/config/locale/translations/as.json index aa42483dde..572ed80f1a 100644 --- a/app/config/locale/translations/as.json +++ b/app/config/locale/translations/as.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s দল", "emails.verification.subject": "একাউণ্ট প্ৰমাণীকৰণ", - "emails.verification.hello": "নমস্কাৰ {{user}}", + "emails.verification.hello": "নমস্কাৰ {{user}},", "emails.verification.body": "আপোনাৰ ইমেইল ঠিকনা প্ৰমাণিত কৰিবলৈ এই লিংকটো অনুসৰণ কৰক।", "emails.verification.footer": "যদি আপুনি এই ঠিকনাটো সত্যাপিত কৰিবলৈ কোৱা নাই, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।", - "emails.verification.thanks": "ধন্যবাদ", + "emails.verification.thanks": "ধন্যবাদ,", "emails.verification.signature": "{{project}} দল", "emails.magicSession.subject": "লগইন", - "emails.magicSession.hello": "নমস্কাৰ", + "emails.magicSession.hello": "নমস্কাৰ,", "emails.magicSession.body": "লগইন কৰিবলৈ এই লিংকটো অনুসৰণ কৰক।", "emails.magicSession.footer": "যদি আপুনি এই ইমেইল ব্যৱহাৰ কৰি লগইন কৰিবলৈ কোৱা নাছিল, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।", - "emails.magicSession.thanks": "ধন্যবাদ", + "emails.magicSession.thanks": "ধন্যবাদ,", "emails.magicSession.signature": "{{project}} দল", "emails.recovery.subject": "পাছৱাৰ্ড ৰিছেট", - "emails.recovery.hello": "ধন্যবাদ {{user}}", + "emails.recovery.hello": "ধন্যবাদ {{user}},", "emails.recovery.body": "আপোনাৰ {{project}} পাছৱৰ্ড ৰিছেট কৰিবলৈ এই লিংকটো অনুসৰণ কৰক।.", "emails.recovery.footer": "যদি আপুনি আপোনাৰ পাছৱৰ্ড ৰিছেট কৰিবলৈ কোৱা নাছিল, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।", - "emails.recovery.thanks": "ধন্যবাদ", + "emails.recovery.thanks": "ধন্যবাদ,", "emails.recovery.signature": "{{project}} দল", "emails.invitation.subject": "%s বছৰত %s দললৈ নিমন্ত্ৰণ", - "emails.invitation.hello": "নমস্কাৰ", + "emails.invitation.hello": "নমস্কাৰ,", "emails.invitation.body": "এই মেইলটো আপোনালৈ প্ৰেৰণ কৰা হৈছিল কাৰণ {{owner}} জনে আপোনাক {{project}} বছৰবয়সত {{team}} দলৰ সদস্য হ'বলৈ আমন্ত্ৰণ জনাব বিচাৰিছিল।", "emails.invitation.footer": "যদি আপুনি আগ্ৰহী নহয়, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।", - "emails.invitation.thanks": "ধন্যবাদ", + "emails.invitation.thanks": "ধন্যবাদ,", "emails.invitation.signature": "{{project}} দল", "locale.country.unknown": "অজ্ঞাত ", "countries.af": "আফগানিস্তান ", @@ -245,10 +245,10 @@ "emails.otpSession.thanks": "ধন্যবাদ,", "emails.otpSession.signature": "{{project}} দল", "emails.certificate.subject": "%sৰ বাবে প্ৰমাণপত্ৰ ব্যৰ্থতা", - "emails.certificate.hello": "নমস্কাৰ", + "emails.certificate.hello": "নমস্কাৰ,", "emails.certificate.body": "আপোনাৰ ডোমেইন '{{domain}}' ৰ বাবে প্ৰমাণপত্ৰটো উত্‌পন্ন কৰিব পৰা নগ'ল। এয়া প্ৰচেষ্টা নম্বৰ {{attempt}}, আৰু বিফলতাৰ কাৰণ হ'ল: {{error}}", "emails.certificate.footer": "আপোনাৰ পূৰ্বৰ প্ৰমাণপত্ৰটো প্ৰথম ব্ৰিফল হোৱাৰ দিনৰ পৰা ৩০ দিনলৈ বৈধ থাকিব। আমি এই ঘটনাটোৰ তদন্ত কৰিবলৈ উচ্চ পৰামৰ্শ দিয়ে, অন্যথা আপোনাৰ ডোমেইনটো অবৈধ SSL যোগাযোগ অবিহনে থাকিব।", - "emails.certificate.thanks": "ধন্যবাদ", + "emails.certificate.thanks": "ধন্যবাদ,", "emails.certificate.signature": "{{project}} দল", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/az.json b/app/config/locale/translations/az.json index df1264fe8d..5988c51786 100644 --- a/app/config/locale/translations/az.json +++ b/app/config/locale/translations/az.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Komandası", "emails.verification.subject": "Hesab Doğrulama", - "emails.verification.hello": "Salam {{user}}", + "emails.verification.hello": "Salam {{user}},", "emails.verification.body": "E-poçt ünvanınızı təsdiq etmək üçün bu linki izləyin.", "emails.verification.footer": "Bu ünvanı doğrulamağı xahiş etməmisinizsə, bu mesajı gözardı edə bilərsiniz.", - "emails.verification.thanks": "Təşəkkürlər", + "emails.verification.thanks": "Təşəkkürlər,", "emails.verification.signature": "{{project}} komandası", "emails.magicSession.subject": "Daxil Olmaq", - "emails.magicSession.hello": "Salam", + "emails.magicSession.hello": "Salam,", "emails.magicSession.body": "Daxil olmaq üçün bu linki izləyin.", "emails.magicSession.footer": "Bu e-poçtdan istifadə edərək giriş istəməmisinizsə, bu mesajı görməməzlikdən gələ bilərsiniz.", - "emails.magicSession.thanks": "Təşəkkürlər", + "emails.magicSession.thanks": "Təşəkkürlər,", "emails.magicSession.signature": "{{project}} komandası", "emails.recovery.subject": "Şifrə Sıfırlanması", - "emails.recovery.hello": "Salam {{user}}", + "emails.recovery.hello": "Salam {{user}},", "emails.recovery.body": "{{project}} şifrənizi sıfırlamaq üçün bu linki izləyin.", "emails.recovery.footer": "Şifrənizi sıfırlamağı xahiş etməmisinizsə, bu mesajı gözardı edə bilərsiniz.", - "emails.recovery.thanks": "Təşəkkürlər", + "emails.recovery.thanks": "Təşəkkürlər,", "emails.recovery.signature": "{{project}} komandası", "emails.invitation.subject": "%s Komandasına Dəvət %sdə", - "emails.invitation.hello": "Salam", + "emails.invitation.hello": "Salam,", "emails.invitation.body": "{{owner}}, {{project}}də {{team}} komandasına üzv olmağa dəvət etmək istədiyi üçün bu məktub sizə göndərildi.", "emails.invitation.footer": "Əgər maraqlanmırsınızsa, bu mesajı gözardı edə bilərsiniz.", - "emails.invitation.thanks": "Təşəkkürlər", + "emails.invitation.thanks": "Təşəkkürlər,", "emails.invitation.signature": "{{project}} komandası", "locale.country.unknown": "Naməlum", "countries.af": "Əfqanıstan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Bu e-poçtun təhlükəsizlik ifadəsi {{phrase}}-dir. Əgər bu ifadə daxil olarkən göstərilən ifadə ilə üst-üstə düşürsə, bu e-poçta etibar edə bilərsiniz.", "emails.otpSession.thanks": "Sağ olun,", "emails.otpSession.signature": "{{project}} komandası" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/be.json b/app/config/locale/translations/be.json index a33916f623..f03a9d5bef 100644 --- a/app/config/locale/translations/be.json +++ b/app/config/locale/translations/be.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Каманда %s", "emails.verification.subject": "Верыфікацыя акаўнта", - "emails.verification.hello": "Прывітанне {{user}}", + "emails.verification.hello": "Прывітанне {{user}},", "emails.verification.body": "Перайдзіце па гэтай спасылцы, каб пацвердзіць свой адрас электроннай пошты", "emails.verification.footer": "Калі вы не запытвалі пацвярджэнне гэтага адрасу, праігнаруйце гэтае паведамленне.", - "emails.verification.thanks": "Дзякуем", + "emails.verification.thanks": "Дзякуем,", "emails.verification.signature": "каманда {{project}}", "emails.magicSession.subject": "Лагін", - "emails.magicSession.hello": "Прывітанне", + "emails.magicSession.hello": "Прывітанне,", "emails.magicSession.body": "Перайдзіце па спасылцы, каб увайсці.", "emails.magicSession.footer": "Калі вы не прасілі ўвайсці, выкарыстоўваючы гэты адрас электроннай пошты, праігнаруйце гэтае паведамленне.", - "emails.magicSession.thanks": "Дзякуем", + "emails.magicSession.thanks": "Дзякуем,", "emails.magicSession.signature": "каманда {{project}}", "emails.recovery.subject": "Скід пароля", - "emails.recovery.hello": "Прывітанне, {{user}}", + "emails.recovery.hello": "Прывітанне, {{user}},", "emails.recovery.body": "Перайдзіце па гэтай спасылцы, каб скінуць пароль для праекта {{project}}.", "emails.recovery.footer": "Калі вы не прасілі скінуць пароль, вы можаце праігнараваць гэта паведамленне.", - "emails.recovery.thanks": "Дзякуем", + "emails.recovery.thanks": "Дзякуем,", "emails.recovery.signature": "каманда {{project}}", "emails.invitation.subject": "Запрошення до Команди %s у %s", - "emails.invitation.hello": "Прывітанне", + "emails.invitation.hello": "Прывітанне,", "emails.invitation.body": "Гэта паведамленне было адпраўлена вам, таму што {{owner}} хацеў запрасіць вас стаць членам каманды {{team}} у {{project}}.", "emails.invitation.footer": "Калі вам гэта не цікава, вы можаце праігнараваць гэтае паведамленне.", - "emails.invitation.thanks": "Дзякуем", + "emails.invitation.thanks": "Дзякуем,", "emails.invitation.signature": "каманда {{project}}", "locale.country.unknown": "Невядомы", "countries.af": "Афганістан", @@ -245,10 +245,10 @@ "emails.otpSession.thanks": "Дзякуй,", "emails.otpSession.signature": "каманда {{project}}", "emails.certificate.subject": "Сведчанне няўдалае для %s", - "emails.certificate.hello": "Прывітанне", + "emails.certificate.hello": "Прывітанне,", "emails.certificate.body": "Сертыфікат для вашага дамена '{{domain}}' не можа быць створаны. Гэта спроба нумар {{attempt}}, і прычынай няўдачы з'яўляецца: {{error}}", "emails.certificate.footer": "Ваш папярэдні сертыфікат будзе дзейнічаць 30 дзён з моманту першай няўдачы. Мы высока рэкамендуем расследаваць гэтую сітуацыю, інакш ваш дамен апынецца без дзейнага сертыфіката SSL-злучэння.", - "emails.certificate.thanks": "Дзякуй", + "emails.certificate.thanks": "Дзякуй,", "emails.certificate.signature": "каманда {{project}}", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/bg.json b/app/config/locale/translations/bg.json index 2dad3aecbe..086c6b283e 100644 --- a/app/config/locale/translations/bg.json +++ b/app/config/locale/translations/bg.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Екип", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Неизвестно", "countries.af": "Афганистан", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Фразата за сигурност за този имейл е {{phrase}}. Можете да се доверите на този имейл, ако тази фраза съвпада с фразата, показана по време на вписването.", "emails.otpSession.thanks": "Благодаря,", "emails.otpSession.signature": "екип на {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/bh.json b/app/config/locale/translations/bh.json index 347f6f5d31..5cf06bd1dd 100644 --- a/app/config/locale/translations/bh.json +++ b/app/config/locale/translations/bh.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s टीम", "emails.verification.subject": "खाता प्रमाणिकरण", - "emails.verification.hello": "नमस्ते {{user}}", + "emails.verification.hello": "नमस्ते {{user}},", "emails.verification.body": "ईमेल प्रमाणिकरण करे क लेल दिहल गइल लिंक फॉलो करें|", "emails.verification.footer": "अगर ई पता को सत्यापित करे के लिए ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।", - "emails.verification.thanks": "धन्यवाद", + "emails.verification.thanks": "धन्यवाद,", "emails.verification.signature": "{{project}} टीम", "emails.magicSession.subject": "लॉग इन करीं|", - "emails.magicSession.hello": "प्रणाम", + "emails.magicSession.hello": "प्रणाम,", "emails.magicSession.body": "लॉग इन करें लेल दिहल गइल लिंक फॉलो करें|", "emails.magicSession.footer": "अगर लॉग इन करे के लिए ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।", - "emails.magicSession.thanks": "धन्यवाद", + "emails.magicSession.thanks": "धन्यवाद,", "emails.magicSession.signature": "{{project}} टीम", "emails.recovery.subject": "पासवर्ड बदल क लेल|", - "emails.recovery.hello": "प्रणाम {{user}}", + "emails.recovery.hello": "प्रणाम {{user}},", "emails.recovery.body": "पासवर्ड बदल क लेल दिहल गइल लिंक फॉलो करें|", "emails.recovery.footer": "अगर पासवर्ड बदल क लेल ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।", - "emails.recovery.thanks": "धन्यवाद", + "emails.recovery.thanks": "धन्यवाद,", "emails.recovery.signature": "{{project}} टीम", "emails.invitation.subject": "%s टीम क %s पे न्योता देवे क लेल|", - "emails.invitation.hello": "प्रणाम", + "emails.invitation.hello": "प्रणाम,", "emails.invitation.body": "ई मेल आपके एही लेल भेजल गईल रहल काहे क {{owner}} आपके {{project}} क {{team}} टीम का सदस्य बनावे चाहित रहे|", "emails.invitation.footer": "अगर आवे क इच्छा ना होवत, तो आप ई संदेश क अनदेखा कर सकत अछि।", - "emails.invitation.thanks": "धन्यवाद", + "emails.invitation.thanks": "धन्यवाद,", "emails.invitation.signature": "{{project}} टीम", "locale.country.unknown": "अनजान", "countries.af": "अफ़ग़ानिस्तान", @@ -242,13 +242,13 @@ "emails.otpSession.description": "जब आपको सुरक्षित रूप से अपना {{project}} खाता में साइन इन करे खातिर कहल जाए तऽ निम्नलिखित सत्यापन कोड दर्ज करीं। ई 15 मिनट में खत्म हो जई।", "emails.otpSession.clientInfo": "एह साइन इन के अनुरोध {{agentClient}} पर {{agentDevice}} {{agentOs}} का प्रयोग करि कऽ कइल गइल बा। यदि तूँ एह साइन इन के अनुरोध ना कइले रहीं, त तूँ एह ईमेल के नजरअंदाज कर सकेला।", "emails.otpSession.securityPhrase": "एही ईमेल खातिर सुरक्षा वाक्य {{phrase}} हऽ। अगर ई वाक्य साइन इन कइला के समय देखावल गेल वाक्य से मेल खाता, त एह ईमेल पर भरोसा कर सकैत छी।", - "emails.otpSession.thanks": "धन्यवाद", + "emails.otpSession.thanks": "धन्यवाद,", "emails.otpSession.signature": "{{project}} टीम", "emails.certificate.subject": "%s लेल प्रमाणपत्र असफलта", - "emails.certificate.hello": "नमस्ते", + "emails.certificate.hello": "नमस्ते,", "emails.certificate.body": "आपके डोमेन '{{domain}}' के लिए प्रमाणपत्र नहीं बनाया जा सका। ई प्रयास संख्या {{attempt}} है, और ई असफलता के कारण रहे: {{error}}", "emails.certificate.footer": "तोहार पिछलका प्रमाणपत्र पहिल असफलता से 30 दिन धरी मान्य होईत। हम बहुत जोर देके सलाह देतानी कि एह मामला के जांच करीं, नहीं त तोहार डोमेन बिना कोनो मान्य SSL संवाद के रहि जाईत।", - "emails.certificate.thanks": "धन्यवाद", + "emails.certificate.thanks": "धन्यवाद,", "emails.certificate.signature": "{{project}} टीम", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/bn.json b/app/config/locale/translations/bn.json index 897faea7c1..495f56e012 100644 --- a/app/config/locale/translations/bn.json +++ b/app/config/locale/translations/bn.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s টীম", "emails.verification.subject": "বিষয়", - "emails.verification.hello": "নমস্কার {{user}}", + "emails.verification.hello": "নমস্কার {{user}},", "emails.verification.body": "এই লিঙ্কের মাধ্যমে ইমেইল যাচাই করুন।", "emails.verification.footer": "আপনি যদি এই ঠিকানা যাচাই করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।", - "emails.verification.thanks": "ধন্যবাদ", + "emails.verification.thanks": "ধন্যবাদ,", "emails.verification.signature": "{{project}} টীম", "emails.magicSession.subject": "লগ ইন", - "emails.magicSession.hello": "নমস্কার", + "emails.magicSession.hello": "নমস্কার,", "emails.magicSession.body": "এই লিঙ্কের মাধ্যমে লগ ইন করুন।", "emails.magicSession.footer": "আপনি যদি এই ইমেলটি ব্যবহার করে লগইন করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।", - "emails.magicSession.thanks": "ধন্যবাদ", + "emails.magicSession.thanks": "ধন্যবাদ,", "emails.magicSession.signature": "{{project}} টীম", "emails.recovery.subject": "পাসওয়ার্ড রিসেট", - "emails.recovery.hello": "নমস্কার {{user}}", + "emails.recovery.hello": "নমস্কার {{user}},", "emails.recovery.body": "এই লিঙ্কের মাধ্যমে আপনার {{project}} পাসওয়ার্ড পুনরায় সেট করুন।", "emails.recovery.footer": "আপনি যদি আপনার পাসওয়ার্ড পুনরায় সেট করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।", - "emails.recovery.thanks": "ধন্যবাদ", + "emails.recovery.thanks": "ধন্যবাদ,", "emails.recovery.signature": "{{project}} টীম", "emails.invitation.subject": "%s টিমকে %s তে আমন্ত্রণ জানান", - "emails.invitation.hello": "নমস্কার", + "emails.invitation.hello": "নমস্কার,", "emails.invitation.body": "এই মেইলটি আপনাকে পাঠানো হয়েছে কারণ {{owner}} আপনাকে {{project}} এর সাথে যুক্ত {{team}} টিমের সদস্য হওয়ার জন্য আমন্ত্রণ জানাতে চেয়েছিলেন।", "emails.invitation.footer": "যদি এটি আপনার জন্য প্রয়োজনীয় না হয়, আপনি এই বার্তাটি উপেক্ষা করতে পারেন।", - "emails.invitation.thanks": "ধন্যবাদ", + "emails.invitation.thanks": "ধন্যবাদ,", "emails.invitation.signature": "{{project}} টীম", "locale.country.unknown": "অজানা", "countries.af": "আফগানিস্তান", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "এই ইমেইলের জন্য সুরক্ষা বাক্য হলো {{phrase}}। যদি এই বাক্যটি সাইন ইনের সময় দেখানো বাক্যের সাথে মেলে, তাহলে আপনি এই ইমেইলটিকে বিশ্বাস করতে পারেন।", "emails.otpSession.thanks": "ধন্যবাদ,", "emails.otpSession.signature": "{{project}} দল" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/bs.json b/app/config/locale/translations/bs.json index 1ce2d57a3e..1c69619c01 100644 --- a/app/config/locale/translations/bs.json +++ b/app/config/locale/translations/bs.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Tim", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Nepoznat", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Sigurnosna fraza za ovaj email je {{phrase}}. Možete vjerovati ovom emailu ako se ova fraza podudara sa frazom prikazanom prilikom prijave.", "emails.otpSession.thanks": "Hvala,", "emails.otpSession.signature": "tim {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ca.json b/app/config/locale/translations/ca.json index 94e3ae24c5..98940a4a48 100644 --- a/app/config/locale/translations/ca.json +++ b/app/config/locale/translations/ca.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Equip", "emails.verification.subject": "Verificació del compte", - "emails.verification.hello": "Hola {{user}}", + "emails.verification.hello": "Hola {{user}},", "emails.verification.body": "Accedeix a aquest enllaç per tal de verificar la teva adreça electrònica.", "emails.verification.footer": "Si no has sol·licitat la verificació d'aquesta adreça electrònica, pots ignorar aquest missatge.", - "emails.verification.thanks": "Gràcies", + "emails.verification.thanks": "Gràcies,", "emails.verification.signature": "Equip {{project}}", "emails.magicSession.subject": "Entrar", - "emails.magicSession.hello": "Hola", + "emails.magicSession.hello": "Hola,", "emails.magicSession.body": "Accedeix a aquest enllaç per a entrar.", "emails.magicSession.footer": "Si no has sol·licitat entrar amb aquesta adreça electrònica, pots ignorar aquest missatge.", - "emails.magicSession.thanks": "Gràcies", + "emails.magicSession.thanks": "Gràcies,", "emails.magicSession.signature": "Equip {{project}}", "emails.recovery.subject": "Reinicialitzar contrasenya", - "emails.recovery.hello": "Hola {{user}}", + "emails.recovery.hello": "Hola {{user}},", "emails.recovery.body": "Accedeix a aquest enllaç per a reinicialitzar la teva contrasenya de {{project}}.", "emails.recovery.footer": "Si no has sol·licitat reinicialitzar la teva contrasenya, pots ignorar aquest missatge.", - "emails.recovery.thanks": "Gràcies", + "emails.recovery.thanks": "Gràcies,", "emails.recovery.signature": "Equip {{project}}", "emails.invitation.subject": "Invitació a l'equip %s a s%", - "emails.invitation.hello": "Hola", + "emails.invitation.hello": "Hola,", "emails.invitation.body": "Aquest correu se t'ha enviat perquè {{owner}} vol convidar-te a formar part de l'equip {{team}} al {{project}}.", "emails.invitation.footer": "Si no és del teu interès, pots ignorar aquest missatge.", - "emails.invitation.thanks": "Gràcies", + "emails.invitation.thanks": "Gràcies,", "emails.invitation.signature": "Equip {{project}}", "locale.country.unknown": "Desconegut", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "La frase de seguretat d'aquest correu electrònic és {{phrase}}. Podeu confiar en aquest correu electrònic si aquesta frase coincideix amb la frase mostrada durant l'inici de sessió.", "emails.otpSession.thanks": "Gràcies,", "emails.otpSession.signature": "equip {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/cs.json b/app/config/locale/translations/cs.json index 4e3c533c77..c67e9299da 100644 --- a/app/config/locale/translations/cs.json +++ b/app/config/locale/translations/cs.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s tým", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Neznámý", "countries.af": "Afghánistán", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Bezpečnostní fráze pro tento e-mail je {{phrase}}. Tomuto e-mailu můžete důvěřovat, pokud se tato fráze shoduje s frází zobrazenou při přihlášení.", "emails.otpSession.thanks": "Děkuji,", "emails.otpSession.signature": "tým {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/da.json b/app/config/locale/translations/da.json index d50d9c46c6..9cec74dbed 100644 --- a/app/config/locale/translations/da.json +++ b/app/config/locale/translations/da.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Konto Verifikation", - "emails.verification.hello": "Hej {{user}}", + "emails.verification.hello": "Hej {{user}},", "emails.verification.body": "Følg dette link, for at verificere din email adresse.", "emails.verification.footer": "Hvis du ikke har bedt om at verificere denne adresse, ignorer venligst denne besked.", - "emails.verification.thanks": "Tak", + "emails.verification.thanks": "Tak,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Hej", + "emails.magicSession.hello": "Hej,", "emails.magicSession.body": "Følg dette link for at logge ind.", "emails.magicSession.footer": "Hvis du ikke har bedt om at logge ind med denne email, ignorer venligst denne besked.", - "emails.magicSession.thanks": "Tak", + "emails.magicSession.thanks": "Tak,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Nulstil Password", - "emails.recovery.hello": "Hej {{user}}", + "emails.recovery.hello": "Hej {{user}},", "emails.recovery.body": "Følg dette link for at nulstille koden til {{project}}.", "emails.recovery.footer": "Hvis du ikke har bedt om at nulstille dit password, ignorer venligst denne besked.", - "emails.recovery.thanks": "Tak", + "emails.recovery.thanks": "Tak,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Invitation til %s Team på %s", - "emails.invitation.hello": "Hej", + "emails.invitation.hello": "Hej,", "emails.invitation.body": "Denne mail blev sendt til dig, fordi {{owner}} vil invitere dig til at blive medlem af {{team}} teamet på {{project}}.", "emails.invitation.footer": "Hvis du ikke er interesseret, ignorer venligst denne besked.", - "emails.invitation.thanks": "Tak", + "emails.invitation.thanks": "Tak,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Ukendt", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Sikkerhedsfrasen for denne e-mail er {{phrase}}. Du kan stole på denne e-mail, hvis denne frase matcher frasen vist under login.", "emails.otpSession.thanks": "Tak,", "emails.otpSession.signature": "{{project}} team" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/de.json b/app/config/locale/translations/de.json index 2279fcf4c0..38b1e46870 100644 --- a/app/config/locale/translations/de.json +++ b/app/config/locale/translations/de.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Kontoverifizierung", - "emails.verification.hello": "Hey {{user}}", + "emails.verification.hello": "Hey {{user}},", "emails.verification.body": "Folge diesem Link, um deine E-Mail-Adresse zu bestätigen.", "emails.verification.footer": "Solltest du keine Verifizierung dieser E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.", - "emails.verification.thanks": "Danke", + "emails.verification.thanks": "Danke,", "emails.verification.signature": "{{project}}-Team", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Hey", + "emails.magicSession.hello": "Hey,", "emails.magicSession.body": "Folge diesem Link, um dich einzuloggen.", "emails.magicSession.footer": "Solltest du keinen Login für diese E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.", - "emails.magicSession.thanks": "Danke", + "emails.magicSession.thanks": "Danke,", "emails.magicSession.signature": "{{project}}-Team", "emails.recovery.subject": "Kennwort zurücksetzen", - "emails.recovery.hello": "Hallo {{user}}", + "emails.recovery.hello": "Hallo {{user}},", "emails.recovery.body": "Folge diesem Link, um dein {{project}}-Kennwort zurückzusetzen.", "emails.recovery.footer": "Solltest du keine Kennwort-Zurücksetzung angefordert haben, kannst du diese Nachricht ignorieren.", - "emails.recovery.thanks": "Danke", + "emails.recovery.thanks": "Danke,", "emails.recovery.signature": "{{project}}-Team", "emails.invitation.subject": "Einladung zum %s-Team auf %s", - "emails.invitation.hello": "Hello", + "emails.invitation.hello": "Hello,", "emails.invitation.body": "Du erhälst diese E-Mail, weil {{owner}} dich in das Team {{team}} auf {{project}} eingeladen hat.", "emails.invitation.footer": "Wenn du nicht interessiert bist, kannst du diese Nachricht ignorieren.", - "emails.invitation.thanks": "Danke", + "emails.invitation.thanks": "Danke,", "emails.invitation.signature": "{{project}}-Team", "locale.country.unknown": "Unbekannt", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Die Sicherheitsphrase für diese E-Mail lautet {{phrase}}. Sie können dieser E-Mail vertrauen, wenn diese Phrase mit der Phrase übereinstimmt, die beim Anmelden angezeigt wird.", "emails.otpSession.thanks": "Danke,", "emails.otpSession.signature": "{{project}} Team" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/el.json b/app/config/locale/translations/el.json index 16c165ea39..1ef9cd30df 100644 --- a/app/config/locale/translations/el.json +++ b/app/config/locale/translations/el.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Ομάδα %s", "emails.verification.subject": "Επαλήθευση Λογαριασμού", - "emails.verification.hello": "Γεια σου {{user}}", + "emails.verification.hello": "Γεια σου {{user}},", "emails.verification.body": "Ακολουθήστε αυτό το link για να επαληθεύσετε τη δ/νση του email σας", "emails.verification.footer": "Εάν δεν ζητήσατε επαλήθευση αυτής της δ/νσης email, μπορείτε να αγνοήσετε αυτό το μήνυμα", - "emails.verification.thanks": "Ευχαριστούμε", + "emails.verification.thanks": "Ευχαριστούμε,", "emails.verification.signature": "Η ομάδα του {{project}}", "emails.magicSession.subject": "Είσοδος", - "emails.magicSession.hello": "Γεια σου", + "emails.magicSession.hello": "Γεια σου,", "emails.magicSession.body": "Ακολουθήστε αυτό το link για να συνδεθείτε", "emails.magicSession.footer": "Εάν δεν ζητήσατε να συνδεθείτε χρησιμοποιώντας αυτό το email, μπορείτε να αγνοήσετε αυτό το μήνυμα.", - "emails.magicSession.thanks": "Ευχαριστούμε", + "emails.magicSession.thanks": "Ευχαριστούμε,", "emails.magicSession.signature": "Η ομάδα του {{project}}", "emails.recovery.subject": "Αλλαγή κωδικού πρόσβασης", - "emails.recovery.hello": "Γεια σου {{user}}", + "emails.recovery.hello": "Γεια σου {{user}},", "emails.recovery.body": "Ακολουθήστε αυτό το link για να αλλάξετε τον {{project}} κωδικό σας", "emails.recovery.footer": "Εάν δεν ζητήσατε αλλαγή του κωδικού σας πρόσβασης, μπορείτε να αγνοήσετε αυτό το μήνυμα", - "emails.recovery.thanks": "Ευχαριστούμε", + "emails.recovery.thanks": "Ευχαριστούμε,", "emails.recovery.signature": "Η ομάδα του {{project}}", "emails.invitation.subject": "Πρόσκληση στην %s Ομάδα στον %s", - "emails.invitation.hello": "Γεια σου", + "emails.invitation.hello": "Γεια σου,", "emails.invitation.body": "Αυτό το email στάλθηκε επειδή ο/η {{owner}} θέλει να σας προσκαλέσει να γίνετε μέλος της ομάδας {{team}} του {{project}}.", "emails.invitation.footer": "Εάν δεν ενδιαφέρεστε, μπορείτε να αγνοήσετε αυτό το μήνυμα.", - "emails.invitation.thanks": "Ευχαριστούμε", + "emails.invitation.thanks": "Ευχαριστούμε,", "emails.invitation.signature": "Η ομάδα του {{project}}", "locale.country.unknown": "Άγνωστο", "countries.af": "Αφγανιστάν", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Η φράση ασφαλείας για αυτό το email είναι {{phrase}}. Μπορείτε να εμπιστευτείτε αυτό το email αν αυτή η φράση ταιριάζει με τη φράση που εμφανίστηκε κατά την είσοδο.", "emails.otpSession.thanks": "Ευχαριστώ,", "emails.otpSession.signature": "ομάδα {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index 937ab298de..d9dfddb017 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -4,13 +4,13 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Account Verification", - "emails.verification.hello": "Hello {{user}}", + "emails.verification.hello": "Hello {{user}},", "emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.", "emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.", - "emails.verification.thanks": "Thanks", + "emails.verification.thanks": "Thanks,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "{{project}} Login", - "emails.magicSession.hello": "Hello {{user}}", + "emails.magicSession.hello": "Hello {{user}},", "emails.magicSession.optionButton": "Click the button below to securely sign in to your {{b}}{{project}}{{/b}} account. This link will expire in 1 hour.", "emails.magicSession.buttonText": "Sign in to {{project}}", "emails.magicSession.optionUrl": "If you are unable to sign in using the button above, please visit the following link:", @@ -19,44 +19,44 @@ "emails.magicSession.thanks": "Thanks,", "emails.magicSession.signature": "{{project}} team", "emails.sessionAlert.subject": "Security alert: new session on your {{project}} account", - "emails.sessionAlert.hello":"Hello {{user}}", + "emails.sessionAlert.hello": "Hello {{user}},", "emails.sessionAlert.body": "A new session has been created on your {{b}}{{project}}{{/b}} account, {{b}}on {{date}}, {{year}} at {{time}} UTC{{/b}}.\nHere are the details of the new session: ", "emails.sessionAlert.listDevice": "Device: {{b}}{{device}}{{/b}}", "emails.sessionAlert.listIpAddress": "IP Address: {{b}}{{ipAddress}}{{/b}}", "emails.sessionAlert.listCountry": "Country: {{b}}{{country}}{{/b}}", - "emails.sessionAlert.footer": "If this was you, there's nothing more you need to do.\nIf you didn't initiate this session or suspect any unauthorized activity, please secure your account.", + "emails.sessionAlert.footer": "If this was you, there's nothing more you need to do.\nIf you didn't initiate this session or suspect any unauthorized activity, please secure your account.", "emails.sessionAlert.thanks": "Thanks,", "emails.sessionAlert.signature": "{{project}} team", "emails.otpSession.subject": "OTP for {{project}} Login", - "emails.otpSession.hello": "Hello {{user}}", + "emails.otpSession.hello": "Hello {{user}},", "emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{b}}{{project}}{{/b}} account. This code will expire in 15 minutes.", "emails.otpSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.", "emails.otpSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.", "emails.otpSession.thanks": "Thanks,", "emails.otpSession.signature": "{{project}} team", "emails.mfaChallenge.subject": "Verification Code for {{project}}", - "emails.mfaChallenge.hello": "Hello {{user}}", + "emails.mfaChallenge.hello": "Hello {{user}},", "emails.mfaChallenge.description": "Enter the following verification code to verify your email and activate two-step verification in {{b}}{{project}}{{/b}}. This code will expire in 15 minutes.", "emails.mfaChallenge.clientInfo": "This verification code was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the verification code, you can safely ignore this email.", "emails.mfaChallenge.thanks": "Thanks,", "emails.mfaChallenge.signature": "{{project}} team", "emails.recovery.subject": "Password Reset", - "emails.recovery.hello": "Hello {{user}}", + "emails.recovery.hello": "Hello {{user}},", "emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.", "emails.recovery.footer": "If you didn't ask to reset your password, you can ignore this message.", - "emails.recovery.thanks": "Thanks", + "emails.recovery.thanks": "Thanks,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Invitation to %s Team at %s", - "emails.invitation.hello": "Hello {{user}}", + "emails.invitation.hello": "Hello {{user}},", "emails.invitation.body": "This mail was sent to you because {{b}}{{owner}}{{/b}} wanted to invite you to become a member of the {{b}}{{team}}{{/b}} team at {{b}}{{project}}{{/b}}.", "emails.invitation.footer": "If you are not interested, you can ignore this message.", - "emails.invitation.thanks": "Thanks", + "emails.invitation.thanks": "Thanks,", "emails.invitation.signature": "{{project}} team", "emails.certificate.subject": "Certificate failure for %s", - "emails.certificate.hello": "Hello", + "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.thanks": "Thanks,", "emails.certificate.signature": "{{project}} team", "sms.verification.body": "{{secret}}", "locale.country.unknown": "Unknown", diff --git a/app/config/locale/translations/eo.json b/app/config/locale/translations/eo.json index 406bd4f52c..ba80bc602d 100644 --- a/app/config/locale/translations/eo.json +++ b/app/config/locale/translations/eo.json @@ -3,28 +3,28 @@ "settings.direction": "ltr", "emails.sender": "Teamo %s", "emails.verification.subject": "Konta Konfirmo", - "emails.verification.hello": "Saluton {{user}}", + "emails.verification.hello": "Saluton {{user}},", "emails.verification.body": "Alklaku ĉi tiun ligon por kontroli vian retpoŝtan adreson.", "emails.verification.footer": "Se vi ne petis ĉi tiun konfirmon de ĉi tiu retpoŝto, vi povas ignori ĉi tiun mesaĝon.", - "emails.verification.thanks": "Dankegon.", + "emails.verification.thanks": "Dankegon.,", "emails.verification.signature": "Teamo {{project}}", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Saluton", + "emails.magicSession.hello": "Saluton,", "emails.magicSession.body": "Alklaku ĉi tiun ligon por eniri.", "emails.magicSession.footer": "Se vi ne petis ĉi tiun konfirmon de ĉi tiu retpoŝto, vi povas ignori ĉi tiun mesaĝon.", - "emails.magicSession.thanks": "Dankegon", + "emails.magicSession.thanks": "Dankegon,", "emails.magicSession.signature": "Teamo {{project}}", "emails.recovery.subject": "Parsvorta Restarigo", - "emails.recovery.hello": "Saluton {{user}}", + "emails.recovery.hello": "Saluton {{user}},", "emails.recovery.body": "Alklaku ĉi tiun ligon por reagordi vian pasvorton. {{project}}", "emails.recovery.footer": "Se vi ne petis reagordi vian pasvorton, vi povas ignori ĉi tiun mesaĝon.", - "emails.recovery.thanks": "Dankegon", + "emails.recovery.thanks": "Dankegon,", "emails.recovery.signature": "Teamo {{project}}", "emails.invitation.subject": "Invito al la Teamo %s em %s", - "emails.invitation.hello": "Dankegon", + "emails.invitation.hello": "Dankegon,", "emails.invitation.body": "Ĉi tiu retpoŝto estis sendita ĉar la {{owner}} volas inviti vin fariĝi membro de la Teamo {{team}} en {{project}}.", "emails.invitation.footer": "Se vi ne interesiĝas, vi povas ignori ĉi tiun mesaĝon.", - "emails.invitation.thanks": "Dankegon", + "emails.invitation.thanks": "Dankegon,", "emails.invitation.signature": "Teamo {{project}}", "locale.country.unknown": "Unknown", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Sekureca frazo por ĉi tiu retpoŝto estas {{phrase}}. Vi povas fidi ĉi tiun retpoŝton se tiu ĉi frazo kongruas kun la frazo montrita dum ensaluto.", "emails.otpSession.thanks": "Dankon,", "emails.otpSession.signature": "teamo de {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/es.json b/app/config/locale/translations/es.json index 0e02f816fe..ff98fd28c7 100644 --- a/app/config/locale/translations/es.json +++ b/app/config/locale/translations/es.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "El equipo de %s", "emails.verification.subject": "Verificación de cuenta", - "emails.verification.hello": "Hola, {{name}}.", + "emails.verification.hello": "Hola, {{name}}.,", "emails.verification.body": "Haz clic en este enlace para verificar tu correo:", "emails.verification.footer": "Si no has solicitado verificar este correo, puedes ignorar este mensaje.", - "emails.verification.thanks": "Gracias.", + "emails.verification.thanks": "Gracias.,", "emails.verification.signature": "El equipo de {{project}}.", "emails.magicSession.subject": "Inicio de sesión", - "emails.magicSession.hello": "Hola", + "emails.magicSession.hello": "Hola,", "emails.magicSession.body": "Haz clic en este enlace para iniciar sesión:", "emails.magicSession.footer": "Si no has solicitado iniciar sesión usando este correo, puedes ignorar este mensaje.", - "emails.magicSession.thanks": "Gracias.", + "emails.magicSession.thanks": "Gracias.,", "emails.magicSession.signature": "El equipo de {{project}}", "emails.recovery.subject": "Restablecer contraseña", - "emails.recovery.hello": "Hola, {{name}}.", + "emails.recovery.hello": "Hola, {{name}}.,", "emails.recovery.body": "Haz clic en este enlace para restablecer la contraseña de {{project}}:", "emails.recovery.footer": "Si no has solicitado restablecer la contraseña, puedes ignorar este mensaje.", - "emails.recovery.thanks": "Gracias.", + "emails.recovery.thanks": "Gracias.,", "emails.recovery.signature": "El equipo de {{project}}", "emails.invitation.subject": "Invitación al equipo %s en %s", - "emails.invitation.hello": "Hola", + "emails.invitation.hello": "Hola,", "emails.invitation.body": "Este correo ha sido enviado a petición de {{owner}} quién quiere invitarte a formar parte del equipo {{team}} en {{project}}.", "emails.invitation.footer": "Si no estás interesado, puedes ignorar este mensaje.", - "emails.invitation.thanks": "Gracias.", + "emails.invitation.thanks": "Gracias.,", "emails.invitation.signature": "El equipo de {{project}}", "locale.country.unknown": "Desconocido", "countries.af": "Afganistán", @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "La frase de seguridad para este correo electrónico es {{phrase}}. Puedes confiar en este correo electrónico si esta frase coincide con la frase que se muestra durante el inicio de sesión.", "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón anterior, visita el siguiente enlace:", "emails.otpSession.subject": "Inicio de sesión en {{project}}", - "emails.otpSession.hello": "Hola", + "emails.otpSession.hello": "Hola,", "emails.otpSession.description": "Ingrese el siguiente código de verificación cuando se le solicite para iniciar sesión de forma segura en su cuenta de {{project}}. Expirará en 15 minutos.", "emails.otpSession.clientInfo": "Este inicio de sesión fue solicitado usando {{agentClient}} en {{agentDevice}} {{agentOs}}. Si no solicitaste el inicio de sesión, puedes ignorar este correo electrónico de forma segura.", "emails.otpSession.securityPhrase": "La frase de seguridad para este correo electrónico es {{phrase}}. Puedes confiar en este correo si esta frase coincide con la frase mostrada durante el inicio de sesión.", - "emails.otpSession.thanks": "Gracias.", + "emails.otpSession.thanks": "Gracias.,", "emails.otpSession.signature": "El equipo de {{project}}" } diff --git a/app/config/locale/translations/fa.json b/app/config/locale/translations/fa.json index 9620b2c3f0..f826a75118 100644 --- a/app/config/locale/translations/fa.json +++ b/app/config/locale/translations/fa.json @@ -4,28 +4,28 @@ "settings.direction": "rtl", "emails.sender": "تیم %s", "emails.verification.subject": "تأیید حساب", - "emails.verification.hello": "سلام {{user}}", + "emails.verification.hello": "سلام {{user}}،", "emails.verification.body": "برای تأیید ایمیل‌تان پیوند زیر را دنبال کنید.", "emails.verification.footer": "اگر شما درخواست تأیید حساب نداده‌اید، می‌توانید این پیام را نادیده بگیرید.", - "emails.verification.thanks": "سپاس فراوان", + "emails.verification.thanks": "سپاس فراوان،", "emails.verification.signature": "تیم {{user}}", "emails.magicSession.subject": "ورود به حساب کاربری", "emails.magicSession.hello": "سلام،", "emails.magicSession.body": "برای ورود به حساب‌تان پیوند زیر را دنبال کنید.", "emails.magicSession.footer": "اگر شما درخواست ورود به حساب کاربری با استفاده از این ایمیل را نداد‌ه‌اید، می‌توانید این پیام را نادیده بگیرید.", - "emails.magicSession.thanks": "سپاس فراوان", + "emails.magicSession.thanks": "سپاس فراوان،", "emails.magicSession.signature": "تیم {{user}}", "emails.recovery.subject": "بازیابی گذرواژه", - "emails.recovery.hello": "سلام {{user}}", + "emails.recovery.hello": "سلام {{user}}،", "emails.recovery.body": "برای بازیابی گذرواژه‌تان پیوند زیر را دنبال کنید.", "emails.recovery.footer": "اگر شما درخواست بازیابی گذرواژه نداده‌اید، می‌توانید این پیام را نادیده بگیرید.", - "emails.recovery.thanks": "سپاس فراوان", + "emails.recovery.thanks": "سپاس فراوان،", "emails.recovery.signature": "تیم {{user}}", "emails.invitation.subject": "دعوت به تیم %s در %s", - "emails.invitation.hello": "سلام", + "emails.invitation.hello": "سلام،", "emails.invitation.body": "این ایمیل برای شما فرستاده شده‌است زیرا {{owner}} می‌خواهد شما را به تیم {{team}} در پروژه‌ی {{project}} بیفزاید.", "emails.invitation.footer": "اگر علاقه ندارید، می‌توانید این پیام را نادیده بگیرید.", - "emails.invitation.thanks": "سپاس فراوان", + "emails.invitation.thanks": "سپاس فراوان،", "emails.invitation.signature": "تیم {{user}}", "locale.country.unknown": "ناشناخته", "countries.af": "افغانستان", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "عبارت امنیتی برای این ایمیل {{phrase}} است. اگر این عبارت با عبارت نشان داده شده هنگام ورود به سیستم مطابقت داشته باشد، می‌توانید به این ایمیل اعتماد کنید.", "emails.otpSession.thanks": "متشکرم،", "emails.otpSession.signature": "تیم {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/fi.json b/app/config/locale/translations/fi.json index d86810d925..ca61a95653 100644 --- a/app/config/locale/translations/fi.json +++ b/app/config/locale/translations/fi.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Tiimi", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Unknown", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Tämän sähköpostin turvalause on {{phrase}}. Voit luottaa tähän sähköpostiin, jos tämä lause vastaa kirjautumisen yhteydessä näytettyä lausetta.", "emails.otpSession.thanks": "Kiitos,", "emails.otpSession.signature": "{{project}} -tiimi" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/fo.json b/app/config/locale/translations/fo.json index 3853dbab9f..a982fd0590 100644 --- a/app/config/locale/translations/fo.json +++ b/app/config/locale/translations/fo.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Lið", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Ókjent", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Trygdarorðið fyri hesa teldupostin er {{phrase}}. Tú kanst líta á hesa teldupostin um hetta orðið passar við orðið víst tá tú ritaði inn.", "emails.otpSession.thanks": "Takk,", "emails.otpSession.signature": "{{project}} lið" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/fr.json b/app/config/locale/translations/fr.json index d73f4e7c81..1b60cb1910 100644 --- a/app/config/locale/translations/fr.json +++ b/app/config/locale/translations/fr.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Équipe %s", "emails.verification.subject": "Vérification du compte", - "emails.verification.hello": "Bonjour {{user}}", + "emails.verification.hello": "Bonjour {{user}},", "emails.verification.body": "Suivez ce lien pour vérifier votre adresse e-mail.", "emails.verification.footer": "Si vous n'avez pas demandé à vérifier cette adresse, vous pouvez ignorer ce message.", - "emails.verification.thanks": "Merci", + "emails.verification.thanks": "Merci,", "emails.verification.signature": "Équipe {{project}}", "emails.magicSession.subject": "Connexion", - "emails.magicSession.hello": "Bonjour", + "emails.magicSession.hello": "Bonjour,", "emails.magicSession.body": "Suivez ce lien pour vous connecter.", "emails.magicSession.footer": "Si vous n'avez pas demandé à vous connecter en utilisant cet e-mail, vous pouvez ignorer ce message.", - "emails.magicSession.thanks": "Merci", + "emails.magicSession.thanks": "Merci,", "emails.magicSession.signature": "L'équipe {{project}}", "emails.recovery.subject": "Réinitialisation du mot de passe", - "emails.recovery.hello": "Bonjour {{user}}", + "emails.recovery.hello": "Bonjour {{user}},", "emails.recovery.body": "Suivez ce lien pour réinitialiser votre mot de passe pour {{project}}.", "emails.recovery.footer": "Si vous n'avez pas demandé à réinitialiser votre mot de passe, vous pouvez ignorer ce message.", - "emails.recovery.thanks": "Merci", + "emails.recovery.thanks": "Merci,", "emails.recovery.signature": "L'équipe {{project}}", "emails.invitation.subject": "Invitation à l'équipe %s de %s", - "emails.invitation.hello": "Bonjour", + "emails.invitation.hello": "Bonjour,", "emails.invitation.body": "Cet e-mail vous a été envoyé parce que {{owner}} souhaite vous inviter à devenir membre de l'équipe {{team}} pour {{project}}.", "emails.invitation.footer": "Si vous n'êtes pas intéressé, vous pouvez ignorer ce message.", - "emails.invitation.thanks": "Merci", + "emails.invitation.thanks": "Merci,", "emails.invitation.signature": "L'équipe {{project}}", "locale.country.unknown": "Inconnu", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "La phrase de sécurité pour cet e-mail est {{phrase}}. Vous pouvez faire confiance à cet e-mail si cette phrase correspond à celle affichée lors de la connexion.", "emails.otpSession.thanks": "Merci,", "emails.otpSession.signature": "équipe {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ga.json b/app/config/locale/translations/ga.json index b7a641ac01..3ed68ad8c3 100644 --- a/app/config/locale/translations/ga.json +++ b/app/config/locale/translations/ga.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Foireann", "emails.verification.subject": "Fíoraithe cuntais", - "emails.verification.hello": "Haigh {{user}}", + "emails.verification.hello": "Haigh {{user}},", "emails.verification.body": "Lean an nasc seo chun do ríomhphost a fhíorú.", "emails.verification.footer": "Mura ndearna tú iarratas an seoladh seo a fhíoru, déan neamhaird den teachtaireacht seo.", - "emails.verification.thanks": "Go raibh maith agat", + "emails.verification.thanks": "Go raibh maith agat,", "emails.verification.signature": "{{project}} foireann", "emails.magicSession.subject": "Logáil isteach", - "emails.magicSession.hello": "Haigh", + "emails.magicSession.hello": "Haigh,", "emails.magicSession.body": "Lean an nasc seo chun logáil isteach.", "emails.magicSession.footer": "Mura ndearna tú iarratas logáil isteach leis an ríomhphost seo, déan neamhaird den teachtaireacht seo.", - "emails.magicSession.thanks": "Go raibh maith agat", + "emails.magicSession.thanks": "Go raibh maith agat,", "emails.magicSession.signature": "{{project}} foireann", "emails.recovery.subject": "Athshocrú pasfhocail", - "emails.recovery.hello": "Haigh {{user}}", + "emails.recovery.hello": "Haigh {{user}},", "emails.recovery.body": "Lean an nasc seo chun do pasfhocal {{project}} a athshocrú.", "emails.recovery.footer": "Mura ndearna tú iarratas do pasfhocal a athshocrú, déan neamhaird den teachtaireacht seo.", - "emails.recovery.thanks": "Go raibh maith agat", + "emails.recovery.thanks": "Go raibh maith agat,", "emails.recovery.signature": "{{project}} foireann", "emails.invitation.subject": "Cuireadh do %s foireann ag %s", - "emails.invitation.hello": "Haigh", + "emails.invitation.hello": "Haigh,", "emails.invitation.body": "Seoladh an ríomhphost seo chugat mar ba mhaith le {{owner}} cuireadh a thabhairt duit bheith mar bhall den fhoireann {{team}} ag obair ar {{project}}.", "emails.invitation.footer": "Is cuma leat? Déan neamhaird den teachtaireacht seo.", - "emails.invitation.thanks": "Go raibh maith agat", + "emails.invitation.thanks": "Go raibh maith agat,", "emails.invitation.signature": "{{project}} foireann", "locale.country.unknown": "Neamhaithnid", "countries.af": "An Afganastáin", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Frása slándála don ríomhphost seo ná {{phrase}}. Is féidir muinín a bheith agat as an ríomhphost seo má mheaitseálann an frása seo leis an bhfrása a taispeántar le linn síniú isteach.", "emails.otpSession.thanks": "Go raibh maith agat,", "emails.otpSession.signature": "foireann {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/gu.json b/app/config/locale/translations/gu.json index 8c41c76c54..54378caa9e 100644 --- a/app/config/locale/translations/gu.json +++ b/app/config/locale/translations/gu.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ટીમ", "emails.verification.subject": "ખાતાની ચકાસણી", - "emails.verification.hello": "નમસ્કાર {{user}}", + "emails.verification.hello": "નમસ્કાર {{user}},", "emails.verification.body": "તમારું ઇમેઇલ સરનામું ચકાસવા માટે આ લિંકને અનુસરો.", "emails.verification.footer": "જો તમે આ સરનામાંની ચકાસણી કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.", - "emails.verification.thanks": "આભાર", + "emails.verification.thanks": "આભાર,", "emails.verification.signature": "{{project}} ટીમ", "emails.magicSession.subject": "પ્રવેશ કરો", - "emails.magicSession.hello": "નમસ્કાર", + "emails.magicSession.hello": "નમસ્કાર,", "emails.magicSession.body": "પ્રવેશ કરવા માટે આ લિંકને અનુસરો.", "emails.magicSession.footer": "જો તમે આ ઇમેઇલનો ઉપયોગ કરીને પ્રવેશ કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.", - "emails.magicSession.thanks": "આભાર", + "emails.magicSession.thanks": "આભાર,", "emails.magicSession.signature": "{{project}} ટીમ", "emails.recovery.subject": "પાસવર્ડ ફરીથી સેટ કરો", - "emails.recovery.hello": "નમસ્કાર {{user}}", + "emails.recovery.hello": "નમસ્કાર {{user}},", "emails.recovery.body": "તમારો {{project}} પાસવર્ડ ફરીથી સેટ કરવા માટે આ લિંકને અનુસરો.", "emails.recovery.footer": "જો તમે તમારો પાસવર્ડ ફરીથી સેટ કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.", - "emails.recovery.thanks": "આભાર", + "emails.recovery.thanks": "આભાર,", "emails.recovery.signature": "{{project}} ટીમ", "emails.invitation.subject": "%s ટીમને %s પર આમંત્રણ", - "emails.invitation.hello": "નમસ્કાર", + "emails.invitation.hello": "નમસ્કાર,", "emails.invitation.body": "આ મેઇલ તમને મોકલવામાં આવ્યો હતો કારણ કે {{owner}} તમને {{project}} માં {{team}} ટીમના સભ્ય બનવા માટે આમંત્રિત કરવા માંગતા હતો.", "emails.invitation.footer": "જો તમને રસ નથી, તો તમે આ સંદેશને અવગણી શકો છો.", - "emails.invitation.thanks": "આભાર", + "emails.invitation.thanks": "આભાર,", "emails.invitation.signature": "{{project}} ટીમ", "locale.country.unknown": "અજાણ", "countries.af": "અફઘાનિસ્તાન", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "આ ઇમેઇલ માટેનો સુરક્ષા શબ્દ {{phrase}} છે. જો આ શબ્દ સાઇન ઇન વખતે દર્શાવેલા શબ્દ સાથે મેળ ખાતો હોય તો તમે આ ઇમેઇલ પર વિશ્વાસ કરી શકો છો.", "emails.otpSession.thanks": "આભાર,", "emails.otpSession.signature": "{{project}} ટીમ" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/he.json b/app/config/locale/translations/he.json index 81705d3492..b3d4dea2a8 100644 --- a/app/config/locale/translations/he.json +++ b/app/config/locale/translations/he.json @@ -4,28 +4,28 @@ "settings.direction": "rtl", "emails.sender": "צוות %s", "emails.verification.subject": "אימות חשבון", - "emails.verification.hello": "שלום {{user}}", + "emails.verification.hello": "שלום {{user}},", "emails.verification.body": "לחץ על קישור זה כדי לאמת את כתובת הדוא\"ל שלך.", "emails.verification.footer": "אם לא ביקשת לאמת כתובת זו, תוכל להתעלם מהודעה זו.", - "emails.verification.thanks": "תודה", + "emails.verification.thanks": "תודה,", "emails.verification.signature": "צוות {{project}}", "emails.magicSession.subject": "כניסה למערכת", - "emails.magicSession.hello": "שלום", + "emails.magicSession.hello": "שלום,", "emails.magicSession.body": "לחץ על קישור זה כדי להיכנס.", "emails.magicSession.footer": "אם לא ביקשת להיכנס באמצעות דוא\"ל זה, תוכל להתעלם מהודעה זו.", - "emails.magicSession.thanks": "תודה", + "emails.magicSession.thanks": "תודה,", "emails.magicSession.signature": "צוות {{project}}", "emails.recovery.subject": "איפוס סיסמא", - "emails.recovery.hello": "שלום {{user}}", + "emails.recovery.hello": "שלום {{user}},", "emails.recovery.body": "עקוב אחר קישור זה כדי לאפס את סיסמתך ב-{{project}}.", "emails.recovery.footer": "אם לא ביקשת לאפס את הסיסמה, תוכל להתעלם מהודעה זו.", - "emails.recovery.thanks": "תודה", + "emails.recovery.thanks": "תודה,", "emails.recovery.signature": "צוות {{project}}", "emails.invitation.subject": "הזמנה לצוות %s ב- %s", - "emails.invitation.hello": "שלום", + "emails.invitation.hello": "שלום,", "emails.invitation.body": "דואר זה נשלח אליך מכיוון ש {{owner}} רצה להזמין אותך להיות חבר בצוות {{team}} ב-{{project}}.", "emails.invitation.footer": "אם אינך מעוניין, תוכל להתעלם מהודעה זו.", - "emails.invitation.thanks": "תודה", + "emails.invitation.thanks": "תודה,", "emails.invitation.signature": "צוות {{project}}", "locale.country.unknown": "לא ידוע", "countries.af": "אפגניסטן", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "משפט האבטחה למייל זה הוא {{phrase}}. אתה יכול לסמוך על המייל הזה אם המשפט הזה תואם את המשפט שהוצג במהלך הכניסה למערכת.", "emails.otpSession.thanks": "תודה,", "emails.otpSession.signature": "צוות {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/hi.json b/app/config/locale/translations/hi.json index d764205ad6..1c4d531d60 100644 --- a/app/config/locale/translations/hi.json +++ b/app/config/locale/translations/hi.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s टीम", "emails.verification.subject": "अकाउंट वेरिफिकेशन ", - "emails.verification.hello": "नमस्ते {{user}}", + "emails.verification.hello": "नमस्ते {{user}},", "emails.verification.body": "इस लिंक के माध्यम से अपने ईमेल को सत्यापित कीजिये।", "emails.verification.footer": "यदि आप इस पते को सत्यापित नहीं करना चाहते हैं, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।", - "emails.verification.thanks": "धन्यवाद", + "emails.verification.thanks": "धन्यवाद,", "emails.verification.signature": "{{project}} टीम", "emails.magicSession.subject": "लॉग इन", - "emails.magicSession.hello": "नमस्ते", + "emails.magicSession.hello": "नमस्ते,", "emails.magicSession.body": "इस लिंक के माध्यम से लॉग-इन करें।", "emails.magicSession.footer": "यदि आप इस ईमेल द्वारा लॉगिन नहीं करना चाहते हैं, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।", - "emails.magicSession.thanks": "धन्यवाद", + "emails.magicSession.thanks": "धन्यवाद,", "emails.magicSession.signature": "{{project}} टीम", "emails.recovery.subject": "पासवर्ड रीसेट", - "emails.recovery.hello": "नमस्ते {{user}}", + "emails.recovery.hello": "नमस्ते {{user}},", "emails.recovery.body": "इस लिंक के माध्यम से अपना {{project}} पासवर्ड रीसेट करें।", "emails.recovery.footer": "यदि आप अपना पासवर्ड रीसेट नहीं करना चाहते हैं, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।", - "emails.recovery.thanks": "धन्यवाद", + "emails.recovery.thanks": "धन्यवाद,", "emails.recovery.signature": "{{project}} टीम", "emails.invitation.subject": "%s टीम का यहाँ %s पर आमंत्रण", - "emails.invitation.hello": "नमस्ते", + "emails.invitation.hello": "नमस्ते,", "emails.invitation.body": "यह मेल आपको इसलिए भेजा गया है क्योंकि {{owner}} आपको {{team}} टीम का सदस्य बनाना चाहते है, जो {{project}} से जुड़ा हुआ है।", "emails.invitation.footer": "यदि आप इसमें रूचि नहीं रखते, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।", - "emails.invitation.thanks": "धन्यवाद", + "emails.invitation.thanks": "धन्यवाद,", "emails.invitation.signature": "{{project}} टीम", "locale.country.unknown": "अज्ञात", "countries.af": "अफ़ग़ानिस्तान", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "इस ईमेल के लिए सुरक्षा वाक्यांश {{phrase}} है। अगर यह वाक्यांश साइन इन के दौरान दिखाए गए वाक्यांश से मेल खाता है, तो आप इस ईमेल पर भरोसा कर सकते हैं।", "emails.otpSession.thanks": "धन्यवाद,", "emails.otpSession.signature": "{{project}} टीम" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/hr.json b/app/config/locale/translations/hr.json index 8e537f12ec..e5bf4719a9 100644 --- a/app/config/locale/translations/hr.json +++ b/app/config/locale/translations/hr.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Tim", "emails.verification.subject": "Verifikacija računa", - "emails.verification.hello": "Pozdrav {{user}}", + "emails.verification.hello": "Pozdrav {{user}},", "emails.verification.body": "Slijedite ovu poveznicu da biste potvrdili svoju adresu e-pošte.", "emails.verification.footer": "Ukoliko niste zatražili potvrdu ove adrese, možete zanemariti ovu poruku.", - "emails.verification.thanks": "Hvala", + "emails.verification.thanks": "Hvala,", "emails.verification.signature": "{{project}} tim", "emails.magicSession.subject": "Prijavite se", - "emails.magicSession.hello": "Pozdrav", + "emails.magicSession.hello": "Pozdrav,", "emails.magicSession.body": "Slijedite ovu poveznicu za prijavu.", "emails.magicSession.footer": "Ako niste zatražili prijavu putem ove e-pošte, možete zanemariti ovu poruku.", - "emails.magicSession.thanks": "Hvala", + "emails.magicSession.thanks": "Hvala,", "emails.magicSession.signature": "{{project}} tim", "emails.recovery.subject": "Ponovno postavljanje lozinke", - "emails.recovery.hello": "Pozdrav {{user}}", + "emails.recovery.hello": "Pozdrav {{user}},", "emails.recovery.body": "Slijedite ovu poveznicu za ponovno postavljanje {{project}} lozinke.", "emails.recovery.footer": "Ako niste zatražili ponovno postavljanje Vaše lozinke, možete zanemariti ovu poruku.", - "emails.recovery.thanks": "Hvala", + "emails.recovery.thanks": "Hvala,", "emails.recovery.signature": "{{project}} tim", "emails.invitation.subject": "Pozivnica za %s tim na %s", - "emails.invitation.hello": "Pozdrav", + "emails.invitation.hello": "Pozdrav,", "emails.invitation.body": "Ova poruka Vam je poslana jer Vas je {{owner}} htio pozvati da postanete član {{team}} tima na {{project}}.", "emails.invitation.footer": "Ukoliko niste zainteresirani, možete zanemariti ovu poruku.", - "emails.invitation.thanks": "Hvala", + "emails.invitation.thanks": "Hvala,", "emails.invitation.signature": "{{project}} tim", "locale.country.unknown": "Nepoznato", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Sigurnosna fraza za ovaj e-mail je {{phrase}}. Možete vjerovati ovom e-mailu ako se ova fraza podudara s frazom prikazanom prilikom prijave.", "emails.otpSession.thanks": "Hvala,", "emails.otpSession.signature": "tim {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/hu.json b/app/config/locale/translations/hu.json index fded03aee1..589cb61859 100644 --- a/app/config/locale/translations/hu.json +++ b/app/config/locale/translations/hu.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Csapat", "emails.verification.subject": "Fiók Megerősítése", - "emails.verification.hello": "Szia {{user}}", + "emails.verification.hello": "Szia {{user}},", "emails.verification.body": "Kattints a linkre, hogy megerősítsd az email címedet.", "emails.verification.footer": "Ha nem te kérted a címed megerősítését, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.", - "emails.verification.thanks": "Köszönettel", + "emails.verification.thanks": "Köszönettel,", "emails.verification.signature": "a {{project}} csapat", "emails.magicSession.subject": "Bejelentkezés", - "emails.magicSession.hello": "Szia", + "emails.magicSession.hello": "Szia,", "emails.magicSession.body": "Kattints a linkre a bejelentkezéshez.", "emails.magicSession.footer": "Ha nem te szerettél volna bejelentkezni ezzel az email címmel, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.", - "emails.magicSession.thanks": "Köszönettel", + "emails.magicSession.thanks": "Köszönettel,", "emails.magicSession.signature": "a {{project}} csapat", "emails.recovery.subject": "Jelszó Visszaállítása", - "emails.recovery.hello": "Hahó, {{user}}", + "emails.recovery.hello": "Hahó, {{user}},", "emails.recovery.body": "Kattints a linkre a {{project}} jelszavad visszaállításához.", "emails.recovery.footer": "Ha nem te kezdeményezted a jelszavad visszaállítását, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.", - "emails.recovery.thanks": "Köszönettel", + "emails.recovery.thanks": "Köszönettel,", "emails.recovery.signature": "a {{project}} csapat", "emails.invitation.subject": "Meghívó a(z) %s csapatba, a(z) %s projektbe", - "emails.invitation.hello": "Szia", + "emails.invitation.hello": "Szia,", "emails.invitation.body": "Ezt a levelet azért kaptad, mert {{owner}} meghívott, hogy légy a {{team}} csapat tagja a {{project}} projektben.", "emails.invitation.footer": "Ha nem érdekel a lehetőség, nyugodtan hagyd figyelmen kívül ezt az üzenetet.", - "emails.invitation.thanks": "Köszönettel", + "emails.invitation.thanks": "Köszönettel,", "emails.invitation.signature": "a {{project}} csapat", "locale.country.unknown": "Ismeretlen", "countries.af": "Afganisztán", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Az e-mailhez tartozó biztonsági kód: {{phrase}}. Ennek az e-mailnek megbízhat, ha a megjelenített kód megegyezik a bejelentkezéskor megjelenő kóddal.", "emails.otpSession.thanks": "Köszönöm,", "emails.otpSession.signature": "{{project}} csapat" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/hy.json b/app/config/locale/translations/hy.json index 2c4e72ebe3..c845526607 100644 --- a/app/config/locale/translations/hy.json +++ b/app/config/locale/translations/hy.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Թիմ %s", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Անհայտ", "countries.af": "Աֆղանստան", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Այս էլ.փոստի անվտանգության արտահայտությունը {{phrase}} է: Կարող եք վստահել այս էլ.փոստին, եթե այս արտահայտությունը համընկնում է մուտք գործելու պահին տրված արտահայտության հետ։", "emails.otpSession.thanks": "Շնորհակալ եմ,", "emails.otpSession.signature": "{{project}} թիմ" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/id.json b/app/config/locale/translations/id.json index 90b096e39e..c28b15f15d 100644 --- a/app/config/locale/translations/id.json +++ b/app/config/locale/translations/id.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Tim %s", "emails.verification.subject": "Verifikasi Akun", - "emails.verification.hello": "Hai {{user}}", + "emails.verification.hello": "Hai {{user}},", "emails.verification.body": "Ikuti tautan ini untuk memverifikasi alamat email Anda.", "emails.verification.footer": "Jika Anda tidak meminta untuk memverifikasi alamat email ini, Anda dapat mengabaikan pesan ini.", - "emails.verification.thanks": "Terima kasih", + "emails.verification.thanks": "Terima kasih,", "emails.verification.signature": "Tim {{project}}", "emails.magicSession.subject": "Masuk", - "emails.magicSession.hello": "Hai", + "emails.magicSession.hello": "Hai,", "emails.magicSession.body": "Ikuti tautan ini untuk masuk.", "emails.magicSession.footer": "Jika Anda tidak meminta untuk masuk menggunakan email ini, Anda dapat mengabaikan pesan ini.", - "emails.magicSession.thanks": "Terima kasih", + "emails.magicSession.thanks": "Terima kasih,", "emails.magicSession.signature": "Tim {{project}}", "emails.recovery.subject": "Atur Ulang Kata Sandi", - "emails.recovery.hello": "Halo {{user}}", + "emails.recovery.hello": "Halo {{user}},", "emails.recovery.body": "Ikuti tautan ini untuk menyetel ulang kata sandi {{project}} Anda.", "emails.recovery.footer": "Jika Anda tidak meminta untuk menyetel ulang kata sandi, Anda dapat mengabaikan pesan ini.", - "emails.recovery.thanks": "Terima kasih", + "emails.recovery.thanks": "Terima kasih,", "emails.recovery.signature": "Tim {{project}}", "emails.invitation.subject": "Undangan ke Tim %s di %s", - "emails.invitation.hello": "Halo", + "emails.invitation.hello": "Halo,", "emails.invitation.body": "Email ini dikirimkan kepada Anda karena {{owner}} ingin mengundang Anda untuk menjadi anggota tim {{team}} di {{project}}.", "emails.invitation.footer": "Jika Anda tidak tertarik, Anda dapat mengabaikan pesan ini.", - "emails.invitation.thanks": "Terima kasih", + "emails.invitation.thanks": "Terima kasih,", "emails.invitation.signature": "Tim {{project}}", "locale.country.unknown": "Tidak diketahui", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Frasa keamanan untuk email ini adalah {{phrase}}. Anda dapat mempercayai email ini jika frasa tersebut cocok dengan frasa yang ditampilkan saat masuk.", "emails.otpSession.thanks": "Terima kasih,", "emails.otpSession.signature": "tim {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/is.json b/app/config/locale/translations/is.json index 039d6849b7..5fede4dda0 100644 --- a/app/config/locale/translations/is.json +++ b/app/config/locale/translations/is.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Teymi", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Óþekktur", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Öryggissetning fyrir þetta tölvupóst er {{phrase}}. Þú getur treyst þessum tölvupósti ef þessi setning passar við setninguna sem birtist við innskráningu.", "emails.otpSession.thanks": "Takk,", "emails.otpSession.signature": "{{project}} liðið" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/it.json b/app/config/locale/translations/it.json index d0716dd1e2..8d45de9903 100644 --- a/app/config/locale/translations/it.json +++ b/app/config/locale/translations/it.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Team %s", "emails.verification.subject": "Verifica account", - "emails.verification.hello": "Ciao {{user}}", + "emails.verification.hello": "Ciao {{user}},", "emails.verification.body": "Clicca questo link per verificare il tuo indirizzo email.", "emails.verification.footer": "Se non hai richiesto la verifica dell’indirizzo email, puoi ignorare questo messaggio.", - "emails.verification.thanks": "Grazie", + "emails.verification.thanks": "Grazie,", "emails.verification.signature": "Il team {{project}}", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Ciao", + "emails.magicSession.hello": "Ciao,", "emails.magicSession.body": "Clicca questo link per accedere.", "emails.magicSession.footer": "Se non hai richiesto di effettuare l’accesso, puoi ignorare questo messaggio.", - "emails.magicSession.thanks": "Grazie", + "emails.magicSession.thanks": "Grazie,", "emails.magicSession.signature": "Il team {{project}}", "emails.recovery.subject": "Reimpostazione password", - "emails.recovery.hello": "Ciao {{user}}", + "emails.recovery.hello": "Ciao {{user}},", "emails.recovery.body": "Clicca questo link per reimpostare la tua password di {{project}}.", "emails.recovery.footer": "Se non hai richiesto la reimpostazione della password, puoi ignorare questo messaggio.", - "emails.recovery.thanks": "Grazie", + "emails.recovery.thanks": "Grazie,", "emails.recovery.signature": "Il team {{project}}", "emails.invitation.subject": "Invito al Team %s per %s", - "emails.invitation.hello": "Ciao", + "emails.invitation.hello": "Ciao,", "emails.invitation.body": "Hai ricevuto questa email perché {{owner}} ti ha invitato a diventare un membro del team {{team}} di {{project}}.", "emails.invitation.footer": "Ignora questo messaggio se non sei interessatə.", - "emails.invitation.thanks": "Grazie", + "emails.invitation.thanks": "Grazie,", "emails.invitation.signature": "Il team {{project}}", "locale.country.unknown": "Sconosciuto", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "La frase di sicurezza per questa email è {{phrase}}. Puoi fidarti di questa email se questa frase corrisponde alla frase mostrata durante l'accesso.", "emails.otpSession.thanks": "Grazie,", "emails.otpSession.signature": "team {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ja.json b/app/config/locale/translations/ja.json index 6482488cf5..76d9a0cb1f 100644 --- a/app/config/locale/translations/ja.json +++ b/app/config/locale/translations/ja.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s チーム", "emails.verification.subject": "アカウント認証", - "emails.verification.hello": "こんにちは{{user}}さん", + "emails.verification.hello": "こんにちは{{user}}さん、", "emails.verification.body": "メールアドレスを有効化するためには下記リンクをクリックして下さい。", "emails.verification.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。", - "emails.verification.thanks": "ご利用いただきありがとうございます。", + "emails.verification.thanks": "ご利用いただきありがとうございます。、", "emails.verification.signature": "{{project}}チーム", "emails.magicSession.subject": "ログイン", - "emails.magicSession.hello": "こんにちは", + "emails.magicSession.hello": "こんにちは、", "emails.magicSession.body": "ログインするためには下記リンクをクリックしてください。", "emails.magicSession.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。", - "emails.magicSession.thanks": "ご利用いただきありがとうございます。", + "emails.magicSession.thanks": "ご利用いただきありがとうございます。、", "emails.magicSession.signature": "{{project}}チーム", "emails.recovery.subject": "パスワードリセット", - "emails.recovery.hello": "こんにちは{{user}}さん", + "emails.recovery.hello": "こんにちは{{user}}さん、", "emails.recovery.body": "パスワードをリセットするためには下記リンクをクリックしてください。", "emails.recovery.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。", - "emails.recovery.thanks": "ご利用いただきありがとうございます。", + "emails.recovery.thanks": "ご利用いただきありがとうございます。、", "emails.recovery.signature": "{{project}}チーム", "emails.invitation.subject": "%sチームへの招待が%sから来ました。", - "emails.invitation.hello": "こんにちは", + "emails.invitation.hello": "こんにちは、", "emails.invitation.body": "{{owner}}さんが{{project}}の{{team}}チームにあなたを招待しています。", "emails.invitation.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。", - "emails.invitation.thanks": "ご利用いただきありがとうございます。", + "emails.invitation.thanks": "ご利用いただきありがとうございます。、", "emails.invitation.signature": "{{project}}チーム", "locale.country.unknown": "不明", "countries.af": "アフガニスタン", @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "このメールのセキュリティフレーズは{{phrase}}です。サインイン時に表示されたフレーズと一致する場合、このメールは信頼できます。", "emails.magicSession.optionUrl": "上記のボタンを使用してサインインすることができない場合は、次のリンクにアクセスしてください:", "emails.otpSession.subject": "プロジェクト ログイン", - "emails.otpSession.hello": "こんにちは。", + "emails.otpSession.hello": "こんにちは。、", "emails.otpSession.description": "以下の確認コードを入力して、{{project}}アカウントに安全にサインインしてください。このコードは15分後に失効します。", "emails.otpSession.clientInfo": "このサインインは、{{agentClient}} を使い {{agentDevice}} {{agentOs}} で要求されました。サインインを要求していない場合、このメールを無視しても安全です。", "emails.otpSession.securityPhrase": "このメールのセキュリティフレーズは{{phrase}}です。サインイン時に表示されたフレーズと一致する場合、このメールを信頼できます。", - "emails.otpSession.thanks": "ありがとうございます。", + "emails.otpSession.thanks": "ありがとうございます。、", "emails.otpSession.signature": "{{project}} チーム" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/jv.json b/app/config/locale/translations/jv.json index 7f91a8dcef..889e968b4d 100644 --- a/app/config/locale/translations/jv.json +++ b/app/config/locale/translations/jv.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Tim %s", "emails.verification.subject": "Verifikasi Akun", - "emails.verification.hello": "Hai {{user}}", + "emails.verification.hello": "Hai {{user}},", "emails.verification.body": "Klik link iki kanggo verifikasi alamat email sampeyan.", "emails.verification.footer": "Yen sampeyan ora njaluk verifikasi alamat iki, sampeyan iso nglirwakake pesen iki.", - "emails.verification.thanks": "Matur nuwun", + "emails.verification.thanks": "Matur nuwun,", "emails.verification.signature": "Tim {{project}}", "emails.magicSession.subject": "Masuk", - "emails.magicSession.hello": "Hai", + "emails.magicSession.hello": "Hai,", "emails.magicSession.body": "Klik link iki kanggo masuk.", "emails.magicSession.footer": "Yen sampeyan ora njaluk masuk nggunakake alamat email iki, sampeyan iso nglirwakake pesen iki.", - "emails.magicSession.thanks": "Matur nuwun", + "emails.magicSession.thanks": "Matur nuwun,", "emails.magicSession.signature": "Tim {{project}}", "emails.recovery.subject": "Setel ulang sandi", - "emails.recovery.hello": "Halo {{user}}", + "emails.recovery.hello": "Halo {{user}},", "emails.recovery.body": "Klik link iki kanggo setel ulang sandi {{project}}.", "emails.recovery.footer": "Yen sampeyan ora njaluk setel ulang sandi, sampeyan iso nglirwakake pesen iki.", - "emails.recovery.thanks": "Matur nuwun", + "emails.recovery.thanks": "Matur nuwun,", "emails.recovery.signature": "Tim {{project}}", "emails.invitation.subject": "Undangan ke Tim %s di %s", - "emails.invitation.hello": "Halo", + "emails.invitation.hello": "Halo,", "emails.invitation.body": "Email iki dikirim menyang sampeyan amarga {{owner}} pengin ngajak sampeyan dadi anggota tim {{team}} di {{project}}.", "emails.invitation.footer": "Yen sampeyan ora tertarik, sampeyan iso nglirwakake pesen iki.", - "emails.invitation.thanks": "Matur nuwun", + "emails.invitation.thanks": "Matur nuwun,", "emails.invitation.signature": "Tim {{project}}", "locale.country.unknown": "Ora dingerteni", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Tembung keamanan kanggo email iki yaiku {{phrase}}. Sampeyan bisa percaya email iki menawa tembung kasebut cocog karo tembung sing ditampilake nalika mlebu.", "emails.otpSession.thanks": "Matur nuwun,", "emails.otpSession.signature": "tim {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/km.json b/app/config/locale/translations/km.json index 72c362a77c..12ac05e8da 100644 --- a/app/config/locale/translations/km.json +++ b/app/config/locale/translations/km.json @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "ឃ្លាសម្ងាត់សម្រាប់អ៊ីមែលនេះគឺ {{phrase}}។ អ្នកអាចទុកចិត្តលើអ៊ីមែលនេះប្រសិនបើឃ្លានេះត្រូវគ្នាជាមួយឃ្លាដែលបង្ហាញឡើងពេលចូលប្រើ។", "emails.magicSession.optionUrl": "ប្រសិនបើអ្នកមិនអាចចូលប្រើប្រាស់ដោយប្រើប៊ូតុងខាងលើនេះទេ សូមចូលទៅកាន់តំណភ្ជាប់ខាងក្រោម៖", "emails.otpSession.subject": "ការចូល {{project}}", - "emails.otpSession.hello": "ជំរាបសួរ,", + "emails.otpSession.hello": "ជំរាបសួរ", "emails.otpSession.description": "បញ្ចូលលេខកូដផ្ទៀងផ្ទាត់ខាងក្រោមនេះនៅពេលដែលបានស្នើ ដើម្បីចូលទៅកាន់គណនី {{project}} របស់អ្នកដោយមានសុវត្ថិភាព។ វានឹងផុតកំណត់ក្នុងរយៈពេល 15 នាទី។", "emails.otpSession.clientInfo": "ការចូលប្រព័ន្ធនេះត្រូវបានស្នើរបស់អ្នកប្រើប្រាស់តាមរយៈ {{agentClient}} នៅលើ {{agentDevice}} {{agentOs}}។ ប្រសិនបើអ្នកមិនបានស្នើរការចូលប្រព័ន្ធនេះទេ អ្នកអាចមិនអើពើអ៊ីម៉ែលនេះបាន។", "emails.otpSession.securityPhrase": "ឃ្លាសម្រាប់សុវត្ថិភាពអ៊ីមែលនេះគឺ {{phrase}}។ អ្នកអាចទុកចិត្តនូវអ៊ីមែលនេះប្រសិនបើឃ្លានេះត្រូវគ្នាជាមួយឃ្លាដែលបានបង្ហាញពេលចូលគណនី។", - "emails.otpSession.thanks": "អរគុណ,", + "emails.otpSession.thanks": "អរគុណ", "emails.otpSession.signature": "ក្រុម {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/kn.json b/app/config/locale/translations/kn.json index 429958fc1a..ba57c21155 100644 --- a/app/config/locale/translations/kn.json +++ b/app/config/locale/translations/kn.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ತಂಡ", "emails.verification.subject": "ಖಾತೆ ಪರಿಶೀಲನೆ", - "emails.verification.hello": "ನಮಸ್ಕಾರ {{user}}", + "emails.verification.hello": "ನಮಸ್ಕಾರ {{user}},", "emails.verification.body": "ನಿಮ್ಮ ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ", "emails.verification.footer": "ನೀವು ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ", - "emails.verification.thanks": "ಧನ್ಯವಾದಗಳು", + "emails.verification.thanks": "ಧನ್ಯವಾದಗಳು,", "emails.verification.signature": "{{project}} ತಂಡ", "emails.magicSession.subject": "ಲಾಗಿನ್", - "emails.magicSession.hello": "ನಮಸ್ಕಾರ", + "emails.magicSession.hello": "ನಮಸ್ಕಾರ,", "emails.magicSession.body": "ಲಾಗಿನ್ ಮಾಡಲಿಕ್ಕೆ ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ", "emails.magicSession.footer": "ನೀವು ಈ ಇಮೇಲನಿಂದ ಲಾಗಿನ್ ಮಾಡಲು ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ", - "emails.magicSession.thanks": "ಧನ್ಯವಾದಗಳು", + "emails.magicSession.thanks": "ಧನ್ಯವಾದಗಳು,", "emails.magicSession.signature": "{{project}} ತಂಡ", "emails.recovery.subject": "ಗುಪ್ತಪದ ಮರುಹೊಂದಿಸಿ", - "emails.recovery.hello": "ನಮಸ್ಕಾರ {{user}}", + "emails.recovery.hello": "ನಮಸ್ಕಾರ {{user}},", "emails.recovery.body": "ನಿಮ್ಮ {{project}} ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ", "emails.recovery.footer": "ನೀವು ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ", - "emails.recovery.thanks": "ಧನ್ಯವಾದಗಳು", + "emails.recovery.thanks": "ಧನ್ಯವಾದಗಳು,", "emails.recovery.signature": "{{project}} ತಂಡ", "emails.invitation.subject": "%s ತಂಡಕ್ಕೆ %s ರಲ್ಲಿ ಆಹ್ವಾನ", - "emails.invitation.hello": "ನಮಸ್ಕಾರ", + "emails.invitation.hello": "ನಮಸ್ಕಾರ,", "emails.invitation.body": "ಈ ಇಮೇಲ್ ನಿಮಗೆ ಬಂದಿದೆ ಏಕೆಂದರೆ {{owner}} ನಿಮ್ಮನ್ನು {{team}} ತಂಡದ {{project}}ರಲ್ಲಿ ಸದಸ್ಯ ಆಗಲಿಕ್ಕೆ ಆಹ್ವಾನಿಸಿದ್ದಾರೆ", "emails.invitation.footer": "ನಿಮಗೆ ಆಸಕ್ತಿಯಿಲ್ಲದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ", - "emails.invitation.thanks": "ಧನ್ಯವಾದಗಳು", + "emails.invitation.thanks": "ಧನ್ಯವಾದಗಳು,", "emails.invitation.signature": "{{project}} ತಂಡ", "locale.country.unknown": "Unknown", "countries.af": "ಅಫ್ಘಾನಿಸ್ತಾನ", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "ಈ ಇಮೇಲ್‌ಗೆ ಭದ್ರತಾ ಪದವು {{phrase}}. ನೀವು ಸೈನ್ ಇನ್ ಮಾಡುವಾಗ ತೋರಿಸಿದ ಪದವು ಇದರೊಂದಿಗೆ ಹೊಂದಿಕೊಂಡರೆ ಈ ಇಮೇಲನ್ನು ನೀವು ನಂಬಬಹುದು.", "emails.otpSession.thanks": "ಧನ್ಯವಾದಗಳು,", "emails.otpSession.signature": "ಪ್ರಾಜೆಕ್ಟ್ ತಂಡ" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ko.json b/app/config/locale/translations/ko.json index 372b7f1664..c33c961130 100644 --- a/app/config/locale/translations/ko.json +++ b/app/config/locale/translations/ko.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s 팀", "emails.verification.subject": "계정 인증", - "emails.verification.hello": "안녕하세요 {{user}}님", + "emails.verification.hello": "안녕하세요 {{user}}님、", "emails.verification.body": "이메일 인증을 위해 링크를 클릭하여주세요.", "emails.verification.footer": "이메일 인증을 부탁하지 않으셨다면 이 메시지를 무시하여주세요.", - "emails.verification.thanks": "감사합니다", + "emails.verification.thanks": "감사합니다、", "emails.verification.signature": "{{project}} 팀", "emails.magicSession.subject": "로그인", - "emails.magicSession.hello": "안녕하세요", + "emails.magicSession.hello": "안녕하세요、", "emails.magicSession.body": "로그인 하시려면 링크를 클릭하여주세요.", "emails.magicSession.footer": "이 이메일 계정으로 로그인 신청을 하지 않으셨다면 이 메세지를 무시하여주세요.", - "emails.magicSession.thanks": "감사합니다", + "emails.magicSession.thanks": "감사합니다、", "emails.magicSession.signature": "{{project}} 팀", "emails.recovery.subject": "비밀번호 재설정", - "emails.recovery.hello": "안녕하세요 {{user}}님", + "emails.recovery.hello": "안녕하세요 {{user}}님、", "emails.recovery.body": "{{project}}의 비밀번호 재설정을 위해 링크를 클릭하여주세요.", "emails.recovery.footer": "비밀번호 재설정 신청을 하지 않으셨다면 이 메세지를 무시하여주세요.", - "emails.recovery.thanks": "감사합니다", + "emails.recovery.thanks": "감사합니다、", "emails.recovery.signature": "{{project}} 팀", "emails.invitation.subject": "초대장 %s 팀 - %s", - "emails.invitation.hello": "안녕하세요", + "emails.invitation.hello": "안녕하세요、", "emails.invitation.body": "{{owner}}님이 귀하를 {{project}}의 {{team}} 팀으로 초대합니다.", "emails.invitation.footer": "팀에 합류할 의사가 없으시면 이 메세지를 무시하여주세요.", - "emails.invitation.thanks": "감사합니다", + "emails.invitation.thanks": "감사합니다、", "emails.invitation.signature": "{{project}} 팀", "locale.country.unknown": "알려지지 않은", "countries.af": "아프가니스탄", @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "이 이메일의 보안 구절은 {{phrase}}입니다. 로그인할 때 표시되는 구절과 일치한다면 이 이메일을 신뢰할 수 있습니다.", "emails.magicSession.optionUrl": "위의 버튼을 사용하여 로그인할 수 없다면, 다음 링크를 방문해 주세요:", "emails.otpSession.subject": "{{project}} 로그인", - "emails.otpSession.hello": "안녕하세요,", + "emails.otpSession.hello": "안녕하세요、", "emails.otpSession.description": "다음 인증 코드를 입력하면 보안을 유지하며 {{project}} 계정에 안전하게 로그인할 수 있습니다. 15분 후에 만료됩니다.", "emails.otpSession.clientInfo": "이 로그인은 {{agentClient}}을 사용하여 {{agentDevice}} {{agentOs}}에서 요청되었습니다. 로그인을 요청하지 않았다면, 이 이메일을 안심하고 무시하셔도 됩니다.", "emails.otpSession.securityPhrase": "이 이메일의 보안 구절은 {{phrase}}입니다. 로그인하는 동안 표시된 구절과 이 구절이 일치하면 이 이메일을 신뢰할 수 있습니다.", - "emails.otpSession.thanks": "감사합니다,", + "emails.otpSession.thanks": "감사합니다、", "emails.otpSession.signature": "{{project}} 팀" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/la.json b/app/config/locale/translations/la.json index 9ccbaba86e..bebef26854 100644 --- a/app/config/locale/translations/la.json +++ b/app/config/locale/translations/la.json @@ -4,28 +4,28 @@ "settings.direction": "ltr*", "emails.sender": "%s team", "emails.verification.subject": "Ratio comprobatio", - "emails.verification.hello": "Salve ibi {{user}}", + "emails.verification.hello": "Salve ibi {{user}},", "emails.verification.body": "Sequere hanc nexum ut quin inscriptionem tuum.", "emails.verification.footer": "Si verificationem huius inscriptionis non postulasti, nuntium hunc ignorare potes.", - "emails.verification.thanks": "Gratias", + "emails.verification.thanks": "Gratias,", "emails.verification.signature": "{{project}} Team", "emails.magicSession.subject": "Log in", - "emails.magicSession.hello": "Salve ibi", + "emails.magicSession.hello": "Salve ibi,", "emails.magicSession.body": "Hanc nexum cum login", "emails.magicSession.footer": "Si verificationem huius inscriptionis non postulasti, nuntium hunc ignorare potes.", - "emails.magicSession.thanks": "Gratias", + "emails.magicSession.thanks": "Gratias,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Recuperet password", - "emails.recovery.hello": "Salve ibi {{user}}", + "emails.recovery.hello": "Salve ibi {{user}},", "emails.recovery.body": "Sequere hanc conjunctionem ut recipias project password {{project}}", "emails.recovery.footer": "Si tesseram tuam recuperare non petis, nuntium hunc ignorare potes", - "emails.recovery.thanks": "Gratias", + "emails.recovery.thanks": "Gratias,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Invitatio pro %s in quadrigis %s", - "emails.invitation.hello": "Salve ibi", + "emails.invitation.hello": "Salve ibi,", "emails.invitation.body": "Haec inscriptio ad te missa est quia dominus incepto {{owner}} te invitare vult ut membrum {{team}} quadrigis fias ad {{project}}", "emails.invitation.footer": "Si non quaero, potes hunc nuntium ignorare", - "emails.invitation.thanks": "Gratias", + "emails.invitation.thanks": "Gratias,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Ignotum", "countries.af": "Afghanistan", @@ -245,10 +245,10 @@ "emails.otpSession.thanks": "Gratias,", "emails.otpSession.signature": "{{project}} team -> {{project}} grex", "emails.certificate.subject": "Defectio testimonii pro %s", - "emails.certificate.hello": "Salve", + "emails.certificate.hello": "Salve,", "emails.certificate.body": "Certificatum pro dominio tuo '{{domain}}' generari non potuit. Hoc conatus num. {{attempt}} est, et defectus causatus est ab: {{error}}", "emails.certificate.footer": "Praeclarum tuum testificationem valet ad XXX dies a primo defectu. Magnopere suademus ut hoc casum investiges, alioquin dominium tuum sine valida SSL communicatione erit.", - "emails.certificate.thanks": "Gratias", + "emails.certificate.thanks": "Gratias,", "emails.certificate.signature": "team {{project}}", "sms.verification.body": "{{secret}}" } diff --git a/app/config/locale/translations/lb.json b/app/config/locale/translations/lb.json index 3f590d5323..91b52e4a18 100644 --- a/app/config/locale/translations/lb.json +++ b/app/config/locale/translations/lb.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Kont Verifikatioun", - "emails.verification.hello": "Hey {{user}}", + "emails.verification.hello": "Hey {{user}},", "emails.verification.body": "Follegt dëse Link fir Är E -Mail Adress z'iwwerpréiwen.", "emails.verification.footer": "Wann Dir net gefrot hutt dës Adress z'iwwerpréiwen, kënnt Dir dëse Message ignoréieren.", - "emails.verification.thanks": "Merci", + "emails.verification.thanks": "Merci,", "emails.verification.signature": "{{project}} équipe", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Hey", + "emails.magicSession.hello": "Hey,", "emails.magicSession.body": "Follegt dëse Link fir umellen.", "emails.magicSession.footer": "Wann Dir net gefrot hutt Iech mat dëser E -Mail anzemelden, kënnt Dir dëse Message ignoréieren.", - "emails.magicSession.thanks": "Merci", + "emails.magicSession.thanks": "Merci,", "emails.magicSession.signature": "{{project}} équipe", "emails.recovery.subject": "Password Reset", - "emails.recovery.hello": "Hello {{user}}", + "emails.recovery.hello": "Hello {{user}},", "emails.recovery.body": "Follegt dëse Link fir Äert {{project}} Passwuert zréckzesetzen.", "emails.recovery.footer": "Wann Dir net gefrot hutt Äert Passwuert zréckzesetzen, kënnt Dir dëse Message ignoréieren.", - "emails.recovery.thanks": "Merci", + "emails.recovery.thanks": "Merci,", "emails.recovery.signature": "{{project}} équipe", "emails.invitation.subject": "Invitatioun un %s équipe bei %s", - "emails.invitation.hello": "Hallo", + "emails.invitation.hello": "Hallo,", "emails.invitation.body": "Dës E -Mail gouf un Iech geschéckt well {{owner}} Iech invitéiere wëllt fir Member vum {{team}} Team bei {{project}} ze ginn.", "emails.invitation.footer": "Wann Dir net interesséiert sidd, kënnt Dir dëse Message ignoréieren.", - "emails.invitation.thanks": "Merci", + "emails.invitation.thanks": "Merci,", "emails.invitation.signature": "{{project}} équipe", "locale.country.unknown": "Onbekannt", "countries.af": "Afghanistan", @@ -244,4 +244,4 @@ "emails.otpSession.securityPhrase": "D'Sécherheetsausso fir dësen E-Mail ass {{phrase}}. Dir kënnt dësem E-Mail vertrauen, wann dës Ausso mat der Ausso iwwereneestëmmt, déi beim Umellen gewise ginn ass.", "emails.otpSession.thanks": "Merci,", "emails.otpSession.signature": "{{project}} Equipe" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/lt.json b/app/config/locale/translations/lt.json index f72250c98e..94c874ce82 100644 --- a/app/config/locale/translations/lt.json +++ b/app/config/locale/translations/lt.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s komanda", "emails.verification.subject": "Paskyros Patvirtinimas", - "emails.verification.hello": "Labas {{user}}", + "emails.verification.hello": "Labas {{user}},", "emails.verification.body": "Spauskite šią nuorodą, kad patvirtintumėte savo el. paštą.", "emails.verification.footer": "Jei neprašėte patvirtinti šio el. pašto, galite ignoruoti šį pranešimą.", - "emails.verification.thanks": "Ačiū", + "emails.verification.thanks": "Ačiū,", "emails.verification.signature": "{{project}} komanda", "emails.magicSession.subject": "Prisijungti", - "emails.magicSession.hello": "Labas", + "emails.magicSession.hello": "Labas,", "emails.magicSession.body": "Spauskite šią nuorodą, kad prisijungtumėte.", "emails.magicSession.footer": "Jei neprašėte prisijungti naudojantis šiuo el. paštu, galite ignoruoti šį pranešimą.", - "emails.magicSession.thanks": "Ačiū", + "emails.magicSession.thanks": "Ačiū,", "emails.magicSession.signature": "{{project}} komanda", "emails.recovery.subject": "Slaptažodžio Atkūrimas", - "emails.recovery.hello": "Labas {{user}}", + "emails.recovery.hello": "Labas {{user}},", "emails.recovery.body": "Spauskite šią nuorodą, kad atkurtumėte projekto {{project}} slaptažodį.", "emails.recovery.footer": "Jei neprašėte atkurti savo slaptažodzio, galite ignoruoti šį pranešimą.", - "emails.recovery.thanks": "Ačiū", + "emails.recovery.thanks": "Ačiū,", "emails.recovery.signature": "{{project}} komanda", "emails.invitation.subject": "Pakvietimas į %s komandą %s projekte", - "emails.invitation.hello": "Labas", + "emails.invitation.hello": "Labas,", "emails.invitation.body": "Šis el. laiškas buvo atsiųstas jums, nes {{owner}} norėjo jus pakviesti tapti projekto {{project}} dalimi {{team}} komandoje.", "emails.invitation.footer": "Jei jūsų tai nedomina, galite ignoruoti šį pranešimą.", - "emails.invitation.thanks": "Ačiū", + "emails.invitation.thanks": "Ačiū,", "emails.invitation.signature": "{{project}} komanda", "locale.country.unknown": "Nežinoma", "countries.af": "Afganistanas", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Šio el. laiško saugumo frazė yra {{phrase}}. Galite pasitikėti šiuo el. laišku, jei ši frazė atitinka frazę, rodytą prisijungimo metu.", "emails.otpSession.thanks": "Ačiū,", "emails.otpSession.signature": "{{project}} komanda" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/lv.json b/app/config/locale/translations/lv.json index 66604a0e3e..b4a396367c 100644 --- a/app/config/locale/translations/lv.json +++ b/app/config/locale/translations/lv.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s komanda", "emails.verification.subject": "Konta verifikācija", - "emails.verification.hello": "Sveicināti, {{user}}", + "emails.verification.hello": "Sveicināti, {{user}},", "emails.verification.body": "Sekojiet saitei, lai apstiprinātu savu e-pasta adresi.", "emails.verification.footer": "Ja Jūs nepieprasījāt šīs adreses apstiprinājumu, lūdzu, ignorējiet šo ziņu.", - "emails.verification.thanks": "Paldies", + "emails.verification.thanks": "Paldies,", "emails.verification.signature": "{{project}} komanda", "emails.magicSession.subject": "Ieiet", - "emails.magicSession.hello": "Sveicināti", + "emails.magicSession.hello": "Sveicināti,", "emails.magicSession.body": "Sekojiet saitei, lai ieietu.", "emails.magicSession.footer": "Ja Jūs nepieprasījāt ieiet ar šo e-pasta adresi, lūdzu, ignorējiet šo ziņu.", - "emails.magicSession.thanks": "Paldies", + "emails.magicSession.thanks": "Paldies,", "emails.magicSession.signature": "{{project}} komanda", "emails.recovery.subject": "Paroles atjaunināšana", - "emails.recovery.hello": "Labdien, {{user}}", + "emails.recovery.hello": "Labdien, {{user}},", "emails.recovery.body": "Sekojiet saitei, lai atjauninātu {{project}} paroli.", "emails.recovery.footer": "Ja Jūs nepieprasījāt paroles atjaunināšanu, lūdzu, ignorējiet šo ziņu.", - "emails.recovery.thanks": "Paldies", + "emails.recovery.thanks": "Paldies,", "emails.recovery.signature": "{{project}} komanda", "emails.invitation.subject": "Ielūgums piebiedroties %s komandai %s projektā.", - "emails.invitation.hello": "Labdien", + "emails.invitation.hello": "Labdien,", "emails.invitation.body": "Šis e-pasts tika nosūtīts Jums, jo {{owner}} vēlējās Jūs ielūgt kļūt par {{team}} komandas biedru {{project}} projektā.", "emails.invitation.footer": "Ja Jūs neesat ieinteresēts, lūdzu, ignorējiet šo ziņu.", - "emails.invitation.thanks": "Paldies", + "emails.invitation.thanks": "Paldies,", "emails.invitation.signature": "{{project}} komanda", "locale.country.unknown": "Nav zināms", "countries.af": "Afganistāna", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Drošības frāze šim e-pastam ir {{phrase}}. Šim e-pastam var uzticēties, ja šī frāze sakrīt ar frāzi, kas parādīta pieslēdzoties.", "emails.otpSession.thanks": "Paldies,", "emails.otpSession.signature": "{{project}} komanda" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ml.json b/app/config/locale/translations/ml.json index 60e84e2a92..1b57d87865 100644 --- a/app/config/locale/translations/ml.json +++ b/app/config/locale/translations/ml.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ടീം", "emails.verification.subject": "അക്കൗണ്ട് സ്ഥിരീകരണം", - "emails.verification.hello": "നമസ്കാരം {{user}}", + "emails.verification.hello": "നമസ്കാരം {{user}},", "emails.verification.body": "നിങ്ങളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുന്നതിനായി ഈ ലിങ്ക് പിന്തുടരുക.", "emails.verification.footer": "ഈ വിലാസം സ്ഥിരീകരിക്കാന്‍ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, നിങ്ങൾക്ക് ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.", - "emails.verification.thanks": "നന്ദി", + "emails.verification.thanks": "നന്ദി,", "emails.verification.signature": "{{project}} ടീം", "emails.magicSession.subject": "ലോഗിൻ", - "emails.magicSession.hello": "നമസ്കാരം", + "emails.magicSession.hello": "നമസ്കാരം,", "emails.magicSession.body": "ലോഗിൻ ചെയ്യുന്നതിനായി ഈ ലിങ്ക് പിന്തുടരുക.", "emails.magicSession.footer": "ഈ ഇമെയിൽ ഉപയോഗിച്ച് ലോഗിൻ ചെയ്യാൻ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.", - "emails.magicSession.thanks": "നന്ദി", + "emails.magicSession.thanks": "നന്ദി,", "emails.magicSession.signature": "{{project}} ടീം", "emails.recovery.subject": "രഹസ്യവാക്ക് പുനക്രമീകരണം", - "emails.recovery.hello": "നമസ്കാരം {{user}}", + "emails.recovery.hello": "നമസ്കാരം {{user}},", "emails.recovery.body": "നിങ്ങളുടെ {{Project}} രഹസ്യവാക്ക് പുനക്രമീകരിക്കുന്നതിന് ഈ ലിങ്ക് പിന്തുടരുക.", "emails.recovery.footer": "നിങ്ങളുടെ രഹസ്യവാക്ക് പുനക്രമീകരിക്കാന്‍ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.", - "emails.recovery.thanks": "നന്ദി", + "emails.recovery.thanks": "നന്ദി,", "emails.recovery.signature": "{{project}} ടീം", "emails.invitation.subject": "%s -ലെ %s ടീമിലേക്കുള്ള ക്ഷണം", - "emails.invitation.hello": "നമസ്കാരം", + "emails.invitation.hello": "നമസ്കാരം,", "emails.invitation.body": "നിങ്ങളെ {{project}} -ലെ {{team}} ടീമിലെ അംഗമാകുവാന്‍ ക്ഷണിക്കാൻ {{owner}} ആഗ്രഹിക്കുന്നതിനാലാണ് ഈ മെയിൽ നിങ്ങൾക്ക് അയക്കുന്നത്.", "emails.invitation.footer": "നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.", - "emails.invitation.thanks": "നന്ദി", + "emails.invitation.thanks": "നന്ദി,", "emails.invitation.signature": "{{project}} ടീം", "locale.country.unknown": "Unknown", "countries.af": "അഫ്ഗാനിസ്ഥാൻ", @@ -245,10 +245,10 @@ "emails.otpSession.thanks": "നന്ദി,", "emails.otpSession.signature": "പ്രോജക്ട് ടീം", "emails.certificate.subject": "%s ന് സർട്ടിഫിക്കറ്റ് പരാജയപ്പെട്ടു", - "emails.certificate.hello": "ഹലോ", + "emails.certificate.hello": "ഹലോ,", "emails.certificate.body": "നിങ്ങളുടെ ഡൊമൈൻ '{{domain}}'നു വേണ്ടിയുള്ള സർട്ടിഫിക്കറ്റ് ഉണ്ടാക്കാനായില്ല. ഇത് ശ്രമം നമ്പർ {{attempt}} ആണ്, പരാജയപ്പെട്ടത് ഇതു മൂലമാണ്: {{error}}", "emails.certificate.footer": "നിങ്ങളുടെ മുൻപത്തെ സർട്ടിഫിക്കറ്റ് ആദ്യ പരാജയത്തിനു ശേഷം 30 ദിവസം വരെ സാധുവായിരിക്കും. ഈ കേസ് അന്വേഷിച്ചു നോക്കുന്നത് ഞങ്ങൾ ശക്തമായി ശുപാർശ ചെയ്യുന്നു, അല്ലെങ്കിൽ നിങ്ങളുടെ ഡൊമെയ്‌ൻ സാധുവായ SSL കമ്മ്യൂണിക്കേഷനില്ലാത്ത ഒരു അവസ്ഥയിലാകും.", - "emails.certificate.thanks": "നന്ദി", + "emails.certificate.thanks": "നന്ദി,", "emails.certificate.signature": "{{project}} ടീം", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/mr.json b/app/config/locale/translations/mr.json index 4edd6bf617..6550d1c1ba 100644 --- a/app/config/locale/translations/mr.json +++ b/app/config/locale/translations/mr.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s टीम", "emails.verification.subject": "खाते सत्यापन", - "emails.verification.hello": "नमस्कार {{user}}", + "emails.verification.hello": "नमस्कार {{user}},", "emails.verification.body": "आपला ईमेल पत्ता सत्यापित करण्यासाठी या दुव्याचे अनुसरण करा.", "emails.verification.footer": "आपण या पत्त्याची पडताळणी करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.", - "emails.verification.thanks": "धन्यवाद", + "emails.verification.thanks": "धन्यवाद,", "emails.verification.signature": "{{project}} संघ", "emails.magicSession.subject": "लॉगिन करा", - "emails.magicSession.hello": "नमस्कार ", + "emails.magicSession.hello": "नमस्कार ,", "emails.magicSession.body": "लॉगिन करण्यासाठी या लिंकचे अनुसरण करा.", "emails.magicSession.footer": "आपण या ईमेलचा वापर करून लॉगिन करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.", - "emails.magicSession.thanks": "धन्यवाद", + "emails.magicSession.thanks": "धन्यवाद,", "emails.magicSession.signature": "{{project}} संघ", "emails.recovery.subject": "पासवर्ड रीसेट", - "emails.recovery.hello": "नमस्कार {{user}}", + "emails.recovery.hello": "नमस्कार {{user}},", "emails.recovery.body": "आपला {{project}}चे पासवर्ड रीसेट करण्यासाठी या लिंकचे अनुसरण करा", "emails.recovery.footer": "आपण आपला पासवर्ड रीसेट करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.", - "emails.recovery.thanks": "धन्यवाद", + "emails.recovery.thanks": "धन्यवाद,", "emails.recovery.signature": "{{project}} संघ", "emails.invitation.subject": "%s संघ %s येथे सामील होण्यासाठी आमंत्रण", - "emails.invitation.hello": "नमस्कार", + "emails.invitation.hello": "नमस्कार,", "emails.invitation.body": "हा मेल तुम्हाला पाठवला होता कारण {{owner}} तुम्हाला {{project}} येथे {{team}} टीमचे सदस्य होण्यासाठी आमंत्रित करू इच्छित होते.", "emails.invitation.footer": "आपल्याला स्वारस्य नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.", - "emails.invitation.thanks": "धन्यवाद", + "emails.invitation.thanks": "धन्यवाद,", "emails.invitation.signature": "{{project}} संघ", "locale.country.unknown": "अज्ञात", "countries.af": "अफगानिस्तान", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "या ईमेलसाठीचे सुरक्षा वाक्यांश {{phrase}} आहे. जर हे वाक्यांश साइन इन करताना दाखवल्या गेलेल्या वाक्यांशाशी जुळत असेल तर आपण या ईमेलवर विश्वास ठेवू शकता.", "emails.otpSession.thanks": "धन्यवाद,", "emails.otpSession.signature": "{{project}} संघ" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ms.json b/app/config/locale/translations/ms.json index ded7587d34..a02c36b075 100644 --- a/app/config/locale/translations/ms.json +++ b/app/config/locale/translations/ms.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Pengesahan Akaun", - "emails.verification.hello": "Hey {{user}}", + "emails.verification.hello": "Hey {{user}},", "emails.verification.body": "Tekan pautan ini untuk mengesahkan alamat email anda.", "emails.verification.footer": "Sekiranya anda tidak membuat permintaan untuk mengesahkan email ini, sila abaikan mesej ini.", - "emails.verification.thanks": "Terima kasih", + "emails.verification.thanks": "Terima kasih,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "Log masuk", - "emails.magicSession.hello": "Hey", + "emails.magicSession.hello": "Hey,", "emails.magicSession.body": "Tekan pautan ini untuk log masuk.", "emails.magicSession.footer": "Sekiranya anda tidak membuat permintaan untuk log masuk menggunakan email ini, sila abaikan mesej ini.", - "emails.magicSession.thanks": "Terima kasih", + "emails.magicSession.thanks": "Terima kasih,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Menetap semula Kata Laluan", - "emails.recovery.hello": "Hello {{user}}", + "emails.recovery.hello": "Hello {{user}},", "emails.recovery.body": "Tekan pautan ini untuk menetapkan semula kata laluan {{project}}.", "emails.recovery.footer": "Sekiranya anda tidak membuat permintaan menetap semula kata laluan, sila abaikan mesej ini.", - "emails.recovery.thanks": "Terima kasih", + "emails.recovery.thanks": "Terima kasih,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Jemputan ke pasukan %s di %s", - "emails.invitation.hello": "Hello", + "emails.invitation.hello": "Hello,", "emails.invitation.body": "Anda menerima mel ini kerana {{owner}} ingin menjemput anda untuk menjadi ahli pasukan {{team}} di {{project}}.", "emails.invitation.footer": "Sekiranya anda tidak berminat, sila abaikan mesej ini.", - "emails.invitation.thanks": "Terima kasih", + "emails.invitation.thanks": "Terima kasih,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Tidak Diketahui", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Frasa keselamatan untuk email ini adalah {{phrase}}. Anda boleh mempercayai email ini jika frasa ini sepadan dengan frasa yang ditunjukkan semasa log masuk.", "emails.otpSession.thanks": "Terima kasih,", "emails.otpSession.signature": "pasukan {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/nb.json b/app/config/locale/translations/nb.json index f8680e8993..daf18abc1c 100644 --- a/app/config/locale/translations/nb.json +++ b/app/config/locale/translations/nb.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Kontobekreftelse", - "emails.verification.hello": "Hei {{user}}", + "emails.verification.hello": "Hei {{user}},", "emails.verification.body": "Følg denne lenken for å bekrefte din e-postadresse.", "emails.verification.footer": "Dersom du ikke ba om å bekrefte e-postadressen, kan du se bort fra denne meldingen.", - "emails.verification.thanks": "Takk", + "emails.verification.thanks": "Takk,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "Pålogging", - "emails.magicSession.hello": "Hei", + "emails.magicSession.hello": "Hei,", "emails.magicSession.body": "Følg denne lenken for å logge på.", "emails.magicSession.footer": "Dersom du ikke ba om å logge på med denne e-postadressen, kan du se bort fra denne meldingen.", - "emails.magicSession.thanks": "Takk", + "emails.magicSession.thanks": "Takk,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Nullstille passord", - "emails.recovery.hello": "Hei {{user}}", + "emails.recovery.hello": "Hei {{user}},", "emails.recovery.body": "Følg denne lenken for å nullstille ditt {{project}} passord.", "emails.recovery.footer": "Dersom du ikke ba om å nullstille passordet ditt, kan du se bort fra denne meldingen.", - "emails.recovery.thanks": "Takk", + "emails.recovery.thanks": "Takk,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Invitasjon til %s Team ved %s", - "emails.invitation.hello": "Hei", + "emails.invitation.hello": "Hei,", "emails.invitation.body": "Denne meldingen ble sendt til deg fordi {{owner}} ønsket å invitere deg til å bli medlem av {{team}} team ved {{project}}.", "emails.invitation.footer": "Dersom du ikke er interessert, kan du se bort fra denne meldingen.", - "emails.invitation.thanks": "Takk", + "emails.invitation.thanks": "Takk,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Ukjent", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Sikkerhetsfrasen for denne e-posten er {{phrase}}. Du kan stole på denne e-posten hvis denne frasen stemmer overens med frasen som ble vist under pålogging.", "emails.otpSession.thanks": "Takk,", "emails.otpSession.signature": "{{project}} team" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ne.json b/app/config/locale/translations/ne.json index f31609eafc..4f05a9b5ba 100644 --- a/app/config/locale/translations/ne.json +++ b/app/config/locale/translations/ne.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s समूह", "emails.verification.subject": "खाता प्रमाणिकरण", - "emails.verification.hello": "नमस्ते {{user}}", + "emails.verification.hello": "नमस्ते {{user}},", "emails.verification.body": "इमेल ठेगाना प्रमाणित गर्नको लागी यो लिंकमा जानुहोस।", "emails.verification.footer": "यदि तपाइँले आफ्नो खाता प्रमाणित गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।", - "emails.verification.thanks": "धन्यवाद", + "emails.verification.thanks": "धन्यवाद,", "emails.verification.signature": "{{project}} समूह", "emails.magicSession.subject": "लगइन", - "emails.magicSession.hello": "नमस्ते", + "emails.magicSession.hello": "नमस्ते,", "emails.magicSession.body": "लगइन गर्नको लागी यो लिंकमा जानुहोस।", "emails.magicSession.footer": "यदि तपाइँले यो इमेल प्रयोग गरेर लगइन गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।", - "emails.magicSession.thanks": "धन्यवाद", + "emails.magicSession.thanks": "धन्यवाद,", "emails.magicSession.signature": "{{project}} समूह", "emails.recovery.subject": "पासवर्ड रिसेट", - "emails.recovery.hello": "नमस्ते {{user}}", + "emails.recovery.hello": "नमस्ते {{user}},", "emails.recovery.body": "{{project}}को पासवर्ड रिसेट गर्नको लागी यो लिंकमा जानुहोस।", "emails.recovery.footer": "यदि तपाइँले आफ्नो पासवर्ड रिसेट गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।", - "emails.recovery.thanks": "धन्यवाद", + "emails.recovery.thanks": "धन्यवाद,", "emails.recovery.signature": "{{project}} समूह", "emails.invitation.subject": "%s समूहको लागि %s मा निमन्त्रणा", - "emails.invitation.hello": "नमस्ते", + "emails.invitation.hello": "नमस्ते,", "emails.invitation.body": "{{owner}}ले तपाइँलाई {{project}}मा {{team}}को सदस्य बन्न आमन्त्रित गर्न चाहनु भएको छ। त्येसैले तपाइँलाई यो सन्देश पठाइएको हो।", "emails.invitation.footer": "यदि तपाइँ इच्छुक हुनुहुन्न भने, तपाइँले यो सन्देशलाई बेवास्ता गर्न सक्नुहुन्छ।", - "emails.invitation.thanks": "धन्यवाद", + "emails.invitation.thanks": "धन्यवाद,", "emails.invitation.signature": "{{project}} समूह", "locale.country.unknown": "अज्ञात", "countries.af": "अफगानिस्तान", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "यस ईमेलको लागि सुरक्षा वाक्य {{phrase}} हो। यदि यो वाक्य साइन इन गर्दा देखाइएको वाक्यसँग मेल खान्छ भने तपाईँले यो ईमेलमा विश्वास गर्न सक्नुहुन्छ।", "emails.otpSession.thanks": "धन्यवाद,", "emails.otpSession.signature": "{{project}} टिम" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/nl.json b/app/config/locale/translations/nl.json index 55e48fa753..cae82a9a37 100644 --- a/app/config/locale/translations/nl.json +++ b/app/config/locale/translations/nl.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Account Verificatie", - "emails.verification.hello": "Hoi {{user}}", + "emails.verification.hello": "Hoi {{user}},", "emails.verification.body": "Volg deze link om uw e-mail te verifieren", "emails.verification.footer": "Als u geen aanvraag voor verificatie heeft gemaakt, kan u deze mail negeren", - "emails.verification.thanks": "Bedankt", + "emails.verification.thanks": "Bedankt,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Hoi", + "emails.magicSession.hello": "Hoi,", "emails.magicSession.body": "Volg deze link om in te loggen", "emails.magicSession.footer": "Als u geen aanvraag heeft gemaakt om met deze mail in te loggen, kan u deze mail negeren", - "emails.magicSession.thanks": "Bedankt", + "emails.magicSession.thanks": "Bedankt,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Wachtwoord Herinstellen", - "emails.recovery.hello": "Hallo {{user}}", + "emails.recovery.hello": "Hallo {{user}},", "emails.recovery.body": "Volg deze link om het wachtwoord van uw project {{project}} te wijzigen", "emails.recovery.footer": "Als u geen aanvraag heeft gemaakt om uw wachtwoord te wijzigen, kan u deze mail negeren", - "emails.recovery.thanks": "Bedankt", + "emails.recovery.thanks": "Bedankt,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Uitnodiging van %s Team uit %s", "emails.invitation.hello": "Hallo,", "emails.invitation.body": "U ontvangt deze mail want u was uitgenodig door {{owner}} om lid van het {{team}} team te worden in {{project}} ", "emails.invitation.footer": "Als u niet geintereseerd bent, kan u deze mail negeren.", - "emails.invitation.thanks": "Bedankt", + "emails.invitation.thanks": "Bedankt,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Onbekend", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "De beveiligingszin voor deze e-mail is {{phrase}}. U kunt deze e-mail vertrouwen als deze zin overeenkomt met de zin die wordt getoond tijdens het inloggen.", "emails.otpSession.thanks": "Bedankt,", "emails.otpSession.signature": "{{project}} team" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/nn.json b/app/config/locale/translations/nn.json index 6ab037466f..44be0f9845 100644 --- a/app/config/locale/translations/nn.json +++ b/app/config/locale/translations/nn.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Team", "emails.verification.subject": "Kontostadfesting", - "emails.verification.hello": "Hallo {{user}}", + "emails.verification.hello": "Hallo {{user}},", "emails.verification.body": "Følg denne lenkja for å bekrefta din e-postadresse.", "emails.verification.footer": "Om du ikkje bad om å bekrefta e-postadressa, kan du ignorera denne meldinga.", - "emails.verification.thanks": "Takk", + "emails.verification.thanks": "Takk,", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "Pålogging", - "emails.magicSession.hello": "Hei", + "emails.magicSession.hello": "Hei,", "emails.magicSession.body": "Følg denne lenkja for å logge på.", "emails.magicSession.footer": "Om du ikkje ba om å logge på med denne e-postadressa, kan du ignorera denne meldinga.", - "emails.magicSession.thanks": "Takk", + "emails.magicSession.thanks": "Takk,", "emails.magicSession.signature": "{{project}} team", "emails.recovery.subject": "Nullstilla passord", - "emails.recovery.hello": "Hallo {{user}}", + "emails.recovery.hello": "Hallo {{user}},", "emails.recovery.body": "Følg denne lenkja for å nullstilla ditt {{project}} passord.", "emails.recovery.footer": "Om du ikkje ba om å nullstilla passordet ditt, kan du ignorera denne meldinga.", - "emails.recovery.thanks": "Takk", + "emails.recovery.thanks": "Takk,", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Innbyding til %s Team ved %s", - "emails.invitation.hello": "Hallo", + "emails.invitation.hello": "Hallo,", "emails.invitation.body": "Denne meldinga ble sendt til deg fordi {{owner}} ynskja å invitera deg til å bli medlem av {{team}} team i {{project}}.", "emails.invitation.footer": "Om du ikkje er interessert, kan du ignorera denne meldinga.", - "emails.invitation.thanks": "Takk", + "emails.invitation.thanks": "Takk,", "emails.invitation.signature": "{{project}} team", "locale.country.unknown": "Ukjend", "countries.af": "Afghanistan", @@ -245,10 +245,10 @@ "emails.otpSession.thanks": "Takk,", "emails.otpSession.signature": "{{project}}-laget", "emails.certificate.subject": "Sertifikatfeil for %s", - "emails.certificate.hello": "Hei", + "emails.certificate.hello": "Hei,", "emails.certificate.body": "Sertifikatet for domenet ditt '{{domain}}' kunne ikkje opprettast. Dette er forsøk nr. {{attempt}}, og feilen blei forårsaka av: {{error}}", "emails.certificate.footer": "Førre sertifikatet ditt vil vere gyldig i 30 dagar sidan den første feilen. Vi rår sterkt til at du undersøkjer denne saka, elles vil domenet ditt ende opp utan gyldig SSL-kommunikasjon.", - "emails.certificate.thanks": "Takk", + "emails.certificate.thanks": "Takk,", "emails.certificate.signature": "{{project}} team", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/or.json b/app/config/locale/translations/or.json index 08b150fbb7..efd516f23a 100644 --- a/app/config/locale/translations/or.json +++ b/app/config/locale/translations/or.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ଦଳ", "emails.verification.subject": "ଖାତା ଯାଞ୍ଚ", - "emails.verification.hello": "ନମସ୍କାର {{user}}", + "emails.verification.hello": "ନମସ୍କାର {{user}},", "emails.verification.body": "ଆପଣଙ୍କର ଇମେଲ୍ ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ ଏହି ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ |", "emails.verification.footer": "ଯଦି ଆପଣ ଏହି ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |", - "emails.verification.thanks": "ଧନ୍ୟବାଦ", + "emails.verification.thanks": "ଧନ୍ୟବାଦ,", "emails.verification.signature": "{{project}} ଦଳ", "emails.magicSession.subject": "ଲଗଇନ୍ କରନ୍ତୁ", - "emails.magicSession.hello": "ନମସ୍କାର", + "emails.magicSession.hello": "ନମସ୍କାର,", "emails.magicSession.body": "ଲଗଇନ୍ କରିବାକୁ ଏହି ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ |", "emails.magicSession.footer": "ଯଦି ଆପଣ ଏହି ଇମେଲ୍ ବ୍ୟବହାର କରି ଲଗଇନ୍ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |", - "emails.magicSession.thanks": "ଧନ୍ୟବାଦ", + "emails.magicSession.thanks": "ଧନ୍ୟବାଦ,", "emails.magicSession.signature": "{{project}} ଦଳ", "emails.recovery.subject": "ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରନ୍ତୁ |", - "emails.recovery.hello": "ନମସ୍କାର {{user}}", + "emails.recovery.hello": "ନମସ୍କାର {{user}},", "emails.recovery.body": "ଆପଣଙ୍କର {{project}} ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ ଏହି ଲିଙ୍କକୁ ଅନୁସରଣ କରନ୍ତୁ |", "emails.recovery.footer": "ଯଦି ଆପଣ ଆପଣଙ୍କର ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |", - "emails.recovery.thanks": "ଧନ୍ୟବାଦ", + "emails.recovery.thanks": "ଧନ୍ୟବାଦ,", "emails.recovery.signature": "{{project}} ଦଳ", "emails.invitation.subject": "%s ରେ %s ଦଳକୁ ନିମନ୍ତ୍ରଣ |", - "emails.invitation.hello": "ନମସ୍କାର", + "emails.invitation.hello": "ନମସ୍କାର,", "emails.invitation.body": "ଏହି ମେଲ୍ ଆପଣଙ୍କୁ ପଠାଯାଇଥିଲା କାରଣ {{owner}} ଆପଣଙ୍କୁ {{project} ରେ {{team}} ଦଳର ସଦସ୍ୟ ହେବାକୁ ଆମନ୍ତ୍ରଣ କରିବାକୁ ଚାହୁଁଥିଲେ |", "emails.invitation.footer": "ଯଦି ଆପଣ ଆଗ୍ରହୀ ନୁହଁନ୍ତି, ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଅଣଦେଖା କରିପାରିବେ |", - "emails.invitation.thanks": "ଧନ୍ୟବାଦ", + "emails.invitation.thanks": "ଧନ୍ୟବାଦ,", "emails.invitation.signature": "{{project}} ଦଳ", "locale.country.unknown": "ଅଜ୍ଞାତ", "countries.af": "ଆଫଗାନିସ୍ତାନ", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "ଏହି ଇମେଲର ସୁରକ୍ଷା ବାକ୍ୟାଂଶ ହେଉଛି {{phrase}}। ସାଇନ୍ ଇନ୍ କରିବା ସମୟରେ ଦେଖାଯାଇଥିବା ବାକ୍ୟାଂଶ ସହ ଏହା ମେଳେ ଯଦି, ଆପଣ ଏହି ଇମେଲକୁ ଆସ୍ଥା କରି ପାରିବେ।", "emails.otpSession.thanks": "ଧନ୍ୟବାଦ,", "emails.otpSession.signature": "ପ୍ରକଳ୍ପ ଟିମ୍ବ୍" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/pa.json b/app/config/locale/translations/pa.json index 76efde346b..de71be9f49 100644 --- a/app/config/locale/translations/pa.json +++ b/app/config/locale/translations/pa.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ਟੀਮ", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "ਅਣਜਾਣ", "countries.af": "ਅਫਗਾਨਿਸਤਾਨ", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "ਇਸ ਈਮੇਲ ਲਈ ਸੁਰੱਖਿਆ ਵਾਕ ਹੈ {{phrase}}। ਜੇ ਇਹ ਵਾਕ ਸਾਈਨ ਇਨ ਕਰਨ ਸਮੇਂ ਦਿਖਾਈ ਦੇਣ ਵਾਲੇ ਵਾਕ ਨਾਲ ਮੇਲ ਖਾਂਦਾ ਹੈ ਤਾਂ ਤੁਸੀਂ ਇਸ ਈਮੇਲ 'ਤੇ ਭਰੋਸਾ ਕਰ ਸਕਦੇ ਹੋ।", "emails.otpSession.thanks": "ਧੰਨਵਾਦ,", "emails.otpSession.signature": "{{project}} ਟੀਮ" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/pl.json b/app/config/locale/translations/pl.json index e596d2c04b..ee5811fb59 100644 --- a/app/config/locale/translations/pl.json +++ b/app/config/locale/translations/pl.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Zespół %s", "emails.verification.subject": "Weryfikacja konta", - "emails.verification.hello": "Cześć {{user}}", + "emails.verification.hello": "Cześć {{user}},", "emails.verification.body": "Przejdź do tego linku, aby zweryfikować swój adres e-mail.", "emails.verification.footer": "Jeśli to nie Ty prosiłeś o zweryfikowanie tego adresu, zignoruj tę wiadomość.", - "emails.verification.thanks": "Dziękujemy", + "emails.verification.thanks": "Dziękujemy,", "emails.verification.signature": "Zespół {{project}}", "emails.magicSession.subject": "Logowanie", - "emails.magicSession.hello": "Cześć", + "emails.magicSession.hello": "Cześć,", "emails.magicSession.body": "Kliknij w ten link, aby zalogować się.", "emails.magicSession.footer": "Jeśli to nie Ty prosiłeś o logowanie przy użyciu tego adresu e-mail, zignoruj tę wiadomość.", - "emails.magicSession.thanks": "Dziękujemy", + "emails.magicSession.thanks": "Dziękujemy,", "emails.magicSession.signature": "Zespół {{project}}", "emails.recovery.subject": "Resetowanie hasła", - "emails.recovery.hello": "Cześć {{user}}", + "emails.recovery.hello": "Cześć {{user}},", "emails.recovery.body": "Przejdź do tego linku, aby zresetować hasło dla {{project}}.", "emails.recovery.footer": "Jeśli to nie Ty prosiłeś o zresetowanie swojego hasła, zignoruj tę wiadomość.", - "emails.recovery.thanks": "Dziękujemy", + "emails.recovery.thanks": "Dziękujemy,", "emails.recovery.signature": "Zespół {{project}}", "emails.invitation.subject": "Zaproszenie do zespołu %s w %s", - "emails.invitation.hello": "Cześć", + "emails.invitation.hello": "Cześć,", "emails.invitation.body": "Otrzymujesz tę wiadomość, ponieważ {{owner}} zaprasza Cię do grona członków zespołu {{team}} w projekcie {{project}}.", "emails.invitation.footer": "Jeśli nie jesteś zainteresowany, zignoruj tę wiadomość.", - "emails.invitation.thanks": "Dziękujemy", + "emails.invitation.thanks": "Dziękujemy,", "emails.invitation.signature": "Zespół {{project}}", "locale.country.unknown": "Nieznany", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Hasłem zabezpieczającym dla tego e-maila jest {{phrase}}. Możesz zaufać temu e-mailowi, jeśli hasło zgadza się z hasłem wyświetlonym podczas logowania.", "emails.otpSession.thanks": "Dzięki,", "emails.otpSession.signature": "team {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/pt-br.json b/app/config/locale/translations/pt-br.json index b2c4931011..a53ca79813 100644 --- a/app/config/locale/translations/pt-br.json +++ b/app/config/locale/translations/pt-br.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Time %s", "emails.verification.subject": "Verificação da Conta", - "emails.verification.hello": "Olá {{user}}", + "emails.verification.hello": "Olá {{user}},", "emails.verification.body": "Clique neste link para verificar o seu endereço de e-mail.", "emails.verification.footer": "Se você não solicitou a verificação deste e-mail, ignore essa mensagem.", - "emails.verification.thanks": "Muito obrigado", + "emails.verification.thanks": "Muito obrigado,", "emails.verification.signature": "Time {{project}}", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Olá", + "emails.magicSession.hello": "Olá,", "emails.magicSession.body": "Clique neste link para entrar.", "emails.magicSession.footer": "Se você não solicitou conectar-se com este e-mail, ignore essa mensagem.", - "emails.magicSession.thanks": "Muito obrigado", + "emails.magicSession.thanks": "Muito obrigado,", "emails.magicSession.signature": "Time {{project}}", "emails.recovery.subject": "Redefinição de senha", - "emails.recovery.hello": "Olá {{user}}", + "emails.recovery.hello": "Olá {{user}},", "emails.recovery.body": "Clique neste link para redefinir sua senha do {{project}}.", "emails.recovery.footer": "Se você não solicitou a redefinição da sua senha, você pode ignorar essa mensagem.", - "emails.recovery.thanks": "Muito obrigado", + "emails.recovery.thanks": "Muito obrigado,", "emails.recovery.signature": "Time {{project}}", "emails.invitation.subject": "Convite para o Time %s em %s", - "emails.invitation.hello": "Olá", + "emails.invitation.hello": "Olá,", "emails.invitation.body": "Este e-mail foi enviado porque {{owner}} deseja convidar você a se tornar membro do Time {{team}} em {{project}}.", "emails.invitation.footer": "Caso não tenha interesse, ignore essa mensagem.", - "emails.invitation.thanks": "Muito obrigado", + "emails.invitation.thanks": "Muito obrigado,", "emails.invitation.signature": "Time {{project}}", "locale.country.unknown": "Desconhecido", "countries.af": "Afeganistão", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "A frase de segurança para este e-mail é {{phrase}}. Você pode confiar neste e-mail se esta frase corresponder à frase mostrada durante o login.", "emails.otpSession.thanks": "Obrigado,", "emails.otpSession.signature": "equipe {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/pt-pt.json b/app/config/locale/translations/pt-pt.json index 2dab03c9dd..d85dca9300 100644 --- a/app/config/locale/translations/pt-pt.json +++ b/app/config/locale/translations/pt-pt.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Equipa %s", "emails.verification.subject": "Verificação de contas", - "emails.verification.hello": "Hey {{user}}", + "emails.verification.hello": "Hey {{user}},", "emails.verification.body": "Siga esta ligação para verificar o seu endereço de correio electrónico.", "emails.verification.footer": "Se não pediu para verificar este endereço, pode ignorar esta mensagem.", - "emails.verification.thanks": "Obrigado", + "emails.verification.thanks": "Obrigado,", "emails.verification.signature": "Equipa {{project}}", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Olá ", + "emails.magicSession.hello": "Olá ,", "emails.magicSession.body": "Siga esta ligação para iniciar sessão.", "emails.magicSession.footer": "Se não pediu para entrar usando este e-mail, pode ignorar esta mensagem.", - "emails.magicSession.thanks": "Obrigado", + "emails.magicSession.thanks": "Obrigado,", "emails.magicSession.signature": "Equipa {{project}}", "emails.recovery.subject": "Redefinição de senha", - "emails.recovery.hello": "Olá {{user}}", + "emails.recovery.hello": "Olá {{user}},", "emails.recovery.body": "Utilize este link para redefinir a palavra-passe do seu projecto {{project}}", "emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.", - "emails.recovery.thanks": "Obrigado", + "emails.recovery.thanks": "Obrigado,", "emails.recovery.signature": "Equipa {{project}}", "emails.invitation.subject": "Convite à equipa de %s às %s", - "emails.invitation.hello": "Olá", + "emails.invitation.hello": "Olá,", "emails.invitation.body": "Este correio foi-lhe enviado porque {{owner}} queria convidá-lo a tornar-se membro da equipa {{team}} da {{project}}.", "emails.invitation.footer": "Se não estiver interessado, pode ignorar esta mensagem.", - "emails.invitation.thanks": "Obrigado", + "emails.invitation.thanks": "Obrigado,", "emails.invitation.signature": "Equipa {{project}}", "locale.country.unknown": "Desconhecido", "countries.af": "Afeganistão", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "A frase de segurança para este email é {{phrase}}. Você pode confiar neste email se essa frase corresponder à frase mostrada durante o login.", "emails.otpSession.thanks": "Obrigado,", "emails.otpSession.signature": "equipe {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ro.json b/app/config/locale/translations/ro.json index 45fb71d190..04cb22dd6b 100644 --- a/app/config/locale/translations/ro.json +++ b/app/config/locale/translations/ro.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Echipa", "emails.verification.subject": "Verificare cont", - "emails.verification.hello": "Bună ziua, {{user}}", + "emails.verification.hello": "Bună ziua, {{user}},", "emails.verification.body": "Click pe acest link pentru a valida adresa de email.", "emails.verification.footer": "Dacă nu ai cerut validarea adresei de email, poți ignora acest mesaj.", - "emails.verification.thanks": "Mulțumim", + "emails.verification.thanks": "Mulțumim,", "emails.verification.signature": "Echipa {{project}}", "emails.magicSession.subject": "Login", - "emails.magicSession.hello": "Bună ziua", + "emails.magicSession.hello": "Bună ziua,", "emails.magicSession.body": "Urmează acest link pentru logare.", "emails.magicSession.footer": "Dacă nu ai incercat să te loghezi folosing această adresa de email, poți ignora acest mesaj.", - "emails.magicSession.thanks": "Mulțumim", + "emails.magicSession.thanks": "Mulțumim,", "emails.magicSession.signature": "Echipa {{project}}", "emails.recovery.subject": "Resetare parolă", - "emails.recovery.hello": "Bună ziua, {{user}}", + "emails.recovery.hello": "Bună ziua, {{user}},", "emails.recovery.body": "Click aici pentru a reseta parola pentru {{project}}", "emails.recovery.footer": "Dacă nu ai cerut să îți schimbi parola, ignoră acest mesaj.", - "emails.recovery.thanks": "Mulțumim", + "emails.recovery.thanks": "Mulțumim,", "emails.recovery.signature": "Echipa {{project}}", "emails.invitation.subject": "Invitatie catre %s Echipa la %s", - "emails.invitation.hello": "Bună ziua", + "emails.invitation.hello": "Bună ziua,", "emails.invitation.body": "Acest email a fost trimis pentru că {{owner}} a vrut ca tu să devii membru al echipei {{team}} la {{project}}.", "emails.invitation.footer": "Dacă nu esti interesat, poți ignora acest email.", - "emails.invitation.thanks": "Mulțumim", + "emails.invitation.thanks": "Mulțumim,", "emails.invitation.signature": "Echipa {{project}}", "locale.country.unknown": "Necunoscut", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Fraza de securitate pentru acest e-mail este {{phrase}}. Puteți avea încredere în acest e-mail dacă fraza se potrivește cu cea afișată în timpul autentificării.", "emails.otpSession.thanks": "Mulțumesc,", "emails.otpSession.signature": "echipa {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ru.json b/app/config/locale/translations/ru.json index a1d740bea2..029aa06ee7 100644 --- a/app/config/locale/translations/ru.json +++ b/app/config/locale/translations/ru.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Команда %s", "emails.verification.subject": "Верификация аккаунта", - "emails.verification.hello": "Здравствуйте, {{user}}", + "emails.verification.hello": "Здравствуйте, {{user}},", "emails.verification.body": "Перейдите по ссылке, чтобы подтвердить свой адрес электронной почты.", "emails.verification.footer": "Если вы не запрашивали подтверждение этого адреса, проигнорируйте это сообщение.", - "emails.verification.thanks": "Спасибо", + "emails.verification.thanks": "Спасибо,", "emails.verification.signature": "команда {{project}}", "emails.magicSession.subject": "Логин", - "emails.magicSession.hello": "Здравствуйте", + "emails.magicSession.hello": "Здравствуйте,", "emails.magicSession.body": "Перейдите по ссылке, чтобы войти.", "emails.magicSession.footer": "Если вы не просили войти, используя этот адрес электронной почты, проигнорируйте это сообщение.", - "emails.magicSession.thanks": "Спасибо", + "emails.magicSession.thanks": "Спасибо,", "emails.magicSession.signature": "команда {{project}}", "emails.recovery.subject": "Сброс пароля", - "emails.recovery.hello": "Здравствуйте, {{user}}", + "emails.recovery.hello": "Здравствуйте, {{user}},", "emails.recovery.body": "Перейдите по этой ссылке для того чтобы сбросить свой пароль для проекта {{project}}", "emails.recovery.footer": "Если вы не запрашивали сброс пароля, проигнорируйте это сообщение.", - "emails.recovery.thanks": "Спасибо", + "emails.recovery.thanks": "Спасибо,", "emails.recovery.signature": "команда {{project}}", "emails.invitation.subject": "Приглашение в команду %s по проекту %s", - "emails.invitation.hello": "Здравствуйте", + "emails.invitation.hello": "Здравствуйте,", "emails.invitation.body": "Это письмо отправлено вам, потому что {{owner}} приглашает стать членом команды {{team}} в проекте {{project}}.", "emails.invitation.footer": "Если вы не заинтересованы, проигнорируйте это сообщение.", - "emails.invitation.thanks": "Спасибо", + "emails.invitation.thanks": "Спасибо,", "emails.invitation.signature": "команда {{project}}", "locale.country.unknown": "Неизвестно", "countries.af": "Афганистан", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Фраза безопасности для этого письма {{phrase}}. Вы можете доверять этому письму, если эта фраза совпадает с фразой, показанной во время входа в систему.", "emails.otpSession.thanks": "Спасибо,", "emails.otpSession.signature": "команда {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sa.json b/app/config/locale/translations/sa.json index b82a3ed9ba..7aa8c90d77 100644 --- a/app/config/locale/translations/sa.json +++ b/app/config/locale/translations/sa.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s गणः", "emails.verification.subject": "पञ्जिकानिर्णायनम्‌", - "emails.verification.hello": "अयि {{user}}", + "emails.verification.hello": "अयि {{user}},", "emails.verification.body": "ई-पत्रनिर्णायनार्थमिदं संयोगसूत्रमनुसरतु।", "emails.verification.footer": "यदि अस्य संकेतस्य निर्णायनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्‌।", - "emails.verification.thanks": "धन्यवादः", + "emails.verification.thanks": "धन्यवादः,", "emails.verification.signature": "{{project}} गणः", "emails.magicSession.subject": "संप्रवेशः", - "emails.magicSession.hello": "अयि", + "emails.magicSession.hello": "अयि,", "emails.magicSession.body": "संप्रवेशार्थमिदं संयोगसूत्रमनुसरतु।", "emails.magicSession.footer": "अनेन ई-पत्रण यदि संप्रवेशो नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्‌।", - "emails.magicSession.thanks": "धन्यवादः", + "emails.magicSession.thanks": "धन्यवादः,", "emails.magicSession.signature": "{{project}} गणः", "emails.recovery.subject": "कूटशब्दपुनयाेजनम्‌", - "emails.recovery.hello": "अयि भो {{user}}", + "emails.recovery.hello": "अयि भो {{user}},", "emails.recovery.body": "{{project}} कूटशब्दपुनयाेजनाय संयोगमेनमनुसरतु।", "emails.recovery.footer": "यदि कूटशब्दस्य पुनयाेजनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्‌।", - "emails.recovery.thanks": "धन्यवादः", + "emails.recovery.thanks": "धन्यवादः,", "emails.recovery.signature": "{{project}} गणः", "emails.invitation.subject": "गणस्य आमन्त्रणम्‌ %s इति %s", - "emails.invitation.hello": "अयि भो", + "emails.invitation.hello": "अयि भो,", "emails.invitation.body": "{{owner}} {{team}} गणे {{project}} मध्ये भवद्योगदानमच्छितीति हेतोः पत्रमदिं भवत्सकाशं प्रेषतिम्।", "emails.invitation.footer": "यदि भवदनिच्छा तर्हि वात्र्तामिमामुपेक्षताम्‌।", - "emails.invitation.thanks": "धन्यवादः", + "emails.invitation.thanks": "धन्यवादः,", "emails.invitation.signature": "{{project}} गणः", "locale.country.unknown": "अज्ञातम्‌ ", "countries.af": "आफगानिस्थानम्‌", @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "العبارة الأمنية لهذا البريد الإلكتروني هي {{phrase}}. يمكنك الوثوق بهذا البريد الإلكتروني إذا كانت هذه العبارة متطابقة مع العبارة المعروضة أثناء تسجيل الدخول.", "emails.magicSession.optionUrl": "إذا لم تتمكن من تسجيل الدخول باستخدام الزر أعلاه، يرجى زيارة الرابط التالي:", "emails.otpSession.subject": "प्रवेशनम्", - "emails.otpSession.hello": "नमस्ते।", + "emails.otpSession.hello": "नमस्ते।,", "emails.otpSession.description": "प्रविष्ट कुरु अनुसृत विश्वासनीयकोडम् यदा पृच्छ्यसे भवतः {{project}} खातायां सुरक्षितरूपेण प्रवेशे। एषः पन्द्रह मिनितेषु समाप्तिं गच्छति।", "emails.otpSession.clientInfo": "एष प्रवेशनं प्रार्थितं {{agentClient}} नाम प्रतिनिधौ {{agentDevice}} {{agentOs}} इत्यस्मिन्। यदि त्वमेव प्रवेशनं न प्रार्थितवानसि, तर्हि त्वमनेन ईपत्रेण उपेक्षितुं शक्नोसि।", "emails.otpSession.securityPhrase": "अस्य ईमेलस्य सुरक्षा वाक्यं {{phrase}} अस्ति। यदि अयं वाक्यः प्रवेशकाले दृष्टवाक्येन साम्यं याति तर्हि अस्माकं ईमेलं विश्वसनीयम् अस्ति।", - "emails.otpSession.thanks": "धन्यवादाः", + "emails.otpSession.thanks": "धन्यवादाः,", "emails.otpSession.signature": "कार्यक्रमस्य समूहः" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sd.json b/app/config/locale/translations/sd.json index 69cad52549..3f1f7678db 100644 --- a/app/config/locale/translations/sd.json +++ b/app/config/locale/translations/sd.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s ٽيم", "emails.verification.subject": " اڪائونٽ جي تصديق", - "emails.verification.hello": "سلام {{user}}", + "emails.verification.hello": "سلام {{user}},", "emails.verification.body": "پنھنجي اي ميل ايڊريس جي تصديق ڪرڻ لاءِ ھن لنڪ تي عمل ڪريو.", "emails.verification.footer": "جيڪڏھن توھان نه پ askيا ھئا ھن ايڊريس جي تصديق ڪرڻ لاءِ ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.", - "emails.verification.thanks": "مهرباني", + "emails.verification.thanks": "مهرباني,", "emails.verification.signature": "{{project}} ٽيم", "emails.magicSession.subject": "لاگ ان", - "emails.magicSession.hello": "هي ،", + "emails.magicSession.hello": "هي ,", "emails.magicSession.body": "لاگ ان ٿيڻ لاءِ ھن لنڪ تي عمل ڪريو.", "emails.magicSession.footer": "جيڪڏھن توھان نه پ پيا ھي لاگ ان استعمال ڪندي اي ميل ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.", - "emails.magicSession.thanks": "مهرباني", + "emails.magicSession.thanks": "مهرباني,", "emails.magicSession.signature": "{{project}} ٽيم", "emails.recovery.subject": "پاسورڊ ري سيٽ", - "emails.recovery.hello": "هيلو {{user}}", + "emails.recovery.hello": "هيلو {{user}},", "emails.recovery.body": "ھن لنڪ تي عمل ڪريو پنھنجو {{project}} پاسورڊ ري سيٽ ڪرڻ لاءِ.", "emails.recovery.footer": "جيڪڏھن توھان نه پ پيو ھو پنھنجي پاسورڊ کي ري سيٽ ڪرڻ لاءِ ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.", - "emails.recovery.thanks": "مهرباني", + "emails.recovery.thanks": "مهرباني,", "emails.recovery.signature": "{{project}} ٽيم", "emails.invitation.subject": "%s ٽيم %s تيجي دعوت", - "emails.invitation.hello": "هيلو", + "emails.invitation.hello": "هيلو,", "emails.invitation.body": "ھي اي ميل توھان ڏانھن موڪليو ويو آھي {اڪاڻ ته {{owner}} توھان کي دعوت ڏيڻ چاھي ٿو ته توھان {{team}} ٽيم جو ميمبر بڻجي {{project}} تي.", "emails.invitation.footer": "جيڪڏھن توھان دلچسپي نٿا رکو ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.", - "emails.invitation.thanks": "مهرباني", + "emails.invitation.thanks": "مهرباني,", "emails.invitation.signature": "{{project}} ٽيم", "locale.country.unknown": "نامعلوم", "countries.af": "افغانستان", @@ -238,17 +238,17 @@ "emails.magicSession.clientInfo": "هي سائن ان درخواست ورتو {{agentClient}} استعمال ڪري ٿو {{agentDevice}} {{agentOs}}. جيڪڏهن توهان سائن ان جي درخواست ڪئي نه ورتي، ته توهان هن اي ميل کي محفوظ طور تي نظر انداز ڪري سگهو ٿا.", "emails.magicSession.securityPhrase": "اس ای میل جو سیکيورٽي جملو {{phrase}} آهي. جيڪڏهن هن جملو توهان جي سائن ان وقتي ڏيکاري واري جملي سان ميل آهي ته توهان اس ای میل تي اعتماد ڪري سگھو ٿا.", "emails.otpSession.subject": "پروجيڪٽ جي لاگ ان", - "emails.otpSession.hello": "ہيلو،", + "emails.otpSession.hello": "ہيلو,", "emails.otpSession.description": "جڏهن توهان کي محفوظ طريقي سان اپني {{project}} اڪائونٽ ۾ سائن ان ڪرڻ لاءِ ڪہي ويندي، ته هيٺيان دنل ويريفڪيشن ڪوڊ ڏيو. هي 15 منٽن ۾ ختم ٿي ويندي.", "emails.otpSession.clientInfo": "هي سائن ان توهان جو درخواست گهريو ويو آهي {{agentClient}} جي واپار ۾ {{agentDevice}} {{agentOs}} تي. جيڪڏهن توهان سائن ان جي درخواست ڪئي نه آهي، ته توهان هن ايميل کي نظر انداز ڪري سگهو ٿا.", "emails.otpSession.securityPhrase": "هن ای میل لاءِ سیکيورٽي جملو {{phrase}} آھي. توهان هن ای میل تي اعتماد ڪري سگهو ٿا جيڪڏهن هن جملو لاڳو ٿيندڙ جملي سان ميل کاندي.", - "emails.otpSession.thanks": "مهرباني", + "emails.otpSession.thanks": "مهرباني,", "emails.otpSession.signature": "پروجيڪٽ جي ٽيم", "emails.certificate.subject": "%s لاءِ سند جو ناکامی", - "emails.certificate.hello": "هيلو", + "emails.certificate.hello": "هيلو,", "emails.certificate.body": "توهان جي ڊومين '{{domain}}' لاءِ سرٽيفڪيٽ ٺاهڻ جو نه ٿي سگهيو. هي ڪوشش نمبر {{attempt}} آهي، ۽ ناڪامي جو سبب ٿيو: {{error}}", "emails.certificate.footer": "توهان جو اڳيون سرٽيفڪيٽ اولهو فئيلر جي ݙينهن کان ٣٠ ݙينهن لاءِ ماني ويندو. اسان ان جي چھان بني جي بھرپور خواهش ڪنداسين، نہ ته توهان جو ݙومين بغير ڪوري SSL ڪميونڪيشن آڻي ويندي.", - "emails.certificate.thanks": "شُكريا", + "emails.certificate.thanks": "شُكريا,", "emails.certificate.signature": "ٽيم", "sms.verification.body": "{{secret}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/si.json b/app/config/locale/translations/si.json index f1c4b7c86b..536e8d3604 100644 --- a/app/config/locale/translations/si.json +++ b/app/config/locale/translations/si.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s කණ්ඩායම", "emails.verification.subject": "ගිණුම් සත්‍යාපනය", - "emails.verification.hello": "හේයි {{user}}", + "emails.verification.hello": "හේයි {{user}},", "emails.verification.body": "ඔබගේ විද්‍යුත් තැපැල් ලිපිනය සත්‍යාපනය කිරීමට මෙම සම්බන්ධකය අනුගමනය කරන්න.", "emails.verification.footer": "මෙම ලිපිනය සත්‍යාපනය කරන ලෙස ඔබ ඉල්ලුවේ නැත්නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.", - "emails.verification.thanks": "ස්තුතියි", + "emails.verification.thanks": "ස්තුතියි,", "emails.verification.signature": "{{project}} කණ්ඩායම", "emails.magicSession.subject": "ප්‍රවේශ වන්න", - "emails.magicSession.hello": "හේයි", + "emails.magicSession.hello": "හේයි,", "emails.magicSession.body": "ප්‍රවේශ වීමට මෙම සම්බන්ධකය අනුගමනය කරන්න.", "emails.magicSession.footer": "මෙම විද්‍යුත් තැපෑල භාවිතයෙන් ප්‍රවේශ වීමට ඔබ ඉල්ලුවේ නැත්නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.", - "emails.magicSession.thanks": "ස්තුතියි", + "emails.magicSession.thanks": "ස්තුතියි,", "emails.magicSession.signature": "{{project}} කණ්ඩායම", "emails.recovery.subject": "මුරපද යළි පිහිටුවීම", - "emails.recovery.hello": "ආයුබෝවන් {{user}}", + "emails.recovery.hello": "ආයුබෝවන් {{user}},", "emails.recovery.body": "ඔබගේ {{project}} මුරපදය නැවත සැකසීමට මෙම සම්බන්ධකය අනුගමනය කරන්න.", "emails.recovery.footer": "ඔබගේ මුරපදය නැවත සකසන ලෙස ඔබ ඉල්ලුවේ නැත්නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.", - "emails.recovery.thanks": "ස්තුතියි", + "emails.recovery.thanks": "ස්තුතියි,", "emails.recovery.signature": "{{project}} කණ්ඩායම", "emails.invitation.subject": "%s කණ්ඩායමට ආරාධනා %s හි", - "emails.invitation.hello": "ආයුබෝවන්", + "emails.invitation.hello": "ආයුබෝවන්,", "emails.invitation.body": "මෙම තැපැල් ඔබට එව්වේ, {{owner}} හට {{project}} හි {{team}} කණ්ඩායමේ සාමාජිකයෙකු වීමට ඔබට ආරාධනා කිරීමට අවශ්‍ය වූ බැවිනි.", "emails.invitation.footer": "ඔබ උනන්දුවක් නොදක්වන්නේ නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.", - "emails.invitation.thanks": "ස්තුතියි", + "emails.invitation.thanks": "ස්තුතියි,", "emails.invitation.signature": "{{project}} කණ්ඩායම", "locale.country.unknown": "නොදන්නා", "countries.af": "ඇෆ්ගනිස්ථානය", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "මෙම ඊමේල්ට සඳහා ආරක්ෂක පාඨය {{phrase}}. පුරන්න විට පෙන්වන පාඨයට මෙම පාඨය ගැලපෙනවා නම්, ඔබට මෙම ඊමේල් විශ්වාස කළ හැකිය.", "emails.otpSession.thanks": "ස්තුතියි,", "emails.otpSession.signature": "{{project}} කණ්ඩායම" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sk.json b/app/config/locale/translations/sk.json index 457e756c9a..93c12c0881 100644 --- a/app/config/locale/translations/sk.json +++ b/app/config/locale/translations/sk.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Tím", "emails.verification.subject": "Overenie účtu", - "emails.verification.hello": "Ahoj {{user}}", + "emails.verification.hello": "Ahoj {{user}},", "emails.verification.body": "Použi tento link pre overenie svojej emailovej adresy.", "emails.verification.footer": "Ak si nepožiadal o overenie tejto adresy, môžeš túto správu ignorovať.", - "emails.verification.thanks": "Ďakujeme.", + "emails.verification.thanks": "Ďakujeme.,", "emails.verification.signature": "{{project}} tím", "emails.magicSession.subject": "Prihlásenie", - "emails.magicSession.hello": "Ahoj", + "emails.magicSession.hello": "Ahoj,", "emails.magicSession.body": "Použi tento link pre prihlásenie.", "emails.magicSession.footer": "Ak si nepožiadal o prihlásenie cez email, túto správu môžeš ignorovať.", - "emails.magicSession.thanks": "Ďakujeme", + "emails.magicSession.thanks": "Ďakujeme,", "emails.magicSession.signature": "{{project}} tím", "emails.recovery.subject": "Obnovenie hesla", - "emails.recovery.hello": "Ahoj {{user}}", + "emails.recovery.hello": "Ahoj {{user}},", "emails.recovery.body": "Použi tento link pre obnovenie svojho {{project}} hesla.", "emails.recovery.footer": "Ak si nepožiadal o obnovu svojho hesla, túto správu môžeš ignorovať.", - "emails.recovery.thanks": "Ďakujeme", + "emails.recovery.thanks": "Ďakujeme,", "emails.recovery.signature": "{{project}} tím", "emails.invitation.subject": "Pozvánka do %s Tímu v %s", - "emails.invitation.hello": "Ahoj", + "emails.invitation.hello": "Ahoj,", "emails.invitation.body": "Tento email ti bol zaslaný, pretože {{owner}} ťa pozval, aby si sa stal členom {{team}} tímu v projekte {{project}}.", "emails.invitation.footer": "Ak nemáš záujem, môžeš túto správu ignorovať.", - "emails.invitation.thanks": "Ďakujeme", + "emails.invitation.thanks": "Ďakujeme,", "emails.invitation.signature": "{{project}} tím", "locale.country.unknown": "Neznámy", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Bezpečnostná fráza pre tento e-mail je {{phrase}}. Tento e-mail môžete dôverovať, ak táto fráza zodpovedá fráze zobrazenej počas prihlasovania.", "emails.otpSession.thanks": "Ďakujem,", "emails.otpSession.signature": "tím {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sl.json b/app/config/locale/translations/sl.json index ec7b4c1ebf..f7c4f41255 100644 --- a/app/config/locale/translations/sl.json +++ b/app/config/locale/translations/sl.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Ekipa", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "Neznano", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Varnostni stavek za to e-pošto je {{phrase}}. Temu e-sporočilu lahko zaupate, če se ta stavek ujema s stavkom, ki je prikazan ob prijavi.", "emails.otpSession.thanks": "Hvala,", "emails.otpSession.signature": "ekipa {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sn.json b/app/config/locale/translations/sn.json index d8b2f2c682..d17a98ff42 100644 --- a/app/config/locale/translations/sn.json +++ b/app/config/locale/translations/sn.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Chikwata che%s", "emails.verification.subject": "Kuratidzi kuti ndiwe muridzi weakaundi", - "emails.verification.hello": "Hesi {{user}}", + "emails.verification.hello": "Hesi {{user}},", "emails.verification.body": "Tevedza chinongedzo ichi kuti uratidze kuti kero iyi ndeyako.", "emails.verification.footer": "Kana usina kukumbira kuti uratidze kuti kero iyi ndeyako, unogona kufuratira meseji iyi.", - "emails.verification.thanks": "Ndatenda", + "emails.verification.thanks": "Ndatenda,", "emails.verification.signature": "Chikwata che{{project}}", "emails.magicSession.subject": "Pinda", - "emails.magicSession.hello": "Hesi", + "emails.magicSession.hello": "Hesi,", "emails.magicSession.body": "Baya chinongedzo ichi kuti upinde muakaundi yako.", "emails.magicSession.footer": "Kana usina kukumbira kupinda muakaundi yako uchishandisa email iyi, unogona kufuratira meseji iyi.", - "emails.magicSession.thanks": "Ndatenda", + "emails.magicSession.thanks": "Ndatenda,", "emails.magicSession.signature": "Chikwata che{{project}}", "emails.recovery.subject": "Kuchinja pasiwedhi", - "emails.recovery.hello": "Mhoro {{user}}", + "emails.recovery.hello": "Mhoro {{user}},", "emails.recovery.body": "Baya chinongedzo ichi kuti uchinje pasiwedhi yako ye{{project}}.", "emails.recovery.footer": "Kana usina kukumbira kuchinja pasiwedhi yako, unogona kufuratira meseji iyi.", - "emails.recovery.thanks": "Ndatenda", + "emails.recovery.thanks": "Ndatenda,", "emails.recovery.signature": "Chikwata che{{project}}", "emails.invitation.subject": "Kukokwa kuchikwata che%s ku%s", - "emails.invitation.hello": "Mhoro", + "emails.invitation.hello": "Mhoro,", "emails.invitation.body": "Tsamba iyi yatumirwa kwauri nekuti {{owner}} anga achida kuti uve nhengo yechikwata che{{team}} pachirongwa che{{project}}.", "emails.invitation.footer": "Kana usiri kufarira kuve nhengo yechikwata ichi, unogona kufuratira meseji iyi.", - "emails.invitation.thanks": "Ndatenda", + "emails.invitation.thanks": "Ndatenda,", "emails.invitation.signature": "Chikwata che{{project}}", "locale.country.unknown": "Haizivikanwe", "countries.af": "Afuganisitani", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Chirevo chekuchengetedza cheemail iyi ndechekuti {{phrase}}. Unogona kuvimba neemail iyi kana chirevo ichi chichienderana nechirevo chakaratidzwa panguva yekupinda.", "emails.otpSession.thanks": "Ndatenda,", "emails.otpSession.signature": "chikwata {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sq.json b/app/config/locale/translations/sq.json index 0fb066a8ea..85aa6637f6 100644 --- a/app/config/locale/translations/sq.json +++ b/app/config/locale/translations/sq.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Grup %s", "emails.verification.subject": "", - "emails.verification.hello": "", + "emails.verification.hello": ",", "emails.verification.body": "", "emails.verification.footer": "", - "emails.verification.thanks": "", + "emails.verification.thanks": ",", "emails.verification.signature": "", "emails.magicSession.subject": "", - "emails.magicSession.hello": "", + "emails.magicSession.hello": ",", "emails.magicSession.body": "", "emails.magicSession.footer": "", - "emails.magicSession.thanks": "", + "emails.magicSession.thanks": ",", "emails.magicSession.signature": "", "emails.recovery.subject": "", - "emails.recovery.hello": "", + "emails.recovery.hello": ",", "emails.recovery.body": "", "emails.recovery.footer": "", - "emails.recovery.thanks": "", + "emails.recovery.thanks": ",", "emails.recovery.signature": "", "emails.invitation.subject": "", - "emails.invitation.hello": "", + "emails.invitation.hello": ",", "emails.invitation.body": "", "emails.invitation.footer": "", - "emails.invitation.thanks": "", + "emails.invitation.thanks": ",", "emails.invitation.signature": "", "locale.country.unknown": "I panjohur", "countries.af": "Afganistani", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Fjala e sigurisë për këtë email është {{phrase}}. Ju mund të besoni këtë email nëse kjo fjalë përputhet me fjalën që shfaqet gjatë kyçjes.", "emails.otpSession.thanks": "Faleminderit,", "emails.otpSession.signature": "ekipi i {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/sv.json b/app/config/locale/translations/sv.json index b838c05084..8997fd53f8 100644 --- a/app/config/locale/translations/sv.json +++ b/app/config/locale/translations/sv.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s-teamet", "emails.verification.subject": "Verifiera konto", - "emails.verification.hello": "Hej {{user}}", + "emails.verification.hello": "Hej {{user}},", "emails.verification.body": "Klicka på denna länk för att verifiera din email", "emails.verification.footer": "Om du inte bad om att verifiera den här e-postadressen kan du ignorera detta mail.", - "emails.verification.thanks": "Tack", + "emails.verification.thanks": "Tack,", "emails.verification.signature": "{{project}} teamet", "emails.magicSession.subject": "Logga in", - "emails.magicSession.hello": "Hej", + "emails.magicSession.hello": "Hej,", "emails.magicSession.body": "Klicka på denna länk för att logga in.", "emails.magicSession.footer": "Om du inte bad om att logga in med denna e-postadress kan du ignorera detta mail.", - "emails.magicSession.thanks": "Tack", + "emails.magicSession.thanks": "Tack,", "emails.magicSession.signature": "{{project}} teamet", "emails.recovery.subject": "Återställ lösenord", - "emails.recovery.hello": "Hej {{user}}", + "emails.recovery.hello": "Hej {{user}},", "emails.recovery.body": "Klicka på denna länk för att återställa lösenordet på {{project}}", "emails.recovery.footer": "Om du inte bad om att återställa ditt lösenord kan du ignorera detta mail.", - "emails.recovery.thanks": "Tack", + "emails.recovery.thanks": "Tack,", "emails.recovery.signature": "{{project}} teamet", "emails.invitation.subject": "Inbjudan till %s teamet på %s", - "emails.invitation.hello": "Hej", + "emails.invitation.hello": "Hej,", "emails.invitation.body": "Detta mail skickades till dig eftersom {{owner}} ville bjuda in dig att bli medlem i teamet {{team}} på {{project}}.", "emails.invitation.footer": "Om du inte är intresserad kan du ignorera detta mail.", - "emails.invitation.thanks": "Tack", + "emails.invitation.thanks": "Tack,", "emails.invitation.signature": "{{project}} teamet", "locale.country.unknown": "Okänt", "countries.af": "Afghanistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Säkerhetsfrasen för detta e-postmeddelande är {{phrase}}. Du kan lita på detta e-postmeddelande om frasen stämmer överens med frasen som visades vid inloggningen.", "emails.otpSession.thanks": "Tack,", "emails.otpSession.signature": "{{project}} team" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ta.json b/app/config/locale/translations/ta.json index 659306c977..f0695867a9 100644 --- a/app/config/locale/translations/ta.json +++ b/app/config/locale/translations/ta.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s குழு", "emails.verification.subject": "கணக்கு சரிபார்ப்பு", - "emails.verification.hello": "ஏய் {{user}}", + "emails.verification.hello": "ஏய் {{user}},", "emails.verification.body": "உங்கள் மின்னஞ்சல் முகவரியைச் சரிபார்க்க இந்த இணைப்பைப் பின்தொடரவும்.", "emails.verification.footer": "இந்த முகவரியைச் சரிபார்க்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.", - "emails.verification.thanks": "நன்றி", + "emails.verification.thanks": "நன்றி,", "emails.verification.signature": "{{project}} குழு ", "emails.magicSession.subject": "உள்நுழைய", - "emails.magicSession.hello": "ஏய்", + "emails.magicSession.hello": "ஏய்,", "emails.magicSession.body": "இந்த இணைப்பைப் பின்தொடரவும் உள்நுழைய", "emails.magicSession.footer": "இந்த மின்னஞ்சலைப் பயன்படுத்தி உள்நுழையுமாறு உங்களிடம் கேட்கப்படாவிட்டால், இந்தச் செய்தியைப் புறக்கணிக்கலாம்.", - "emails.magicSession.thanks": "நன்றி", + "emails.magicSession.thanks": "நன்றி,", "emails.magicSession.signature": "{{project}} குழு", "emails.recovery.subject": "கடவுச்சொல் மீட்டமைப்பு", - "emails.recovery.hello": "வணக்கம் {{user}}", + "emails.recovery.hello": "வணக்கம் {{user}},", "emails.recovery.body": "மீட்டமைக்க இந்த இணைப்பைப் பின்தொடரவும் {{project}} கடவுச்சொல்.", "emails.recovery.footer": "உங்கள் கடவுச்சொல்லை மீட்டமைக்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.", - "emails.recovery.thanks": "நன்றி", + "emails.recovery.thanks": "நன்றி,", "emails.recovery.signature": "{{project}} குழு", "emails.invitation.subject": "அழைப்பிதழ் %s குழு %s ", - "emails.invitation.hello": "வணக்கம்", + "emails.invitation.hello": "வணக்கம்,", "emails.invitation.body": "{{project}} இல் {{team}} குழுவில் உறுப்பினராக உங்களை {{owner}} அழைக்க விரும்புவதால், இந்த அஞ்சல் உங்களுக்கு அனுப்பப்பட்டது.", "emails.invitation.footer": "உங்களுக்கு ஆர்வம் இல்லை என்றால், இந்த செய்தியை நீங்கள் புறக்கணிக்கலாம்.", - "emails.invitation.thanks": "நன்றி", + "emails.invitation.thanks": "நன்றி,", "emails.invitation.signature": "{{project}} குழு", "locale.country.unknown": "அறியவில்லை", "countries.af": "ஆப்கானித்தான்", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "இந்த மின்னஞ்சலுக்கான பாதுகாப்பு வாசகம் {{phrase}} ஆகும். இந்த வாசகம் உள்நுழையும் போது காட்டப்பட்ட வாசகத்துடன் பொருந்துமானால், இந்த மின்னஞ்சலை நம்பலாம்.", "emails.otpSession.thanks": "நன்றி,", "emails.otpSession.signature": "{{project}} குழு" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/te.json b/app/config/locale/translations/te.json index 019b4581ca..870b0b82a2 100644 --- a/app/config/locale/translations/te.json +++ b/app/config/locale/translations/te.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s జట్టు", "emails.verification.subject": "ఖాతా ధృవీకరణ", - "emails.verification.hello": "నమస్కారము {{user}}", + "emails.verification.hello": "నమస్కారము {{user}},", "emails.verification.body": "ఈ లింక్ ద్వారా ఇమెయిల్ ని ధృవీకరించండి", "emails.verification.footer": "మీరు ఈ చిరునామాను ధృవీకరించమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు", - "emails.verification.thanks": "ధన్యవాదాలు", + "emails.verification.thanks": "ధన్యవాదాలు,", "emails.verification.signature": "{{project}} జట్", "emails.magicSession.subject": "లాగిన్", - "emails.magicSession.hello": "నమస్కారము", + "emails.magicSession.hello": "నమస్కారము,", "emails.magicSession.body": "లాగిన్ చేయడానికి ఈ లింక్ ని అనుసరించండి", "emails.magicSession.footer": "మీరు ఈ ఇమెయిల్ ని ఉపయోగించి లాగిన్ చేయమని అడగకపోతే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు", - "emails.magicSession.thanks": "ధన్యవాదాలు", + "emails.magicSession.thanks": "ధన్యవాదాలు,", "emails.magicSession.signature": "{{project}} జట్", "emails.recovery.subject": "పాస్వర్డ్ రీసెట్", - "emails.recovery.hello": "నమస్కారమ {{user}}", + "emails.recovery.hello": "నమస్కారమ {{user}},", "emails.recovery.body": "మీ {{project}} పాస్వర్డ్ ని రీసెట్ చేయడానికి ఈ లింక్ ని అనుసరించండి", "emails.recovery.footer": "మీరు మీ పాస్వర్డ్ ని రీసెట్ చేయమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు", - "emails.recovery.thanks": "ధన్యవాదాల", + "emails.recovery.thanks": "ధన్యవాదాల,", "emails.recovery.signature": "{{project}} జట్", "emails.invitation.subject": "%s వద్ద %s బృందానికి ఆహ్వానం", - "emails.invitation.hello": "నమస్కారమ", + "emails.invitation.hello": "నమస్కారమ,", "emails.invitation.body": "{{owner}} మిమ్మల్ని {{project}} లో {{team}} బృందంలో సభ్యునిగా ఉండమని ఆహ్వానించాలనుకుంటున్నందున ఈ మెయిల్ మీకు పంపబడింది.", "emails.invitation.footer": "మీకు ఆసక్తి లేకుంటే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు.", - "emails.invitation.thanks": "ధన్యవాదాల", + "emails.invitation.thanks": "ధన్యవాదాల,", "emails.invitation.signature": "{{project}} జట్", "locale.country.unknown": "తెలియని", "countries.af": "ఆఫ్ఘనిస్తాన్", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "ఈ ఇమెయిల్‌కు భద్రతా పదం {{phrase}}. మీరు సైన్ ఇన్ సమయంలో చూపించబడిన పదంతో ఈ పదం సరిపోలుస్తుంటే ఈ ఇమెయిల్‌ను నమ్మవచ్చు.", "emails.otpSession.thanks": "ధన్యవాదాలు,", "emails.otpSession.signature": "ప్రాజెక్టు బృందం" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/th.json b/app/config/locale/translations/th.json index 97d224de1f..5a53b16055 100644 --- a/app/config/locale/translations/th.json +++ b/app/config/locale/translations/th.json @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "วลีรักษาความปลอดภัยสำหรับอีเมลนี้คือ {{phrase}} คุณสามารถเชื่อถืออีเมลนี้ได้หากวลีนี้ตรงกับวลีที่แสดงในระหว่างการเข้าสู่ระบบ", "emails.magicSession.optionUrl": "หากคุณไม่สามารถเข้าสู่ระบบโดยใช้ปุ่มด้านบน โปรดเยี่ยมชมลิงก์ต่อไปนี้:", "emails.otpSession.subject": "การเข้าสู่ระบบ {{project}}", - "emails.otpSession.hello": "สวัสดี,", + "emails.otpSession.hello": "สวัสดี", "emails.otpSession.description": "ป้อนรหัสยืนยันต่อไปนี้เมื่อได้รับการสั่งให้ทำเพื่อลงชื่อเข้าใช้บัญชี {{project}} ของคุณอย่างปลอดภัย รหัสนี้จะหมดอายุใน 15 นาที.", "emails.otpSession.clientInfo": "การลงชื่อเข้าใช้งานนี้ได้รับการทำผ่าน {{agentClient}} บน {{agentDevice}} {{agentOs}} หากคุณไม่ได้ทำการขอลงชื่อเข้าใช้นี้ คุณสามารถเพิกเฉยต่ออีเมลนี้ได้เลย", "emails.otpSession.securityPhrase": "วลีความปลอดภัยสำหรับอีเมลนี้คือ {{phrase}} คุณสามารถเชื่อถืออีเมลนี้ได้หากวลีนี้ตรงกับวลีที่แสดงขณะลงชื่อเข้าใช้งาน.", "emails.otpSession.thanks": "ขอบคุณครับ/ค่ะ", "emails.otpSession.signature": "ทีม {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/tl.json b/app/config/locale/translations/tl.json index e6df9f8aef..6d0be01095 100644 --- a/app/config/locale/translations/tl.json +++ b/app/config/locale/translations/tl.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Pangkat ng %s", "emails.verification.subject": "Pagpapatunay ng account", - "emails.verification.hello": "Kamusta {{user}}", + "emails.verification.hello": "Kamusta {{user}},", "emails.verification.body": "Sundin ang link na ito upang ma-verify ang iyong email address.", "emails.verification.footer": "Kung hindi mo hiningi na i-verify ang address na ito, maaari mong balewalain ang mensahe na ito.", - "emails.verification.thanks": "Salamat", + "emails.verification.thanks": "Salamat,", "emails.verification.signature": "Pangkat ng {{project}}", "emails.magicSession.subject": "Mag log in", - "emails.magicSession.hello": "Kamusta ", + "emails.magicSession.hello": "Kamusta ,", "emails.magicSession.body": "Sundin ang link na ito upang mag-login.", "emails.magicSession.footer": "Kung hindi mo hiningi na mag-login gamit ang email na ito, maaari mong balewalain ang mensahe na ito.", - "emails.magicSession.thanks": "Salamat", + "emails.magicSession.thanks": "Salamat,", "emails.magicSession.signature": "Pangkat ng {{project}}", "emails.recovery.subject": "I-reset ang password", - "emails.recovery.hello": "Kamusta {{user}}", + "emails.recovery.hello": "Kamusta {{user}},", "emails.recovery.body": "Sundin ang link na ito upang i-reset ang password ng iyong {{project}}.", "emails.recovery.footer": "Kung hindi mo hiningi na i-reset ang iyong password, maaari mong balewalain ang mensahe na ito.", - "emails.recovery.thanks": "Salamat", + "emails.recovery.thanks": "Salamat,", "emails.recovery.signature": "Pangkat ng {{project}}", "emails.invitation.subject": "Imbitasyon para sa Pangkat %s sa %s", - "emails.invitation.hello": "Kamusta", + "emails.invitation.hello": "Kamusta,", "emails.invitation.body": "Ipinadala sa iyo ang mail na ito dahil gusto kang imbitahan ni {{owner}} na maging miyembro ng Pangkat {{team}} sa ilalim ng proyektong {{project}}.", "emails.invitation.footer": "Kung ikaw ay hindi interesado, maaari mong balewalain ang mensaheng ito.", - "emails.invitation.thanks": "Salamat", + "emails.invitation.thanks": "Salamat,", "emails.invitation.signature": "Pangkat ng {{project}}", "locale.country.unknown": "Hindi kilala", "countries.af": "Apganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Ang security phrase para sa email na ito ay {{phrase}}. Maaari mong pagkatiwalaan ang email na ito kung ang phrase na ito ay tugma sa phrase na ipinakita noong nag-sign in.", "emails.otpSession.thanks": "Salamat,", "emails.otpSession.signature": "team ng {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/tr.json b/app/config/locale/translations/tr.json index 808a20576c..115050c2e2 100644 --- a/app/config/locale/translations/tr.json +++ b/app/config/locale/translations/tr.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s Takımı", "emails.verification.subject": "Hesabını Doğrula", - "emails.verification.hello": "Merhaba {{user}}", + "emails.verification.hello": "Merhaba {{user}},", "emails.verification.body": "Eposta adresini doğrulamak için bu bağlantıyı kullanın.", "emails.verification.footer": "Eğer bu eposta adresini doğrulamak isteyen siz değilseniz devam etmeyin.", - "emails.verification.thanks": "Teşekkürler", + "emails.verification.thanks": "Teşekkürler,", "emails.verification.signature": "{{project}} takımı", "emails.magicSession.subject": "Giriş", - "emails.magicSession.hello": "Merhaba", + "emails.magicSession.hello": "Merhaba,", "emails.magicSession.body": "Giriş yapmak için tıklayın.", "emails.magicSession.footer": "Eğer bu eposta adresini kullanarak giriş yapmak istemediyseniz devam etmeyin.", - "emails.magicSession.thanks": "Teşekkürler", + "emails.magicSession.thanks": "Teşekkürler,", "emails.magicSession.signature": "{{project}} takımı", "emails.recovery.subject": "Şifremi Sıfırla", - "emails.recovery.hello": "Merhaba {{user}}", + "emails.recovery.hello": "Merhaba {{user}},", "emails.recovery.body": "{{project}} şifrenizi sıfırlamak için bu bağlantıyı kullanın.", "emails.recovery.footer": "Eğer şifre sıfırlama talebinde bulunmadıysanız devam etmeyin.", - "emails.recovery.thanks": "Teşekkürler", + "emails.recovery.thanks": "Teşekkürler,", "emails.recovery.signature": "{{project}} takımı", "emails.invitation.subject": "%s üzerinde %s Takımına Davet", - "emails.invitation.hello": "Merhaba", + "emails.invitation.hello": "Merhaba,", "emails.invitation.body": "Bu epostayı aldınız, çünkü {{owner}} sizi {{project}} üzerinde {{team}} takımının üyesi olmaya davet etti.", "emails.invitation.footer": "Eğer ilgilenmiyorsanız devam etmeyin.", - "emails.invitation.thanks": "Teşekkürler", + "emails.invitation.thanks": "Teşekkürler,", "emails.invitation.signature": "{{project}} takımı", "locale.country.unknown": "Bilinmeyen", "countries.af": "Afganistan", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Bu e-postanın güvenlik ifadesi {{phrase}}. Giriş sırasında gösterilen ifade ile bu ifade eşleşiyorsa bu e-postaya güvenebilirsiniz.", "emails.otpSession.thanks": "Teşekkürler,", "emails.otpSession.signature": "{{project}} takımı" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/uk.json b/app/config/locale/translations/uk.json index 78e3a6c556..3f66bd1c58 100644 --- a/app/config/locale/translations/uk.json +++ b/app/config/locale/translations/uk.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "Команда %s", "emails.verification.subject": "Верифікація акаунта", - "emails.verification.hello": "Вітаємо, {{user}}", + "emails.verification.hello": "Вітаємо, {{user}},", "emails.verification.body": "Перейдіть за цим посиланням, щоб підтвердити свою електронну адресу.", "emails.verification.footer": "Якщо ви не запитували підтвердження цієї адреси, ви можете ігнорувати це повідомлення.", - "emails.verification.thanks": "Дякуємо", + "emails.verification.thanks": "Дякуємо,", "emails.verification.signature": "команда {{project}}", "emails.magicSession.subject": "Логін", - "emails.magicSession.hello": "Вітаємо", + "emails.magicSession.hello": "Вітаємо,", "emails.magicSession.body": "Перейдіть за цим посиланням, щоб увійти.", "emails.magicSession.footer": "Якщо ви не просили увійти за допомогою цієї електронної пошти, ви можете ігнорувати це повідомлення.", - "emails.magicSession.thanks": "Дякуємо", + "emails.magicSession.thanks": "Дякуємо,", "emails.magicSession.signature": "команда {{project}}", "emails.recovery.subject": "Скидання пароля", - "emails.recovery.hello": "Вітаємо, {{user}}", + "emails.recovery.hello": "Вітаємо, {{user}},", "emails.recovery.body": "Перейдіть за цим посиланням для того щоб скинути свій пароль для проекту {{project}}", "emails.recovery.footer": "Якщо ви не запитували скидання паролю, проігноруйте це повідомлення.", - "emails.recovery.thanks": "Дякуємо", + "emails.recovery.thanks": "Дякуємо,", "emails.recovery.signature": "команда {{project}}", "emails.invitation.subject": "Запрошення до %s Команди у %s", - "emails.invitation.hello": "Вітаємо", + "emails.invitation.hello": "Вітаємо,", "emails.invitation.body": "Цей лист був надісланий вам тому що {{owner}} запрошує вас стати членом команди {{team}} у проекті {{project}}.", "emails.invitation.footer": "Якщо ви не зацікавлені, проігноруйте це повідомлення.", - "emails.invitation.thanks": "Дякуємо", + "emails.invitation.thanks": "Дякуємо,", "emails.invitation.signature": "команда {{project}}", "locale.country.unknown": "Невідомо", "countries.af": "Афганістан", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "Фраза безпеки для цього електронного листа - {{phrase}}. Ви можете довіряти цьому електронному листу, якщо ця фраза відповідає фразі, показаній під час входу в систему.", "emails.otpSession.thanks": "Дякую,", "emails.otpSession.signature": "команда {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/ur.json b/app/config/locale/translations/ur.json index 060cea0736..9d6aa47762 100644 --- a/app/config/locale/translations/ur.json +++ b/app/config/locale/translations/ur.json @@ -4,28 +4,28 @@ "settings.direction": "rtl", "emails.sender": "%s ٹیم", "emails.verification.subject": "اکاؤنٹ کی تصدیق", - "emails.verification.hello": "خوش آمدید {{user}}", + "emails.verification.hello": "خوش آمدید {{user}}،", "emails.verification.body": "براہ کرم اپنے ای میل کی تصدیق کے لیے درج ذیل لنک پر عمل کریں۔", "emails.verification.footer": "اگر آپ نے اس پتے کی تصدیق کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔", - "emails.verification.thanks": "شکریہ", + "emails.verification.thanks": "شکریہ،", "emails.verification.signature": "ٹیم۔ {{project}}", "emails.magicSession.subject": "اگ ان کریں", - "emails.magicSession.hello": "خوش آمدید", + "emails.magicSession.hello": "خوش آمدید،", "emails.magicSession.body": "لاگ ان کرنے کے لیے اس لنک پر عمل کریں۔", "emails.magicSession.footer": "اگر آپ نے اس ای میل کا استعمال کرتے ہوئے لاگ ان کرنے کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔", - "emails.magicSession.thanks": "شکریہ", + "emails.magicSession.thanks": "شکریہ،", "emails.magicSession.signature": "ٹیم۔ {{project}}", "emails.recovery.subject": "پاس ورڈ ری سیٹ۔", - "emails.recovery.hello": "ہیلو {{user}}", + "emails.recovery.hello": "ہیلو {{user}}،", "emails.recovery.body": "{{project}} کا پاس ورڈ تبدیل کرنے کے لیے درج ذیل لنک پر عمل کریں", "emails.recovery.footer": "اگر آپ نے اپنا پاس ورڈ دوبارہ ترتیب دینے کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔", - "emails.recovery.thanks": "شکریہ", + "emails.recovery.thanks": "شکریہ،", "emails.recovery.signature": "ٹیم۔ {{project}}", "emails.invitation.subject": "%s پر %s ٹیم کو دعوت", - "emails.invitation.hello": "خوش آمدید", + "emails.invitation.hello": "خوش آمدید،", "emails.invitation.body": "یہ پیغام آپ کو اس لیے بھیجا گیا تھا کہ {{owner}} نے آپ کو {{project}} میں {{team}} ٹیم کا رکن بننے کی دعوت بھیجی", "emails.invitation.footer": "اگر آپ دلچسپی نہیں رکھتے تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔", - "emails.invitation.thanks": "شکریہ", + "emails.invitation.thanks": "شکریہ،", "emails.invitation.signature": "ٹیم۔ {{project}", "locale.country.unknown": "نامعلوم", "countries.af": "افغانستان", @@ -245,4 +245,4 @@ "emails.otpSession.securityPhrase": "اس ایمیل کے لئے حفاظتی جملہ {{phrase}} ہے۔ اگر یہ جملہ سائن ان کے دوران دکھائے گئے جملے سے میل کھاتا ہے تو آپ اس ایمیل پر بھروسہ کر سکتے ہیں۔", "emails.otpSession.thanks": "شکریہ،", "emails.otpSession.signature": "ٹیم {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/vi.json b/app/config/locale/translations/vi.json index cf04a5b737..76a545a1d4 100644 --- a/app/config/locale/translations/vi.json +++ b/app/config/locale/translations/vi.json @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "Cụm từ bảo mật cho email này là {{phrase}}. Bạn có thể tin tưởng email này nếu cụm từ này khớp với cụm từ hiển thị khi đăng nhập.", "emails.magicSession.optionUrl": "Nếu bạn không thể đăng nhập bằng cách sử dụng nút ở trên, vui lòng truy cập liên kết sau:", "emails.otpSession.subject": "Đăng nhập {{project}}", - "emails.otpSession.hello": "Xin chào,", + "emails.otpSession.hello": "Xin chào", "emails.otpSession.description": "Nhập mã xác minh sau đây khi được yêu cầu để đăng nhập an toàn vào tài khoản {{project}} của bạn. Mã này sẽ hết hạn trong 15 phút.", "emails.otpSession.clientInfo": "Đăng nhập này được yêu cầu sử dụng {{agentClient}} trên {{agentDevice}} {{agentOs}}. Nếu bạn không yêu cầu đăng nhập, bạn có thể bỏ qua email này một cách an toàn.", "emails.otpSession.securityPhrase": "Cụm từ bảo mật cho email này là {{phrase}}. Bạn có thể tin tưởng email này nếu cụm từ này khớp với cụm từ hiển thị khi đăng nhập.", - "emails.otpSession.thanks": "Cảm ơn,", + "emails.otpSession.thanks": "Cảm ơn", "emails.otpSession.signature": "nhóm {{project}}" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/zh-cn.json b/app/config/locale/translations/zh-cn.json index 0bfbc54e0e..5e35a89bfe 100644 --- a/app/config/locale/translations/zh-cn.json +++ b/app/config/locale/translations/zh-cn.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s 小组", "emails.verification.subject": "帐户验证", - "emails.verification.hello": "你好 {{user}}", + "emails.verification.hello": "你好 {{user}}、", "emails.verification.body": "点此链接验证您的电子邮件地址。", "emails.verification.footer": "如果您没有要求验证此地址,则可忽略此消息。", - "emails.verification.thanks": "谢谢", + "emails.verification.thanks": "谢谢、", "emails.verification.signature": "{{project}} 团队", "emails.magicSession.subject": "登录", - "emails.magicSession.hello": "你好", + "emails.magicSession.hello": "你好、", "emails.magicSession.body": "点此链接登录。", "emails.magicSession.footer": "如果您没有要求使用此电子邮件登录,则可忽略此消息。", - "emails.magicSession.thanks": "谢谢", + "emails.magicSession.thanks": "谢谢、", "emails.magicSession.signature": "{{project}} 团队", "emails.recovery.subject": "重设密码", - "emails.recovery.hello": "你好 {{user}}", + "emails.recovery.hello": "你好 {{user}}、", "emails.recovery.body": "点此链接重置您的 {{project}} 密码。", "emails.recovery.footer": "如果您没有要求重置密码,则可以忽略此消息。", - "emails.recovery.thanks": "谢谢", + "emails.recovery.thanks": "谢谢、", "emails.recovery.signature": "{{project}} 团队", "emails.invitation.subject": "邀请 %s 团队在 %s", - "emails.invitation.hello": "你好", + "emails.invitation.hello": "你好、", "emails.invitation.body": "这封邮件发送给您是因为 {{owner}} 想邀请您成为 {{team}} 团队在 {{project}}.", "emails.invitation.footer": "如果您不感兴趣,可以忽略此消息。", - "emails.invitation.thanks": "谢谢", + "emails.invitation.thanks": "谢谢、", "emails.invitation.signature": "{{project}} 团队", "locale.country.unknown": "未知", "countries.af": "阿富汗", @@ -239,10 +239,10 @@ "emails.magicSession.securityPhrase": "此电子邮件的安全短语是{{phrase}}。如果此短语与登录时显示的短语相匹配,则您可以信任此电子邮件。", "emails.magicSession.optionUrl": "如果您无法使用上面的按钮登录,请访问以下链接:", "emails.otpSession.subject": "{{project}} 登录", - "emails.otpSession.hello": "你好,\n", + "emails.otpSession.hello": "你好,\n、", "emails.otpSession.description": "在提示时输入以下验证码以安全登录您的{{project}}账户。该验证码将在15分钟后过期。", "emails.otpSession.clientInfo": "此次登录是通过{{agentClient}}在{{agentDevice}} {{agentOs}}上请求的。如果您没有请求登录,可以放心忽略此电子邮件。", "emails.otpSession.securityPhrase": "此电子邮件的安全短语是{{phrase}}。如果此短语与登录时显示的短语一致,您可以信任此邮件。", - "emails.otpSession.thanks": "谢谢,", + "emails.otpSession.thanks": "谢谢,、", "emails.otpSession.signature": "{{project}} 团队" -} \ No newline at end of file +} diff --git a/app/config/locale/translations/zh-tw.json b/app/config/locale/translations/zh-tw.json index 24729de6b3..146dd0a401 100644 --- a/app/config/locale/translations/zh-tw.json +++ b/app/config/locale/translations/zh-tw.json @@ -4,28 +4,28 @@ "settings.direction": "ltr", "emails.sender": "%s 小組", "emails.verification.subject": "帳戶驗證", - "emails.verification.hello": "嗨 {{user}}", + "emails.verification.hello": "嗨 {{user}}、", "emails.verification.body": "按照此連結驗證您的電子郵件地址。", "emails.verification.footer": "如果您沒有要求驗證此地址,則可以忽略此消息。", - "emails.verification.thanks": "謝謝", + "emails.verification.thanks": "謝謝、", "emails.verification.signature": "{{project}} 團隊", "emails.magicSession.subject": "登入", - "emails.magicSession.hello": "嗨", + "emails.magicSession.hello": "嗨、", "emails.magicSession.body": "點此連結登入。", "emails.magicSession.footer": "如果您沒有要求使用此電子郵件登入,則可以忽略此消息。", - "emails.magicSession.thanks": "謝謝", + "emails.magicSession.thanks": "謝謝、", "emails.magicSession.signature": "{{project}} 團隊", "emails.recovery.subject": "重設密碼", - "emails.recovery.hello": "您好 {{user}}", + "emails.recovery.hello": "您好 {{user}}、", "emails.recovery.body": "按照此連結重置您的 {{project}} 密碼。", "emails.recovery.footer": "如果您沒有要求重置密碼,則可以忽略此消息。", - "emails.recovery.thanks": "謝謝", + "emails.recovery.thanks": "謝謝、", "emails.recovery.signature": "{{project}} 團隊", "emails.invitation.subject": "邀請 %s 團隊在 %s", - "emails.invitation.hello": "您好", + "emails.invitation.hello": "您好、", "emails.invitation.body": "發送這封郵件給您是因為 {{owner}} 想邀請您成為 {{team}} 團隊在 {{project}}。", "emails.invitation.footer": "如果您不感興趣,可以忽略此消息。", - "emails.invitation.thanks": "謝謝", + "emails.invitation.thanks": "謝謝、", "emails.invitation.signature": "{{project}} 團隊", "locale.country.unknown": "未知", "countries.af": "阿富汗", @@ -239,10 +239,10 @@ "sms.verification.body": "{{secret}}", "emails.magicSession.securityPhrase": "這封電子郵件的安全密語是{{phrase}}。如果此密語與登入時顯示的密語相符,您就可以信任此郵件。", "emails.otpSession.subject": "{{project}} 登入", - "emails.otpSession.hello": "你好,", + "emails.otpSession.hello": "你好,、", "emails.otpSession.description": "在提示时輸入以下驗證碼以安全地登入您的{{project}}帳戶。該驗證碼將在15分鐘後過期。", "emails.otpSession.clientInfo": "這次的登入是使用{{agentClient}}在{{agentDevice}} {{agentOs}}上請求的。如果您沒有請求這次的登入,您可以放心地忽略這封電子郵件。", "emails.otpSession.securityPhrase": "這封電子郵件的安全口令是{{phrase}}。如果這個口令與登入時顯示的口令相匹配,您可以信任這封電子郵件。", - "emails.otpSession.thanks": "謝謝,", + "emails.otpSession.thanks": "謝謝,、", "emails.otpSession.signature": "{{project}} 團隊" -} \ No newline at end of file +} diff --git a/app/config/runtimes/specifications.php b/app/config/runtimes/specifications.php index d3625db8a2..68880f4d4e 100644 --- a/app/config/runtimes/specifications.php +++ b/app/config/runtimes/specifications.php @@ -6,7 +6,7 @@ return [ Specification::S_05VCPU_512MB => [ 'slug' => Specification::S_05VCPU_512MB, 'memory' => 512, - 'cpus' => 0.5 + 'cpus' => 1 // TODO: revert this, it's a temporary change to test function performance. ], Specification::S_1VCPU_512MB => [ 'slug' => Specification::S_1VCPU_512MB, diff --git a/app/config/specs/open-api3-1.6.x-client.json b/app/config/specs/open-api3-1.6.x-client.json index c00d4e2d07..e3cd909b4e 100644 --- a/app/config/specs/open-api3-1.6.x-client.json +++ b/app/config/specs/open-api3-1.6.x-client.json @@ -4945,7 +4945,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -5033,7 +5033,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -5150,7 +5150,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -5226,7 +5226,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -5280,7 +5280,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -5766,7 +5766,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -5851,7 +5851,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -5928,7 +5928,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -6016,7 +6016,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -6116,7 +6116,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -6190,7 +6190,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -6281,7 +6281,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -6350,7 +6350,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -6419,7 +6419,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -6637,7 +6637,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -6713,7 +6713,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -6791,7 +6791,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -6878,7 +6878,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -6942,7 +6942,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -7018,7 +7018,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -7069,7 +7069,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -7084,7 +7084,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -7172,7 +7172,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -7270,7 +7270,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -7285,7 +7285,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -7359,7 +7359,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -7448,7 +7448,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -7524,7 +7524,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -7624,7 +7624,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -7687,7 +7687,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -9266,12 +9266,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -9301,7 +9301,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -9826,7 +9826,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -9848,6 +9848,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -9857,7 +9862,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/open-api3-1.6.x-console.json b/app/config/specs/open-api3-1.6.x-console.json index 87c61ada7b..369fea741a 100644 --- a/app/config/specs/open-api3-1.6.x-console.json +++ b/app/config/specs/open-api3-1.6.x-console.json @@ -4465,7 +4465,7 @@ }, "x-appwrite": { "method": "chat", - "weight": 332, + "weight": 333, "cookies": false, "type": "", "deprecated": false, @@ -4534,7 +4534,7 @@ }, "x-appwrite": { "method": "variables", - "weight": 331, + "weight": 332, "cookies": false, "type": "", "deprecated": false, @@ -7477,7 +7477,7 @@ "size": { "type": "integer", "description": "Maximum size of the string attribute.", - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -9308,7 +9308,7 @@ }, "x-appwrite": { "method": "list", - "weight": 288, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -9383,7 +9383,7 @@ }, "x-appwrite": { "method": "create", - "weight": 287, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -9487,7 +9487,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9630,7 +9631,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 289, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -9681,7 +9682,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 290, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -9733,7 +9734,7 @@ }, "x-appwrite": { "method": "listTemplates", - "weight": 313, + "weight": 314, "cookies": false, "type": "", "deprecated": false, @@ -9835,7 +9836,7 @@ }, "x-appwrite": { "method": "getTemplate", - "weight": 314, + "weight": 315, "cookies": false, "type": "", "deprecated": false, @@ -9897,7 +9898,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 293, + "weight": 294, "cookies": false, "type": "", "deprecated": false, @@ -9971,7 +9972,7 @@ }, "x-appwrite": { "method": "get", - "weight": 291, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -10032,7 +10033,7 @@ }, "x-appwrite": { "method": "update", - "weight": 294, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -10143,7 +10144,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -10256,7 +10258,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 297, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -10319,7 +10321,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 299, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -10404,7 +10406,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 298, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -10502,7 +10504,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 300, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -10573,7 +10575,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 296, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -10637,7 +10639,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 301, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -10703,7 +10705,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 302, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -10790,7 +10792,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 303, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -10856,7 +10858,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 295, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -10931,7 +10933,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -11019,7 +11021,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -11136,7 +11138,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -11203,7 +11205,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 307, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -11276,7 +11278,7 @@ }, "x-appwrite": { "method": "getFunctionUsage", - "weight": 292, + "weight": 293, "cookies": false, "type": "", "deprecated": false, @@ -11360,7 +11362,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 309, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -11421,7 +11423,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 308, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -11509,7 +11511,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 310, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -11580,7 +11582,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 311, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -11668,7 +11670,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 312, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -11741,7 +11743,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -11795,7 +11797,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -13671,7 +13673,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 389, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -13749,7 +13751,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 386, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -13895,7 +13897,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 393, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -14043,7 +14045,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 388, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -14200,7 +14202,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 395, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -14359,7 +14361,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 387, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -14470,7 +14472,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 394, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -14584,7 +14586,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 392, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -14639,7 +14641,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 396, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -14703,7 +14705,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 390, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -14780,7 +14782,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 391, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -14857,7 +14859,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 361, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -14935,7 +14937,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 360, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -15042,7 +15044,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 373, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -15152,7 +15154,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 359, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -15239,7 +15241,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 372, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -15329,7 +15331,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 351, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -15446,7 +15448,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 364, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -15566,7 +15568,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 354, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -15663,7 +15665,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 367, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -15763,7 +15765,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 352, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -15870,7 +15872,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 365, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -15980,7 +15982,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 353, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -16125,7 +16127,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 366, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -16272,7 +16274,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 355, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -16369,7 +16371,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 368, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -16469,7 +16471,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 356, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -16566,7 +16568,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 369, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -16666,7 +16668,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 357, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -16763,7 +16765,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 370, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -16863,7 +16865,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 358, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -16960,7 +16962,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 371, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -17060,7 +17062,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 363, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -17115,7 +17117,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 374, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -17179,7 +17181,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 362, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -17256,7 +17258,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 383, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -17333,7 +17335,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 376, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -17409,7 +17411,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 375, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -17494,7 +17496,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 378, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -17556,7 +17558,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 379, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -17635,7 +17637,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 380, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -17699,7 +17701,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 377, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -17776,7 +17778,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 382, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -17862,7 +17864,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -17954,7 +17956,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 384, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -18019,7 +18021,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -18096,7 +18098,7 @@ }, "x-appwrite": { "method": "list", - "weight": 338, + "weight": 339, "cookies": false, "type": "", "deprecated": false, @@ -18125,7 +18127,7 @@ "parameters": [ { "name": "queries", - "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, resources, statusCounters, resourceData, errors", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, statusCounters, resourceData, errors", "required": false, "schema": { "type": "array", @@ -18172,7 +18174,7 @@ }, "x-appwrite": { "method": "createAppwriteMigration", - "weight": 333, + "weight": 334, "cookies": false, "type": "", "deprecated": false, @@ -18262,7 +18264,7 @@ }, "x-appwrite": { "method": "getAppwriteReport", - "weight": 340, + "weight": 341, "cookies": false, "type": "", "deprecated": false, @@ -18357,7 +18359,7 @@ }, "x-appwrite": { "method": "createFirebaseMigration", - "weight": 335, + "weight": 336, "cookies": false, "type": "", "deprecated": false, @@ -18428,7 +18430,7 @@ }, "x-appwrite": { "method": "deleteFirebaseAuth", - "weight": 346, + "weight": 347, "cookies": false, "type": "", "deprecated": false, @@ -18478,7 +18480,7 @@ }, "x-appwrite": { "method": "createFirebaseOAuthMigration", - "weight": 334, + "weight": 335, "cookies": false, "type": "", "deprecated": false, @@ -18556,7 +18558,7 @@ }, "x-appwrite": { "method": "listFirebaseProjects", - "weight": 345, + "weight": 346, "cookies": false, "type": "", "deprecated": false, @@ -18606,7 +18608,7 @@ }, "x-appwrite": { "method": "getFirebaseReport", - "weight": 341, + "weight": 342, "cookies": false, "type": "", "deprecated": false, @@ -18680,7 +18682,7 @@ }, "x-appwrite": { "method": "getFirebaseReportOAuth", - "weight": 342, + "weight": 343, "cookies": false, "type": "", "deprecated": false, @@ -18754,7 +18756,7 @@ }, "x-appwrite": { "method": "createNHostMigration", - "weight": 337, + "weight": 338, "cookies": false, "type": "", "deprecated": false, @@ -18867,7 +18869,7 @@ }, "x-appwrite": { "method": "getNHostReport", - "weight": 348, + "weight": 349, "cookies": false, "type": "", "deprecated": false, @@ -19002,7 +19004,7 @@ }, "x-appwrite": { "method": "createSupabaseMigration", - "weight": 336, + "weight": 337, "cookies": false, "type": "", "deprecated": false, @@ -19109,7 +19111,7 @@ }, "x-appwrite": { "method": "getSupabaseReport", - "weight": 347, + "weight": 348, "cookies": false, "type": "", "deprecated": false, @@ -19235,7 +19237,7 @@ }, "x-appwrite": { "method": "get", - "weight": 339, + "weight": 340, "cookies": false, "type": "", "deprecated": false, @@ -19295,7 +19297,7 @@ }, "x-appwrite": { "method": "retry", - "weight": 349, + "weight": 350, "cookies": false, "type": "", "deprecated": false, @@ -19348,7 +19350,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 350, + "weight": 351, "cookies": false, "type": "", "deprecated": false, @@ -19410,7 +19412,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 195, + "weight": 196, "cookies": false, "type": "", "deprecated": false, @@ -19500,7 +19502,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 197, + "weight": 198, "cookies": false, "type": "", "deprecated": false, @@ -19548,7 +19550,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 196, + "weight": 197, "cookies": false, "type": "", "deprecated": false, @@ -19623,7 +19625,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 198, + "weight": 199, "cookies": false, "type": "", "deprecated": false, @@ -19683,7 +19685,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 199, + "weight": 200, "cookies": false, "type": "", "deprecated": false, @@ -19760,7 +19762,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 200, + "weight": 201, "cookies": false, "type": "", "deprecated": false, @@ -20210,7 +20212,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 169, + "weight": 170, "cookies": false, "type": "", "deprecated": false, @@ -20447,7 +20449,7 @@ }, "x-appwrite": { "method": "updateAuthDuration", - "weight": 162, + "weight": 163, "cookies": false, "type": "", "deprecated": false, @@ -20528,7 +20530,7 @@ }, "x-appwrite": { "method": "updateAuthLimit", - "weight": 161, + "weight": 162, "cookies": false, "type": "", "deprecated": false, @@ -20609,7 +20611,7 @@ }, "x-appwrite": { "method": "updateAuthSessionsLimit", - "weight": 167, + "weight": 168, "cookies": false, "type": "", "deprecated": false, @@ -20668,6 +20670,99 @@ } } }, + "\/projects\/{projectId}\/auth\/memberships-privacy": { + "patch": { + "summary": "Update project memberships privacy attributes", + "operationId": "projectsUpdateMembershipsPrivacy", + "tags": [ + "projects" + ], + "description": "", + "responses": { + "200": { + "description": "Project", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/project" + } + } + } + } + }, + "x-appwrite": { + "method": "updateMembershipsPrivacy", + "weight": 161, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "projects\/update-memberships-privacy.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "projects.write", + "platforms": [ + "console" + ], + "packaging": false, + "offline-model": "", + "offline-key": "", + "offline-response-key": "$id", + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [] + } + ], + "parameters": [ + { + "name": "projectId", + "description": "Project unique ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "userName": { + "type": "boolean", + "description": "Set to true to show userName to members of a team.", + "x-example": false + }, + "userEmail": { + "type": "boolean", + "description": "Set to true to show email to members of a team.", + "x-example": false + }, + "mfa": { + "type": "boolean", + "description": "Set to true to show mfa to members of a team.", + "x-example": false + } + }, + "required": [ + "userName", + "userEmail", + "mfa" + ] + } + } + } + } + } + }, "\/projects\/{projectId}\/auth\/mock-numbers": { "patch": { "summary": "Update the mock numbers for the project", @@ -20690,7 +20785,7 @@ }, "x-appwrite": { "method": "updateMockNumbers", - "weight": 168, + "weight": 169, "cookies": false, "type": "", "deprecated": false, @@ -20774,7 +20869,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordDictionary", - "weight": 165, + "weight": 166, "cookies": false, "type": "", "deprecated": false, @@ -20855,7 +20950,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordHistory", - "weight": 164, + "weight": 165, "cookies": false, "type": "", "deprecated": false, @@ -20936,7 +21031,7 @@ }, "x-appwrite": { "method": "updatePersonalDataCheck", - "weight": 166, + "weight": 167, "cookies": false, "type": "", "deprecated": false, @@ -21098,7 +21193,7 @@ }, "x-appwrite": { "method": "updateAuthStatus", - "weight": 163, + "weight": 164, "cookies": false, "type": "", "deprecated": false, @@ -21200,7 +21295,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 181, + "weight": 182, "cookies": false, "type": "", "deprecated": false, @@ -21289,7 +21384,7 @@ }, "x-appwrite": { "method": "listKeys", - "weight": 177, + "weight": 178, "cookies": false, "type": "", "deprecated": false, @@ -21349,7 +21444,7 @@ }, "x-appwrite": { "method": "createKey", - "weight": 176, + "weight": 177, "cookies": false, "type": "", "deprecated": false, @@ -21444,7 +21539,7 @@ }, "x-appwrite": { "method": "getKey", - "weight": 178, + "weight": 179, "cookies": false, "type": "", "deprecated": false, @@ -21514,7 +21609,7 @@ }, "x-appwrite": { "method": "updateKey", - "weight": 179, + "weight": 180, "cookies": false, "type": "", "deprecated": false, @@ -21610,7 +21705,7 @@ }, "x-appwrite": { "method": "deleteKey", - "weight": 180, + "weight": 181, "cookies": false, "type": "", "deprecated": false, @@ -21821,7 +21916,7 @@ }, "x-appwrite": { "method": "listPlatforms", - "weight": 183, + "weight": 184, "cookies": false, "type": "", "deprecated": false, @@ -21881,7 +21976,7 @@ }, "x-appwrite": { "method": "createPlatform", - "weight": 182, + "weight": 183, "cookies": false, "type": "", "deprecated": false, @@ -22002,7 +22097,7 @@ }, "x-appwrite": { "method": "getPlatform", - "weight": 184, + "weight": 185, "cookies": false, "type": "", "deprecated": false, @@ -22072,7 +22167,7 @@ }, "x-appwrite": { "method": "updatePlatform", - "weight": 185, + "weight": 186, "cookies": false, "type": "", "deprecated": false, @@ -22169,7 +22264,7 @@ }, "x-appwrite": { "method": "deletePlatform", - "weight": 186, + "weight": 187, "cookies": false, "type": "", "deprecated": false, @@ -22424,7 +22519,7 @@ }, "x-appwrite": { "method": "updateSmtp", - "weight": 187, + "weight": 188, "cookies": false, "type": "", "deprecated": false, @@ -22544,7 +22639,7 @@ }, "x-appwrite": { "method": "createSmtpTest", - "weight": 188, + "weight": 189, "cookies": false, "type": "", "deprecated": false, @@ -22758,7 +22853,7 @@ }, "x-appwrite": { "method": "getEmailTemplate", - "weight": 190, + "weight": 191, "cookies": false, "type": "", "deprecated": false, @@ -22984,7 +23079,7 @@ }, "x-appwrite": { "method": "updateEmailTemplate", - "weight": 192, + "weight": 193, "cookies": false, "type": "", "deprecated": false, @@ -23250,7 +23345,7 @@ }, "x-appwrite": { "method": "deleteEmailTemplate", - "weight": 194, + "weight": 195, "cookies": false, "type": "", "deprecated": false, @@ -23478,7 +23573,7 @@ }, "x-appwrite": { "method": "getSmsTemplate", - "weight": 189, + "weight": 190, "cookies": false, "type": "", "deprecated": false, @@ -23701,7 +23796,7 @@ }, "x-appwrite": { "method": "updateSmsTemplate", - "weight": 191, + "weight": 192, "cookies": false, "type": "", "deprecated": false, @@ -23943,7 +24038,7 @@ }, "x-appwrite": { "method": "deleteSmsTemplate", - "weight": 193, + "weight": 194, "cookies": false, "type": "", "deprecated": false, @@ -24168,7 +24263,7 @@ }, "x-appwrite": { "method": "listWebhooks", - "weight": 171, + "weight": 172, "cookies": false, "type": "", "deprecated": false, @@ -24228,7 +24323,7 @@ }, "x-appwrite": { "method": "createWebhook", - "weight": 170, + "weight": 171, "cookies": false, "type": "", "deprecated": false, @@ -24345,7 +24440,7 @@ }, "x-appwrite": { "method": "getWebhook", - "weight": 172, + "weight": 173, "cookies": false, "type": "", "deprecated": false, @@ -24415,7 +24510,7 @@ }, "x-appwrite": { "method": "updateWebhook", - "weight": 173, + "weight": 174, "cookies": false, "type": "", "deprecated": false, @@ -24533,7 +24628,7 @@ }, "x-appwrite": { "method": "deleteWebhook", - "weight": 175, + "weight": 176, "cookies": false, "type": "", "deprecated": false, @@ -24605,7 +24700,7 @@ }, "x-appwrite": { "method": "updateWebhookSignature", - "weight": 174, + "weight": 175, "cookies": false, "type": "", "deprecated": false, @@ -24677,7 +24772,7 @@ }, "x-appwrite": { "method": "listRules", - "weight": 316, + "weight": 317, "cookies": false, "type": "", "deprecated": false, @@ -24751,7 +24846,7 @@ }, "x-appwrite": { "method": "createRule", - "weight": 315, + "weight": 316, "cookies": false, "type": "", "deprecated": false, @@ -24837,7 +24932,7 @@ }, "x-appwrite": { "method": "getRule", - "weight": 317, + "weight": 318, "cookies": false, "type": "", "deprecated": false, @@ -24890,7 +24985,7 @@ }, "x-appwrite": { "method": "deleteRule", - "weight": 318, + "weight": 319, "cookies": false, "type": "", "deprecated": false, @@ -24952,7 +25047,7 @@ }, "x-appwrite": { "method": "updateRuleVerification", - "weight": 319, + "weight": 320, "cookies": false, "type": "", "deprecated": false, @@ -25014,7 +25109,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 202, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -25089,7 +25184,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 201, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -25218,7 +25313,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 203, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -25279,7 +25374,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 204, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -25405,7 +25500,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 205, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -25468,7 +25563,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -25556,7 +25651,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -25656,7 +25751,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -25730,7 +25825,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -25821,7 +25916,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -25890,7 +25985,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -25959,7 +26054,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -26177,7 +26272,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -26253,7 +26348,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 215, + "weight": 216, "cookies": false, "type": "", "deprecated": false, @@ -26327,7 +26422,7 @@ }, "x-appwrite": { "method": "getBucketUsage", - "weight": 216, + "weight": 217, "cookies": false, "type": "", "deprecated": false, @@ -26411,7 +26506,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -26489,7 +26584,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -26576,7 +26671,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -26640,7 +26735,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -26716,7 +26811,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -26782,7 +26877,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 230, + "weight": 231, "cookies": false, "type": "", "deprecated": false, @@ -26842,7 +26937,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -26857,7 +26952,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -26945,7 +27040,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -27043,7 +27138,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -27058,7 +27153,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -27132,7 +27227,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -27221,7 +27316,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -27297,7 +27392,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -27396,7 +27491,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -27458,7 +27553,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -27541,7 +27636,7 @@ }, "x-appwrite": { "method": "list", - "weight": 240, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -27616,7 +27711,7 @@ }, "x-appwrite": { "method": "create", - "weight": 231, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -27706,7 +27801,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 234, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -27793,7 +27888,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 232, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -27880,7 +27975,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 248, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -27950,7 +28045,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 271, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -28013,7 +28108,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 233, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -28100,7 +28195,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 236, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -28187,7 +28282,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 237, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -28304,7 +28399,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 238, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -28409,7 +28504,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 235, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -28516,7 +28611,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 273, + "weight": 274, "cookies": false, "type": "", "deprecated": false, @@ -28590,7 +28685,7 @@ }, "x-appwrite": { "method": "get", - "weight": 241, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -28644,7 +28739,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 269, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -28707,7 +28802,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 254, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -28789,7 +28884,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 272, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -28873,7 +28968,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 250, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -28958,7 +29053,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 246, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -29034,7 +29129,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 245, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -29097,7 +29192,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 259, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -29179,7 +29274,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 264, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -29257,7 +29352,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 260, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -29320,7 +29415,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 261, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -29381,7 +29476,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 263, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -29442,7 +29537,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 262, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -29505,7 +29600,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 252, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -29587,7 +29682,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 253, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -29669,7 +29764,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 255, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -29751,7 +29846,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 242, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -29812,7 +29907,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 257, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -29894,7 +29989,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 244, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -29955,7 +30050,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 265, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -30009,7 +30104,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 268, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -30065,7 +30160,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 267, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -30138,7 +30233,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 249, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -30220,7 +30315,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 247, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -30295,7 +30390,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 239, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -30407,7 +30502,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 243, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -30479,7 +30574,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 258, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -30570,7 +30665,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 270, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -30644,7 +30739,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 266, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -30728,7 +30823,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 256, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -30810,7 +30905,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 251, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -30892,7 +30987,7 @@ }, "x-appwrite": { "method": "listRepositories", - "weight": 278, + "weight": 279, "cookies": false, "type": "", "deprecated": false, @@ -30963,7 +31058,7 @@ }, "x-appwrite": { "method": "createRepository", - "weight": 279, + "weight": 280, "cookies": false, "type": "", "deprecated": false, @@ -31050,7 +31145,7 @@ }, "x-appwrite": { "method": "getRepository", - "weight": 280, + "weight": 281, "cookies": false, "type": "", "deprecated": false, @@ -31122,7 +31217,7 @@ }, "x-appwrite": { "method": "listRepositoryBranches", - "weight": 281, + "weight": 282, "cookies": false, "type": "", "deprecated": false, @@ -31194,7 +31289,7 @@ }, "x-appwrite": { "method": "getRepositoryContents", - "weight": 276, + "weight": 277, "cookies": false, "type": "", "deprecated": false, @@ -31277,7 +31372,7 @@ }, "x-appwrite": { "method": "createRepositoryDetection", - "weight": 277, + "weight": 278, "cookies": false, "type": "", "deprecated": false, @@ -31358,7 +31453,7 @@ }, "x-appwrite": { "method": "updateExternalDeployments", - "weight": 286, + "weight": 287, "cookies": false, "type": "", "deprecated": false, @@ -31449,7 +31544,7 @@ }, "x-appwrite": { "method": "listInstallations", - "weight": 283, + "weight": 284, "cookies": false, "type": "", "deprecated": false, @@ -31525,7 +31620,7 @@ }, "x-appwrite": { "method": "getInstallation", - "weight": 284, + "weight": 285, "cookies": false, "type": "", "deprecated": false, @@ -31578,7 +31673,7 @@ }, "x-appwrite": { "method": "deleteInstallation", - "weight": 285, + "weight": 286, "cookies": false, "type": "", "deprecated": false, @@ -34866,12 +34961,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -34901,7 +34996,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -35066,7 +35161,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -35982,6 +36077,21 @@ "description": "Whether or not to send session alert emails to users.", "x-example": true }, + "authMembershipsUserName": { + "type": "boolean", + "description": "Whether or not to show user names in the teams membership response.", + "x-example": true + }, + "authMembershipsUserEmail": { + "type": "boolean", + "description": "Whether or not to show user emails in the teams membership response.", + "x-example": true + }, + "authMembershipsMfa": { + "type": "boolean", + "description": "Whether or not to show user MFA status in the teams membership response.", + "x-example": true + }, "oAuthProviders": { "type": "array", "description": "List of Auth Providers.", @@ -36187,6 +36297,9 @@ "authPersonalDataCheck", "authMockNumbers", "authSessionAlerts", + "authMembershipsUserName", + "authMembershipsUserEmail", + "authMembershipsMfa", "oAuthProviders", "platforms", "webhooks", @@ -37765,7 +37878,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -38403,7 +38516,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -38425,6 +38538,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -38434,7 +38552,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] }, "migration": { @@ -38471,9 +38590,14 @@ "description": "A string containing the type of source of the migration.", "x-example": "Appwrite" }, + "destination": { + "type": "string", + "description": "A string containing the type of destination of the migration.", + "x-example": "Appwrite" + }, "resources": { "type": "array", - "description": "Resources to migration.", + "description": "Resources to migrate.", "items": { "type": "string" }, @@ -38507,6 +38631,7 @@ "status", "stage", "source", + "destination", "resources", "statusCounters", "resourceData", diff --git a/app/config/specs/open-api3-1.6.x-server.json b/app/config/specs/open-api3-1.6.x-server.json index 44270f16af..e84b751743 100644 --- a/app/config/specs/open-api3-1.6.x-server.json +++ b/app/config/specs/open-api3-1.6.x-server.json @@ -6997,7 +6997,7 @@ "size": { "type": "integer", "description": "Maximum size of the string attribute.", - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -8414,7 +8414,7 @@ }, "x-appwrite": { "method": "list", - "weight": 288, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -8490,7 +8490,7 @@ }, "x-appwrite": { "method": "create", - "weight": 287, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -8595,7 +8595,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -8738,7 +8739,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 289, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -8790,7 +8791,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 290, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -8843,7 +8844,7 @@ }, "x-appwrite": { "method": "get", - "weight": 291, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -8905,7 +8906,7 @@ }, "x-appwrite": { "method": "update", - "weight": 294, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -9017,7 +9018,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9130,7 +9132,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 297, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -9194,7 +9196,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 299, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -9280,7 +9282,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 298, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -9379,7 +9381,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 300, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -9451,7 +9453,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 296, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -9516,7 +9518,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 301, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -9583,7 +9585,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 302, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -9671,7 +9673,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 303, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -9738,7 +9740,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 295, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -9814,7 +9816,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -9904,7 +9906,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -10023,7 +10025,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -10092,7 +10094,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 307, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -10166,7 +10168,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 309, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -10228,7 +10230,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 308, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -10317,7 +10319,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 310, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -10389,7 +10391,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 311, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -10478,7 +10480,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 312, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -10552,7 +10554,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -10608,7 +10610,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -12525,7 +12527,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 389, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -12604,7 +12606,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 386, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -12751,7 +12753,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 393, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -12900,7 +12902,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 388, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -13058,7 +13060,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 395, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -13218,7 +13220,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 387, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -13330,7 +13332,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 394, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -13445,7 +13447,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 392, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -13501,7 +13503,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 396, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -13566,7 +13568,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 390, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -13644,7 +13646,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 391, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -13722,7 +13724,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 361, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -13801,7 +13803,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 360, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -13909,7 +13911,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 373, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -14020,7 +14022,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 359, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -14108,7 +14110,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 372, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -14199,7 +14201,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 351, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -14317,7 +14319,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 364, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -14438,7 +14440,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 354, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -14536,7 +14538,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 367, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -14637,7 +14639,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 352, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -14745,7 +14747,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 365, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -14856,7 +14858,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 353, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -15002,7 +15004,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 366, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -15150,7 +15152,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 355, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -15248,7 +15250,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 368, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -15349,7 +15351,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 356, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -15447,7 +15449,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 369, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -15548,7 +15550,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 357, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -15646,7 +15648,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 370, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -15747,7 +15749,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 358, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -15845,7 +15847,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 371, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -15946,7 +15948,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 363, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -16002,7 +16004,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 374, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -16067,7 +16069,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 362, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -16145,7 +16147,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 383, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -16223,7 +16225,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 376, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -16300,7 +16302,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 375, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -16386,7 +16388,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 378, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -16449,7 +16451,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 379, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -16529,7 +16531,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 380, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -16594,7 +16596,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 377, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -16672,7 +16674,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 382, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -16759,7 +16761,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -16853,7 +16855,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 384, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -16919,7 +16921,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -16998,7 +17000,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 202, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -17074,7 +17076,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 201, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -17204,7 +17206,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 203, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -17266,7 +17268,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 204, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -17393,7 +17395,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 205, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -17457,7 +17459,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -17547,7 +17549,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -17649,7 +17651,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -17725,7 +17727,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -17818,7 +17820,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -17889,7 +17891,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -17960,7 +17962,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -18180,7 +18182,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -18258,7 +18260,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -18338,7 +18340,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -18427,7 +18429,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -18493,7 +18495,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -18571,7 +18573,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -18624,7 +18626,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -18639,7 +18641,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -18729,7 +18731,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -18829,7 +18831,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -18844,7 +18846,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -18920,7 +18922,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -19011,7 +19013,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -19089,7 +19091,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -19190,7 +19192,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -19254,7 +19256,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -19339,7 +19341,7 @@ }, "x-appwrite": { "method": "list", - "weight": 240, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -19415,7 +19417,7 @@ }, "x-appwrite": { "method": "create", - "weight": 231, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -19506,7 +19508,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 234, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -19594,7 +19596,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 232, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -19682,7 +19684,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 248, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -19753,7 +19755,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 271, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -19817,7 +19819,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 233, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -19905,7 +19907,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 236, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -19993,7 +19995,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 237, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -20111,7 +20113,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 238, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -20217,7 +20219,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 235, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -20325,7 +20327,7 @@ }, "x-appwrite": { "method": "get", - "weight": 241, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -20380,7 +20382,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 269, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -20444,7 +20446,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 254, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -20527,7 +20529,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 272, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -20612,7 +20614,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 250, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -20698,7 +20700,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 246, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -20775,7 +20777,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 245, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -20839,7 +20841,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 259, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -20922,7 +20924,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 264, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -21001,7 +21003,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 260, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -21065,7 +21067,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 261, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -21127,7 +21129,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 263, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -21189,7 +21191,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 262, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -21253,7 +21255,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 252, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -21336,7 +21338,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 253, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -21419,7 +21421,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 255, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -21502,7 +21504,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 242, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -21564,7 +21566,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 257, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -21647,7 +21649,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 244, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -21709,7 +21711,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 265, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -21764,7 +21766,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 268, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -21821,7 +21823,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 267, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -21895,7 +21897,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 249, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -21978,7 +21980,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 247, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -22054,7 +22056,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 239, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -22167,7 +22169,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 243, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -22240,7 +22242,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 258, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -22332,7 +22334,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 270, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -22407,7 +22409,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 266, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -22492,7 +22494,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 256, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -22575,7 +22577,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 251, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -25596,12 +25598,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -25631,7 +25633,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -25796,7 +25798,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -26608,7 +26610,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -27056,7 +27058,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -27078,6 +27080,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -27087,7 +27094,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index 021ae27c45..e3cd909b4e 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -43,7 +43,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -94,7 +94,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -166,7 +166,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -181,7 +181,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -259,7 +259,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -320,7 +320,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -385,7 +385,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -436,7 +436,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -504,7 +504,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -576,7 +576,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -644,7 +644,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -724,7 +724,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -794,7 +794,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -870,7 +870,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -948,7 +948,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1001,7 +1001,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1052,7 +1052,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1103,7 +1103,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1156,7 +1156,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1228,7 +1228,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1305,7 +1305,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1383,7 +1383,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1434,7 +1434,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1506,7 +1506,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1570,7 +1570,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1585,7 +1585,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1669,7 +1669,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1713,7 +1713,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1766,7 +1766,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1802,7 +1802,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1817,7 +1817,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -1893,7 +1893,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -1954,7 +1954,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\r\n\r\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\n\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "301": { "description": "File" @@ -1962,7 +1962,7 @@ }, "x-appwrite": { "method": "createOAuth2Session", - "weight": 18, + "weight": 19, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2105,7 +2105,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2181,7 +2181,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2257,7 +2257,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2320,7 +2320,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2376,7 +2376,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2441,7 +2441,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2494,7 +2494,7 @@ }, "x-appwrite": { "method": "createPushTarget", - "weight": 53, + "weight": 54, "cookies": false, "type": "", "deprecated": false, @@ -2575,7 +2575,7 @@ }, "x-appwrite": { "method": "updatePushTarget", - "weight": 54, + "weight": 55, "cookies": false, "type": "", "deprecated": false, @@ -2655,7 +2655,7 @@ }, "x-appwrite": { "method": "deletePushTarget", - "weight": 55, + "weight": 56, "cookies": false, "type": "", "deprecated": false, @@ -2703,7 +2703,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2718,7 +2718,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2784,7 +2784,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2799,7 +2799,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -2873,7 +2873,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "File" @@ -2881,7 +2881,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -3009,7 +3009,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -3024,7 +3024,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -3088,7 +3088,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -3103,7 +3103,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -3173,7 +3173,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -3251,7 +3251,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -3305,7 +3305,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3368,7 +3368,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image" @@ -3376,7 +3376,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3496,7 +3496,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3504,7 +3504,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3628,7 +3628,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -3636,7 +3636,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3688,7 +3688,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3696,7 +3696,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -4178,7 +4178,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -4186,7 +4186,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -4262,7 +4262,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -4270,7 +4270,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4356,7 +4356,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image" @@ -4364,7 +4364,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4465,7 +4465,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -4552,7 +4552,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -4661,7 +4661,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -4758,7 +4758,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -4859,7 +4859,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -4945,7 +4945,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -5033,7 +5033,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -5084,7 +5084,7 @@ "body": { "type": "string", "description": "HTTP body of execution. Default value is empty string.", - "x-example": null + "x-example": "" }, "async": { "type": "boolean", @@ -5150,7 +5150,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -5226,7 +5226,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -5280,7 +5280,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -5319,7 +5319,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -5334,7 +5334,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -5388,7 +5388,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -5442,7 +5442,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -5496,7 +5496,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -5550,7 +5550,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -5604,7 +5604,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -5658,7 +5658,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -5712,7 +5712,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -5766,7 +5766,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -5851,7 +5851,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -5928,7 +5928,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -6001,7 +6001,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -6016,7 +6016,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -6116,7 +6116,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -6190,7 +6190,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -6281,7 +6281,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -6350,7 +6350,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -6419,7 +6419,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -6637,7 +6637,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -6713,7 +6713,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -6791,7 +6791,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -6878,7 +6878,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -6942,7 +6942,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -7018,7 +7018,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -7069,7 +7069,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -7084,7 +7084,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -7157,7 +7157,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -7172,7 +7172,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -7270,7 +7270,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -7285,7 +7285,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -7344,7 +7344,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -7359,7 +7359,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -7448,7 +7448,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -7509,7 +7509,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -7524,7 +7524,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -7624,7 +7624,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -7687,7 +7687,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -9266,12 +9266,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -9301,7 +9301,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -9826,7 +9826,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -9848,6 +9848,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -9857,7 +9862,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 04e7c76e13..4e97fecc30 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -43,7 +43,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -93,7 +93,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -171,7 +171,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 9, + "weight": 10, "cookies": false, "type": "", "deprecated": false, @@ -206,7 +206,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -221,7 +221,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -298,7 +298,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -358,7 +358,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -422,7 +422,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -473,7 +473,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -540,7 +540,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -611,7 +611,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -678,7 +678,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -757,7 +757,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -826,7 +826,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -902,7 +902,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -979,7 +979,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1031,7 +1031,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1081,7 +1081,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1131,7 +1131,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1183,7 +1183,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1254,7 +1254,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1330,7 +1330,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1407,7 +1407,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1457,7 +1457,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1528,7 +1528,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1591,7 +1591,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1606,7 +1606,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1689,7 +1689,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1732,7 +1732,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1784,7 +1784,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1820,7 +1820,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1835,7 +1835,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -1911,7 +1911,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -1972,7 +1972,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\r\n\r\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\n\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "301": { "description": "File" @@ -1980,7 +1980,7 @@ }, "x-appwrite": { "method": "createOAuth2Session", - "weight": 18, + "weight": 19, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2123,7 +2123,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2199,7 +2199,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2275,7 +2275,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2337,7 +2337,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2392,7 +2392,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2456,7 +2456,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2508,7 +2508,7 @@ }, "x-appwrite": { "method": "createPushTarget", - "weight": 53, + "weight": 54, "cookies": false, "type": "", "deprecated": false, @@ -2588,7 +2588,7 @@ }, "x-appwrite": { "method": "updatePushTarget", - "weight": 54, + "weight": 55, "cookies": false, "type": "", "deprecated": false, @@ -2667,7 +2667,7 @@ }, "x-appwrite": { "method": "deletePushTarget", - "weight": 55, + "weight": 56, "cookies": false, "type": "", "deprecated": false, @@ -2714,7 +2714,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2729,7 +2729,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2795,7 +2795,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2810,7 +2810,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -2884,7 +2884,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "File" @@ -2892,7 +2892,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -3020,7 +3020,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -3035,7 +3035,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -3099,7 +3099,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -3114,7 +3114,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -3183,7 +3183,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -3260,7 +3260,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -3313,7 +3313,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3375,7 +3375,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image" @@ -3383,7 +3383,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3503,7 +3503,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3511,7 +3511,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3635,7 +3635,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -3643,7 +3643,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3695,7 +3695,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3703,7 +3703,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -4185,7 +4185,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -4193,7 +4193,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -4269,7 +4269,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -4277,7 +4277,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4363,7 +4363,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image" @@ -4371,7 +4371,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4465,7 +4465,7 @@ }, "x-appwrite": { "method": "chat", - "weight": 331, + "weight": 333, "cookies": false, "type": "", "deprecated": false, @@ -4534,7 +4534,7 @@ }, "x-appwrite": { "method": "variables", - "weight": 330, + "weight": 332, "cookies": false, "type": "", "deprecated": false, @@ -4584,7 +4584,7 @@ }, "x-appwrite": { "method": "list", - "weight": 69, + "weight": 70, "cookies": false, "type": "", "deprecated": false, @@ -4644,7 +4644,7 @@ "tags": [ "databases" ], - "description": "Create a new Database.\r\n", + "description": "Create a new Database.\n", "responses": { "201": { "description": "Database", @@ -4659,7 +4659,7 @@ }, "x-appwrite": { "method": "create", - "weight": 68, + "weight": 69, "cookies": false, "type": "", "deprecated": false, @@ -4740,7 +4740,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 113, + "weight": 114, "cookies": false, "type": "", "deprecated": false, @@ -4814,7 +4814,7 @@ }, "x-appwrite": { "method": "get", - "weight": 70, + "weight": 71, "cookies": false, "type": "", "deprecated": false, @@ -4875,7 +4875,7 @@ }, "x-appwrite": { "method": "update", - "weight": 72, + "weight": 73, "cookies": false, "type": "", "deprecated": false, @@ -4953,7 +4953,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 73, + "weight": 74, "cookies": false, "type": "", "deprecated": false, @@ -5016,7 +5016,7 @@ }, "x-appwrite": { "method": "listCollections", - "weight": 75, + "weight": 76, "cookies": false, "type": "", "deprecated": false, @@ -5101,7 +5101,7 @@ }, "x-appwrite": { "method": "createCollection", - "weight": 74, + "weight": 75, "cookies": false, "type": "", "deprecated": false, @@ -5207,7 +5207,7 @@ }, "x-appwrite": { "method": "getCollection", - "weight": 76, + "weight": 77, "cookies": false, "type": "", "deprecated": false, @@ -5278,7 +5278,7 @@ }, "x-appwrite": { "method": "updateCollection", - "weight": 78, + "weight": 79, "cookies": false, "type": "", "deprecated": false, @@ -5379,7 +5379,7 @@ }, "x-appwrite": { "method": "deleteCollection", - "weight": 79, + "weight": 80, "cookies": false, "type": "", "deprecated": false, @@ -5452,7 +5452,7 @@ }, "x-appwrite": { "method": "listAttributes", - "weight": 90, + "weight": 91, "cookies": false, "type": "", "deprecated": false, @@ -5523,7 +5523,7 @@ "tags": [ "databases" ], - "description": "Create a boolean attribute.\r\n", + "description": "Create a boolean attribute.\n", "responses": { "202": { "description": "AttributeBoolean", @@ -5538,7 +5538,7 @@ }, "x-appwrite": { "method": "createBooleanAttribute", - "weight": 87, + "weight": 88, "cookies": false, "type": "", "deprecated": false, @@ -5646,7 +5646,7 @@ }, "x-appwrite": { "method": "updateBooleanAttribute", - "weight": 99, + "weight": 100, "cookies": false, "type": "", "deprecated": false, @@ -5759,7 +5759,7 @@ }, "x-appwrite": { "method": "createDatetimeAttribute", - "weight": 88, + "weight": 89, "cookies": false, "type": "", "deprecated": false, @@ -5867,7 +5867,7 @@ }, "x-appwrite": { "method": "updateDatetimeAttribute", - "weight": 100, + "weight": 101, "cookies": false, "type": "", "deprecated": false, @@ -5965,7 +5965,7 @@ "tags": [ "databases" ], - "description": "Create an email attribute.\r\n", + "description": "Create an email attribute.\n", "responses": { "202": { "description": "AttributeEmail", @@ -5980,7 +5980,7 @@ }, "x-appwrite": { "method": "createEmailAttribute", - "weight": 81, + "weight": 82, "cookies": false, "type": "", "deprecated": false, @@ -6073,7 +6073,7 @@ "tags": [ "databases" ], - "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEmail", @@ -6088,7 +6088,7 @@ }, "x-appwrite": { "method": "updateEmailAttribute", - "weight": 93, + "weight": 94, "cookies": false, "type": "", "deprecated": false, @@ -6186,7 +6186,7 @@ "tags": [ "databases" ], - "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \r\n", + "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \n", "responses": { "202": { "description": "AttributeEnum", @@ -6201,7 +6201,7 @@ }, "x-appwrite": { "method": "createEnumAttribute", - "weight": 82, + "weight": 83, "cookies": false, "type": "", "deprecated": false, @@ -6303,7 +6303,7 @@ "tags": [ "databases" ], - "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEnum", @@ -6318,7 +6318,7 @@ }, "x-appwrite": { "method": "updateEnumAttribute", - "weight": 94, + "weight": 95, "cookies": false, "type": "", "deprecated": false, @@ -6425,7 +6425,7 @@ "tags": [ "databases" ], - "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeFloat", @@ -6440,7 +6440,7 @@ }, "x-appwrite": { "method": "createFloatAttribute", - "weight": 86, + "weight": 87, "cookies": false, "type": "", "deprecated": false, @@ -6543,7 +6543,7 @@ "tags": [ "databases" ], - "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeFloat", @@ -6558,7 +6558,7 @@ }, "x-appwrite": { "method": "updateFloatAttribute", - "weight": 98, + "weight": 99, "cookies": false, "type": "", "deprecated": false, @@ -6668,7 +6668,7 @@ "tags": [ "databases" ], - "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeInteger", @@ -6683,7 +6683,7 @@ }, "x-appwrite": { "method": "createIntegerAttribute", - "weight": 85, + "weight": 86, "cookies": false, "type": "", "deprecated": false, @@ -6786,7 +6786,7 @@ "tags": [ "databases" ], - "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeInteger", @@ -6801,7 +6801,7 @@ }, "x-appwrite": { "method": "updateIntegerAttribute", - "weight": 97, + "weight": 98, "cookies": false, "type": "", "deprecated": false, @@ -6911,7 +6911,7 @@ "tags": [ "databases" ], - "description": "Create IP address attribute.\r\n", + "description": "Create IP address attribute.\n", "responses": { "202": { "description": "AttributeIP", @@ -6926,7 +6926,7 @@ }, "x-appwrite": { "method": "createIpAttribute", - "weight": 83, + "weight": 84, "cookies": false, "type": "", "deprecated": false, @@ -7019,7 +7019,7 @@ "tags": [ "databases" ], - "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeIP", @@ -7034,7 +7034,7 @@ }, "x-appwrite": { "method": "updateIpAttribute", - "weight": 95, + "weight": 96, "cookies": false, "type": "", "deprecated": false, @@ -7132,7 +7132,7 @@ "tags": [ "databases" ], - "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "202": { "description": "AttributeRelationship", @@ -7147,7 +7147,7 @@ }, "x-appwrite": { "method": "createRelationshipAttribute", - "weight": 89, + "weight": 90, "cookies": false, "type": "", "deprecated": false, @@ -7265,7 +7265,7 @@ "tags": [ "databases" ], - "description": "Create a string attribute.\r\n", + "description": "Create a string attribute.\n", "responses": { "202": { "description": "AttributeString", @@ -7280,7 +7280,7 @@ }, "x-appwrite": { "method": "createStringAttribute", - "weight": 80, + "weight": 81, "cookies": false, "type": "", "deprecated": false, @@ -7384,7 +7384,7 @@ "tags": [ "databases" ], - "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeString", @@ -7399,7 +7399,7 @@ }, "x-appwrite": { "method": "updateStringAttribute", - "weight": 92, + "weight": 93, "cookies": false, "type": "", "deprecated": false, @@ -7477,7 +7477,7 @@ "size": { "type": "integer", "description": "Maximum size of the string attribute.", - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -7502,7 +7502,7 @@ "tags": [ "databases" ], - "description": "Create a URL attribute.\r\n", + "description": "Create a URL attribute.\n", "responses": { "202": { "description": "AttributeURL", @@ -7517,7 +7517,7 @@ }, "x-appwrite": { "method": "createUrlAttribute", - "weight": 84, + "weight": 85, "cookies": false, "type": "", "deprecated": false, @@ -7610,7 +7610,7 @@ "tags": [ "databases" ], - "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeURL", @@ -7625,7 +7625,7 @@ }, "x-appwrite": { "method": "updateUrlAttribute", - "weight": 96, + "weight": 97, "cookies": false, "type": "", "deprecated": false, @@ -7769,7 +7769,7 @@ }, "x-appwrite": { "method": "getAttribute", - "weight": 91, + "weight": 92, "cookies": false, "type": "", "deprecated": false, @@ -7842,7 +7842,7 @@ }, "x-appwrite": { "method": "deleteAttribute", - "weight": 102, + "weight": 103, "cookies": false, "type": "", "deprecated": false, @@ -7909,7 +7909,7 @@ "tags": [ "databases" ], - "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "200": { "description": "AttributeRelationship", @@ -7924,7 +7924,7 @@ }, "x-appwrite": { "method": "updateRelationshipAttribute", - "weight": 101, + "weight": 102, "cookies": false, "type": "", "deprecated": false, @@ -8034,7 +8034,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -8121,7 +8121,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -8230,7 +8230,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -8327,7 +8327,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -8428,7 +8428,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -8514,7 +8514,7 @@ }, "x-appwrite": { "method": "listDocumentLogs", - "weight": 110, + "weight": 111, "cookies": false, "type": "", "deprecated": false, @@ -8609,7 +8609,7 @@ }, "x-appwrite": { "method": "listIndexes", - "weight": 104, + "weight": 105, "cookies": false, "type": "", "deprecated": false, @@ -8678,7 +8678,7 @@ "tags": [ "databases" ], - "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\r\nAttributes can be `key`, `fulltext`, and `unique`.", + "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\nAttributes can be `key`, `fulltext`, and `unique`.", "responses": { "202": { "description": "Index", @@ -8693,7 +8693,7 @@ }, "x-appwrite": { "method": "createIndex", - "weight": 103, + "weight": 104, "cookies": false, "type": "", "deprecated": false, @@ -8815,7 +8815,7 @@ }, "x-appwrite": { "method": "getIndex", - "weight": 105, + "weight": 106, "cookies": false, "type": "", "deprecated": false, @@ -8888,7 +8888,7 @@ }, "x-appwrite": { "method": "deleteIndex", - "weight": 106, + "weight": 107, "cookies": false, "type": "", "deprecated": false, @@ -8970,7 +8970,7 @@ }, "x-appwrite": { "method": "listCollectionLogs", - "weight": 77, + "weight": 78, "cookies": false, "type": "", "deprecated": false, @@ -9055,7 +9055,7 @@ }, "x-appwrite": { "method": "getCollectionUsage", - "weight": 115, + "weight": 116, "cookies": false, "type": "", "deprecated": false, @@ -9149,7 +9149,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 71, + "weight": 72, "cookies": false, "type": "", "deprecated": false, @@ -9224,7 +9224,7 @@ }, "x-appwrite": { "method": "getDatabaseUsage", - "weight": 114, + "weight": 115, "cookies": false, "type": "", "deprecated": false, @@ -9308,7 +9308,7 @@ }, "x-appwrite": { "method": "list", - "weight": 287, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -9383,7 +9383,7 @@ }, "x-appwrite": { "method": "create", - "weight": 286, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -9437,6 +9437,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -9455,6 +9456,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -9462,24 +9465,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9622,7 +9631,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 288, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -9658,7 +9667,7 @@ "tags": [ "functions" ], - "description": "List allowed function specifications for this instance.\r\n", + "description": "List allowed function specifications for this instance.\n", "responses": { "200": { "description": "Specifications List", @@ -9673,7 +9682,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 289, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -9725,7 +9734,7 @@ }, "x-appwrite": { "method": "listTemplates", - "weight": 312, + "weight": 314, "cookies": false, "type": "", "deprecated": false, @@ -9827,7 +9836,7 @@ }, "x-appwrite": { "method": "getTemplate", - "weight": 313, + "weight": 315, "cookies": false, "type": "", "deprecated": false, @@ -9889,7 +9898,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 292, + "weight": 294, "cookies": false, "type": "", "deprecated": false, @@ -9963,7 +9972,7 @@ }, "x-appwrite": { "method": "get", - "weight": 290, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -10024,7 +10033,7 @@ }, "x-appwrite": { "method": "update", - "weight": 293, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -10085,6 +10094,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -10103,6 +10113,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -10110,24 +10122,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -10240,7 +10258,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 296, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -10303,7 +10321,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 298, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -10373,7 +10391,7 @@ "tags": [ "functions" ], - "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\r\n\r\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\r\n\r\nUse the \"command\" param to set the entrypoint used to execute your code.", + "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\n\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\n\nUse the \"command\" param to set the entrypoint used to execute your code.", "responses": { "202": { "description": "Deployment", @@ -10388,7 +10406,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 297, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -10486,7 +10504,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 299, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -10557,7 +10575,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 295, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -10621,7 +10639,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 300, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -10687,7 +10705,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 301, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -10774,7 +10792,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 302, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -10840,7 +10858,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 294, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -10915,7 +10933,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -11003,7 +11021,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -11054,7 +11072,7 @@ "body": { "type": "string", "description": "HTTP body of execution. Default value is empty string.", - "x-example": null + "x-example": "" }, "async": { "type": "boolean", @@ -11120,7 +11138,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -11179,7 +11197,7 @@ "tags": [ "functions" ], - "description": "Delete a function execution by its unique ID.\r\n", + "description": "Delete a function execution by its unique ID.\n", "responses": { "204": { "description": "No content" @@ -11187,7 +11205,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 306, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -11260,7 +11278,7 @@ }, "x-appwrite": { "method": "getFunctionUsage", - "weight": 291, + "weight": 293, "cookies": false, "type": "", "deprecated": false, @@ -11344,7 +11362,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 308, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -11405,7 +11423,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 307, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -11493,7 +11511,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 309, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -11564,7 +11582,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 310, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -11652,7 +11670,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 311, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -11725,7 +11743,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -11779,7 +11797,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -11833,7 +11851,7 @@ }, "x-appwrite": { "method": "get", - "weight": 124, + "weight": 125, "cookies": false, "type": "", "deprecated": false, @@ -11884,7 +11902,7 @@ }, "x-appwrite": { "method": "getAntivirus", - "weight": 146, + "weight": 147, "cookies": false, "type": "", "deprecated": false, @@ -11935,7 +11953,7 @@ }, "x-appwrite": { "method": "getCache", - "weight": 127, + "weight": 128, "cookies": false, "type": "", "deprecated": false, @@ -11986,7 +12004,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 133, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -12048,7 +12066,7 @@ }, "x-appwrite": { "method": "getDB", - "weight": 126, + "weight": 127, "cookies": false, "type": "", "deprecated": false, @@ -12099,7 +12117,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 129, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -12150,7 +12168,7 @@ }, "x-appwrite": { "method": "getQueue", - "weight": 128, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -12201,7 +12219,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 135, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -12265,7 +12283,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 134, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -12329,7 +12347,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 136, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -12404,7 +12422,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 137, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -12453,7 +12471,7 @@ "tags": [ "health" ], - "description": "Returns the amount of failed jobs in a given queue.\r\n", + "description": "Returns the amount of failed jobs in a given queue.\n", "responses": { "200": { "description": "Health Queue", @@ -12468,7 +12486,7 @@ }, "x-appwrite": { "method": "getFailedJobs", - "weight": 147, + "weight": 148, "cookies": false, "type": "", "deprecated": false, @@ -12558,7 +12576,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 141, + "weight": 142, "cookies": false, "type": "", "deprecated": false, @@ -12622,7 +12640,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 132, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -12686,7 +12704,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 138, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -12750,7 +12768,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 139, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -12814,7 +12832,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 140, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -12878,7 +12896,7 @@ }, "x-appwrite": { "method": "getQueueUsage", - "weight": 142, + "weight": 143, "cookies": false, "type": "", "deprecated": false, @@ -12942,7 +12960,7 @@ }, "x-appwrite": { "method": "getQueueUsageDump", - "weight": 143, + "weight": 144, "cookies": false, "type": "", "deprecated": false, @@ -13006,7 +13024,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 131, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -13070,7 +13088,7 @@ }, "x-appwrite": { "method": "getStorage", - "weight": 145, + "weight": 146, "cookies": false, "type": "", "deprecated": false, @@ -13121,7 +13139,7 @@ }, "x-appwrite": { "method": "getStorageLocal", - "weight": 144, + "weight": 145, "cookies": false, "type": "", "deprecated": false, @@ -13172,7 +13190,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 130, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -13208,7 +13226,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -13223,7 +13241,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -13277,7 +13295,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -13331,7 +13349,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -13385,7 +13403,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -13439,7 +13457,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -13493,7 +13511,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -13547,7 +13565,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -13601,7 +13619,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -13655,7 +13673,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 388, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -13733,7 +13751,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 385, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -13864,7 +13882,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13879,7 +13897,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 392, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -14027,7 +14045,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 387, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -14169,7 +14187,7 @@ "tags": [ "messaging" ], - "description": "Update a push notification by its unique ID.\r\n", + "description": "Update a push notification by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14184,7 +14202,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 394, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -14343,7 +14361,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 386, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -14439,7 +14457,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14454,7 +14472,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 393, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -14553,7 +14571,7 @@ "tags": [ "messaging" ], - "description": "Get a message by its unique ID.\r\n", + "description": "Get a message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14568,7 +14586,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 391, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -14623,7 +14641,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 395, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -14687,7 +14705,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 389, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -14764,7 +14782,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 390, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -14841,7 +14859,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 360, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -14919,7 +14937,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 359, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -15026,7 +15044,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 372, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -15136,7 +15154,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 358, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -15223,7 +15241,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 371, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -15313,7 +15331,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 350, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -15430,7 +15448,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 363, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -15550,7 +15568,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 353, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -15647,7 +15665,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 366, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -15747,7 +15765,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 351, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -15854,7 +15872,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 364, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -15964,7 +15982,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 352, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -16109,7 +16127,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 365, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -16256,7 +16274,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 354, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -16353,7 +16371,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 367, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -16453,7 +16471,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 355, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -16550,7 +16568,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 368, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -16650,7 +16668,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 356, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -16747,7 +16765,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 369, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -16847,7 +16865,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 357, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -16944,7 +16962,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 370, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -17029,7 +17047,7 @@ "tags": [ "messaging" ], - "description": "Get a provider by its unique ID.\r\n", + "description": "Get a provider by its unique ID.\n", "responses": { "200": { "description": "Provider", @@ -17044,7 +17062,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 362, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -17099,7 +17117,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 373, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -17163,7 +17181,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 361, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -17240,7 +17258,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 382, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -17317,7 +17335,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 375, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -17393,7 +17411,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 374, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -17463,7 +17481,7 @@ "tags": [ "messaging" ], - "description": "Get a topic by its unique ID.\r\n", + "description": "Get a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -17478,7 +17496,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 377, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -17525,7 +17543,7 @@ "tags": [ "messaging" ], - "description": "Update a topic by its unique ID.\r\n", + "description": "Update a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -17540,7 +17558,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 378, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -17619,7 +17637,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 379, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -17683,7 +17701,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 376, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -17760,7 +17778,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 381, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -17846,7 +17864,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -17923,7 +17941,7 @@ "tags": [ "messaging" ], - "description": "Get a subscriber by its unique ID.\r\n", + "description": "Get a subscriber by its unique ID.\n", "responses": { "200": { "description": "Subscriber", @@ -17938,7 +17956,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 383, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -18003,7 +18021,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -18080,7 +18098,7 @@ }, "x-appwrite": { "method": "list", - "weight": 337, + "weight": 339, "cookies": false, "type": "", "deprecated": false, @@ -18109,7 +18127,7 @@ "parameters": [ { "name": "queries", - "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, resources, statusCounters, resourceData, errors", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, statusCounters, resourceData, errors", "required": false, "schema": { "type": "array", @@ -18156,7 +18174,7 @@ }, "x-appwrite": { "method": "createAppwriteMigration", - "weight": 332, + "weight": 334, "cookies": false, "type": "", "deprecated": false, @@ -18246,7 +18264,7 @@ }, "x-appwrite": { "method": "getAppwriteReport", - "weight": 339, + "weight": 341, "cookies": false, "type": "", "deprecated": false, @@ -18341,7 +18359,7 @@ }, "x-appwrite": { "method": "createFirebaseMigration", - "weight": 334, + "weight": 336, "cookies": false, "type": "", "deprecated": false, @@ -18412,7 +18430,7 @@ }, "x-appwrite": { "method": "deleteFirebaseAuth", - "weight": 345, + "weight": 347, "cookies": false, "type": "", "deprecated": false, @@ -18462,7 +18480,7 @@ }, "x-appwrite": { "method": "createFirebaseOAuthMigration", - "weight": 333, + "weight": 335, "cookies": false, "type": "", "deprecated": false, @@ -18540,7 +18558,7 @@ }, "x-appwrite": { "method": "listFirebaseProjects", - "weight": 344, + "weight": 346, "cookies": false, "type": "", "deprecated": false, @@ -18590,7 +18608,7 @@ }, "x-appwrite": { "method": "getFirebaseReport", - "weight": 340, + "weight": 342, "cookies": false, "type": "", "deprecated": false, @@ -18664,7 +18682,7 @@ }, "x-appwrite": { "method": "getFirebaseReportOAuth", - "weight": 341, + "weight": 343, "cookies": false, "type": "", "deprecated": false, @@ -18738,7 +18756,7 @@ }, "x-appwrite": { "method": "createNHostMigration", - "weight": 336, + "weight": 338, "cookies": false, "type": "", "deprecated": false, @@ -18851,7 +18869,7 @@ }, "x-appwrite": { "method": "getNHostReport", - "weight": 347, + "weight": 349, "cookies": false, "type": "", "deprecated": false, @@ -18986,7 +19004,7 @@ }, "x-appwrite": { "method": "createSupabaseMigration", - "weight": 335, + "weight": 337, "cookies": false, "type": "", "deprecated": false, @@ -19093,7 +19111,7 @@ }, "x-appwrite": { "method": "getSupabaseReport", - "weight": 346, + "weight": 348, "cookies": false, "type": "", "deprecated": false, @@ -19219,7 +19237,7 @@ }, "x-appwrite": { "method": "get", - "weight": 338, + "weight": 340, "cookies": false, "type": "", "deprecated": false, @@ -19279,7 +19297,7 @@ }, "x-appwrite": { "method": "retry", - "weight": 348, + "weight": 350, "cookies": false, "type": "", "deprecated": false, @@ -19332,7 +19350,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 349, + "weight": 351, "cookies": false, "type": "", "deprecated": false, @@ -19394,7 +19412,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 194, + "weight": 196, "cookies": false, "type": "", "deprecated": false, @@ -19484,7 +19502,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 196, + "weight": 198, "cookies": false, "type": "", "deprecated": false, @@ -19532,7 +19550,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 195, + "weight": 197, "cookies": false, "type": "", "deprecated": false, @@ -19607,7 +19625,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 197, + "weight": 199, "cookies": false, "type": "", "deprecated": false, @@ -19667,7 +19685,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 198, + "weight": 200, "cookies": false, "type": "", "deprecated": false, @@ -19744,7 +19762,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 199, + "weight": 201, "cookies": false, "type": "", "deprecated": false, @@ -19806,7 +19824,7 @@ }, "x-appwrite": { "method": "list", - "weight": 150, + "weight": 151, "cookies": false, "type": "", "deprecated": false, @@ -19880,7 +19898,7 @@ }, "x-appwrite": { "method": "create", - "weight": 149, + "weight": 150, "cookies": false, "type": "", "deprecated": false, @@ -20017,7 +20035,7 @@ }, "x-appwrite": { "method": "get", - "weight": 151, + "weight": 152, "cookies": false, "type": "", "deprecated": false, @@ -20077,7 +20095,7 @@ }, "x-appwrite": { "method": "update", - "weight": 152, + "weight": 153, "cookies": false, "type": "", "deprecated": false, @@ -20194,7 +20212,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 168, + "weight": 170, "cookies": false, "type": "", "deprecated": false, @@ -20256,7 +20274,7 @@ }, "x-appwrite": { "method": "updateApiStatus", - "weight": 156, + "weight": 157, "cookies": false, "type": "", "deprecated": false, @@ -20350,7 +20368,7 @@ }, "x-appwrite": { "method": "updateApiStatusAll", - "weight": 157, + "weight": 158, "cookies": false, "type": "", "deprecated": false, @@ -20431,7 +20449,7 @@ }, "x-appwrite": { "method": "updateAuthDuration", - "weight": 161, + "weight": 163, "cookies": false, "type": "", "deprecated": false, @@ -20512,7 +20530,7 @@ }, "x-appwrite": { "method": "updateAuthLimit", - "weight": 160, + "weight": 162, "cookies": false, "type": "", "deprecated": false, @@ -20593,7 +20611,7 @@ }, "x-appwrite": { "method": "updateAuthSessionsLimit", - "weight": 166, + "weight": 168, "cookies": false, "type": "", "deprecated": false, @@ -20652,6 +20670,99 @@ } } }, + "\/projects\/{projectId}\/auth\/memberships-privacy": { + "patch": { + "summary": "Update project team sensitive attributes", + "operationId": "projectsUpdateMembershipsPrivacy", + "tags": [ + "projects" + ], + "description": "", + "responses": { + "200": { + "description": "Project", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/project" + } + } + } + } + }, + "x-appwrite": { + "method": "updateMembershipsPrivacy", + "weight": 161, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "projects\/update-memberships-privacy.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "projects.write", + "platforms": [ + "console" + ], + "packaging": false, + "offline-model": "", + "offline-key": "", + "offline-response-key": "$id", + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [] + } + ], + "parameters": [ + { + "name": "projectId", + "description": "Project unique ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "userName": { + "type": "boolean", + "description": "Set to true to show userName to members of a team.", + "x-example": false + }, + "userEmail": { + "type": "boolean", + "description": "Set to true to show email to members of a team.", + "x-example": false + }, + "mfa": { + "type": "boolean", + "description": "Set to true to show mfa to members of a team.", + "x-example": false + } + }, + "required": [ + "userName", + "userEmail", + "mfa" + ] + } + } + } + } + } + }, "\/projects\/{projectId}\/auth\/mock-numbers": { "patch": { "summary": "Update the mock numbers for the project", @@ -20674,7 +20785,7 @@ }, "x-appwrite": { "method": "updateMockNumbers", - "weight": 167, + "weight": 169, "cookies": false, "type": "", "deprecated": false, @@ -20758,7 +20869,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordDictionary", - "weight": 164, + "weight": 166, "cookies": false, "type": "", "deprecated": false, @@ -20839,7 +20950,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordHistory", - "weight": 163, + "weight": 165, "cookies": false, "type": "", "deprecated": false, @@ -20920,7 +21031,7 @@ }, "x-appwrite": { "method": "updatePersonalDataCheck", - "weight": 165, + "weight": 167, "cookies": false, "type": "", "deprecated": false, @@ -21001,7 +21112,7 @@ }, "x-appwrite": { "method": "updateSessionAlerts", - "weight": 159, + "weight": 160, "cookies": false, "type": "", "deprecated": false, @@ -21082,7 +21193,7 @@ }, "x-appwrite": { "method": "updateAuthStatus", - "weight": 162, + "weight": 164, "cookies": false, "type": "", "deprecated": false, @@ -21184,7 +21295,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 180, + "weight": 182, "cookies": false, "type": "", "deprecated": false, @@ -21273,7 +21384,7 @@ }, "x-appwrite": { "method": "listKeys", - "weight": 176, + "weight": 178, "cookies": false, "type": "", "deprecated": false, @@ -21333,7 +21444,7 @@ }, "x-appwrite": { "method": "createKey", - "weight": 175, + "weight": 177, "cookies": false, "type": "", "deprecated": false, @@ -21428,7 +21539,7 @@ }, "x-appwrite": { "method": "getKey", - "weight": 177, + "weight": 179, "cookies": false, "type": "", "deprecated": false, @@ -21498,7 +21609,7 @@ }, "x-appwrite": { "method": "updateKey", - "weight": 178, + "weight": 180, "cookies": false, "type": "", "deprecated": false, @@ -21594,7 +21705,7 @@ }, "x-appwrite": { "method": "deleteKey", - "weight": 179, + "weight": 181, "cookies": false, "type": "", "deprecated": false, @@ -21666,7 +21777,7 @@ }, "x-appwrite": { "method": "updateOAuth2", - "weight": 158, + "weight": 159, "cookies": false, "type": "", "deprecated": false, @@ -21805,7 +21916,7 @@ }, "x-appwrite": { "method": "listPlatforms", - "weight": 182, + "weight": 184, "cookies": false, "type": "", "deprecated": false, @@ -21865,7 +21976,7 @@ }, "x-appwrite": { "method": "createPlatform", - "weight": 181, + "weight": 183, "cookies": false, "type": "", "deprecated": false, @@ -21986,7 +22097,7 @@ }, "x-appwrite": { "method": "getPlatform", - "weight": 183, + "weight": 185, "cookies": false, "type": "", "deprecated": false, @@ -22056,7 +22167,7 @@ }, "x-appwrite": { "method": "updatePlatform", - "weight": 184, + "weight": 186, "cookies": false, "type": "", "deprecated": false, @@ -22153,7 +22264,7 @@ }, "x-appwrite": { "method": "deletePlatform", - "weight": 185, + "weight": 187, "cookies": false, "type": "", "deprecated": false, @@ -22225,7 +22336,7 @@ }, "x-appwrite": { "method": "updateServiceStatus", - "weight": 154, + "weight": 155, "cookies": false, "type": "", "deprecated": false, @@ -22327,7 +22438,7 @@ }, "x-appwrite": { "method": "updateServiceStatusAll", - "weight": 155, + "weight": 156, "cookies": false, "type": "", "deprecated": false, @@ -22408,7 +22519,7 @@ }, "x-appwrite": { "method": "updateSmtp", - "weight": 186, + "weight": 188, "cookies": false, "type": "", "deprecated": false, @@ -22528,7 +22639,7 @@ }, "x-appwrite": { "method": "createSmtpTest", - "weight": 187, + "weight": 189, "cookies": false, "type": "", "deprecated": false, @@ -22661,7 +22772,7 @@ }, "x-appwrite": { "method": "updateTeam", - "weight": 153, + "weight": 154, "cookies": false, "type": "", "deprecated": false, @@ -22742,7 +22853,7 @@ }, "x-appwrite": { "method": "getEmailTemplate", - "weight": 189, + "weight": 191, "cookies": false, "type": "", "deprecated": false, @@ -22968,7 +23079,7 @@ }, "x-appwrite": { "method": "updateEmailTemplate", - "weight": 191, + "weight": 193, "cookies": false, "type": "", "deprecated": false, @@ -23234,7 +23345,7 @@ }, "x-appwrite": { "method": "deleteEmailTemplate", - "weight": 193, + "weight": 195, "cookies": false, "type": "", "deprecated": false, @@ -23462,7 +23573,7 @@ }, "x-appwrite": { "method": "getSmsTemplate", - "weight": 188, + "weight": 190, "cookies": false, "type": "", "deprecated": false, @@ -23685,7 +23796,7 @@ }, "x-appwrite": { "method": "updateSmsTemplate", - "weight": 190, + "weight": 192, "cookies": false, "type": "", "deprecated": false, @@ -23927,7 +24038,7 @@ }, "x-appwrite": { "method": "deleteSmsTemplate", - "weight": 192, + "weight": 194, "cookies": false, "type": "", "deprecated": false, @@ -24152,7 +24263,7 @@ }, "x-appwrite": { "method": "listWebhooks", - "weight": 170, + "weight": 172, "cookies": false, "type": "", "deprecated": false, @@ -24212,7 +24323,7 @@ }, "x-appwrite": { "method": "createWebhook", - "weight": 169, + "weight": 171, "cookies": false, "type": "", "deprecated": false, @@ -24329,7 +24440,7 @@ }, "x-appwrite": { "method": "getWebhook", - "weight": 171, + "weight": 173, "cookies": false, "type": "", "deprecated": false, @@ -24399,7 +24510,7 @@ }, "x-appwrite": { "method": "updateWebhook", - "weight": 172, + "weight": 174, "cookies": false, "type": "", "deprecated": false, @@ -24517,7 +24628,7 @@ }, "x-appwrite": { "method": "deleteWebhook", - "weight": 174, + "weight": 176, "cookies": false, "type": "", "deprecated": false, @@ -24589,7 +24700,7 @@ }, "x-appwrite": { "method": "updateWebhookSignature", - "weight": 173, + "weight": 175, "cookies": false, "type": "", "deprecated": false, @@ -24661,7 +24772,7 @@ }, "x-appwrite": { "method": "listRules", - "weight": 315, + "weight": 317, "cookies": false, "type": "", "deprecated": false, @@ -24735,7 +24846,7 @@ }, "x-appwrite": { "method": "createRule", - "weight": 314, + "weight": 316, "cookies": false, "type": "", "deprecated": false, @@ -24821,7 +24932,7 @@ }, "x-appwrite": { "method": "getRule", - "weight": 316, + "weight": 318, "cookies": false, "type": "", "deprecated": false, @@ -24874,7 +24985,7 @@ }, "x-appwrite": { "method": "deleteRule", - "weight": 317, + "weight": 319, "cookies": false, "type": "", "deprecated": false, @@ -24936,7 +25047,7 @@ }, "x-appwrite": { "method": "updateRuleVerification", - "weight": 318, + "weight": 320, "cookies": false, "type": "", "deprecated": false, @@ -24998,7 +25109,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 201, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -25073,7 +25184,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 200, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -25202,7 +25313,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 202, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -25263,7 +25374,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 203, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -25389,7 +25500,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 204, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -25452,7 +25563,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -25525,7 +25636,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -25540,7 +25651,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -25640,7 +25751,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -25714,7 +25825,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -25805,7 +25916,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -25874,7 +25985,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -25943,7 +26054,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -26161,7 +26272,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -26237,7 +26348,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 214, + "weight": 216, "cookies": false, "type": "", "deprecated": false, @@ -26311,7 +26422,7 @@ }, "x-appwrite": { "method": "getBucketUsage", - "weight": 215, + "weight": 217, "cookies": false, "type": "", "deprecated": false, @@ -26395,7 +26506,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -26473,7 +26584,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -26560,7 +26671,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -26624,7 +26735,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -26700,7 +26811,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -26766,7 +26877,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 229, + "weight": 231, "cookies": false, "type": "", "deprecated": false, @@ -26826,7 +26937,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -26841,7 +26952,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -26914,7 +27025,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -26929,7 +27040,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -27027,7 +27138,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -27042,7 +27153,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -27101,7 +27212,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -27116,7 +27227,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -27205,7 +27316,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -27266,7 +27377,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -27281,7 +27392,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -27380,7 +27491,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -27442,7 +27553,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -27525,7 +27636,7 @@ }, "x-appwrite": { "method": "list", - "weight": 239, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -27600,7 +27711,7 @@ }, "x-appwrite": { "method": "create", - "weight": 230, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -27690,7 +27801,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 233, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -27777,7 +27888,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 231, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -27864,7 +27975,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 247, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -27934,7 +28045,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 270, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -27997,7 +28108,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 232, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -28084,7 +28195,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 235, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -28171,7 +28282,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 236, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -28288,7 +28399,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 237, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -28393,7 +28504,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 234, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -28500,7 +28611,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 272, + "weight": 274, "cookies": false, "type": "", "deprecated": false, @@ -28574,7 +28685,7 @@ }, "x-appwrite": { "method": "get", - "weight": 240, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -28628,7 +28739,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 268, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -28691,7 +28802,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 253, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -28773,7 +28884,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 271, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -28842,7 +28953,7 @@ "tags": [ "users" ], - "description": "Update the user labels by its unique ID. \r\n\r\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", + "description": "Update the user labels by its unique ID. \n\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", "responses": { "200": { "description": "User", @@ -28857,7 +28968,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 249, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -28942,7 +29053,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 245, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -29018,7 +29129,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 244, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -29081,7 +29192,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 258, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -29163,7 +29274,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 263, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -29241,7 +29352,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 259, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -29304,7 +29415,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 260, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -29365,7 +29476,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 262, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -29426,7 +29537,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 261, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -29489,7 +29600,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 251, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -29571,7 +29682,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 252, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -29653,7 +29764,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 254, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -29735,7 +29846,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 241, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -29796,7 +29907,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 256, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -29878,7 +29989,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 243, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -29924,7 +30035,7 @@ "tags": [ "users" ], - "description": "Creates a session for a user. Returns an immediately usable session object.\r\n\r\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", + "description": "Creates a session for a user. Returns an immediately usable session object.\n\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", "responses": { "201": { "description": "Session", @@ -29939,7 +30050,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 264, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -29993,7 +30104,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 267, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -30049,7 +30160,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 266, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -30122,7 +30233,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 248, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -30204,7 +30315,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 246, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -30279,7 +30390,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 238, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -30391,7 +30502,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 242, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -30463,7 +30574,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 257, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -30554,7 +30665,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 269, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -30613,7 +30724,7 @@ "tags": [ "users" ], - "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\r\n", + "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\n", "responses": { "201": { "description": "Token", @@ -30628,7 +30739,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 265, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -30712,7 +30823,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 255, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -30794,7 +30905,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 250, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -30876,7 +30987,7 @@ }, "x-appwrite": { "method": "listRepositories", - "weight": 277, + "weight": 279, "cookies": false, "type": "", "deprecated": false, @@ -30947,7 +31058,7 @@ }, "x-appwrite": { "method": "createRepository", - "weight": 278, + "weight": 280, "cookies": false, "type": "", "deprecated": false, @@ -31034,7 +31145,7 @@ }, "x-appwrite": { "method": "getRepository", - "weight": 279, + "weight": 281, "cookies": false, "type": "", "deprecated": false, @@ -31106,7 +31217,7 @@ }, "x-appwrite": { "method": "listRepositoryBranches", - "weight": 280, + "weight": 282, "cookies": false, "type": "", "deprecated": false, @@ -31178,7 +31289,7 @@ }, "x-appwrite": { "method": "getRepositoryContents", - "weight": 275, + "weight": 277, "cookies": false, "type": "", "deprecated": false, @@ -31261,7 +31372,7 @@ }, "x-appwrite": { "method": "createRepositoryDetection", - "weight": 276, + "weight": 278, "cookies": false, "type": "", "deprecated": false, @@ -31342,7 +31453,7 @@ }, "x-appwrite": { "method": "updateExternalDeployments", - "weight": 285, + "weight": 287, "cookies": false, "type": "", "deprecated": false, @@ -31433,7 +31544,7 @@ }, "x-appwrite": { "method": "listInstallations", - "weight": 282, + "weight": 284, "cookies": false, "type": "", "deprecated": false, @@ -31509,7 +31620,7 @@ }, "x-appwrite": { "method": "getInstallation", - "weight": 283, + "weight": 285, "cookies": false, "type": "", "deprecated": false, @@ -31562,7 +31673,7 @@ }, "x-appwrite": { "method": "deleteInstallation", - "weight": 284, + "weight": 286, "cookies": false, "type": "", "deprecated": false, @@ -34850,12 +34961,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -34885,7 +34996,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -35050,7 +35161,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -35966,6 +36077,21 @@ "description": "Whether or not to send session alert emails to users.", "x-example": true }, + "membershipsUserName": { + "type": "boolean", + "description": "Whether or not to show user names in the teams membership response.", + "x-example": true + }, + "membershipsUserEmail": { + "type": "boolean", + "description": "Whether or not to show user emails in the teams membership response.", + "x-example": true + }, + "membershipsMfa": { + "type": "boolean", + "description": "Whether or not to show user MFA status in the teams membership response.", + "x-example": true + }, "oAuthProviders": { "type": "array", "description": "List of Auth Providers.", @@ -36046,6 +36172,17 @@ "description": "SMTP server secure protocol", "x-example": "tls" }, + "pingCount": { + "type": "integer", + "description": "Number of times the ping was received for this project.", + "x-example": 1, + "format": "int32" + }, + "pingedAt": { + "type": "string", + "description": "Last ping datetime in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "authEmailPassword": { "type": "boolean", "description": "Email\/Password auth method status", @@ -36160,6 +36297,9 @@ "authPersonalDataCheck", "authMockNumbers", "authSessionAlerts", + "membershipsUserName", + "membershipsUserEmail", + "membershipsMfa", "oAuthProviders", "platforms", "webhooks", @@ -36173,6 +36313,8 @@ "smtpUsername", "smtpPassword", "smtpSecure", + "pingCount", + "pingedAt", "authEmailPassword", "authUsersAuthMagicURL", "authEmailOtp", @@ -37736,7 +37878,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -38374,7 +38516,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -38396,6 +38538,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -38405,7 +38552,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] }, "migration": { @@ -38419,7 +38567,7 @@ }, "$createdAt": { "type": "string", - "description": "Variable creation date in ISO 8601 format.", + "description": "Migration creation date in ISO 8601 format.", "x-example": "2020-10-15T06:38:00.000+00:00" }, "$updatedAt": { @@ -38442,9 +38590,14 @@ "description": "A string containing the type of source of the migration.", "x-example": "Appwrite" }, + "destination": { + "type": "string", + "description": "A string containing the type of destination of the migration.", + "x-example": "Appwrite" + }, "resources": { "type": "array", - "description": "Resources to migration.", + "description": "Resources to migrate.", "items": { "type": "string" }, @@ -38478,6 +38631,7 @@ "status", "stage", "source", + "destination", "resources", "statusCounters", "resourceData", diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index 274eac9686..e84b751743 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -43,7 +43,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -95,7 +95,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -167,7 +167,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -182,7 +182,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -261,7 +261,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -323,7 +323,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -389,7 +389,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -440,7 +440,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -509,7 +509,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -582,7 +582,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -651,7 +651,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -732,7 +732,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -803,7 +803,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -879,7 +879,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -958,7 +958,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1012,7 +1012,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1064,7 +1064,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1116,7 +1116,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1170,7 +1170,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1243,7 +1243,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1321,7 +1321,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1400,7 +1400,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1452,7 +1452,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1525,7 +1525,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1590,7 +1590,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1605,7 +1605,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1690,7 +1690,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1735,7 +1735,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1789,7 +1789,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1825,7 +1825,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1840,7 +1840,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -1916,7 +1916,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -1992,7 +1992,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2068,7 +2068,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2144,7 +2144,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2208,7 +2208,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2265,7 +2265,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2331,7 +2331,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2370,7 +2370,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2385,7 +2385,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2451,7 +2451,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2466,7 +2466,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -2540,7 +2540,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "File" @@ -2548,7 +2548,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2676,7 +2676,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2691,7 +2691,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -2755,7 +2755,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -2770,7 +2770,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -2841,7 +2841,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -2920,7 +2920,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -2975,7 +2975,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3039,7 +3039,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image" @@ -3047,7 +3047,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3169,7 +3169,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3177,7 +3177,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3303,7 +3303,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -3311,7 +3311,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3365,7 +3365,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3373,7 +3373,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -3857,7 +3857,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image" @@ -3865,7 +3865,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -3943,7 +3943,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image" @@ -3951,7 +3951,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4039,7 +4039,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image" @@ -4047,7 +4047,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4150,7 +4150,7 @@ }, "x-appwrite": { "method": "list", - "weight": 69, + "weight": 70, "cookies": false, "type": "", "deprecated": false, @@ -4211,7 +4211,7 @@ "tags": [ "databases" ], - "description": "Create a new Database.\r\n", + "description": "Create a new Database.\n", "responses": { "201": { "description": "Database", @@ -4226,7 +4226,7 @@ }, "x-appwrite": { "method": "create", - "weight": 68, + "weight": 69, "cookies": false, "type": "", "deprecated": false, @@ -4308,7 +4308,7 @@ }, "x-appwrite": { "method": "get", - "weight": 70, + "weight": 71, "cookies": false, "type": "", "deprecated": false, @@ -4370,7 +4370,7 @@ }, "x-appwrite": { "method": "update", - "weight": 72, + "weight": 73, "cookies": false, "type": "", "deprecated": false, @@ -4449,7 +4449,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 73, + "weight": 74, "cookies": false, "type": "", "deprecated": false, @@ -4513,7 +4513,7 @@ }, "x-appwrite": { "method": "listCollections", - "weight": 75, + "weight": 76, "cookies": false, "type": "", "deprecated": false, @@ -4599,7 +4599,7 @@ }, "x-appwrite": { "method": "createCollection", - "weight": 74, + "weight": 75, "cookies": false, "type": "", "deprecated": false, @@ -4706,7 +4706,7 @@ }, "x-appwrite": { "method": "getCollection", - "weight": 76, + "weight": 77, "cookies": false, "type": "", "deprecated": false, @@ -4778,7 +4778,7 @@ }, "x-appwrite": { "method": "updateCollection", - "weight": 78, + "weight": 79, "cookies": false, "type": "", "deprecated": false, @@ -4880,7 +4880,7 @@ }, "x-appwrite": { "method": "deleteCollection", - "weight": 79, + "weight": 80, "cookies": false, "type": "", "deprecated": false, @@ -4954,7 +4954,7 @@ }, "x-appwrite": { "method": "listAttributes", - "weight": 90, + "weight": 91, "cookies": false, "type": "", "deprecated": false, @@ -5026,7 +5026,7 @@ "tags": [ "databases" ], - "description": "Create a boolean attribute.\r\n", + "description": "Create a boolean attribute.\n", "responses": { "202": { "description": "AttributeBoolean", @@ -5041,7 +5041,7 @@ }, "x-appwrite": { "method": "createBooleanAttribute", - "weight": 87, + "weight": 88, "cookies": false, "type": "", "deprecated": false, @@ -5150,7 +5150,7 @@ }, "x-appwrite": { "method": "updateBooleanAttribute", - "weight": 99, + "weight": 100, "cookies": false, "type": "", "deprecated": false, @@ -5264,7 +5264,7 @@ }, "x-appwrite": { "method": "createDatetimeAttribute", - "weight": 88, + "weight": 89, "cookies": false, "type": "", "deprecated": false, @@ -5373,7 +5373,7 @@ }, "x-appwrite": { "method": "updateDatetimeAttribute", - "weight": 100, + "weight": 101, "cookies": false, "type": "", "deprecated": false, @@ -5472,7 +5472,7 @@ "tags": [ "databases" ], - "description": "Create an email attribute.\r\n", + "description": "Create an email attribute.\n", "responses": { "202": { "description": "AttributeEmail", @@ -5487,7 +5487,7 @@ }, "x-appwrite": { "method": "createEmailAttribute", - "weight": 81, + "weight": 82, "cookies": false, "type": "", "deprecated": false, @@ -5581,7 +5581,7 @@ "tags": [ "databases" ], - "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEmail", @@ -5596,7 +5596,7 @@ }, "x-appwrite": { "method": "updateEmailAttribute", - "weight": 93, + "weight": 94, "cookies": false, "type": "", "deprecated": false, @@ -5695,7 +5695,7 @@ "tags": [ "databases" ], - "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \r\n", + "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \n", "responses": { "202": { "description": "AttributeEnum", @@ -5710,7 +5710,7 @@ }, "x-appwrite": { "method": "createEnumAttribute", - "weight": 82, + "weight": 83, "cookies": false, "type": "", "deprecated": false, @@ -5813,7 +5813,7 @@ "tags": [ "databases" ], - "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEnum", @@ -5828,7 +5828,7 @@ }, "x-appwrite": { "method": "updateEnumAttribute", - "weight": 94, + "weight": 95, "cookies": false, "type": "", "deprecated": false, @@ -5936,7 +5936,7 @@ "tags": [ "databases" ], - "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeFloat", @@ -5951,7 +5951,7 @@ }, "x-appwrite": { "method": "createFloatAttribute", - "weight": 86, + "weight": 87, "cookies": false, "type": "", "deprecated": false, @@ -6055,7 +6055,7 @@ "tags": [ "databases" ], - "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeFloat", @@ -6070,7 +6070,7 @@ }, "x-appwrite": { "method": "updateFloatAttribute", - "weight": 98, + "weight": 99, "cookies": false, "type": "", "deprecated": false, @@ -6181,7 +6181,7 @@ "tags": [ "databases" ], - "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeInteger", @@ -6196,7 +6196,7 @@ }, "x-appwrite": { "method": "createIntegerAttribute", - "weight": 85, + "weight": 86, "cookies": false, "type": "", "deprecated": false, @@ -6300,7 +6300,7 @@ "tags": [ "databases" ], - "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeInteger", @@ -6315,7 +6315,7 @@ }, "x-appwrite": { "method": "updateIntegerAttribute", - "weight": 97, + "weight": 98, "cookies": false, "type": "", "deprecated": false, @@ -6426,7 +6426,7 @@ "tags": [ "databases" ], - "description": "Create IP address attribute.\r\n", + "description": "Create IP address attribute.\n", "responses": { "202": { "description": "AttributeIP", @@ -6441,7 +6441,7 @@ }, "x-appwrite": { "method": "createIpAttribute", - "weight": 83, + "weight": 84, "cookies": false, "type": "", "deprecated": false, @@ -6535,7 +6535,7 @@ "tags": [ "databases" ], - "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeIP", @@ -6550,7 +6550,7 @@ }, "x-appwrite": { "method": "updateIpAttribute", - "weight": 95, + "weight": 96, "cookies": false, "type": "", "deprecated": false, @@ -6649,7 +6649,7 @@ "tags": [ "databases" ], - "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "202": { "description": "AttributeRelationship", @@ -6664,7 +6664,7 @@ }, "x-appwrite": { "method": "createRelationshipAttribute", - "weight": 89, + "weight": 90, "cookies": false, "type": "", "deprecated": false, @@ -6783,7 +6783,7 @@ "tags": [ "databases" ], - "description": "Create a string attribute.\r\n", + "description": "Create a string attribute.\n", "responses": { "202": { "description": "AttributeString", @@ -6798,7 +6798,7 @@ }, "x-appwrite": { "method": "createStringAttribute", - "weight": 80, + "weight": 81, "cookies": false, "type": "", "deprecated": false, @@ -6903,7 +6903,7 @@ "tags": [ "databases" ], - "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeString", @@ -6918,7 +6918,7 @@ }, "x-appwrite": { "method": "updateStringAttribute", - "weight": 92, + "weight": 93, "cookies": false, "type": "", "deprecated": false, @@ -6997,7 +6997,7 @@ "size": { "type": "integer", "description": "Maximum size of the string attribute.", - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -7022,7 +7022,7 @@ "tags": [ "databases" ], - "description": "Create a URL attribute.\r\n", + "description": "Create a URL attribute.\n", "responses": { "202": { "description": "AttributeURL", @@ -7037,7 +7037,7 @@ }, "x-appwrite": { "method": "createUrlAttribute", - "weight": 84, + "weight": 85, "cookies": false, "type": "", "deprecated": false, @@ -7131,7 +7131,7 @@ "tags": [ "databases" ], - "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeURL", @@ -7146,7 +7146,7 @@ }, "x-appwrite": { "method": "updateUrlAttribute", - "weight": 96, + "weight": 97, "cookies": false, "type": "", "deprecated": false, @@ -7291,7 +7291,7 @@ }, "x-appwrite": { "method": "getAttribute", - "weight": 91, + "weight": 92, "cookies": false, "type": "", "deprecated": false, @@ -7365,7 +7365,7 @@ }, "x-appwrite": { "method": "deleteAttribute", - "weight": 102, + "weight": 103, "cookies": false, "type": "", "deprecated": false, @@ -7433,7 +7433,7 @@ "tags": [ "databases" ], - "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "200": { "description": "AttributeRelationship", @@ -7448,7 +7448,7 @@ }, "x-appwrite": { "method": "updateRelationshipAttribute", - "weight": 101, + "weight": 102, "cookies": false, "type": "", "deprecated": false, @@ -7559,7 +7559,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -7648,7 +7648,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -7759,7 +7759,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -7858,7 +7858,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -7961,7 +7961,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -8049,7 +8049,7 @@ }, "x-appwrite": { "method": "listIndexes", - "weight": 104, + "weight": 105, "cookies": false, "type": "", "deprecated": false, @@ -8119,7 +8119,7 @@ "tags": [ "databases" ], - "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\r\nAttributes can be `key`, `fulltext`, and `unique`.", + "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\nAttributes can be `key`, `fulltext`, and `unique`.", "responses": { "202": { "description": "Index", @@ -8134,7 +8134,7 @@ }, "x-appwrite": { "method": "createIndex", - "weight": 103, + "weight": 104, "cookies": false, "type": "", "deprecated": false, @@ -8257,7 +8257,7 @@ }, "x-appwrite": { "method": "getIndex", - "weight": 105, + "weight": 106, "cookies": false, "type": "", "deprecated": false, @@ -8331,7 +8331,7 @@ }, "x-appwrite": { "method": "deleteIndex", - "weight": 106, + "weight": 107, "cookies": false, "type": "", "deprecated": false, @@ -8414,7 +8414,7 @@ }, "x-appwrite": { "method": "list", - "weight": 287, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -8490,7 +8490,7 @@ }, "x-appwrite": { "method": "create", - "weight": 286, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -8545,6 +8545,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -8563,6 +8564,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -8570,24 +8573,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -8730,7 +8739,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 288, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -8767,7 +8776,7 @@ "tags": [ "functions" ], - "description": "List allowed function specifications for this instance.\r\n", + "description": "List allowed function specifications for this instance.\n", "responses": { "200": { "description": "Specifications List", @@ -8782,7 +8791,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 289, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -8835,7 +8844,7 @@ }, "x-appwrite": { "method": "get", - "weight": 290, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -8897,7 +8906,7 @@ }, "x-appwrite": { "method": "update", - "weight": 293, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -8959,6 +8968,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -8977,6 +8987,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -8984,24 +8996,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9114,7 +9132,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 296, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -9178,7 +9196,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 298, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -9249,7 +9267,7 @@ "tags": [ "functions" ], - "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\r\n\r\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\r\n\r\nUse the \"command\" param to set the entrypoint used to execute your code.", + "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\n\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\n\nUse the \"command\" param to set the entrypoint used to execute your code.", "responses": { "202": { "description": "Deployment", @@ -9264,7 +9282,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 297, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -9363,7 +9381,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 299, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -9435,7 +9453,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 295, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -9500,7 +9518,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 300, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -9567,7 +9585,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 301, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -9655,7 +9673,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 302, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -9722,7 +9740,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 294, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -9798,7 +9816,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -9888,7 +9906,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -9941,7 +9959,7 @@ "body": { "type": "string", "description": "HTTP body of execution. Default value is empty string.", - "x-example": null + "x-example": "" }, "async": { "type": "boolean", @@ -10007,7 +10025,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -10068,7 +10086,7 @@ "tags": [ "functions" ], - "description": "Delete a function execution by its unique ID.\r\n", + "description": "Delete a function execution by its unique ID.\n", "responses": { "204": { "description": "No content" @@ -10076,7 +10094,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 306, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -10150,7 +10168,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 308, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -10212,7 +10230,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 307, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -10301,7 +10319,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 309, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -10373,7 +10391,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 310, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -10462,7 +10480,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 311, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -10536,7 +10554,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -10592,7 +10610,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -10648,7 +10666,7 @@ }, "x-appwrite": { "method": "get", - "weight": 124, + "weight": 125, "cookies": false, "type": "", "deprecated": false, @@ -10700,7 +10718,7 @@ }, "x-appwrite": { "method": "getAntivirus", - "weight": 146, + "weight": 147, "cookies": false, "type": "", "deprecated": false, @@ -10752,7 +10770,7 @@ }, "x-appwrite": { "method": "getCache", - "weight": 127, + "weight": 128, "cookies": false, "type": "", "deprecated": false, @@ -10804,7 +10822,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 133, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -10867,7 +10885,7 @@ }, "x-appwrite": { "method": "getDB", - "weight": 126, + "weight": 127, "cookies": false, "type": "", "deprecated": false, @@ -10919,7 +10937,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 129, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -10971,7 +10989,7 @@ }, "x-appwrite": { "method": "getQueue", - "weight": 128, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -11023,7 +11041,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 135, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -11088,7 +11106,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 134, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -11153,7 +11171,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 136, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -11229,7 +11247,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 137, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -11279,7 +11297,7 @@ "tags": [ "health" ], - "description": "Returns the amount of failed jobs in a given queue.\r\n", + "description": "Returns the amount of failed jobs in a given queue.\n", "responses": { "200": { "description": "Health Queue", @@ -11294,7 +11312,7 @@ }, "x-appwrite": { "method": "getFailedJobs", - "weight": 147, + "weight": 148, "cookies": false, "type": "", "deprecated": false, @@ -11385,7 +11403,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 141, + "weight": 142, "cookies": false, "type": "", "deprecated": false, @@ -11450,7 +11468,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 132, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -11515,7 +11533,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 138, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -11580,7 +11598,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 139, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -11645,7 +11663,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 140, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -11710,7 +11728,7 @@ }, "x-appwrite": { "method": "getQueueUsage", - "weight": 142, + "weight": 143, "cookies": false, "type": "", "deprecated": false, @@ -11775,7 +11793,7 @@ }, "x-appwrite": { "method": "getQueueUsageDump", - "weight": 143, + "weight": 144, "cookies": false, "type": "", "deprecated": false, @@ -11840,7 +11858,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 131, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -11905,7 +11923,7 @@ }, "x-appwrite": { "method": "getStorage", - "weight": 145, + "weight": 146, "cookies": false, "type": "", "deprecated": false, @@ -11957,7 +11975,7 @@ }, "x-appwrite": { "method": "getStorageLocal", - "weight": 144, + "weight": 145, "cookies": false, "type": "", "deprecated": false, @@ -12009,7 +12027,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 130, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -12046,7 +12064,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -12061,7 +12079,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -12117,7 +12135,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -12173,7 +12191,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -12229,7 +12247,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -12285,7 +12303,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -12341,7 +12359,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -12397,7 +12415,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -12453,7 +12471,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -12509,7 +12527,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 388, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -12588,7 +12606,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 385, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -12720,7 +12738,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -12735,7 +12753,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 392, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -12884,7 +12902,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 387, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -13027,7 +13045,7 @@ "tags": [ "messaging" ], - "description": "Update a push notification by its unique ID.\r\n", + "description": "Update a push notification by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13042,7 +13060,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 394, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -13202,7 +13220,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 386, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -13299,7 +13317,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13314,7 +13332,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 393, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -13414,7 +13432,7 @@ "tags": [ "messaging" ], - "description": "Get a message by its unique ID.\r\n", + "description": "Get a message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13429,7 +13447,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 391, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -13485,7 +13503,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 395, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -13550,7 +13568,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 389, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -13628,7 +13646,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 390, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -13706,7 +13724,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 360, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -13785,7 +13803,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 359, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -13893,7 +13911,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 372, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -14004,7 +14022,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 358, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -14092,7 +14110,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 371, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -14183,7 +14201,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 350, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -14301,7 +14319,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 363, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -14422,7 +14440,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 353, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -14520,7 +14538,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 366, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -14621,7 +14639,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 351, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -14729,7 +14747,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 364, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -14840,7 +14858,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 352, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -14986,7 +15004,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 365, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -15134,7 +15152,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 354, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -15232,7 +15250,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 367, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -15333,7 +15351,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 355, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -15431,7 +15449,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 368, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -15532,7 +15550,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 356, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -15630,7 +15648,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 369, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -15731,7 +15749,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 357, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -15829,7 +15847,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 370, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -15915,7 +15933,7 @@ "tags": [ "messaging" ], - "description": "Get a provider by its unique ID.\r\n", + "description": "Get a provider by its unique ID.\n", "responses": { "200": { "description": "Provider", @@ -15930,7 +15948,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 362, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -15986,7 +16004,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 373, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -16051,7 +16069,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 361, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -16129,7 +16147,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 382, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -16207,7 +16225,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 375, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -16284,7 +16302,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 374, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -16355,7 +16373,7 @@ "tags": [ "messaging" ], - "description": "Get a topic by its unique ID.\r\n", + "description": "Get a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -16370,7 +16388,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 377, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -16418,7 +16436,7 @@ "tags": [ "messaging" ], - "description": "Update a topic by its unique ID.\r\n", + "description": "Update a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -16433,7 +16451,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 378, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -16513,7 +16531,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 379, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -16578,7 +16596,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 376, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -16656,7 +16674,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 381, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -16743,7 +16761,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -16822,7 +16840,7 @@ "tags": [ "messaging" ], - "description": "Get a subscriber by its unique ID.\r\n", + "description": "Get a subscriber by its unique ID.\n", "responses": { "200": { "description": "Subscriber", @@ -16837,7 +16855,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 383, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -16903,7 +16921,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -16982,7 +17000,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 201, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -17058,7 +17076,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 200, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -17188,7 +17206,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 202, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -17250,7 +17268,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 203, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -17377,7 +17395,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 204, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -17441,7 +17459,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -17516,7 +17534,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -17531,7 +17549,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -17633,7 +17651,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -17709,7 +17727,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -17802,7 +17820,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -17873,7 +17891,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -17944,7 +17962,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -18164,7 +18182,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -18242,7 +18260,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -18322,7 +18340,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -18411,7 +18429,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -18477,7 +18495,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -18555,7 +18573,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -18608,7 +18626,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -18623,7 +18641,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -18698,7 +18716,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -18713,7 +18731,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -18813,7 +18831,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -18828,7 +18846,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -18889,7 +18907,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -18904,7 +18922,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -18995,7 +19013,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -19058,7 +19076,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -19073,7 +19091,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -19174,7 +19192,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -19238,7 +19256,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -19323,7 +19341,7 @@ }, "x-appwrite": { "method": "list", - "weight": 239, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -19399,7 +19417,7 @@ }, "x-appwrite": { "method": "create", - "weight": 230, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -19490,7 +19508,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 233, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -19578,7 +19596,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 231, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -19666,7 +19684,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 247, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -19737,7 +19755,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 270, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -19801,7 +19819,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 232, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -19889,7 +19907,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 235, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -19977,7 +19995,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 236, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -20095,7 +20113,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 237, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -20201,7 +20219,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 234, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -20309,7 +20327,7 @@ }, "x-appwrite": { "method": "get", - "weight": 240, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -20364,7 +20382,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 268, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -20428,7 +20446,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 253, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -20511,7 +20529,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 271, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -20581,7 +20599,7 @@ "tags": [ "users" ], - "description": "Update the user labels by its unique ID. \r\n\r\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", + "description": "Update the user labels by its unique ID. \n\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", "responses": { "200": { "description": "User", @@ -20596,7 +20614,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 249, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -20682,7 +20700,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 245, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -20759,7 +20777,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 244, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -20823,7 +20841,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 258, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -20906,7 +20924,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 263, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -20985,7 +21003,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 259, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -21049,7 +21067,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 260, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -21111,7 +21129,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 262, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -21173,7 +21191,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 261, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -21237,7 +21255,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 251, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -21320,7 +21338,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 252, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -21403,7 +21421,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 254, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -21486,7 +21504,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 241, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -21548,7 +21566,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 256, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -21631,7 +21649,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 243, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -21678,7 +21696,7 @@ "tags": [ "users" ], - "description": "Creates a session for a user. Returns an immediately usable session object.\r\n\r\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", + "description": "Creates a session for a user. Returns an immediately usable session object.\n\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", "responses": { "201": { "description": "Session", @@ -21693,7 +21711,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 264, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -21748,7 +21766,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 267, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -21805,7 +21823,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 266, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -21879,7 +21897,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 248, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -21962,7 +21980,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 246, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -22038,7 +22056,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 238, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -22151,7 +22169,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 242, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -22224,7 +22242,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 257, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -22316,7 +22334,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 269, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -22376,7 +22394,7 @@ "tags": [ "users" ], - "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\r\n", + "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\n", "responses": { "201": { "description": "Token", @@ -22391,7 +22409,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 265, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -22476,7 +22494,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 255, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -22559,7 +22577,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 250, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -25580,12 +25598,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -25615,7 +25633,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -25780,7 +25798,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -26592,7 +26610,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -27040,7 +27058,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -27062,6 +27080,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -27071,7 +27094,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/swagger2-1.6.x-client.json b/app/config/specs/swagger2-1.6.x-client.json index f070b1a4b0..b1b9ce8dca 100644 --- a/app/config/specs/swagger2-1.6.x-client.json +++ b/app/config/specs/swagger2-1.6.x-client.json @@ -5101,7 +5101,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -5186,7 +5186,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -5307,7 +5307,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -5381,7 +5381,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -5457,7 +5457,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -5981,7 +5981,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -6070,7 +6070,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -6145,7 +6145,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -6230,7 +6230,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -6324,7 +6324,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -6396,7 +6396,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -6487,7 +6487,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -6561,7 +6561,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -6635,7 +6635,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -6836,7 +6836,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -6910,7 +6910,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -6987,7 +6987,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -7081,7 +7081,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -7145,7 +7145,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -7222,7 +7222,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -7277,7 +7277,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -7288,7 +7288,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -7373,7 +7373,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -7479,7 +7479,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -7490,7 +7490,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -7562,7 +7562,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -7650,7 +7650,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -7724,7 +7724,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -7822,7 +7822,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -7885,7 +7885,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -9445,12 +9445,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -9480,7 +9480,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -10008,7 +10008,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -10030,6 +10030,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -10039,7 +10044,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/swagger2-1.6.x-console.json b/app/config/specs/swagger2-1.6.x-console.json index ef651e4723..9ce9d5f60d 100644 --- a/app/config/specs/swagger2-1.6.x-console.json +++ b/app/config/specs/swagger2-1.6.x-console.json @@ -4659,7 +4659,7 @@ }, "x-appwrite": { "method": "chat", - "weight": 332, + "weight": 333, "cookies": false, "type": "", "deprecated": false, @@ -4731,7 +4731,7 @@ }, "x-appwrite": { "method": "variables", - "weight": 331, + "weight": 332, "cookies": false, "type": "", "deprecated": false, @@ -7650,7 +7650,7 @@ "type": "integer", "description": "Maximum size of the string attribute.", "default": null, - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -9427,7 +9427,7 @@ }, "x-appwrite": { "method": "list", - "weight": 288, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -9501,7 +9501,7 @@ }, "x-appwrite": { "method": "create", - "weight": 287, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -9609,7 +9609,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9734,7 +9735,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -9772,7 +9773,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 289, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -9825,7 +9826,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 290, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -9879,7 +9880,7 @@ }, "x-appwrite": { "method": "listTemplates", - "weight": 313, + "weight": 314, "cookies": false, "type": "", "deprecated": false, @@ -9977,7 +9978,7 @@ }, "x-appwrite": { "method": "getTemplate", - "weight": 314, + "weight": 315, "cookies": false, "type": "", "deprecated": false, @@ -10039,7 +10040,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 293, + "weight": 294, "cookies": false, "type": "", "deprecated": false, @@ -10113,7 +10114,7 @@ }, "x-appwrite": { "method": "get", - "weight": 291, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -10174,7 +10175,7 @@ }, "x-appwrite": { "method": "update", - "weight": 294, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -10284,7 +10285,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -10386,7 +10388,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -10415,7 +10417,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 297, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -10478,7 +10480,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 299, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -10560,7 +10562,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 298, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -10654,7 +10656,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 300, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -10723,7 +10725,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 296, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -10787,7 +10789,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 301, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -10853,7 +10855,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 302, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -10937,7 +10939,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 303, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -11008,7 +11010,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 295, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -11081,7 +11083,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -11166,7 +11168,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -11287,7 +11289,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -11354,7 +11356,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 307, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -11425,7 +11427,7 @@ }, "x-appwrite": { "method": "getFunctionUsage", - "weight": 292, + "weight": 293, "cookies": false, "type": "", "deprecated": false, @@ -11507,7 +11509,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 309, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -11568,7 +11570,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 308, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -11656,7 +11658,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 310, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -11725,7 +11727,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 311, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -11813,7 +11815,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 312, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -11884,7 +11886,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -11960,7 +11962,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -13888,7 +13890,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 389, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -13965,7 +13967,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 386, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -14125,7 +14127,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 393, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -14282,7 +14284,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 388, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -14457,7 +14459,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 395, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -14629,7 +14631,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 387, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -14749,7 +14751,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 394, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -14867,7 +14869,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 392, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -14926,7 +14928,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 396, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -14990,7 +14992,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 390, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -15066,7 +15068,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 391, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -15142,7 +15144,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 361, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -15219,7 +15221,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 360, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -15336,7 +15338,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 373, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -15451,7 +15453,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 359, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -15544,7 +15546,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 372, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -15635,7 +15637,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 351, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -15764,7 +15766,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 364, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -15891,7 +15893,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 354, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -15996,7 +15998,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 367, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -16099,7 +16101,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 352, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -16216,7 +16218,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 365, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -16331,7 +16333,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 353, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -16492,7 +16494,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 366, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -16650,7 +16652,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 355, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -16755,7 +16757,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 368, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -16858,7 +16860,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 356, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -16963,7 +16965,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 369, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -17066,7 +17068,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 357, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -17171,7 +17173,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 370, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -17274,7 +17276,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 358, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -17379,7 +17381,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 371, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -17482,7 +17484,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 363, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -17541,7 +17543,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 374, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -17605,7 +17607,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 362, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -17681,7 +17683,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 383, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -17757,7 +17759,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 376, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -17832,7 +17834,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 375, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -17924,7 +17926,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 378, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -17986,7 +17988,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 379, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -18069,7 +18071,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 380, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -18133,7 +18135,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 377, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -18209,7 +18211,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 382, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -18292,7 +18294,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -18384,7 +18386,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 384, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -18451,7 +18453,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -18526,7 +18528,7 @@ }, "x-appwrite": { "method": "list", - "weight": 338, + "weight": 339, "cookies": false, "type": "", "deprecated": false, @@ -18555,7 +18557,7 @@ "parameters": [ { "name": "queries", - "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, resources, statusCounters, resourceData, errors", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, statusCounters, resourceData, errors", "required": false, "type": "array", "collectionFormat": "multi", @@ -18601,7 +18603,7 @@ }, "x-appwrite": { "method": "createAppwriteMigration", - "weight": 333, + "weight": 334, "cookies": false, "type": "", "deprecated": false, @@ -18697,7 +18699,7 @@ }, "x-appwrite": { "method": "getAppwriteReport", - "weight": 340, + "weight": 341, "cookies": false, "type": "", "deprecated": false, @@ -18787,7 +18789,7 @@ }, "x-appwrite": { "method": "createFirebaseMigration", - "weight": 335, + "weight": 336, "cookies": false, "type": "", "deprecated": false, @@ -18869,7 +18871,7 @@ }, "x-appwrite": { "method": "deleteFirebaseAuth", - "weight": 346, + "weight": 347, "cookies": false, "type": "", "deprecated": false, @@ -18921,7 +18923,7 @@ }, "x-appwrite": { "method": "createFirebaseOAuthMigration", - "weight": 334, + "weight": 335, "cookies": false, "type": "", "deprecated": false, @@ -19003,7 +19005,7 @@ }, "x-appwrite": { "method": "listFirebaseProjects", - "weight": 345, + "weight": 346, "cookies": false, "type": "", "deprecated": false, @@ -19055,7 +19057,7 @@ }, "x-appwrite": { "method": "getFirebaseReport", - "weight": 341, + "weight": 342, "cookies": false, "type": "", "deprecated": false, @@ -19128,7 +19130,7 @@ }, "x-appwrite": { "method": "getFirebaseReportOAuth", - "weight": 342, + "weight": 343, "cookies": false, "type": "", "deprecated": false, @@ -19201,7 +19203,7 @@ }, "x-appwrite": { "method": "createNHostMigration", - "weight": 337, + "weight": 338, "cookies": false, "type": "", "deprecated": false, @@ -19324,7 +19326,7 @@ }, "x-appwrite": { "method": "getNHostReport", - "weight": 348, + "weight": 349, "cookies": false, "type": "", "deprecated": false, @@ -19446,7 +19448,7 @@ }, "x-appwrite": { "method": "createSupabaseMigration", - "weight": 336, + "weight": 337, "cookies": false, "type": "", "deprecated": false, @@ -19562,7 +19564,7 @@ }, "x-appwrite": { "method": "getSupabaseReport", - "weight": 347, + "weight": 348, "cookies": false, "type": "", "deprecated": false, @@ -19677,7 +19679,7 @@ }, "x-appwrite": { "method": "get", - "weight": 339, + "weight": 340, "cookies": false, "type": "", "deprecated": false, @@ -19737,7 +19739,7 @@ }, "x-appwrite": { "method": "retry", - "weight": 349, + "weight": 350, "cookies": false, "type": "", "deprecated": false, @@ -19792,7 +19794,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 350, + "weight": 351, "cookies": false, "type": "", "deprecated": false, @@ -19854,7 +19856,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 195, + "weight": 196, "cookies": false, "type": "", "deprecated": false, @@ -19940,7 +19942,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 197, + "weight": 198, "cookies": false, "type": "", "deprecated": false, @@ -19990,7 +19992,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 196, + "weight": 197, "cookies": false, "type": "", "deprecated": false, @@ -20069,7 +20071,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 198, + "weight": 199, "cookies": false, "type": "", "deprecated": false, @@ -20129,7 +20131,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 199, + "weight": 200, "cookies": false, "type": "", "deprecated": false, @@ -20208,7 +20210,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 200, + "weight": 201, "cookies": false, "type": "", "deprecated": false, @@ -20682,7 +20684,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 169, + "weight": 170, "cookies": false, "type": "", "deprecated": false, @@ -20918,7 +20920,7 @@ }, "x-appwrite": { "method": "updateAuthDuration", - "weight": 162, + "weight": 163, "cookies": false, "type": "", "deprecated": false, @@ -20998,7 +21000,7 @@ }, "x-appwrite": { "method": "updateAuthLimit", - "weight": 161, + "weight": 162, "cookies": false, "type": "", "deprecated": false, @@ -21078,7 +21080,7 @@ }, "x-appwrite": { "method": "updateAuthSessionsLimit", - "weight": 167, + "weight": 168, "cookies": false, "type": "", "deprecated": false, @@ -21134,6 +21136,100 @@ ] } }, + "\/projects\/{projectId}\/auth\/memberships-privacy": { + "patch": { + "summary": "Update project memberships privacy attributes", + "operationId": "projectsUpdateMembershipsPrivacy", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "projects" + ], + "description": "", + "responses": { + "200": { + "description": "Project", + "schema": { + "$ref": "#\/definitions\/project" + } + } + }, + "x-appwrite": { + "method": "updateMembershipsPrivacy", + "weight": 161, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "projects\/update-memberships-privacy.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "projects.write", + "platforms": [ + "console" + ], + "packaging": false, + "offline-model": "", + "offline-key": "", + "offline-response-key": "$id", + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [] + } + ], + "parameters": [ + { + "name": "projectId", + "description": "Project unique ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "userName": { + "type": "boolean", + "description": "Set to true to show userName to members of a team.", + "default": null, + "x-example": false + }, + "userEmail": { + "type": "boolean", + "description": "Set to true to show email to members of a team.", + "default": null, + "x-example": false + }, + "mfa": { + "type": "boolean", + "description": "Set to true to show mfa to members of a team.", + "default": null, + "x-example": false + } + }, + "required": [ + "userName", + "userEmail", + "mfa" + ] + } + } + ] + } + }, "\/projects\/{projectId}\/auth\/mock-numbers": { "patch": { "summary": "Update the mock numbers for the project", @@ -21158,7 +21254,7 @@ }, "x-appwrite": { "method": "updateMockNumbers", - "weight": 168, + "weight": 169, "cookies": false, "type": "", "deprecated": false, @@ -21241,7 +21337,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordDictionary", - "weight": 165, + "weight": 166, "cookies": false, "type": "", "deprecated": false, @@ -21321,7 +21417,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordHistory", - "weight": 164, + "weight": 165, "cookies": false, "type": "", "deprecated": false, @@ -21401,7 +21497,7 @@ }, "x-appwrite": { "method": "updatePersonalDataCheck", - "weight": 166, + "weight": 167, "cookies": false, "type": "", "deprecated": false, @@ -21561,7 +21657,7 @@ }, "x-appwrite": { "method": "updateAuthStatus", - "weight": 163, + "weight": 164, "cookies": false, "type": "", "deprecated": false, @@ -21660,7 +21756,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 181, + "weight": 182, "cookies": false, "type": "", "deprecated": false, @@ -21749,7 +21845,7 @@ }, "x-appwrite": { "method": "listKeys", - "weight": 177, + "weight": 178, "cookies": false, "type": "", "deprecated": false, @@ -21809,7 +21905,7 @@ }, "x-appwrite": { "method": "createKey", - "weight": 176, + "weight": 177, "cookies": false, "type": "", "deprecated": false, @@ -21905,7 +22001,7 @@ }, "x-appwrite": { "method": "getKey", - "weight": 178, + "weight": 179, "cookies": false, "type": "", "deprecated": false, @@ -21973,7 +22069,7 @@ }, "x-appwrite": { "method": "updateKey", - "weight": 179, + "weight": 180, "cookies": false, "type": "", "deprecated": false, @@ -22070,7 +22166,7 @@ }, "x-appwrite": { "method": "deleteKey", - "weight": 180, + "weight": 181, "cookies": false, "type": "", "deprecated": false, @@ -22281,7 +22377,7 @@ }, "x-appwrite": { "method": "listPlatforms", - "weight": 183, + "weight": 184, "cookies": false, "type": "", "deprecated": false, @@ -22341,7 +22437,7 @@ }, "x-appwrite": { "method": "createPlatform", - "weight": 182, + "weight": 183, "cookies": false, "type": "", "deprecated": false, @@ -22465,7 +22561,7 @@ }, "x-appwrite": { "method": "getPlatform", - "weight": 184, + "weight": 185, "cookies": false, "type": "", "deprecated": false, @@ -22533,7 +22629,7 @@ }, "x-appwrite": { "method": "updatePlatform", - "weight": 185, + "weight": 186, "cookies": false, "type": "", "deprecated": false, @@ -22632,7 +22728,7 @@ }, "x-appwrite": { "method": "deletePlatform", - "weight": 186, + "weight": 187, "cookies": false, "type": "", "deprecated": false, @@ -22884,7 +22980,7 @@ }, "x-appwrite": { "method": "updateSmtp", - "weight": 187, + "weight": 188, "cookies": false, "type": "", "deprecated": false, @@ -23013,7 +23109,7 @@ }, "x-appwrite": { "method": "createSmtpTest", - "weight": 188, + "weight": 189, "cookies": false, "type": "", "deprecated": false, @@ -23233,7 +23329,7 @@ }, "x-appwrite": { "method": "getEmailTemplate", - "weight": 190, + "weight": 191, "cookies": false, "type": "", "deprecated": false, @@ -23455,7 +23551,7 @@ }, "x-appwrite": { "method": "updateEmailTemplate", - "weight": 192, + "weight": 193, "cookies": false, "type": "", "deprecated": false, @@ -23720,7 +23816,7 @@ }, "x-appwrite": { "method": "deleteEmailTemplate", - "weight": 194, + "weight": 195, "cookies": false, "type": "", "deprecated": false, @@ -23944,7 +24040,7 @@ }, "x-appwrite": { "method": "getSmsTemplate", - "weight": 189, + "weight": 190, "cookies": false, "type": "", "deprecated": false, @@ -24163,7 +24259,7 @@ }, "x-appwrite": { "method": "updateSmsTemplate", - "weight": 191, + "weight": 192, "cookies": false, "type": "", "deprecated": false, @@ -24400,7 +24496,7 @@ }, "x-appwrite": { "method": "deleteSmsTemplate", - "weight": 193, + "weight": 194, "cookies": false, "type": "", "deprecated": false, @@ -24621,7 +24717,7 @@ }, "x-appwrite": { "method": "listWebhooks", - "weight": 171, + "weight": 172, "cookies": false, "type": "", "deprecated": false, @@ -24681,7 +24777,7 @@ }, "x-appwrite": { "method": "createWebhook", - "weight": 170, + "weight": 171, "cookies": false, "type": "", "deprecated": false, @@ -24803,7 +24899,7 @@ }, "x-appwrite": { "method": "getWebhook", - "weight": 172, + "weight": 173, "cookies": false, "type": "", "deprecated": false, @@ -24871,7 +24967,7 @@ }, "x-appwrite": { "method": "updateWebhook", - "weight": 173, + "weight": 174, "cookies": false, "type": "", "deprecated": false, @@ -24994,7 +25090,7 @@ }, "x-appwrite": { "method": "deleteWebhook", - "weight": 175, + "weight": 176, "cookies": false, "type": "", "deprecated": false, @@ -25064,7 +25160,7 @@ }, "x-appwrite": { "method": "updateWebhookSignature", - "weight": 174, + "weight": 175, "cookies": false, "type": "", "deprecated": false, @@ -25134,7 +25230,7 @@ }, "x-appwrite": { "method": "listRules", - "weight": 316, + "weight": 317, "cookies": false, "type": "", "deprecated": false, @@ -25207,7 +25303,7 @@ }, "x-appwrite": { "method": "createRule", - "weight": 315, + "weight": 316, "cookies": false, "type": "", "deprecated": false, @@ -25298,7 +25394,7 @@ }, "x-appwrite": { "method": "getRule", - "weight": 317, + "weight": 318, "cookies": false, "type": "", "deprecated": false, @@ -25353,7 +25449,7 @@ }, "x-appwrite": { "method": "deleteRule", - "weight": 318, + "weight": 319, "cookies": false, "type": "", "deprecated": false, @@ -25415,7 +25511,7 @@ }, "x-appwrite": { "method": "updateRuleVerification", - "weight": 319, + "weight": 320, "cookies": false, "type": "", "deprecated": false, @@ -25477,7 +25573,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 202, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -25551,7 +25647,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 201, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -25692,7 +25788,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 203, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -25753,7 +25849,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 204, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -25888,7 +25984,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 205, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -25951,7 +26047,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -26036,7 +26132,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -26130,7 +26226,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -26202,7 +26298,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -26293,7 +26389,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -26367,7 +26463,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -26441,7 +26537,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -26642,7 +26738,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -26716,7 +26812,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 215, + "weight": 216, "cookies": false, "type": "", "deprecated": false, @@ -26790,7 +26886,7 @@ }, "x-appwrite": { "method": "getBucketUsage", - "weight": 216, + "weight": 217, "cookies": false, "type": "", "deprecated": false, @@ -26872,7 +26968,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -26949,7 +27045,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -27043,7 +27139,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -27107,7 +27203,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -27184,7 +27280,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -27250,7 +27346,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 230, + "weight": 231, "cookies": false, "type": "", "deprecated": false, @@ -27313,7 +27409,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -27324,7 +27420,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -27409,7 +27505,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -27515,7 +27611,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -27526,7 +27622,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -27598,7 +27694,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -27686,7 +27782,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -27760,7 +27856,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -27857,7 +27953,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -27919,7 +28015,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -28001,7 +28097,7 @@ }, "x-appwrite": { "method": "list", - "weight": 240, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -28075,7 +28171,7 @@ }, "x-appwrite": { "method": "create", - "weight": 231, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -28172,7 +28268,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 234, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -28265,7 +28361,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 232, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -28358,7 +28454,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 248, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -28429,7 +28525,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 271, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -28492,7 +28588,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 233, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -28585,7 +28681,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 236, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -28678,7 +28774,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 237, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -28806,7 +28902,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 238, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -28920,7 +29016,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 235, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -29034,7 +29130,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 273, + "weight": 274, "cookies": false, "type": "", "deprecated": false, @@ -29108,7 +29204,7 @@ }, "x-appwrite": { "method": "get", - "weight": 241, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -29164,7 +29260,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 269, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -29227,7 +29323,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 254, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -29308,7 +29404,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 272, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -29392,7 +29488,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 250, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -29476,7 +29572,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 246, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -29551,7 +29647,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 245, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -29614,7 +29710,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 259, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -29695,7 +29791,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 264, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -29771,7 +29867,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 260, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -29834,7 +29930,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 261, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -29895,7 +29991,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 263, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -29956,7 +30052,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 262, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -30019,7 +30115,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 252, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -30100,7 +30196,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 253, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -30181,7 +30277,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 255, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -30262,7 +30358,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 242, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -30323,7 +30419,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 257, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -30404,7 +30500,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 244, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -30465,7 +30561,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 265, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -30521,7 +30617,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 268, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -30579,7 +30675,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 267, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -30650,7 +30746,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 249, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -30731,7 +30827,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 247, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -30805,7 +30901,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 239, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -30920,7 +31016,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 243, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -30990,7 +31086,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 258, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -31084,7 +31180,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 270, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -31156,7 +31252,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 266, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -31240,7 +31336,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 256, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -31321,7 +31417,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 251, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -31402,7 +31498,7 @@ }, "x-appwrite": { "method": "listRepositories", - "weight": 278, + "weight": 279, "cookies": false, "type": "", "deprecated": false, @@ -31471,7 +31567,7 @@ }, "x-appwrite": { "method": "createRepository", - "weight": 279, + "weight": 280, "cookies": false, "type": "", "deprecated": false, @@ -31558,7 +31654,7 @@ }, "x-appwrite": { "method": "getRepository", - "weight": 280, + "weight": 281, "cookies": false, "type": "", "deprecated": false, @@ -31628,7 +31724,7 @@ }, "x-appwrite": { "method": "listRepositoryBranches", - "weight": 281, + "weight": 282, "cookies": false, "type": "", "deprecated": false, @@ -31698,7 +31794,7 @@ }, "x-appwrite": { "method": "getRepositoryContents", - "weight": 276, + "weight": 277, "cookies": false, "type": "", "deprecated": false, @@ -31777,7 +31873,7 @@ }, "x-appwrite": { "method": "createRepositoryDetection", - "weight": 277, + "weight": 278, "cookies": false, "type": "", "deprecated": false, @@ -31857,7 +31953,7 @@ }, "x-appwrite": { "method": "updateExternalDeployments", - "weight": 286, + "weight": 287, "cookies": false, "type": "", "deprecated": false, @@ -31945,7 +32041,7 @@ }, "x-appwrite": { "method": "listInstallations", - "weight": 283, + "weight": 284, "cookies": false, "type": "", "deprecated": false, @@ -32020,7 +32116,7 @@ }, "x-appwrite": { "method": "getInstallation", - "weight": 284, + "weight": 285, "cookies": false, "type": "", "deprecated": false, @@ -32075,7 +32171,7 @@ }, "x-appwrite": { "method": "deleteInstallation", - "weight": 285, + "weight": 286, "cookies": false, "type": "", "deprecated": false, @@ -35373,12 +35469,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -35408,7 +35504,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -35574,7 +35670,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -36495,6 +36591,21 @@ "description": "Whether or not to send session alert emails to users.", "x-example": true }, + "authMembershipsUserName": { + "type": "boolean", + "description": "Whether or not to show user names in the teams membership response.", + "x-example": true + }, + "authMembershipsUserEmail": { + "type": "boolean", + "description": "Whether or not to show user emails in the teams membership response.", + "x-example": true + }, + "authMembershipsMfa": { + "type": "boolean", + "description": "Whether or not to show user MFA status in the teams membership response.", + "x-example": true + }, "oAuthProviders": { "type": "array", "description": "List of Auth Providers.", @@ -36704,6 +36815,9 @@ "authPersonalDataCheck", "authMockNumbers", "authSessionAlerts", + "authMembershipsUserName", + "authMembershipsUserEmail", + "authMembershipsMfa", "oAuthProviders", "platforms", "webhooks", @@ -38326,7 +38440,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -38967,7 +39081,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -38989,6 +39103,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -38998,7 +39117,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] }, "migration": { @@ -39035,9 +39155,14 @@ "description": "A string containing the type of source of the migration.", "x-example": "Appwrite" }, + "destination": { + "type": "string", + "description": "A string containing the type of destination of the migration.", + "x-example": "Appwrite" + }, "resources": { "type": "array", - "description": "Resources to migration.", + "description": "Resources to migrate.", "items": { "type": "string" }, @@ -39073,6 +39198,7 @@ "status", "stage", "source", + "destination", "resources", "statusCounters", "resourceData", diff --git a/app/config/specs/swagger2-1.6.x-server.json b/app/config/specs/swagger2-1.6.x-server.json index 37018916fa..2c8e80c65e 100644 --- a/app/config/specs/swagger2-1.6.x-server.json +++ b/app/config/specs/swagger2-1.6.x-server.json @@ -7157,7 +7157,7 @@ "type": "integer", "description": "Maximum size of the string attribute.", "default": null, - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -8535,7 +8535,7 @@ }, "x-appwrite": { "method": "list", - "weight": 288, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -8610,7 +8610,7 @@ }, "x-appwrite": { "method": "create", - "weight": 287, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -8719,7 +8719,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -8844,7 +8845,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -8882,7 +8883,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 289, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -8936,7 +8937,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 290, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -8991,7 +8992,7 @@ }, "x-appwrite": { "method": "get", - "weight": 291, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -9053,7 +9054,7 @@ }, "x-appwrite": { "method": "update", - "weight": 294, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -9164,7 +9165,8 @@ "cpp-20", "bun-1.0", "bun-1.1", - "go-1.23" + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9266,7 +9268,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -9295,7 +9297,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 297, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -9359,7 +9361,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 299, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -9442,7 +9444,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 298, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -9537,7 +9539,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 300, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -9607,7 +9609,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 296, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -9672,7 +9674,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 301, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -9739,7 +9741,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 302, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -9824,7 +9826,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 303, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -9896,7 +9898,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 295, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -9970,7 +9972,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 305, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -10057,7 +10059,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 304, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -10180,7 +10182,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 306, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -10249,7 +10251,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 307, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -10321,7 +10323,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 309, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -10383,7 +10385,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 308, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -10472,7 +10474,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 310, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -10542,7 +10544,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 311, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -10631,7 +10633,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 312, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -10703,7 +10705,7 @@ }, "x-appwrite": { "method": "query", - "weight": 330, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -10781,7 +10783,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 329, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -12750,7 +12752,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 389, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -12828,7 +12830,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 386, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -12989,7 +12991,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 393, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -13147,7 +13149,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 388, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -13323,7 +13325,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 395, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -13496,7 +13498,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 387, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -13617,7 +13619,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 394, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -13736,7 +13738,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 392, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -13796,7 +13798,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 396, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -13861,7 +13863,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 390, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -13938,7 +13940,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 391, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -14015,7 +14017,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 361, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -14093,7 +14095,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 360, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -14211,7 +14213,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 373, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -14327,7 +14329,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 359, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -14421,7 +14423,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 372, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -14513,7 +14515,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 351, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -14643,7 +14645,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 364, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -14771,7 +14773,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 354, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -14877,7 +14879,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 367, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -14981,7 +14983,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 352, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -15099,7 +15101,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 365, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -15215,7 +15217,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 353, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -15377,7 +15379,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 366, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -15536,7 +15538,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 355, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -15642,7 +15644,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 368, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -15746,7 +15748,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 356, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -15852,7 +15854,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 369, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -15956,7 +15958,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 357, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -16062,7 +16064,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 370, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -16166,7 +16168,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 358, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -16272,7 +16274,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 371, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -16376,7 +16378,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 363, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -16436,7 +16438,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 374, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -16501,7 +16503,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 362, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -16578,7 +16580,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 383, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -16655,7 +16657,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 376, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -16731,7 +16733,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 375, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -16824,7 +16826,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 378, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -16887,7 +16889,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 379, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -16971,7 +16973,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 380, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -17036,7 +17038,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 377, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -17113,7 +17115,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 382, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -17197,7 +17199,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 381, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -17291,7 +17293,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 384, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -17359,7 +17361,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 385, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -17436,7 +17438,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 202, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -17511,7 +17513,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 201, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -17653,7 +17655,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 203, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -17715,7 +17717,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 204, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -17851,7 +17853,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 205, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -17915,7 +17917,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 207, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -18002,7 +18004,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 206, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -18098,7 +18100,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 208, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -18172,7 +18174,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 213, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -18265,7 +18267,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 214, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -18341,7 +18343,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 210, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -18417,7 +18419,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 209, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -18620,7 +18622,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 211, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -18696,7 +18698,7 @@ }, "x-appwrite": { "method": "list", - "weight": 218, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -18775,7 +18777,7 @@ }, "x-appwrite": { "method": "create", - "weight": 217, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -18871,7 +18873,7 @@ }, "x-appwrite": { "method": "get", - "weight": 219, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -18937,7 +18939,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 221, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -19016,7 +19018,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 223, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -19073,7 +19075,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -19084,7 +19086,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 225, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -19171,7 +19173,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 224, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -19279,7 +19281,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -19290,7 +19292,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 226, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -19364,7 +19366,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 227, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -19454,7 +19456,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 229, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -19530,7 +19532,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 228, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -19629,7 +19631,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 220, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -19693,7 +19695,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 222, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -19777,7 +19779,7 @@ }, "x-appwrite": { "method": "list", - "weight": 240, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -19852,7 +19854,7 @@ }, "x-appwrite": { "method": "create", - "weight": 231, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -19950,7 +19952,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 234, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -20044,7 +20046,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 232, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -20138,7 +20140,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 248, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -20210,7 +20212,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 271, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -20274,7 +20276,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 233, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -20368,7 +20370,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 236, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -20462,7 +20464,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 237, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -20591,7 +20593,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 238, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -20706,7 +20708,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 235, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -20821,7 +20823,7 @@ }, "x-appwrite": { "method": "get", - "weight": 241, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -20878,7 +20880,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 269, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -20942,7 +20944,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 254, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -21024,7 +21026,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 272, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -21109,7 +21111,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 250, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -21194,7 +21196,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 246, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -21270,7 +21272,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 245, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -21334,7 +21336,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 259, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -21416,7 +21418,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 264, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -21493,7 +21495,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 260, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -21557,7 +21559,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 261, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -21619,7 +21621,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 263, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -21681,7 +21683,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 262, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -21745,7 +21747,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 252, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -21827,7 +21829,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 253, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -21909,7 +21911,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 255, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -21991,7 +21993,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 242, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -22053,7 +22055,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 257, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -22135,7 +22137,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 244, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -22197,7 +22199,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 265, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -22254,7 +22256,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 268, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -22313,7 +22315,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 267, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -22385,7 +22387,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 249, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -22467,7 +22469,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 247, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -22542,7 +22544,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 239, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -22658,7 +22660,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 243, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -22729,7 +22731,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 258, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -22824,7 +22826,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 270, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -22897,7 +22899,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 266, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -22982,7 +22984,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 256, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -23064,7 +23066,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 251, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -26082,12 +26084,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -26117,7 +26119,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -26283,7 +26285,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -27097,7 +27099,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -27548,7 +27550,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -27570,6 +27572,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -27579,7 +27586,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index fce6a871a3..b1b9ce8dca 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -87,7 +87,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -140,7 +140,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -222,7 +222,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -233,7 +233,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -315,7 +315,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -379,7 +379,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -444,7 +444,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -497,7 +497,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -566,7 +566,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -641,7 +641,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -709,7 +709,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -790,7 +790,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -860,7 +860,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -934,7 +934,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -1016,7 +1016,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1071,7 +1071,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1124,7 +1124,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1177,7 +1177,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1232,7 +1232,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1307,7 +1307,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1388,7 +1388,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1470,7 +1470,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1523,7 +1523,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1598,7 +1598,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1670,7 +1670,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1681,7 +1681,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1770,7 +1770,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1818,7 +1818,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1873,7 +1873,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1915,7 +1915,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1926,7 +1926,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -2006,7 +2006,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -2075,7 +2075,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\r\n\r\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\n\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "301": { "description": "No content" @@ -2083,7 +2083,7 @@ }, "x-appwrite": { "method": "createOAuth2Session", - "weight": 18, + "weight": 19, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2221,7 +2221,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2301,7 +2301,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2381,7 +2381,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2444,7 +2444,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2502,7 +2502,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2567,7 +2567,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2622,7 +2622,7 @@ }, "x-appwrite": { "method": "createPushTarget", - "weight": 53, + "weight": 54, "cookies": false, "type": "", "deprecated": false, @@ -2708,7 +2708,7 @@ }, "x-appwrite": { "method": "updatePushTarget", - "weight": 54, + "weight": 55, "cookies": false, "type": "", "deprecated": false, @@ -2784,7 +2784,7 @@ }, "x-appwrite": { "method": "deletePushTarget", - "weight": 55, + "weight": 56, "cookies": false, "type": "", "deprecated": false, @@ -2836,7 +2836,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2847,7 +2847,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2922,7 +2922,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2933,7 +2933,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -3017,7 +3017,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "No content" @@ -3025,7 +3025,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -3152,7 +3152,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -3163,7 +3163,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -3235,7 +3235,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -3246,7 +3246,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -3319,7 +3319,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -3401,7 +3401,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -3457,7 +3457,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3528,7 +3528,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image", @@ -3539,7 +3539,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3657,7 +3657,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3668,7 +3668,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3790,7 +3790,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -3801,7 +3801,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3857,7 +3857,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3868,7 +3868,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -4348,7 +4348,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -4359,7 +4359,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -4435,7 +4435,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -4446,7 +4446,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4530,7 +4530,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image", @@ -4541,7 +4541,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4636,7 +4636,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -4720,7 +4720,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -4828,7 +4828,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -4920,7 +4920,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -5019,7 +5019,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -5101,7 +5101,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -5167,7 +5167,7 @@ "summary": "Create execution", "operationId": "functionsCreateExecution", "consumes": [ - "multipart\/form-data" + "application\/json" ], "produces": [ "multipart\/form-data" @@ -5186,7 +5186,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -5226,65 +5226,59 @@ "in": "path" }, { - "name": "body", - "description": "HTTP body of execution. Default value is empty string.", - "required": false, - "type": "payload", - "default": "", - "in": "formData" - }, - { - "name": "async", - "description": "Execute code in the background. Default value is false.", - "required": false, - "type": "boolean", - "x-example": false, - "default": false, - "in": "formData" - }, - { - "name": "path", - "description": "HTTP path of execution. Path can include query params. Default value is \/", - "required": false, - "type": "string", - "x-example": "", - "default": "\/", - "in": "formData" - }, - { - "name": "method", - "description": "HTTP method of execution. Default value is GET.", - "required": false, - "type": "string", - "x-example": "GET", - "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS" - ], - "x-enum-name": "ExecutionMethod", - "x-enum-keys": [], - "default": "POST", - "in": "formData" - }, - { - "name": "headers", - "description": "HTTP headers of execution. Defaults to empty.", - "required": false, - "type": "object", - "default": [], - "x-example": "{}", - "in": "formData" - }, - { - "name": "scheduledAt", - "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", - "required": false, - "type": "string", - "in": "formData" + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "HTTP body of execution. Default value is empty string.", + "default": "", + "x-example": "" + }, + "async": { + "type": "boolean", + "description": "Execute code in the background. Default value is false.", + "default": false, + "x-example": false + }, + "path": { + "type": "string", + "description": "HTTP path of execution. Path can include query params. Default value is \/", + "default": "\/", + "x-example": "" + }, + "method": { + "type": "string", + "description": "HTTP method of execution. Default value is GET.", + "default": "POST", + "x-example": "GET", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS" + ], + "x-enum-name": "ExecutionMethod", + "x-enum-keys": [] + }, + "headers": { + "type": "object", + "description": "HTTP headers of execution. Defaults to empty.", + "default": [], + "x-example": "{}" + }, + "scheduledAt": { + "type": "string", + "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", + "default": null, + "x-example": null + } + } + } } ] } @@ -5313,7 +5307,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -5387,7 +5381,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -5463,7 +5457,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -5528,7 +5522,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -5539,7 +5533,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -5595,7 +5589,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -5651,7 +5645,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -5707,7 +5701,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -5763,7 +5757,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -5819,7 +5813,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -5875,7 +5869,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -5931,7 +5925,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -5987,7 +5981,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -6076,7 +6070,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -6151,7 +6145,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -6225,7 +6219,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -6236,7 +6230,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -6330,7 +6324,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -6402,7 +6396,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -6493,7 +6487,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -6567,7 +6561,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -6641,7 +6635,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -6842,7 +6836,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -6916,7 +6910,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -6993,7 +6987,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -7087,7 +7081,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -7151,7 +7145,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -7228,7 +7222,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -7283,7 +7277,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -7294,7 +7288,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -7368,7 +7362,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -7379,7 +7373,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -7485,7 +7479,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -7496,7 +7490,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -7557,7 +7551,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -7568,7 +7562,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -7656,7 +7650,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -7719,7 +7713,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -7730,7 +7724,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -7828,7 +7822,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -7891,7 +7885,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -9451,12 +9445,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -9486,7 +9480,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -9590,7 +9584,7 @@ "format": "int32" }, "responseBody": { - "type": "payload", + "type": "string", "description": "HTTP response body. This will return empty unless execution is created as synchronous.", "x-example": "" }, @@ -10014,7 +10008,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -10036,6 +10030,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -10045,7 +10044,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 9200c80593..c7b6bac2d4 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -99,7 +99,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -151,7 +151,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -237,7 +237,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 9, + "weight": 10, "cookies": false, "type": "", "deprecated": false, @@ -278,7 +278,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -289,7 +289,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -370,7 +370,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -433,7 +433,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -497,7 +497,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -550,7 +550,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -618,7 +618,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -692,7 +692,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -759,7 +759,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -839,7 +839,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -908,7 +908,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -982,7 +982,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -1063,7 +1063,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1117,7 +1117,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1169,7 +1169,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1221,7 +1221,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1275,7 +1275,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1349,7 +1349,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1429,7 +1429,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1510,7 +1510,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1562,7 +1562,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1636,7 +1636,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1707,7 +1707,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1718,7 +1718,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1806,7 +1806,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1853,7 +1853,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1907,7 +1907,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1949,7 +1949,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1960,7 +1960,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -2040,7 +2040,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -2109,7 +2109,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\r\n\r\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed.\n\nIf there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "301": { "description": "No content" @@ -2117,7 +2117,7 @@ }, "x-appwrite": { "method": "createOAuth2Session", - "weight": 18, + "weight": 19, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2255,7 +2255,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2335,7 +2335,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2415,7 +2415,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2477,7 +2477,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2534,7 +2534,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2598,7 +2598,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2652,7 +2652,7 @@ }, "x-appwrite": { "method": "createPushTarget", - "weight": 53, + "weight": 54, "cookies": false, "type": "", "deprecated": false, @@ -2737,7 +2737,7 @@ }, "x-appwrite": { "method": "updatePushTarget", - "weight": 54, + "weight": 55, "cookies": false, "type": "", "deprecated": false, @@ -2812,7 +2812,7 @@ }, "x-appwrite": { "method": "deletePushTarget", - "weight": 55, + "weight": 56, "cookies": false, "type": "", "deprecated": false, @@ -2863,7 +2863,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2874,7 +2874,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2949,7 +2949,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2960,7 +2960,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -3044,7 +3044,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "No content" @@ -3052,7 +3052,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -3179,7 +3179,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -3190,7 +3190,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -3262,7 +3262,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -3273,7 +3273,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -3345,7 +3345,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -3426,7 +3426,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -3481,7 +3481,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3551,7 +3551,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image", @@ -3562,7 +3562,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3680,7 +3680,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3691,7 +3691,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3813,7 +3813,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -3824,7 +3824,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3880,7 +3880,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3891,7 +3891,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -4371,7 +4371,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -4382,7 +4382,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -4458,7 +4458,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -4469,7 +4469,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4553,7 +4553,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image", @@ -4564,7 +4564,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4659,7 +4659,7 @@ }, "x-appwrite": { "method": "chat", - "weight": 331, + "weight": 333, "cookies": false, "type": "", "deprecated": false, @@ -4731,7 +4731,7 @@ }, "x-appwrite": { "method": "variables", - "weight": 330, + "weight": 332, "cookies": false, "type": "", "deprecated": false, @@ -4783,7 +4783,7 @@ }, "x-appwrite": { "method": "list", - "weight": 69, + "weight": 70, "cookies": false, "type": "", "deprecated": false, @@ -4846,7 +4846,7 @@ "tags": [ "databases" ], - "description": "Create a new Database.\r\n", + "description": "Create a new Database.\n", "responses": { "201": { "description": "Database", @@ -4857,7 +4857,7 @@ }, "x-appwrite": { "method": "create", - "weight": 68, + "weight": 69, "cookies": false, "type": "", "deprecated": false, @@ -4943,7 +4943,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 113, + "weight": 114, "cookies": false, "type": "", "deprecated": false, @@ -5017,7 +5017,7 @@ }, "x-appwrite": { "method": "get", - "weight": 70, + "weight": 71, "cookies": false, "type": "", "deprecated": false, @@ -5078,7 +5078,7 @@ }, "x-appwrite": { "method": "update", - "weight": 72, + "weight": 73, "cookies": false, "type": "", "deprecated": false, @@ -5158,7 +5158,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 73, + "weight": 74, "cookies": false, "type": "", "deprecated": false, @@ -5221,7 +5221,7 @@ }, "x-appwrite": { "method": "listCollections", - "weight": 75, + "weight": 76, "cookies": false, "type": "", "deprecated": false, @@ -5303,7 +5303,7 @@ }, "x-appwrite": { "method": "createCollection", - "weight": 74, + "weight": 75, "cookies": false, "type": "", "deprecated": false, @@ -5412,7 +5412,7 @@ }, "x-appwrite": { "method": "getCollection", - "weight": 76, + "weight": 77, "cookies": false, "type": "", "deprecated": false, @@ -5481,7 +5481,7 @@ }, "x-appwrite": { "method": "updateCollection", - "weight": 78, + "weight": 79, "cookies": false, "type": "", "deprecated": false, @@ -5584,7 +5584,7 @@ }, "x-appwrite": { "method": "deleteCollection", - "weight": 79, + "weight": 80, "cookies": false, "type": "", "deprecated": false, @@ -5655,7 +5655,7 @@ }, "x-appwrite": { "method": "listAttributes", - "weight": 90, + "weight": 91, "cookies": false, "type": "", "deprecated": false, @@ -5727,7 +5727,7 @@ "tags": [ "databases" ], - "description": "Create a boolean attribute.\r\n", + "description": "Create a boolean attribute.\n", "responses": { "202": { "description": "AttributeBoolean", @@ -5738,7 +5738,7 @@ }, "x-appwrite": { "method": "createBooleanAttribute", - "weight": 87, + "weight": 88, "cookies": false, "type": "", "deprecated": false, @@ -5844,7 +5844,7 @@ }, "x-appwrite": { "method": "updateBooleanAttribute", - "weight": 99, + "weight": 100, "cookies": false, "type": "", "deprecated": false, @@ -5954,7 +5954,7 @@ }, "x-appwrite": { "method": "createDatetimeAttribute", - "weight": 88, + "weight": 89, "cookies": false, "type": "", "deprecated": false, @@ -6060,7 +6060,7 @@ }, "x-appwrite": { "method": "updateDatetimeAttribute", - "weight": 100, + "weight": 101, "cookies": false, "type": "", "deprecated": false, @@ -6159,7 +6159,7 @@ "tags": [ "databases" ], - "description": "Create an email attribute.\r\n", + "description": "Create an email attribute.\n", "responses": { "202": { "description": "AttributeEmail", @@ -6170,7 +6170,7 @@ }, "x-appwrite": { "method": "createEmailAttribute", - "weight": 81, + "weight": 82, "cookies": false, "type": "", "deprecated": false, @@ -6265,7 +6265,7 @@ "tags": [ "databases" ], - "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEmail", @@ -6276,7 +6276,7 @@ }, "x-appwrite": { "method": "updateEmailAttribute", - "weight": 93, + "weight": 94, "cookies": false, "type": "", "deprecated": false, @@ -6375,7 +6375,7 @@ "tags": [ "databases" ], - "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \r\n", + "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \n", "responses": { "202": { "description": "AttributeEnum", @@ -6386,7 +6386,7 @@ }, "x-appwrite": { "method": "createEnumAttribute", - "weight": 82, + "weight": 83, "cookies": false, "type": "", "deprecated": false, @@ -6491,7 +6491,7 @@ "tags": [ "databases" ], - "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEnum", @@ -6502,7 +6502,7 @@ }, "x-appwrite": { "method": "updateEnumAttribute", - "weight": 94, + "weight": 95, "cookies": false, "type": "", "deprecated": false, @@ -6611,7 +6611,7 @@ "tags": [ "databases" ], - "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeFloat", @@ -6622,7 +6622,7 @@ }, "x-appwrite": { "method": "createFloatAttribute", - "weight": 86, + "weight": 87, "cookies": false, "type": "", "deprecated": false, @@ -6729,7 +6729,7 @@ "tags": [ "databases" ], - "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeFloat", @@ -6740,7 +6740,7 @@ }, "x-appwrite": { "method": "updateFloatAttribute", - "weight": 98, + "weight": 99, "cookies": false, "type": "", "deprecated": false, @@ -6853,7 +6853,7 @@ "tags": [ "databases" ], - "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeInteger", @@ -6864,7 +6864,7 @@ }, "x-appwrite": { "method": "createIntegerAttribute", - "weight": 85, + "weight": 86, "cookies": false, "type": "", "deprecated": false, @@ -6971,7 +6971,7 @@ "tags": [ "databases" ], - "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeInteger", @@ -6982,7 +6982,7 @@ }, "x-appwrite": { "method": "updateIntegerAttribute", - "weight": 97, + "weight": 98, "cookies": false, "type": "", "deprecated": false, @@ -7095,7 +7095,7 @@ "tags": [ "databases" ], - "description": "Create IP address attribute.\r\n", + "description": "Create IP address attribute.\n", "responses": { "202": { "description": "AttributeIP", @@ -7106,7 +7106,7 @@ }, "x-appwrite": { "method": "createIpAttribute", - "weight": 83, + "weight": 84, "cookies": false, "type": "", "deprecated": false, @@ -7201,7 +7201,7 @@ "tags": [ "databases" ], - "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeIP", @@ -7212,7 +7212,7 @@ }, "x-appwrite": { "method": "updateIpAttribute", - "weight": 95, + "weight": 96, "cookies": false, "type": "", "deprecated": false, @@ -7311,7 +7311,7 @@ "tags": [ "databases" ], - "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "202": { "description": "AttributeRelationship", @@ -7322,7 +7322,7 @@ }, "x-appwrite": { "method": "createRelationshipAttribute", - "weight": 89, + "weight": 90, "cookies": false, "type": "", "deprecated": false, @@ -7446,7 +7446,7 @@ "tags": [ "databases" ], - "description": "Create a string attribute.\r\n", + "description": "Create a string attribute.\n", "responses": { "202": { "description": "AttributeString", @@ -7457,7 +7457,7 @@ }, "x-appwrite": { "method": "createStringAttribute", - "weight": 80, + "weight": 81, "cookies": false, "type": "", "deprecated": false, @@ -7565,7 +7565,7 @@ "tags": [ "databases" ], - "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeString", @@ -7576,7 +7576,7 @@ }, "x-appwrite": { "method": "updateStringAttribute", - "weight": 92, + "weight": 93, "cookies": false, "type": "", "deprecated": false, @@ -7650,7 +7650,7 @@ "type": "integer", "description": "Maximum size of the string attribute.", "default": null, - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -7681,7 +7681,7 @@ "tags": [ "databases" ], - "description": "Create a URL attribute.\r\n", + "description": "Create a URL attribute.\n", "responses": { "202": { "description": "AttributeURL", @@ -7692,7 +7692,7 @@ }, "x-appwrite": { "method": "createUrlAttribute", - "weight": 84, + "weight": 85, "cookies": false, "type": "", "deprecated": false, @@ -7787,7 +7787,7 @@ "tags": [ "databases" ], - "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeURL", @@ -7798,7 +7798,7 @@ }, "x-appwrite": { "method": "updateUrlAttribute", - "weight": 96, + "weight": 97, "cookies": false, "type": "", "deprecated": false, @@ -7939,7 +7939,7 @@ }, "x-appwrite": { "method": "getAttribute", - "weight": 91, + "weight": 92, "cookies": false, "type": "", "deprecated": false, @@ -8010,7 +8010,7 @@ }, "x-appwrite": { "method": "deleteAttribute", - "weight": 102, + "weight": 103, "cookies": false, "type": "", "deprecated": false, @@ -8075,7 +8075,7 @@ "tags": [ "databases" ], - "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "200": { "description": "AttributeRelationship", @@ -8086,7 +8086,7 @@ }, "x-appwrite": { "method": "updateRelationshipAttribute", - "weight": 101, + "weight": 102, "cookies": false, "type": "", "deprecated": false, @@ -8192,7 +8192,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -8276,7 +8276,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -8384,7 +8384,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -8476,7 +8476,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -8575,7 +8575,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -8657,7 +8657,7 @@ }, "x-appwrite": { "method": "listDocumentLogs", - "weight": 110, + "weight": 111, "cookies": false, "type": "", "deprecated": false, @@ -8747,7 +8747,7 @@ }, "x-appwrite": { "method": "listIndexes", - "weight": 104, + "weight": 105, "cookies": false, "type": "", "deprecated": false, @@ -8817,7 +8817,7 @@ "tags": [ "databases" ], - "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\r\nAttributes can be `key`, `fulltext`, and `unique`.", + "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\nAttributes can be `key`, `fulltext`, and `unique`.", "responses": { "202": { "description": "Index", @@ -8828,7 +8828,7 @@ }, "x-appwrite": { "method": "createIndex", - "weight": 103, + "weight": 104, "cookies": false, "type": "", "deprecated": false, @@ -8950,7 +8950,7 @@ }, "x-appwrite": { "method": "getIndex", - "weight": 105, + "weight": 106, "cookies": false, "type": "", "deprecated": false, @@ -9021,7 +9021,7 @@ }, "x-appwrite": { "method": "deleteIndex", - "weight": 106, + "weight": 107, "cookies": false, "type": "", "deprecated": false, @@ -9099,7 +9099,7 @@ }, "x-appwrite": { "method": "listCollectionLogs", - "weight": 77, + "weight": 78, "cookies": false, "type": "", "deprecated": false, @@ -9181,7 +9181,7 @@ }, "x-appwrite": { "method": "getCollectionUsage", - "weight": 115, + "weight": 116, "cookies": false, "type": "", "deprecated": false, @@ -9271,7 +9271,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 71, + "weight": 72, "cookies": false, "type": "", "deprecated": false, @@ -9345,7 +9345,7 @@ }, "x-appwrite": { "method": "getDatabaseUsage", - "weight": 114, + "weight": 115, "cookies": false, "type": "", "deprecated": false, @@ -9427,7 +9427,7 @@ }, "x-appwrite": { "method": "list", - "weight": 287, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -9501,7 +9501,7 @@ }, "x-appwrite": { "method": "create", - "weight": 286, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -9559,6 +9559,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -9577,6 +9578,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -9584,24 +9587,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9726,7 +9735,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -9764,7 +9773,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 288, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -9806,7 +9815,7 @@ "tags": [ "functions" ], - "description": "List allowed function specifications for this instance.\r\n", + "description": "List allowed function specifications for this instance.\n", "responses": { "200": { "description": "Specifications List", @@ -9817,7 +9826,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 289, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -9871,7 +9880,7 @@ }, "x-appwrite": { "method": "listTemplates", - "weight": 312, + "weight": 314, "cookies": false, "type": "", "deprecated": false, @@ -9969,7 +9978,7 @@ }, "x-appwrite": { "method": "getTemplate", - "weight": 313, + "weight": 315, "cookies": false, "type": "", "deprecated": false, @@ -10031,7 +10040,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 292, + "weight": 294, "cookies": false, "type": "", "deprecated": false, @@ -10105,7 +10114,7 @@ }, "x-appwrite": { "method": "get", - "weight": 290, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -10166,7 +10175,7 @@ }, "x-appwrite": { "method": "update", - "weight": 293, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -10226,6 +10235,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -10244,6 +10254,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -10251,24 +10263,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -10370,7 +10388,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -10399,7 +10417,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 296, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -10462,7 +10480,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 298, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -10533,7 +10551,7 @@ "tags": [ "functions" ], - "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\r\n\r\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\r\n\r\nUse the \"command\" param to set the entrypoint used to execute your code.", + "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\n\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\n\nUse the \"command\" param to set the entrypoint used to execute your code.", "responses": { "202": { "description": "Deployment", @@ -10544,7 +10562,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 297, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -10638,7 +10656,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 299, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -10707,7 +10725,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 295, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -10771,7 +10789,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 300, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -10837,7 +10855,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 301, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -10921,7 +10939,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 302, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -10992,7 +11010,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 294, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -11065,7 +11083,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -11131,7 +11149,7 @@ "summary": "Create execution", "operationId": "functionsCreateExecution", "consumes": [ - "multipart\/form-data" + "application\/json" ], "produces": [ "multipart\/form-data" @@ -11150,7 +11168,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -11190,65 +11208,59 @@ "in": "path" }, { - "name": "body", - "description": "HTTP body of execution. Default value is empty string.", - "required": false, - "type": "payload", - "default": "", - "in": "formData" - }, - { - "name": "async", - "description": "Execute code in the background. Default value is false.", - "required": false, - "type": "boolean", - "x-example": false, - "default": false, - "in": "formData" - }, - { - "name": "path", - "description": "HTTP path of execution. Path can include query params. Default value is \/", - "required": false, - "type": "string", - "x-example": "", - "default": "\/", - "in": "formData" - }, - { - "name": "method", - "description": "HTTP method of execution. Default value is GET.", - "required": false, - "type": "string", - "x-example": "GET", - "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS" - ], - "x-enum-name": "ExecutionMethod", - "x-enum-keys": [], - "default": "POST", - "in": "formData" - }, - { - "name": "headers", - "description": "HTTP headers of execution. Defaults to empty.", - "required": false, - "type": "object", - "default": [], - "x-example": "{}", - "in": "formData" - }, - { - "name": "scheduledAt", - "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", - "required": false, - "type": "string", - "in": "formData" + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "HTTP body of execution. Default value is empty string.", + "default": "", + "x-example": "" + }, + "async": { + "type": "boolean", + "description": "Execute code in the background. Default value is false.", + "default": false, + "x-example": false + }, + "path": { + "type": "string", + "description": "HTTP path of execution. Path can include query params. Default value is \/", + "default": "\/", + "x-example": "" + }, + "method": { + "type": "string", + "description": "HTTP method of execution. Default value is GET.", + "default": "POST", + "x-example": "GET", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS" + ], + "x-enum-name": "ExecutionMethod", + "x-enum-keys": [] + }, + "headers": { + "type": "object", + "description": "HTTP headers of execution. Defaults to empty.", + "default": [], + "x-example": "{}" + }, + "scheduledAt": { + "type": "string", + "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", + "default": null, + "x-example": null + } + } + } } ] } @@ -11277,7 +11289,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -11336,7 +11348,7 @@ "tags": [ "functions" ], - "description": "Delete a function execution by its unique ID.\r\n", + "description": "Delete a function execution by its unique ID.\n", "responses": { "204": { "description": "No content" @@ -11344,7 +11356,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 306, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -11415,7 +11427,7 @@ }, "x-appwrite": { "method": "getFunctionUsage", - "weight": 291, + "weight": 293, "cookies": false, "type": "", "deprecated": false, @@ -11497,7 +11509,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 308, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -11558,7 +11570,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 307, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -11646,7 +11658,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 309, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -11715,7 +11727,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 310, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -11803,7 +11815,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 311, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -11874,7 +11886,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -11950,7 +11962,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -12026,7 +12038,7 @@ }, "x-appwrite": { "method": "get", - "weight": 124, + "weight": 125, "cookies": false, "type": "", "deprecated": false, @@ -12079,7 +12091,7 @@ }, "x-appwrite": { "method": "getAntivirus", - "weight": 146, + "weight": 147, "cookies": false, "type": "", "deprecated": false, @@ -12132,7 +12144,7 @@ }, "x-appwrite": { "method": "getCache", - "weight": 127, + "weight": 128, "cookies": false, "type": "", "deprecated": false, @@ -12185,7 +12197,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 133, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -12247,7 +12259,7 @@ }, "x-appwrite": { "method": "getDB", - "weight": 126, + "weight": 127, "cookies": false, "type": "", "deprecated": false, @@ -12300,7 +12312,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 129, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -12353,7 +12365,7 @@ }, "x-appwrite": { "method": "getQueue", - "weight": 128, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -12406,7 +12418,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 135, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -12470,7 +12482,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 134, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -12534,7 +12546,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 136, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -12607,7 +12619,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 137, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -12660,7 +12672,7 @@ "tags": [ "health" ], - "description": "Returns the amount of failed jobs in a given queue.\r\n", + "description": "Returns the amount of failed jobs in a given queue.\n", "responses": { "200": { "description": "Health Queue", @@ -12671,7 +12683,7 @@ }, "x-appwrite": { "method": "getFailedJobs", - "weight": 147, + "weight": 148, "cookies": false, "type": "", "deprecated": false, @@ -12759,7 +12771,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 141, + "weight": 142, "cookies": false, "type": "", "deprecated": false, @@ -12823,7 +12835,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 132, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -12887,7 +12899,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 138, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -12951,7 +12963,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 139, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -13015,7 +13027,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 140, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -13079,7 +13091,7 @@ }, "x-appwrite": { "method": "getQueueUsage", - "weight": 142, + "weight": 143, "cookies": false, "type": "", "deprecated": false, @@ -13143,7 +13155,7 @@ }, "x-appwrite": { "method": "getQueueUsageDump", - "weight": 143, + "weight": 144, "cookies": false, "type": "", "deprecated": false, @@ -13207,7 +13219,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 131, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -13271,7 +13283,7 @@ }, "x-appwrite": { "method": "getStorage", - "weight": 145, + "weight": 146, "cookies": false, "type": "", "deprecated": false, @@ -13324,7 +13336,7 @@ }, "x-appwrite": { "method": "getStorageLocal", - "weight": 144, + "weight": 145, "cookies": false, "type": "", "deprecated": false, @@ -13377,7 +13389,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 130, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -13419,7 +13431,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -13430,7 +13442,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -13486,7 +13498,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -13542,7 +13554,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -13598,7 +13610,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -13654,7 +13666,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -13710,7 +13722,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -13766,7 +13778,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -13822,7 +13834,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -13878,7 +13890,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 388, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -13955,7 +13967,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 385, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -14104,7 +14116,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14115,7 +14127,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 392, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -14272,7 +14284,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 387, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -14436,7 +14448,7 @@ "tags": [ "messaging" ], - "description": "Update a push notification by its unique ID.\r\n", + "description": "Update a push notification by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14447,7 +14459,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 394, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -14619,7 +14631,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 386, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -14728,7 +14740,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14739,7 +14751,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 393, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -14846,7 +14858,7 @@ "tags": [ "messaging" ], - "description": "Get a message by its unique ID.\r\n", + "description": "Get a message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -14857,7 +14869,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 391, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -14916,7 +14928,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 395, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -14980,7 +14992,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 389, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -15056,7 +15068,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 390, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -15132,7 +15144,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 360, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -15209,7 +15221,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 359, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -15326,7 +15338,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 372, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -15441,7 +15453,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 358, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -15534,7 +15546,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 371, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -15625,7 +15637,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 350, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -15754,7 +15766,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 363, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -15881,7 +15893,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 353, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -15986,7 +15998,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 366, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -16089,7 +16101,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 351, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -16206,7 +16218,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 364, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -16321,7 +16333,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 352, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -16482,7 +16494,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 365, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -16640,7 +16652,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 354, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -16745,7 +16757,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 367, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -16848,7 +16860,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 355, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -16953,7 +16965,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 368, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -17056,7 +17068,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 356, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -17161,7 +17173,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 369, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -17264,7 +17276,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 357, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -17369,7 +17381,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 370, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -17461,7 +17473,7 @@ "tags": [ "messaging" ], - "description": "Get a provider by its unique ID.\r\n", + "description": "Get a provider by its unique ID.\n", "responses": { "200": { "description": "Provider", @@ -17472,7 +17484,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 362, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -17531,7 +17543,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 373, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -17595,7 +17607,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 361, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -17671,7 +17683,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 382, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -17747,7 +17759,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 375, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -17822,7 +17834,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 374, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -17903,7 +17915,7 @@ "tags": [ "messaging" ], - "description": "Get a topic by its unique ID.\r\n", + "description": "Get a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -17914,7 +17926,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 377, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -17965,7 +17977,7 @@ "tags": [ "messaging" ], - "description": "Update a topic by its unique ID.\r\n", + "description": "Update a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -17976,7 +17988,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 378, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -18059,7 +18071,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 379, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -18123,7 +18135,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 376, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -18199,7 +18211,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 381, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -18282,7 +18294,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -18363,7 +18375,7 @@ "tags": [ "messaging" ], - "description": "Get a subscriber by its unique ID.\r\n", + "description": "Get a subscriber by its unique ID.\n", "responses": { "200": { "description": "Subscriber", @@ -18374,7 +18386,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 383, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -18441,7 +18453,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -18516,7 +18528,7 @@ }, "x-appwrite": { "method": "list", - "weight": 337, + "weight": 339, "cookies": false, "type": "", "deprecated": false, @@ -18545,7 +18557,7 @@ "parameters": [ { "name": "queries", - "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, resources, statusCounters, resourceData, errors", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, statusCounters, resourceData, errors", "required": false, "type": "array", "collectionFormat": "multi", @@ -18591,7 +18603,7 @@ }, "x-appwrite": { "method": "createAppwriteMigration", - "weight": 332, + "weight": 334, "cookies": false, "type": "", "deprecated": false, @@ -18687,7 +18699,7 @@ }, "x-appwrite": { "method": "getAppwriteReport", - "weight": 339, + "weight": 341, "cookies": false, "type": "", "deprecated": false, @@ -18777,7 +18789,7 @@ }, "x-appwrite": { "method": "createFirebaseMigration", - "weight": 334, + "weight": 336, "cookies": false, "type": "", "deprecated": false, @@ -18859,7 +18871,7 @@ }, "x-appwrite": { "method": "deleteFirebaseAuth", - "weight": 345, + "weight": 347, "cookies": false, "type": "", "deprecated": false, @@ -18911,7 +18923,7 @@ }, "x-appwrite": { "method": "createFirebaseOAuthMigration", - "weight": 333, + "weight": 335, "cookies": false, "type": "", "deprecated": false, @@ -18993,7 +19005,7 @@ }, "x-appwrite": { "method": "listFirebaseProjects", - "weight": 344, + "weight": 346, "cookies": false, "type": "", "deprecated": false, @@ -19045,7 +19057,7 @@ }, "x-appwrite": { "method": "getFirebaseReport", - "weight": 340, + "weight": 342, "cookies": false, "type": "", "deprecated": false, @@ -19118,7 +19130,7 @@ }, "x-appwrite": { "method": "getFirebaseReportOAuth", - "weight": 341, + "weight": 343, "cookies": false, "type": "", "deprecated": false, @@ -19191,7 +19203,7 @@ }, "x-appwrite": { "method": "createNHostMigration", - "weight": 336, + "weight": 338, "cookies": false, "type": "", "deprecated": false, @@ -19314,7 +19326,7 @@ }, "x-appwrite": { "method": "getNHostReport", - "weight": 347, + "weight": 349, "cookies": false, "type": "", "deprecated": false, @@ -19436,7 +19448,7 @@ }, "x-appwrite": { "method": "createSupabaseMigration", - "weight": 335, + "weight": 337, "cookies": false, "type": "", "deprecated": false, @@ -19552,7 +19564,7 @@ }, "x-appwrite": { "method": "getSupabaseReport", - "weight": 346, + "weight": 348, "cookies": false, "type": "", "deprecated": false, @@ -19667,7 +19679,7 @@ }, "x-appwrite": { "method": "get", - "weight": 338, + "weight": 340, "cookies": false, "type": "", "deprecated": false, @@ -19727,7 +19739,7 @@ }, "x-appwrite": { "method": "retry", - "weight": 348, + "weight": 350, "cookies": false, "type": "", "deprecated": false, @@ -19782,7 +19794,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 349, + "weight": 351, "cookies": false, "type": "", "deprecated": false, @@ -19844,7 +19856,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 194, + "weight": 196, "cookies": false, "type": "", "deprecated": false, @@ -19930,7 +19942,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 196, + "weight": 198, "cookies": false, "type": "", "deprecated": false, @@ -19980,7 +19992,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 195, + "weight": 197, "cookies": false, "type": "", "deprecated": false, @@ -20059,7 +20071,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 197, + "weight": 199, "cookies": false, "type": "", "deprecated": false, @@ -20119,7 +20131,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 198, + "weight": 200, "cookies": false, "type": "", "deprecated": false, @@ -20198,7 +20210,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 199, + "weight": 201, "cookies": false, "type": "", "deprecated": false, @@ -20260,7 +20272,7 @@ }, "x-appwrite": { "method": "list", - "weight": 150, + "weight": 151, "cookies": false, "type": "", "deprecated": false, @@ -20333,7 +20345,7 @@ }, "x-appwrite": { "method": "create", - "weight": 149, + "weight": 150, "cookies": false, "type": "", "deprecated": false, @@ -20485,7 +20497,7 @@ }, "x-appwrite": { "method": "get", - "weight": 151, + "weight": 152, "cookies": false, "type": "", "deprecated": false, @@ -20545,7 +20557,7 @@ }, "x-appwrite": { "method": "update", - "weight": 152, + "weight": 153, "cookies": false, "type": "", "deprecated": false, @@ -20672,7 +20684,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 168, + "weight": 170, "cookies": false, "type": "", "deprecated": false, @@ -20734,7 +20746,7 @@ }, "x-appwrite": { "method": "updateApiStatus", - "weight": 156, + "weight": 157, "cookies": false, "type": "", "deprecated": false, @@ -20828,7 +20840,7 @@ }, "x-appwrite": { "method": "updateApiStatusAll", - "weight": 157, + "weight": 158, "cookies": false, "type": "", "deprecated": false, @@ -20908,7 +20920,7 @@ }, "x-appwrite": { "method": "updateAuthDuration", - "weight": 161, + "weight": 163, "cookies": false, "type": "", "deprecated": false, @@ -20988,7 +21000,7 @@ }, "x-appwrite": { "method": "updateAuthLimit", - "weight": 160, + "weight": 162, "cookies": false, "type": "", "deprecated": false, @@ -21068,7 +21080,7 @@ }, "x-appwrite": { "method": "updateAuthSessionsLimit", - "weight": 166, + "weight": 168, "cookies": false, "type": "", "deprecated": false, @@ -21124,6 +21136,100 @@ ] } }, + "\/projects\/{projectId}\/auth\/memberships-privacy": { + "patch": { + "summary": "Update project team sensitive attributes", + "operationId": "projectsUpdateMembershipsPrivacy", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "projects" + ], + "description": "", + "responses": { + "200": { + "description": "Project", + "schema": { + "$ref": "#\/definitions\/project" + } + } + }, + "x-appwrite": { + "method": "updateMembershipsPrivacy", + "weight": 161, + "cookies": false, + "type": "", + "deprecated": false, + "demo": "projects\/update-memberships-privacy.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "projects.write", + "platforms": [ + "console" + ], + "packaging": false, + "offline-model": "", + "offline-key": "", + "offline-response-key": "$id", + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [] + } + ], + "parameters": [ + { + "name": "projectId", + "description": "Project unique ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "userName": { + "type": "boolean", + "description": "Set to true to show userName to members of a team.", + "default": null, + "x-example": false + }, + "userEmail": { + "type": "boolean", + "description": "Set to true to show email to members of a team.", + "default": null, + "x-example": false + }, + "mfa": { + "type": "boolean", + "description": "Set to true to show mfa to members of a team.", + "default": null, + "x-example": false + } + }, + "required": [ + "userName", + "userEmail", + "mfa" + ] + } + } + ] + } + }, "\/projects\/{projectId}\/auth\/mock-numbers": { "patch": { "summary": "Update the mock numbers for the project", @@ -21148,7 +21254,7 @@ }, "x-appwrite": { "method": "updateMockNumbers", - "weight": 167, + "weight": 169, "cookies": false, "type": "", "deprecated": false, @@ -21231,7 +21337,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordDictionary", - "weight": 164, + "weight": 166, "cookies": false, "type": "", "deprecated": false, @@ -21311,7 +21417,7 @@ }, "x-appwrite": { "method": "updateAuthPasswordHistory", - "weight": 163, + "weight": 165, "cookies": false, "type": "", "deprecated": false, @@ -21391,7 +21497,7 @@ }, "x-appwrite": { "method": "updatePersonalDataCheck", - "weight": 165, + "weight": 167, "cookies": false, "type": "", "deprecated": false, @@ -21471,7 +21577,7 @@ }, "x-appwrite": { "method": "updateSessionAlerts", - "weight": 159, + "weight": 160, "cookies": false, "type": "", "deprecated": false, @@ -21551,7 +21657,7 @@ }, "x-appwrite": { "method": "updateAuthStatus", - "weight": 162, + "weight": 164, "cookies": false, "type": "", "deprecated": false, @@ -21650,7 +21756,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 180, + "weight": 182, "cookies": false, "type": "", "deprecated": false, @@ -21739,7 +21845,7 @@ }, "x-appwrite": { "method": "listKeys", - "weight": 176, + "weight": 178, "cookies": false, "type": "", "deprecated": false, @@ -21799,7 +21905,7 @@ }, "x-appwrite": { "method": "createKey", - "weight": 175, + "weight": 177, "cookies": false, "type": "", "deprecated": false, @@ -21895,7 +22001,7 @@ }, "x-appwrite": { "method": "getKey", - "weight": 177, + "weight": 179, "cookies": false, "type": "", "deprecated": false, @@ -21963,7 +22069,7 @@ }, "x-appwrite": { "method": "updateKey", - "weight": 178, + "weight": 180, "cookies": false, "type": "", "deprecated": false, @@ -22060,7 +22166,7 @@ }, "x-appwrite": { "method": "deleteKey", - "weight": 179, + "weight": 181, "cookies": false, "type": "", "deprecated": false, @@ -22130,7 +22236,7 @@ }, "x-appwrite": { "method": "updateOAuth2", - "weight": 158, + "weight": 159, "cookies": false, "type": "", "deprecated": false, @@ -22271,7 +22377,7 @@ }, "x-appwrite": { "method": "listPlatforms", - "weight": 182, + "weight": 184, "cookies": false, "type": "", "deprecated": false, @@ -22331,7 +22437,7 @@ }, "x-appwrite": { "method": "createPlatform", - "weight": 181, + "weight": 183, "cookies": false, "type": "", "deprecated": false, @@ -22455,7 +22561,7 @@ }, "x-appwrite": { "method": "getPlatform", - "weight": 183, + "weight": 185, "cookies": false, "type": "", "deprecated": false, @@ -22523,7 +22629,7 @@ }, "x-appwrite": { "method": "updatePlatform", - "weight": 184, + "weight": 186, "cookies": false, "type": "", "deprecated": false, @@ -22622,7 +22728,7 @@ }, "x-appwrite": { "method": "deletePlatform", - "weight": 185, + "weight": 187, "cookies": false, "type": "", "deprecated": false, @@ -22692,7 +22798,7 @@ }, "x-appwrite": { "method": "updateServiceStatus", - "weight": 154, + "weight": 155, "cookies": false, "type": "", "deprecated": false, @@ -22794,7 +22900,7 @@ }, "x-appwrite": { "method": "updateServiceStatusAll", - "weight": 155, + "weight": 156, "cookies": false, "type": "", "deprecated": false, @@ -22874,7 +22980,7 @@ }, "x-appwrite": { "method": "updateSmtp", - "weight": 186, + "weight": 188, "cookies": false, "type": "", "deprecated": false, @@ -23003,7 +23109,7 @@ }, "x-appwrite": { "method": "createSmtpTest", - "weight": 187, + "weight": 189, "cookies": false, "type": "", "deprecated": false, @@ -23143,7 +23249,7 @@ }, "x-appwrite": { "method": "updateTeam", - "weight": 153, + "weight": 154, "cookies": false, "type": "", "deprecated": false, @@ -23223,7 +23329,7 @@ }, "x-appwrite": { "method": "getEmailTemplate", - "weight": 189, + "weight": 191, "cookies": false, "type": "", "deprecated": false, @@ -23445,7 +23551,7 @@ }, "x-appwrite": { "method": "updateEmailTemplate", - "weight": 191, + "weight": 193, "cookies": false, "type": "", "deprecated": false, @@ -23710,7 +23816,7 @@ }, "x-appwrite": { "method": "deleteEmailTemplate", - "weight": 193, + "weight": 195, "cookies": false, "type": "", "deprecated": false, @@ -23934,7 +24040,7 @@ }, "x-appwrite": { "method": "getSmsTemplate", - "weight": 188, + "weight": 190, "cookies": false, "type": "", "deprecated": false, @@ -24153,7 +24259,7 @@ }, "x-appwrite": { "method": "updateSmsTemplate", - "weight": 190, + "weight": 192, "cookies": false, "type": "", "deprecated": false, @@ -24390,7 +24496,7 @@ }, "x-appwrite": { "method": "deleteSmsTemplate", - "weight": 192, + "weight": 194, "cookies": false, "type": "", "deprecated": false, @@ -24611,7 +24717,7 @@ }, "x-appwrite": { "method": "listWebhooks", - "weight": 170, + "weight": 172, "cookies": false, "type": "", "deprecated": false, @@ -24671,7 +24777,7 @@ }, "x-appwrite": { "method": "createWebhook", - "weight": 169, + "weight": 171, "cookies": false, "type": "", "deprecated": false, @@ -24793,7 +24899,7 @@ }, "x-appwrite": { "method": "getWebhook", - "weight": 171, + "weight": 173, "cookies": false, "type": "", "deprecated": false, @@ -24861,7 +24967,7 @@ }, "x-appwrite": { "method": "updateWebhook", - "weight": 172, + "weight": 174, "cookies": false, "type": "", "deprecated": false, @@ -24984,7 +25090,7 @@ }, "x-appwrite": { "method": "deleteWebhook", - "weight": 174, + "weight": 176, "cookies": false, "type": "", "deprecated": false, @@ -25054,7 +25160,7 @@ }, "x-appwrite": { "method": "updateWebhookSignature", - "weight": 173, + "weight": 175, "cookies": false, "type": "", "deprecated": false, @@ -25124,7 +25230,7 @@ }, "x-appwrite": { "method": "listRules", - "weight": 315, + "weight": 317, "cookies": false, "type": "", "deprecated": false, @@ -25197,7 +25303,7 @@ }, "x-appwrite": { "method": "createRule", - "weight": 314, + "weight": 316, "cookies": false, "type": "", "deprecated": false, @@ -25288,7 +25394,7 @@ }, "x-appwrite": { "method": "getRule", - "weight": 316, + "weight": 318, "cookies": false, "type": "", "deprecated": false, @@ -25343,7 +25449,7 @@ }, "x-appwrite": { "method": "deleteRule", - "weight": 317, + "weight": 319, "cookies": false, "type": "", "deprecated": false, @@ -25405,7 +25511,7 @@ }, "x-appwrite": { "method": "updateRuleVerification", - "weight": 318, + "weight": 320, "cookies": false, "type": "", "deprecated": false, @@ -25467,7 +25573,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 201, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -25541,7 +25647,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 200, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -25682,7 +25788,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 202, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -25743,7 +25849,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 203, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -25878,7 +25984,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 204, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -25941,7 +26047,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -26015,7 +26121,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -26026,7 +26132,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -26120,7 +26226,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -26192,7 +26298,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -26283,7 +26389,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -26357,7 +26463,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -26431,7 +26537,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -26632,7 +26738,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -26706,7 +26812,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 214, + "weight": 216, "cookies": false, "type": "", "deprecated": false, @@ -26780,7 +26886,7 @@ }, "x-appwrite": { "method": "getBucketUsage", - "weight": 215, + "weight": 217, "cookies": false, "type": "", "deprecated": false, @@ -26862,7 +26968,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -26939,7 +27045,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -27033,7 +27139,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -27097,7 +27203,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -27174,7 +27280,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -27240,7 +27346,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 229, + "weight": 231, "cookies": false, "type": "", "deprecated": false, @@ -27303,7 +27409,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -27314,7 +27420,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -27388,7 +27494,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -27399,7 +27505,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -27505,7 +27611,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -27516,7 +27622,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -27577,7 +27683,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -27588,7 +27694,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -27676,7 +27782,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -27739,7 +27845,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -27750,7 +27856,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -27847,7 +27953,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -27909,7 +28015,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -27991,7 +28097,7 @@ }, "x-appwrite": { "method": "list", - "weight": 239, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -28065,7 +28171,7 @@ }, "x-appwrite": { "method": "create", - "weight": 230, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -28162,7 +28268,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 233, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -28255,7 +28361,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 231, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -28348,7 +28454,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 247, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -28419,7 +28525,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 270, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -28482,7 +28588,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 232, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -28575,7 +28681,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 235, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -28668,7 +28774,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 236, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -28796,7 +28902,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 237, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -28910,7 +29016,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 234, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -29024,7 +29130,7 @@ }, "x-appwrite": { "method": "getUsage", - "weight": 272, + "weight": 274, "cookies": false, "type": "", "deprecated": false, @@ -29098,7 +29204,7 @@ }, "x-appwrite": { "method": "get", - "weight": 240, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -29154,7 +29260,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 268, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -29217,7 +29323,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 253, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -29298,7 +29404,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 271, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -29371,7 +29477,7 @@ "tags": [ "users" ], - "description": "Update the user labels by its unique ID. \r\n\r\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", + "description": "Update the user labels by its unique ID. \n\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", "responses": { "200": { "description": "User", @@ -29382,7 +29488,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 249, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -29466,7 +29572,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 245, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -29541,7 +29647,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 244, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -29604,7 +29710,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 258, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -29685,7 +29791,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 263, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -29761,7 +29867,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 259, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -29824,7 +29930,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 260, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -29885,7 +29991,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 262, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -29946,7 +30052,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 261, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -30009,7 +30115,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 251, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -30090,7 +30196,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 252, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -30171,7 +30277,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 254, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -30252,7 +30358,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 241, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -30313,7 +30419,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 256, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -30394,7 +30500,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 243, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -30444,7 +30550,7 @@ "tags": [ "users" ], - "description": "Creates a session for a user. Returns an immediately usable session object.\r\n\r\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", + "description": "Creates a session for a user. Returns an immediately usable session object.\n\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", "responses": { "201": { "description": "Session", @@ -30455,7 +30561,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 264, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -30511,7 +30617,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 267, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -30569,7 +30675,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 266, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -30640,7 +30746,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 248, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -30721,7 +30827,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 246, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -30795,7 +30901,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 238, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -30910,7 +31016,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 242, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -30980,7 +31086,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 257, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -31074,7 +31180,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 269, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -31135,7 +31241,7 @@ "tags": [ "users" ], - "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\r\n", + "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\n", "responses": { "201": { "description": "Token", @@ -31146,7 +31252,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 265, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -31230,7 +31336,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 255, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -31311,7 +31417,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 250, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -31392,7 +31498,7 @@ }, "x-appwrite": { "method": "listRepositories", - "weight": 277, + "weight": 279, "cookies": false, "type": "", "deprecated": false, @@ -31461,7 +31567,7 @@ }, "x-appwrite": { "method": "createRepository", - "weight": 278, + "weight": 280, "cookies": false, "type": "", "deprecated": false, @@ -31548,7 +31654,7 @@ }, "x-appwrite": { "method": "getRepository", - "weight": 279, + "weight": 281, "cookies": false, "type": "", "deprecated": false, @@ -31618,7 +31724,7 @@ }, "x-appwrite": { "method": "listRepositoryBranches", - "weight": 280, + "weight": 282, "cookies": false, "type": "", "deprecated": false, @@ -31688,7 +31794,7 @@ }, "x-appwrite": { "method": "getRepositoryContents", - "weight": 275, + "weight": 277, "cookies": false, "type": "", "deprecated": false, @@ -31767,7 +31873,7 @@ }, "x-appwrite": { "method": "createRepositoryDetection", - "weight": 276, + "weight": 278, "cookies": false, "type": "", "deprecated": false, @@ -31847,7 +31953,7 @@ }, "x-appwrite": { "method": "updateExternalDeployments", - "weight": 285, + "weight": 287, "cookies": false, "type": "", "deprecated": false, @@ -31935,7 +32041,7 @@ }, "x-appwrite": { "method": "listInstallations", - "weight": 282, + "weight": 284, "cookies": false, "type": "", "deprecated": false, @@ -32010,7 +32116,7 @@ }, "x-appwrite": { "method": "getInstallation", - "weight": 283, + "weight": 285, "cookies": false, "type": "", "deprecated": false, @@ -32065,7 +32171,7 @@ }, "x-appwrite": { "method": "deleteInstallation", - "weight": 284, + "weight": 286, "cookies": false, "type": "", "deprecated": false, @@ -35363,12 +35469,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -35398,7 +35504,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -35564,7 +35670,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -36238,7 +36344,7 @@ "format": "int32" }, "responseBody": { - "type": "payload", + "type": "string", "description": "HTTP response body. This will return empty unless execution is created as synchronous.", "x-example": "" }, @@ -36485,6 +36591,21 @@ "description": "Whether or not to send session alert emails to users.", "x-example": true }, + "membershipsUserName": { + "type": "boolean", + "description": "Whether or not to show user names in the teams membership response.", + "x-example": true + }, + "membershipsUserEmail": { + "type": "boolean", + "description": "Whether or not to show user emails in the teams membership response.", + "x-example": true + }, + "membershipsMfa": { + "type": "boolean", + "description": "Whether or not to show user MFA status in the teams membership response.", + "x-example": true + }, "oAuthProviders": { "type": "array", "description": "List of Auth Providers.", @@ -36569,6 +36690,17 @@ "description": "SMTP server secure protocol", "x-example": "tls" }, + "pingCount": { + "type": "integer", + "description": "Number of times the ping was received for this project.", + "x-example": 1, + "format": "int32" + }, + "pingedAt": { + "type": "string", + "description": "Last ping datetime in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, "authEmailPassword": { "type": "boolean", "description": "Email\/Password auth method status", @@ -36683,6 +36815,9 @@ "authPersonalDataCheck", "authMockNumbers", "authSessionAlerts", + "membershipsUserName", + "membershipsUserEmail", + "membershipsMfa", "oAuthProviders", "platforms", "webhooks", @@ -36696,6 +36831,8 @@ "smtpUsername", "smtpPassword", "smtpSecure", + "pingCount", + "pingedAt", "authEmailPassword", "authUsersAuthMagicURL", "authEmailOtp", @@ -38303,7 +38440,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -38944,7 +39081,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -38966,6 +39103,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -38975,7 +39117,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] }, "migration": { @@ -38989,7 +39132,7 @@ }, "$createdAt": { "type": "string", - "description": "Variable creation date in ISO 8601 format.", + "description": "Migration creation date in ISO 8601 format.", "x-example": "2020-10-15T06:38:00.000+00:00" }, "$updatedAt": { @@ -39012,9 +39155,14 @@ "description": "A string containing the type of source of the migration.", "x-example": "Appwrite" }, + "destination": { + "type": "string", + "description": "A string containing the type of destination of the migration.", + "x-example": "Appwrite" + }, "resources": { "type": "array", - "description": "Resources to migration.", + "description": "Resources to migrate.", "items": { "type": "string" }, @@ -39050,6 +39198,7 @@ "status", "stage", "source", + "destination", "resources", "statusCounters", "resourceData", diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 80c9e6037f..2c8e80c65e 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -102,7 +102,7 @@ }, "x-appwrite": { "method": "get", - "weight": 8, + "weight": 9, "cookies": false, "type": "", "deprecated": false, @@ -156,7 +156,7 @@ }, "x-appwrite": { "method": "create", - "weight": 7, + "weight": 8, "cookies": false, "type": "", "deprecated": false, @@ -238,7 +238,7 @@ "tags": [ "account" ], - "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\r\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\r\n", + "description": "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.\nThis endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.\n", "responses": { "200": { "description": "User", @@ -249,7 +249,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 33, + "weight": 34, "cookies": false, "type": "", "deprecated": false, @@ -332,7 +332,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 56, + "weight": 57, "cookies": false, "type": "", "deprecated": false, @@ -397,7 +397,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 57, + "weight": 58, "cookies": false, "type": "", "deprecated": false, @@ -463,7 +463,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 28, + "weight": 29, "cookies": false, "type": "", "deprecated": false, @@ -516,7 +516,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 30, + "weight": 31, "cookies": false, "type": "", "deprecated": false, @@ -586,7 +586,7 @@ }, "x-appwrite": { "method": "updateMFA", - "weight": 43, + "weight": 44, "cookies": false, "type": "", "deprecated": false, @@ -662,7 +662,7 @@ }, "x-appwrite": { "method": "createMfaAuthenticator", - "weight": 45, + "weight": 46, "cookies": false, "type": "", "deprecated": false, @@ -731,7 +731,7 @@ }, "x-appwrite": { "method": "updateMfaAuthenticator", - "weight": 46, + "weight": 47, "cookies": false, "type": "", "deprecated": false, @@ -813,7 +813,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 50, + "weight": 51, "cookies": false, "type": "", "deprecated": false, @@ -884,7 +884,7 @@ }, "x-appwrite": { "method": "createMfaChallenge", - "weight": 51, + "weight": 52, "cookies": false, "type": "", "deprecated": false, @@ -958,7 +958,7 @@ }, "x-appwrite": { "method": "updateMfaChallenge", - "weight": 52, + "weight": 53, "cookies": false, "type": "", "deprecated": false, @@ -1041,7 +1041,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 44, + "weight": 45, "cookies": false, "type": "", "deprecated": false, @@ -1097,7 +1097,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 49, + "weight": 50, "cookies": false, "type": "", "deprecated": false, @@ -1151,7 +1151,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 47, + "weight": 48, "cookies": false, "type": "", "deprecated": false, @@ -1205,7 +1205,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 48, + "weight": 49, "cookies": false, "type": "", "deprecated": false, @@ -1261,7 +1261,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 31, + "weight": 32, "cookies": false, "type": "", "deprecated": false, @@ -1337,7 +1337,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 32, + "weight": 33, "cookies": false, "type": "", "deprecated": false, @@ -1419,7 +1419,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 34, + "weight": 35, "cookies": false, "type": "", "deprecated": false, @@ -1502,7 +1502,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 29, + "weight": 30, "cookies": false, "type": "", "deprecated": false, @@ -1556,7 +1556,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 35, + "weight": 36, "cookies": false, "type": "", "deprecated": false, @@ -1632,7 +1632,7 @@ }, "x-appwrite": { "method": "createRecovery", - "weight": 37, + "weight": 38, "cookies": false, "type": "", "deprecated": false, @@ -1705,7 +1705,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", + "description": "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST \/account\/recovery](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createRecovery) endpoint.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.", "responses": { "200": { "description": "Token", @@ -1716,7 +1716,7 @@ }, "x-appwrite": { "method": "updateRecovery", - "weight": 38, + "weight": 39, "cookies": false, "type": "", "deprecated": false, @@ -1806,7 +1806,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 10, + "weight": 11, "cookies": false, "type": "", "deprecated": false, @@ -1855,7 +1855,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 11, + "weight": 12, "cookies": false, "type": "", "deprecated": false, @@ -1911,7 +1911,7 @@ }, "x-appwrite": { "method": "createAnonymousSession", - "weight": 16, + "weight": 17, "cookies": false, "type": "", "deprecated": false, @@ -1953,7 +1953,7 @@ "tags": [ "account" ], - "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Session", @@ -1964,7 +1964,7 @@ }, "x-appwrite": { "method": "createEmailPasswordSession", - "weight": 15, + "weight": 16, "cookies": false, "type": "", "deprecated": false, @@ -2044,7 +2044,7 @@ }, "x-appwrite": { "method": "updateMagicURLSession", - "weight": 25, + "weight": 26, "cookies": false, "type": "", "deprecated": true, @@ -2124,7 +2124,7 @@ }, "x-appwrite": { "method": "updatePhoneSession", - "weight": 26, + "weight": 27, "cookies": false, "type": "", "deprecated": true, @@ -2204,7 +2204,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 17, + "weight": 18, "cookies": false, "type": "", "deprecated": false, @@ -2284,7 +2284,7 @@ }, "x-appwrite": { "method": "getSession", - "weight": 12, + "weight": 13, "cookies": false, "type": "", "deprecated": false, @@ -2348,7 +2348,7 @@ }, "x-appwrite": { "method": "updateSession", - "weight": 14, + "weight": 15, "cookies": false, "type": "", "deprecated": false, @@ -2407,7 +2407,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 13, + "weight": 14, "cookies": false, "type": "", "deprecated": false, @@ -2473,7 +2473,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 36, + "weight": 37, "cookies": false, "type": "", "deprecated": false, @@ -2518,7 +2518,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2529,7 +2529,7 @@ }, "x-appwrite": { "method": "createEmailToken", - "weight": 24, + "weight": 25, "cookies": false, "type": "", "deprecated": false, @@ -2604,7 +2604,7 @@ "tags": [ "account" ], - "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\r\n", + "description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n", "responses": { "201": { "description": "Token", @@ -2615,7 +2615,7 @@ }, "x-appwrite": { "method": "createMagicURLToken", - "weight": 23, + "weight": 24, "cookies": false, "type": "", "deprecated": false, @@ -2699,7 +2699,7 @@ "tags": [ "account" ], - "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \r\n\r\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. \n\nIf authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "301": { "description": "No content" @@ -2707,7 +2707,7 @@ }, "x-appwrite": { "method": "createOAuth2Token", - "weight": 22, + "weight": 23, "cookies": false, "type": "webAuth", "deprecated": false, @@ -2834,7 +2834,7 @@ "tags": [ "account" ], - "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\r\n\r\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", + "description": "Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).", "responses": { "201": { "description": "Token", @@ -2845,7 +2845,7 @@ }, "x-appwrite": { "method": "createPhoneToken", - "weight": 27, + "weight": 28, "cookies": false, "type": "", "deprecated": false, @@ -2917,7 +2917,7 @@ "tags": [ "account" ], - "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\r\n\r\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\r\n", + "description": "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#updateVerification). The verification link sent to the user's email address is valid for 7 days.\n\nPlease note that in order to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n", "responses": { "201": { "description": "Token", @@ -2928,7 +2928,7 @@ }, "x-appwrite": { "method": "createVerification", - "weight": 39, + "weight": 40, "cookies": false, "type": "", "deprecated": false, @@ -3002,7 +3002,7 @@ }, "x-appwrite": { "method": "updateVerification", - "weight": 40, + "weight": 41, "cookies": false, "type": "", "deprecated": false, @@ -3085,7 +3085,7 @@ }, "x-appwrite": { "method": "createPhoneVerification", - "weight": 41, + "weight": 42, "cookies": false, "type": "", "deprecated": false, @@ -3142,7 +3142,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 42, + "weight": 43, "cookies": false, "type": "", "deprecated": false, @@ -3214,7 +3214,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", + "description": "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user [GET \/account\/sessions](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#getSessions) endpoint. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.", "responses": { "200": { "description": "Image", @@ -3225,7 +3225,7 @@ }, "x-appwrite": { "method": "getBrowser", - "weight": 59, + "weight": 60, "cookies": false, "type": "location", "deprecated": false, @@ -3345,7 +3345,7 @@ "tags": [ "avatars" ], - "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3356,7 +3356,7 @@ }, "x-appwrite": { "method": "getCreditCard", - "weight": 58, + "weight": 59, "cookies": false, "type": "location", "deprecated": false, @@ -3480,7 +3480,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -3491,7 +3491,7 @@ }, "x-appwrite": { "method": "getFavicon", - "weight": 62, + "weight": 63, "cookies": false, "type": "location", "deprecated": false, @@ -3549,7 +3549,7 @@ "tags": [ "avatars" ], - "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings. Country codes follow the [ISO 3166-1](https:\/\/en.wikipedia.org\/wiki\/ISO_3166-1) standard.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -3560,7 +3560,7 @@ }, "x-appwrite": { "method": "getFlag", - "weight": 60, + "weight": 61, "cookies": false, "type": "location", "deprecated": false, @@ -4042,7 +4042,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\r\n\r\nThis endpoint does not follow HTTP redirects.", + "description": "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 400x400px.\n\nThis endpoint does not follow HTTP redirects.", "responses": { "200": { "description": "Image", @@ -4053,7 +4053,7 @@ }, "x-appwrite": { "method": "getImage", - "weight": 61, + "weight": 62, "cookies": false, "type": "location", "deprecated": false, @@ -4131,7 +4131,7 @@ "tags": [ "avatars" ], - "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\r\n\r\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\r\n\r\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\r\n", + "description": "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.\n\nYou can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\nWhen one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px.\n", "responses": { "200": { "description": "Image", @@ -4142,7 +4142,7 @@ }, "x-appwrite": { "method": "getInitials", - "weight": 64, + "weight": 65, "cookies": false, "type": "location", "deprecated": false, @@ -4228,7 +4228,7 @@ "tags": [ "avatars" ], - "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\r\n", + "description": "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n", "responses": { "200": { "description": "Image", @@ -4239,7 +4239,7 @@ }, "x-appwrite": { "method": "getQR", - "weight": 63, + "weight": 64, "cookies": false, "type": "location", "deprecated": false, @@ -4336,7 +4336,7 @@ }, "x-appwrite": { "method": "list", - "weight": 69, + "weight": 70, "cookies": false, "type": "", "deprecated": false, @@ -4400,7 +4400,7 @@ "tags": [ "databases" ], - "description": "Create a new Database.\r\n", + "description": "Create a new Database.\n", "responses": { "201": { "description": "Database", @@ -4411,7 +4411,7 @@ }, "x-appwrite": { "method": "create", - "weight": 68, + "weight": 69, "cookies": false, "type": "", "deprecated": false, @@ -4498,7 +4498,7 @@ }, "x-appwrite": { "method": "get", - "weight": 70, + "weight": 71, "cookies": false, "type": "", "deprecated": false, @@ -4560,7 +4560,7 @@ }, "x-appwrite": { "method": "update", - "weight": 72, + "weight": 73, "cookies": false, "type": "", "deprecated": false, @@ -4641,7 +4641,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 73, + "weight": 74, "cookies": false, "type": "", "deprecated": false, @@ -4705,7 +4705,7 @@ }, "x-appwrite": { "method": "listCollections", - "weight": 75, + "weight": 76, "cookies": false, "type": "", "deprecated": false, @@ -4788,7 +4788,7 @@ }, "x-appwrite": { "method": "createCollection", - "weight": 74, + "weight": 75, "cookies": false, "type": "", "deprecated": false, @@ -4898,7 +4898,7 @@ }, "x-appwrite": { "method": "getCollection", - "weight": 76, + "weight": 77, "cookies": false, "type": "", "deprecated": false, @@ -4968,7 +4968,7 @@ }, "x-appwrite": { "method": "updateCollection", - "weight": 78, + "weight": 79, "cookies": false, "type": "", "deprecated": false, @@ -5072,7 +5072,7 @@ }, "x-appwrite": { "method": "deleteCollection", - "weight": 79, + "weight": 80, "cookies": false, "type": "", "deprecated": false, @@ -5144,7 +5144,7 @@ }, "x-appwrite": { "method": "listAttributes", - "weight": 90, + "weight": 91, "cookies": false, "type": "", "deprecated": false, @@ -5217,7 +5217,7 @@ "tags": [ "databases" ], - "description": "Create a boolean attribute.\r\n", + "description": "Create a boolean attribute.\n", "responses": { "202": { "description": "AttributeBoolean", @@ -5228,7 +5228,7 @@ }, "x-appwrite": { "method": "createBooleanAttribute", - "weight": 87, + "weight": 88, "cookies": false, "type": "", "deprecated": false, @@ -5335,7 +5335,7 @@ }, "x-appwrite": { "method": "updateBooleanAttribute", - "weight": 99, + "weight": 100, "cookies": false, "type": "", "deprecated": false, @@ -5446,7 +5446,7 @@ }, "x-appwrite": { "method": "createDatetimeAttribute", - "weight": 88, + "weight": 89, "cookies": false, "type": "", "deprecated": false, @@ -5553,7 +5553,7 @@ }, "x-appwrite": { "method": "updateDatetimeAttribute", - "weight": 100, + "weight": 101, "cookies": false, "type": "", "deprecated": false, @@ -5653,7 +5653,7 @@ "tags": [ "databases" ], - "description": "Create an email attribute.\r\n", + "description": "Create an email attribute.\n", "responses": { "202": { "description": "AttributeEmail", @@ -5664,7 +5664,7 @@ }, "x-appwrite": { "method": "createEmailAttribute", - "weight": 81, + "weight": 82, "cookies": false, "type": "", "deprecated": false, @@ -5760,7 +5760,7 @@ "tags": [ "databases" ], - "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an email attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEmail", @@ -5771,7 +5771,7 @@ }, "x-appwrite": { "method": "updateEmailAttribute", - "weight": 93, + "weight": 94, "cookies": false, "type": "", "deprecated": false, @@ -5871,7 +5871,7 @@ "tags": [ "databases" ], - "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \r\n", + "description": "Create an enumeration attribute. The `elements` param acts as a white-list of accepted values for this attribute. \n", "responses": { "202": { "description": "AttributeEnum", @@ -5882,7 +5882,7 @@ }, "x-appwrite": { "method": "createEnumAttribute", - "weight": 82, + "weight": 83, "cookies": false, "type": "", "deprecated": false, @@ -5988,7 +5988,7 @@ "tags": [ "databases" ], - "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an enum attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeEnum", @@ -5999,7 +5999,7 @@ }, "x-appwrite": { "method": "updateEnumAttribute", - "weight": 94, + "weight": 95, "cookies": false, "type": "", "deprecated": false, @@ -6109,7 +6109,7 @@ "tags": [ "databases" ], - "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create a float attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeFloat", @@ -6120,7 +6120,7 @@ }, "x-appwrite": { "method": "createFloatAttribute", - "weight": 86, + "weight": 87, "cookies": false, "type": "", "deprecated": false, @@ -6228,7 +6228,7 @@ "tags": [ "databases" ], - "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a float attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeFloat", @@ -6239,7 +6239,7 @@ }, "x-appwrite": { "method": "updateFloatAttribute", - "weight": 98, + "weight": 99, "cookies": false, "type": "", "deprecated": false, @@ -6353,7 +6353,7 @@ "tags": [ "databases" ], - "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\r\n", + "description": "Create an integer attribute. Optionally, minimum and maximum values can be provided.\n", "responses": { "202": { "description": "AttributeInteger", @@ -6364,7 +6364,7 @@ }, "x-appwrite": { "method": "createIntegerAttribute", - "weight": 85, + "weight": 86, "cookies": false, "type": "", "deprecated": false, @@ -6472,7 +6472,7 @@ "tags": [ "databases" ], - "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an integer attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeInteger", @@ -6483,7 +6483,7 @@ }, "x-appwrite": { "method": "updateIntegerAttribute", - "weight": 97, + "weight": 98, "cookies": false, "type": "", "deprecated": false, @@ -6597,7 +6597,7 @@ "tags": [ "databases" ], - "description": "Create IP address attribute.\r\n", + "description": "Create IP address attribute.\n", "responses": { "202": { "description": "AttributeIP", @@ -6608,7 +6608,7 @@ }, "x-appwrite": { "method": "createIpAttribute", - "weight": 83, + "weight": 84, "cookies": false, "type": "", "deprecated": false, @@ -6704,7 +6704,7 @@ "tags": [ "databases" ], - "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an ip attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeIP", @@ -6715,7 +6715,7 @@ }, "x-appwrite": { "method": "updateIpAttribute", - "weight": 95, + "weight": 96, "cookies": false, "type": "", "deprecated": false, @@ -6815,7 +6815,7 @@ "tags": [ "databases" ], - "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Create relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "202": { "description": "AttributeRelationship", @@ -6826,7 +6826,7 @@ }, "x-appwrite": { "method": "createRelationshipAttribute", - "weight": 89, + "weight": 90, "cookies": false, "type": "", "deprecated": false, @@ -6951,7 +6951,7 @@ "tags": [ "databases" ], - "description": "Create a string attribute.\r\n", + "description": "Create a string attribute.\n", "responses": { "202": { "description": "AttributeString", @@ -6962,7 +6962,7 @@ }, "x-appwrite": { "method": "createStringAttribute", - "weight": 80, + "weight": 81, "cookies": false, "type": "", "deprecated": false, @@ -7071,7 +7071,7 @@ "tags": [ "databases" ], - "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update a string attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeString", @@ -7082,7 +7082,7 @@ }, "x-appwrite": { "method": "updateStringAttribute", - "weight": 92, + "weight": 93, "cookies": false, "type": "", "deprecated": false, @@ -7157,7 +7157,7 @@ "type": "integer", "description": "Maximum size of the string attribute.", "default": null, - "x-example": null + "x-example": 1 }, "newKey": { "type": "string", @@ -7188,7 +7188,7 @@ "tags": [ "databases" ], - "description": "Create a URL attribute.\r\n", + "description": "Create a URL attribute.\n", "responses": { "202": { "description": "AttributeURL", @@ -7199,7 +7199,7 @@ }, "x-appwrite": { "method": "createUrlAttribute", - "weight": 84, + "weight": 85, "cookies": false, "type": "", "deprecated": false, @@ -7295,7 +7295,7 @@ "tags": [ "databases" ], - "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\r\n", + "description": "Update an url attribute. Changing the `default` value will not update already existing documents.\n", "responses": { "200": { "description": "AttributeURL", @@ -7306,7 +7306,7 @@ }, "x-appwrite": { "method": "updateUrlAttribute", - "weight": 96, + "weight": 97, "cookies": false, "type": "", "deprecated": false, @@ -7448,7 +7448,7 @@ }, "x-appwrite": { "method": "getAttribute", - "weight": 91, + "weight": 92, "cookies": false, "type": "", "deprecated": false, @@ -7520,7 +7520,7 @@ }, "x-appwrite": { "method": "deleteAttribute", - "weight": 102, + "weight": 103, "cookies": false, "type": "", "deprecated": false, @@ -7586,7 +7586,7 @@ "tags": [ "databases" ], - "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\r\n", + "description": "Update relationship attribute. [Learn more about relationship attributes](https:\/\/appwrite.io\/docs\/databases-relationships#relationship-attributes).\n", "responses": { "200": { "description": "AttributeRelationship", @@ -7597,7 +7597,7 @@ }, "x-appwrite": { "method": "updateRelationshipAttribute", - "weight": 101, + "weight": 102, "cookies": false, "type": "", "deprecated": false, @@ -7704,7 +7704,7 @@ }, "x-appwrite": { "method": "listDocuments", - "weight": 108, + "weight": 109, "cookies": false, "type": "", "deprecated": false, @@ -7790,7 +7790,7 @@ }, "x-appwrite": { "method": "createDocument", - "weight": 107, + "weight": 108, "cookies": false, "type": "", "deprecated": false, @@ -7900,7 +7900,7 @@ }, "x-appwrite": { "method": "getDocument", - "weight": 109, + "weight": 110, "cookies": false, "type": "", "deprecated": false, @@ -7994,7 +7994,7 @@ }, "x-appwrite": { "method": "updateDocument", - "weight": 111, + "weight": 112, "cookies": false, "type": "", "deprecated": false, @@ -8095,7 +8095,7 @@ }, "x-appwrite": { "method": "deleteDocument", - "weight": 112, + "weight": 113, "cookies": false, "type": "", "deprecated": false, @@ -8179,7 +8179,7 @@ }, "x-appwrite": { "method": "listIndexes", - "weight": 104, + "weight": 105, "cookies": false, "type": "", "deprecated": false, @@ -8250,7 +8250,7 @@ "tags": [ "databases" ], - "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\r\nAttributes can be `key`, `fulltext`, and `unique`.", + "description": "Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request.\nAttributes can be `key`, `fulltext`, and `unique`.", "responses": { "202": { "description": "Index", @@ -8261,7 +8261,7 @@ }, "x-appwrite": { "method": "createIndex", - "weight": 103, + "weight": 104, "cookies": false, "type": "", "deprecated": false, @@ -8384,7 +8384,7 @@ }, "x-appwrite": { "method": "getIndex", - "weight": 105, + "weight": 106, "cookies": false, "type": "", "deprecated": false, @@ -8456,7 +8456,7 @@ }, "x-appwrite": { "method": "deleteIndex", - "weight": 106, + "weight": 107, "cookies": false, "type": "", "deprecated": false, @@ -8535,7 +8535,7 @@ }, "x-appwrite": { "method": "list", - "weight": 287, + "weight": 289, "cookies": false, "type": "", "deprecated": false, @@ -8610,7 +8610,7 @@ }, "x-appwrite": { "method": "create", - "weight": 286, + "weight": 288, "cookies": false, "type": "", "deprecated": false, @@ -8669,6 +8669,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -8687,6 +8688,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -8694,24 +8697,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -8836,7 +8845,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -8874,7 +8883,7 @@ }, "x-appwrite": { "method": "listRuntimes", - "weight": 288, + "weight": 290, "cookies": false, "type": "", "deprecated": false, @@ -8917,7 +8926,7 @@ "tags": [ "functions" ], - "description": "List allowed function specifications for this instance.\r\n", + "description": "List allowed function specifications for this instance.\n", "responses": { "200": { "description": "Specifications List", @@ -8928,7 +8937,7 @@ }, "x-appwrite": { "method": "listSpecifications", - "weight": 289, + "weight": 291, "cookies": false, "type": "", "deprecated": false, @@ -8983,7 +8992,7 @@ }, "x-appwrite": { "method": "get", - "weight": 290, + "weight": 292, "cookies": false, "type": "", "deprecated": false, @@ -9045,7 +9054,7 @@ }, "x-appwrite": { "method": "update", - "weight": 293, + "weight": 295, "cookies": false, "type": "", "deprecated": false, @@ -9106,6 +9115,7 @@ "node-19.0", "node-20.0", "node-21.0", + "node-22", "php-8.0", "php-8.1", "php-8.2", @@ -9124,6 +9134,8 @@ "deno-1.24", "deno-1.35", "deno-1.40", + "deno-1.46", + "deno-2.0", "dart-2.15", "dart-2.16", "dart-2.17", @@ -9131,24 +9143,30 @@ "dart-3.0", "dart-3.1", "dart-3.3", - "dotnet-3.1", + "dart-3.5", "dotnet-6.0", "dotnet-7.0", + "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", + "java-22", "swift-5.5", "swift-5.8", "swift-5.9", + "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", + "kotlin-2.0", "cpp-17", "cpp-20", "bun-1.0", - "go-1.23" + "bun-1.1", + "go-1.23", + "static-1" ], "x-enum-name": null, "x-enum-keys": [] @@ -9250,7 +9268,7 @@ "specification": { "type": "string", "description": "Runtime specification for the function and builds.", - "default": "s-0.5vcpu-512mb", + "default": "s-1vcpu-512mb", "x-example": null } }, @@ -9279,7 +9297,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 296, + "weight": 298, "cookies": false, "type": "", "deprecated": false, @@ -9343,7 +9361,7 @@ }, "x-appwrite": { "method": "listDeployments", - "weight": 298, + "weight": 300, "cookies": false, "type": "", "deprecated": false, @@ -9415,7 +9433,7 @@ "tags": [ "functions" ], - "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\r\n\r\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\r\n\r\nUse the \"command\" param to set the entrypoint used to execute your code.", + "description": "Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.\n\nThis endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https:\/\/appwrite.io\/docs\/functions).\n\nUse the \"command\" param to set the entrypoint used to execute your code.", "responses": { "202": { "description": "Deployment", @@ -9426,7 +9444,7 @@ }, "x-appwrite": { "method": "createDeployment", - "weight": 297, + "weight": 299, "cookies": false, "type": "upload", "deprecated": false, @@ -9521,7 +9539,7 @@ }, "x-appwrite": { "method": "getDeployment", - "weight": 299, + "weight": 301, "cookies": false, "type": "", "deprecated": false, @@ -9591,7 +9609,7 @@ }, "x-appwrite": { "method": "updateDeployment", - "weight": 295, + "weight": 297, "cookies": false, "type": "", "deprecated": false, @@ -9656,7 +9674,7 @@ }, "x-appwrite": { "method": "deleteDeployment", - "weight": 300, + "weight": 302, "cookies": false, "type": "", "deprecated": false, @@ -9723,7 +9741,7 @@ }, "x-appwrite": { "method": "createBuild", - "weight": 301, + "weight": 303, "cookies": false, "type": "", "deprecated": false, @@ -9808,7 +9826,7 @@ }, "x-appwrite": { "method": "updateDeploymentBuild", - "weight": 302, + "weight": 304, "cookies": false, "type": "", "deprecated": false, @@ -9880,7 +9898,7 @@ }, "x-appwrite": { "method": "getDeploymentDownload", - "weight": 294, + "weight": 296, "cookies": false, "type": "location", "deprecated": false, @@ -9954,7 +9972,7 @@ }, "x-appwrite": { "method": "listExecutions", - "weight": 304, + "weight": 306, "cookies": false, "type": "", "deprecated": false, @@ -10022,7 +10040,7 @@ "summary": "Create execution", "operationId": "functionsCreateExecution", "consumes": [ - "multipart\/form-data" + "application\/json" ], "produces": [ "multipart\/form-data" @@ -10041,7 +10059,7 @@ }, "x-appwrite": { "method": "createExecution", - "weight": 303, + "weight": 305, "cookies": false, "type": "", "deprecated": false, @@ -10083,65 +10101,59 @@ "in": "path" }, { - "name": "body", - "description": "HTTP body of execution. Default value is empty string.", - "required": false, - "type": "payload", - "default": "", - "in": "formData" - }, - { - "name": "async", - "description": "Execute code in the background. Default value is false.", - "required": false, - "type": "boolean", - "x-example": false, - "default": false, - "in": "formData" - }, - { - "name": "path", - "description": "HTTP path of execution. Path can include query params. Default value is \/", - "required": false, - "type": "string", - "x-example": "", - "default": "\/", - "in": "formData" - }, - { - "name": "method", - "description": "HTTP method of execution. Default value is GET.", - "required": false, - "type": "string", - "x-example": "GET", - "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS" - ], - "x-enum-name": "ExecutionMethod", - "x-enum-keys": [], - "default": "POST", - "in": "formData" - }, - { - "name": "headers", - "description": "HTTP headers of execution. Defaults to empty.", - "required": false, - "type": "object", - "default": [], - "x-example": "{}", - "in": "formData" - }, - { - "name": "scheduledAt", - "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", - "required": false, - "type": "string", - "in": "formData" + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "HTTP body of execution. Default value is empty string.", + "default": "", + "x-example": "" + }, + "async": { + "type": "boolean", + "description": "Execute code in the background. Default value is false.", + "default": false, + "x-example": false + }, + "path": { + "type": "string", + "description": "HTTP path of execution. Path can include query params. Default value is \/", + "default": "\/", + "x-example": "" + }, + "method": { + "type": "string", + "description": "HTTP method of execution. Default value is GET.", + "default": "POST", + "x-example": "GET", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS" + ], + "x-enum-name": "ExecutionMethod", + "x-enum-keys": [] + }, + "headers": { + "type": "object", + "description": "HTTP headers of execution. Defaults to empty.", + "default": [], + "x-example": "{}" + }, + "scheduledAt": { + "type": "string", + "description": "Scheduled execution time in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.", + "default": null, + "x-example": null + } + } + } } ] } @@ -10170,7 +10182,7 @@ }, "x-appwrite": { "method": "getExecution", - "weight": 305, + "weight": 307, "cookies": false, "type": "", "deprecated": false, @@ -10231,7 +10243,7 @@ "tags": [ "functions" ], - "description": "Delete a function execution by its unique ID.\r\n", + "description": "Delete a function execution by its unique ID.\n", "responses": { "204": { "description": "No content" @@ -10239,7 +10251,7 @@ }, "x-appwrite": { "method": "deleteExecution", - "weight": 306, + "weight": 308, "cookies": false, "type": "", "deprecated": false, @@ -10311,7 +10323,7 @@ }, "x-appwrite": { "method": "listVariables", - "weight": 308, + "weight": 310, "cookies": false, "type": "", "deprecated": false, @@ -10373,7 +10385,7 @@ }, "x-appwrite": { "method": "createVariable", - "weight": 307, + "weight": 309, "cookies": false, "type": "", "deprecated": false, @@ -10462,7 +10474,7 @@ }, "x-appwrite": { "method": "getVariable", - "weight": 309, + "weight": 311, "cookies": false, "type": "", "deprecated": false, @@ -10532,7 +10544,7 @@ }, "x-appwrite": { "method": "updateVariable", - "weight": 310, + "weight": 312, "cookies": false, "type": "", "deprecated": false, @@ -10621,7 +10633,7 @@ }, "x-appwrite": { "method": "deleteVariable", - "weight": 311, + "weight": 313, "cookies": false, "type": "", "deprecated": false, @@ -10693,7 +10705,7 @@ }, "x-appwrite": { "method": "query", - "weight": 329, + "weight": 331, "cookies": false, "type": "graphql", "deprecated": false, @@ -10771,7 +10783,7 @@ }, "x-appwrite": { "method": "mutation", - "weight": 328, + "weight": 330, "cookies": false, "type": "graphql", "deprecated": false, @@ -10849,7 +10861,7 @@ }, "x-appwrite": { "method": "get", - "weight": 124, + "weight": 125, "cookies": false, "type": "", "deprecated": false, @@ -10903,7 +10915,7 @@ }, "x-appwrite": { "method": "getAntivirus", - "weight": 146, + "weight": 147, "cookies": false, "type": "", "deprecated": false, @@ -10957,7 +10969,7 @@ }, "x-appwrite": { "method": "getCache", - "weight": 127, + "weight": 128, "cookies": false, "type": "", "deprecated": false, @@ -11011,7 +11023,7 @@ }, "x-appwrite": { "method": "getCertificate", - "weight": 133, + "weight": 134, "cookies": false, "type": "", "deprecated": false, @@ -11074,7 +11086,7 @@ }, "x-appwrite": { "method": "getDB", - "weight": 126, + "weight": 127, "cookies": false, "type": "", "deprecated": false, @@ -11128,7 +11140,7 @@ }, "x-appwrite": { "method": "getPubSub", - "weight": 129, + "weight": 130, "cookies": false, "type": "", "deprecated": false, @@ -11182,7 +11194,7 @@ }, "x-appwrite": { "method": "getQueue", - "weight": 128, + "weight": 129, "cookies": false, "type": "", "deprecated": false, @@ -11236,7 +11248,7 @@ }, "x-appwrite": { "method": "getQueueBuilds", - "weight": 135, + "weight": 136, "cookies": false, "type": "", "deprecated": false, @@ -11301,7 +11313,7 @@ }, "x-appwrite": { "method": "getQueueCertificates", - "weight": 134, + "weight": 135, "cookies": false, "type": "", "deprecated": false, @@ -11366,7 +11378,7 @@ }, "x-appwrite": { "method": "getQueueDatabases", - "weight": 136, + "weight": 137, "cookies": false, "type": "", "deprecated": false, @@ -11440,7 +11452,7 @@ }, "x-appwrite": { "method": "getQueueDeletes", - "weight": 137, + "weight": 138, "cookies": false, "type": "", "deprecated": false, @@ -11494,7 +11506,7 @@ "tags": [ "health" ], - "description": "Returns the amount of failed jobs in a given queue.\r\n", + "description": "Returns the amount of failed jobs in a given queue.\n", "responses": { "200": { "description": "Health Queue", @@ -11505,7 +11517,7 @@ }, "x-appwrite": { "method": "getFailedJobs", - "weight": 147, + "weight": 148, "cookies": false, "type": "", "deprecated": false, @@ -11594,7 +11606,7 @@ }, "x-appwrite": { "method": "getQueueFunctions", - "weight": 141, + "weight": 142, "cookies": false, "type": "", "deprecated": false, @@ -11659,7 +11671,7 @@ }, "x-appwrite": { "method": "getQueueLogs", - "weight": 132, + "weight": 133, "cookies": false, "type": "", "deprecated": false, @@ -11724,7 +11736,7 @@ }, "x-appwrite": { "method": "getQueueMails", - "weight": 138, + "weight": 139, "cookies": false, "type": "", "deprecated": false, @@ -11789,7 +11801,7 @@ }, "x-appwrite": { "method": "getQueueMessaging", - "weight": 139, + "weight": 140, "cookies": false, "type": "", "deprecated": false, @@ -11854,7 +11866,7 @@ }, "x-appwrite": { "method": "getQueueMigrations", - "weight": 140, + "weight": 141, "cookies": false, "type": "", "deprecated": false, @@ -11919,7 +11931,7 @@ }, "x-appwrite": { "method": "getQueueUsage", - "weight": 142, + "weight": 143, "cookies": false, "type": "", "deprecated": false, @@ -11984,7 +11996,7 @@ }, "x-appwrite": { "method": "getQueueUsageDump", - "weight": 143, + "weight": 144, "cookies": false, "type": "", "deprecated": false, @@ -12049,7 +12061,7 @@ }, "x-appwrite": { "method": "getQueueWebhooks", - "weight": 131, + "weight": 132, "cookies": false, "type": "", "deprecated": false, @@ -12114,7 +12126,7 @@ }, "x-appwrite": { "method": "getStorage", - "weight": 145, + "weight": 146, "cookies": false, "type": "", "deprecated": false, @@ -12168,7 +12180,7 @@ }, "x-appwrite": { "method": "getStorageLocal", - "weight": 144, + "weight": 145, "cookies": false, "type": "", "deprecated": false, @@ -12222,7 +12234,7 @@ }, "x-appwrite": { "method": "getTime", - "weight": 130, + "weight": 131, "cookies": false, "type": "", "deprecated": false, @@ -12265,7 +12277,7 @@ "tags": [ "locale" ], - "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\r\n\r\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", + "description": "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.\n\n([IP Geolocation by DB-IP](https:\/\/db-ip.com))", "responses": { "200": { "description": "Locale", @@ -12276,7 +12288,7 @@ }, "x-appwrite": { "method": "get", - "weight": 116, + "weight": 117, "cookies": false, "type": "", "deprecated": false, @@ -12334,7 +12346,7 @@ }, "x-appwrite": { "method": "listCodes", - "weight": 117, + "weight": 118, "cookies": false, "type": "", "deprecated": false, @@ -12392,7 +12404,7 @@ }, "x-appwrite": { "method": "listContinents", - "weight": 121, + "weight": 122, "cookies": false, "type": "", "deprecated": false, @@ -12450,7 +12462,7 @@ }, "x-appwrite": { "method": "listCountries", - "weight": 118, + "weight": 119, "cookies": false, "type": "", "deprecated": false, @@ -12508,7 +12520,7 @@ }, "x-appwrite": { "method": "listCountriesEU", - "weight": 119, + "weight": 120, "cookies": false, "type": "", "deprecated": false, @@ -12566,7 +12578,7 @@ }, "x-appwrite": { "method": "listCountriesPhones", - "weight": 120, + "weight": 121, "cookies": false, "type": "", "deprecated": false, @@ -12624,7 +12636,7 @@ }, "x-appwrite": { "method": "listCurrencies", - "weight": 122, + "weight": 123, "cookies": false, "type": "", "deprecated": false, @@ -12682,7 +12694,7 @@ }, "x-appwrite": { "method": "listLanguages", - "weight": 123, + "weight": 124, "cookies": false, "type": "", "deprecated": false, @@ -12740,7 +12752,7 @@ }, "x-appwrite": { "method": "listMessages", - "weight": 388, + "weight": 390, "cookies": false, "type": "", "deprecated": false, @@ -12818,7 +12830,7 @@ }, "x-appwrite": { "method": "createEmail", - "weight": 385, + "weight": 387, "cookies": false, "type": "", "deprecated": false, @@ -12968,7 +12980,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -12979,7 +12991,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 392, + "weight": 394, "cookies": false, "type": "", "deprecated": false, @@ -13137,7 +13149,7 @@ }, "x-appwrite": { "method": "createPush", - "weight": 387, + "weight": 389, "cookies": false, "type": "", "deprecated": false, @@ -13302,7 +13314,7 @@ "tags": [ "messaging" ], - "description": "Update a push notification by its unique ID.\r\n", + "description": "Update a push notification by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13313,7 +13325,7 @@ }, "x-appwrite": { "method": "updatePush", - "weight": 394, + "weight": 396, "cookies": false, "type": "", "deprecated": false, @@ -13486,7 +13498,7 @@ }, "x-appwrite": { "method": "createSms", - "weight": 386, + "weight": 388, "cookies": false, "type": "", "deprecated": false, @@ -13596,7 +13608,7 @@ "tags": [ "messaging" ], - "description": "Update an email message by its unique ID.\r\n", + "description": "Update an email message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13607,7 +13619,7 @@ }, "x-appwrite": { "method": "updateSms", - "weight": 393, + "weight": 395, "cookies": false, "type": "", "deprecated": false, @@ -13715,7 +13727,7 @@ "tags": [ "messaging" ], - "description": "Get a message by its unique ID.\r\n", + "description": "Get a message by its unique ID.\n", "responses": { "200": { "description": "Message", @@ -13726,7 +13738,7 @@ }, "x-appwrite": { "method": "getMessage", - "weight": 391, + "weight": 393, "cookies": false, "type": "", "deprecated": false, @@ -13786,7 +13798,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 395, + "weight": 397, "cookies": false, "type": "", "deprecated": false, @@ -13851,7 +13863,7 @@ }, "x-appwrite": { "method": "listMessageLogs", - "weight": 389, + "weight": 391, "cookies": false, "type": "", "deprecated": false, @@ -13928,7 +13940,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 390, + "weight": 392, "cookies": false, "type": "", "deprecated": false, @@ -14005,7 +14017,7 @@ }, "x-appwrite": { "method": "listProviders", - "weight": 360, + "weight": 362, "cookies": false, "type": "", "deprecated": false, @@ -14083,7 +14095,7 @@ }, "x-appwrite": { "method": "createApnsProvider", - "weight": 359, + "weight": 361, "cookies": false, "type": "", "deprecated": false, @@ -14201,7 +14213,7 @@ }, "x-appwrite": { "method": "updateApnsProvider", - "weight": 372, + "weight": 374, "cookies": false, "type": "", "deprecated": false, @@ -14317,7 +14329,7 @@ }, "x-appwrite": { "method": "createFcmProvider", - "weight": 358, + "weight": 360, "cookies": false, "type": "", "deprecated": false, @@ -14411,7 +14423,7 @@ }, "x-appwrite": { "method": "updateFcmProvider", - "weight": 371, + "weight": 373, "cookies": false, "type": "", "deprecated": false, @@ -14503,7 +14515,7 @@ }, "x-appwrite": { "method": "createMailgunProvider", - "weight": 350, + "weight": 352, "cookies": false, "type": "", "deprecated": false, @@ -14633,7 +14645,7 @@ }, "x-appwrite": { "method": "updateMailgunProvider", - "weight": 363, + "weight": 365, "cookies": false, "type": "", "deprecated": false, @@ -14761,7 +14773,7 @@ }, "x-appwrite": { "method": "createMsg91Provider", - "weight": 353, + "weight": 355, "cookies": false, "type": "", "deprecated": false, @@ -14867,7 +14879,7 @@ }, "x-appwrite": { "method": "updateMsg91Provider", - "weight": 366, + "weight": 368, "cookies": false, "type": "", "deprecated": false, @@ -14971,7 +14983,7 @@ }, "x-appwrite": { "method": "createSendgridProvider", - "weight": 351, + "weight": 353, "cookies": false, "type": "", "deprecated": false, @@ -15089,7 +15101,7 @@ }, "x-appwrite": { "method": "updateSendgridProvider", - "weight": 364, + "weight": 366, "cookies": false, "type": "", "deprecated": false, @@ -15205,7 +15217,7 @@ }, "x-appwrite": { "method": "createSmtpProvider", - "weight": 352, + "weight": 354, "cookies": false, "type": "", "deprecated": false, @@ -15367,7 +15379,7 @@ }, "x-appwrite": { "method": "updateSmtpProvider", - "weight": 365, + "weight": 367, "cookies": false, "type": "", "deprecated": false, @@ -15526,7 +15538,7 @@ }, "x-appwrite": { "method": "createTelesignProvider", - "weight": 354, + "weight": 356, "cookies": false, "type": "", "deprecated": false, @@ -15632,7 +15644,7 @@ }, "x-appwrite": { "method": "updateTelesignProvider", - "weight": 367, + "weight": 369, "cookies": false, "type": "", "deprecated": false, @@ -15736,7 +15748,7 @@ }, "x-appwrite": { "method": "createTextmagicProvider", - "weight": 355, + "weight": 357, "cookies": false, "type": "", "deprecated": false, @@ -15842,7 +15854,7 @@ }, "x-appwrite": { "method": "updateTextmagicProvider", - "weight": 368, + "weight": 370, "cookies": false, "type": "", "deprecated": false, @@ -15946,7 +15958,7 @@ }, "x-appwrite": { "method": "createTwilioProvider", - "weight": 356, + "weight": 358, "cookies": false, "type": "", "deprecated": false, @@ -16052,7 +16064,7 @@ }, "x-appwrite": { "method": "updateTwilioProvider", - "weight": 369, + "weight": 371, "cookies": false, "type": "", "deprecated": false, @@ -16156,7 +16168,7 @@ }, "x-appwrite": { "method": "createVonageProvider", - "weight": 357, + "weight": 359, "cookies": false, "type": "", "deprecated": false, @@ -16262,7 +16274,7 @@ }, "x-appwrite": { "method": "updateVonageProvider", - "weight": 370, + "weight": 372, "cookies": false, "type": "", "deprecated": false, @@ -16355,7 +16367,7 @@ "tags": [ "messaging" ], - "description": "Get a provider by its unique ID.\r\n", + "description": "Get a provider by its unique ID.\n", "responses": { "200": { "description": "Provider", @@ -16366,7 +16378,7 @@ }, "x-appwrite": { "method": "getProvider", - "weight": 362, + "weight": 364, "cookies": false, "type": "", "deprecated": false, @@ -16426,7 +16438,7 @@ }, "x-appwrite": { "method": "deleteProvider", - "weight": 373, + "weight": 375, "cookies": false, "type": "", "deprecated": false, @@ -16491,7 +16503,7 @@ }, "x-appwrite": { "method": "listProviderLogs", - "weight": 361, + "weight": 363, "cookies": false, "type": "", "deprecated": false, @@ -16568,7 +16580,7 @@ }, "x-appwrite": { "method": "listSubscriberLogs", - "weight": 382, + "weight": 384, "cookies": false, "type": "", "deprecated": false, @@ -16645,7 +16657,7 @@ }, "x-appwrite": { "method": "listTopics", - "weight": 375, + "weight": 377, "cookies": false, "type": "", "deprecated": false, @@ -16721,7 +16733,7 @@ }, "x-appwrite": { "method": "createTopic", - "weight": 374, + "weight": 376, "cookies": false, "type": "", "deprecated": false, @@ -16803,7 +16815,7 @@ "tags": [ "messaging" ], - "description": "Get a topic by its unique ID.\r\n", + "description": "Get a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -16814,7 +16826,7 @@ }, "x-appwrite": { "method": "getTopic", - "weight": 377, + "weight": 379, "cookies": false, "type": "", "deprecated": false, @@ -16866,7 +16878,7 @@ "tags": [ "messaging" ], - "description": "Update a topic by its unique ID.\r\n", + "description": "Update a topic by its unique ID.\n", "responses": { "200": { "description": "Topic", @@ -16877,7 +16889,7 @@ }, "x-appwrite": { "method": "updateTopic", - "weight": 378, + "weight": 380, "cookies": false, "type": "", "deprecated": false, @@ -16961,7 +16973,7 @@ }, "x-appwrite": { "method": "deleteTopic", - "weight": 379, + "weight": 381, "cookies": false, "type": "", "deprecated": false, @@ -17026,7 +17038,7 @@ }, "x-appwrite": { "method": "listTopicLogs", - "weight": 376, + "weight": 378, "cookies": false, "type": "", "deprecated": false, @@ -17103,7 +17115,7 @@ }, "x-appwrite": { "method": "listSubscribers", - "weight": 381, + "weight": 383, "cookies": false, "type": "", "deprecated": false, @@ -17187,7 +17199,7 @@ }, "x-appwrite": { "method": "createSubscriber", - "weight": 380, + "weight": 382, "cookies": false, "type": "", "deprecated": false, @@ -17270,7 +17282,7 @@ "tags": [ "messaging" ], - "description": "Get a subscriber by its unique ID.\r\n", + "description": "Get a subscriber by its unique ID.\n", "responses": { "200": { "description": "Subscriber", @@ -17281,7 +17293,7 @@ }, "x-appwrite": { "method": "getSubscriber", - "weight": 383, + "weight": 385, "cookies": false, "type": "", "deprecated": false, @@ -17349,7 +17361,7 @@ }, "x-appwrite": { "method": "deleteSubscriber", - "weight": 384, + "weight": 386, "cookies": false, "type": "", "deprecated": false, @@ -17426,7 +17438,7 @@ }, "x-appwrite": { "method": "listBuckets", - "weight": 201, + "weight": 203, "cookies": false, "type": "", "deprecated": false, @@ -17501,7 +17513,7 @@ }, "x-appwrite": { "method": "createBucket", - "weight": 200, + "weight": 202, "cookies": false, "type": "", "deprecated": false, @@ -17643,7 +17655,7 @@ }, "x-appwrite": { "method": "getBucket", - "weight": 202, + "weight": 204, "cookies": false, "type": "", "deprecated": false, @@ -17705,7 +17717,7 @@ }, "x-appwrite": { "method": "updateBucket", - "weight": 203, + "weight": 205, "cookies": false, "type": "", "deprecated": false, @@ -17841,7 +17853,7 @@ }, "x-appwrite": { "method": "deleteBucket", - "weight": 204, + "weight": 206, "cookies": false, "type": "", "deprecated": false, @@ -17905,7 +17917,7 @@ }, "x-appwrite": { "method": "listFiles", - "weight": 206, + "weight": 208, "cookies": false, "type": "", "deprecated": false, @@ -17981,7 +17993,7 @@ "tags": [ "storage" ], - "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\r\n\r\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\r\n\r\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\r\n\r\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\r\n", + "description": "Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/storage#storageCreateBucket) API or directly from your Appwrite console.\n\nLarger files should be uploaded using multiple requests with the [content-range](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.\n\nWhen the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one.\n\nIf you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally.\n", "responses": { "201": { "description": "File", @@ -17992,7 +18004,7 @@ }, "x-appwrite": { "method": "createFile", - "weight": 205, + "weight": 207, "cookies": false, "type": "upload", "deprecated": false, @@ -18088,7 +18100,7 @@ }, "x-appwrite": { "method": "getFile", - "weight": 207, + "weight": 209, "cookies": false, "type": "", "deprecated": false, @@ -18162,7 +18174,7 @@ }, "x-appwrite": { "method": "updateFile", - "weight": 212, + "weight": 214, "cookies": false, "type": "", "deprecated": false, @@ -18255,7 +18267,7 @@ }, "x-appwrite": { "method": "deleteFile", - "weight": 213, + "weight": 215, "cookies": false, "type": "", "deprecated": false, @@ -18331,7 +18343,7 @@ }, "x-appwrite": { "method": "getFileDownload", - "weight": 209, + "weight": 211, "cookies": false, "type": "location", "deprecated": false, @@ -18407,7 +18419,7 @@ }, "x-appwrite": { "method": "getFilePreview", - "weight": 208, + "weight": 210, "cookies": false, "type": "location", "deprecated": false, @@ -18610,7 +18622,7 @@ }, "x-appwrite": { "method": "getFileView", - "weight": 210, + "weight": 212, "cookies": false, "type": "location", "deprecated": false, @@ -18686,7 +18698,7 @@ }, "x-appwrite": { "method": "list", - "weight": 217, + "weight": 219, "cookies": false, "type": "", "deprecated": false, @@ -18765,7 +18777,7 @@ }, "x-appwrite": { "method": "create", - "weight": 216, + "weight": 218, "cookies": false, "type": "", "deprecated": false, @@ -18861,7 +18873,7 @@ }, "x-appwrite": { "method": "get", - "weight": 218, + "weight": 220, "cookies": false, "type": "", "deprecated": false, @@ -18927,7 +18939,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 220, + "weight": 222, "cookies": false, "type": "", "deprecated": false, @@ -19006,7 +19018,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 222, + "weight": 224, "cookies": false, "type": "", "deprecated": false, @@ -19063,7 +19075,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.", + "description": "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Memberships List", @@ -19074,7 +19086,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 224, + "weight": 226, "cookies": false, "type": "", "deprecated": false, @@ -19150,7 +19162,7 @@ "tags": [ "teams" ], - "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\r\n\r\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\r\n\r\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \r\n\r\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\r\n", + "description": "Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team.\n\nYou only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters.\n\nUse the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. \n\nPlease note that to avoid a [Redirect Attack](https:\/\/github.com\/OWASP\/CheatSheetSeries\/blob\/master\/cheatsheets\/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console.\n", "responses": { "201": { "description": "Membership", @@ -19161,7 +19173,7 @@ }, "x-appwrite": { "method": "createMembership", - "weight": 223, + "weight": 225, "cookies": false, "type": "", "deprecated": false, @@ -19269,7 +19281,7 @@ "tags": [ "teams" ], - "description": "Get a team member by the membership unique id. All team members have read access for this resource.", + "description": "Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console.", "responses": { "200": { "description": "Membership", @@ -19280,7 +19292,7 @@ }, "x-appwrite": { "method": "getMembership", - "weight": 225, + "weight": 227, "cookies": false, "type": "", "deprecated": false, @@ -19343,7 +19355,7 @@ "tags": [ "teams" ], - "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\r\n", + "description": "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions).\n", "responses": { "200": { "description": "Membership", @@ -19354,7 +19366,7 @@ }, "x-appwrite": { "method": "updateMembership", - "weight": 226, + "weight": 228, "cookies": false, "type": "", "deprecated": false, @@ -19444,7 +19456,7 @@ }, "x-appwrite": { "method": "deleteMembership", - "weight": 228, + "weight": 230, "cookies": false, "type": "", "deprecated": false, @@ -19509,7 +19521,7 @@ "tags": [ "teams" ], - "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\r\n\r\nIf the request is successful, a session for the user is automatically created.\r\n", + "description": "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\nIf the request is successful, a session for the user is automatically created.\n", "responses": { "200": { "description": "Membership", @@ -19520,7 +19532,7 @@ }, "x-appwrite": { "method": "updateMembershipStatus", - "weight": 227, + "weight": 229, "cookies": false, "type": "", "deprecated": false, @@ -19619,7 +19631,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 219, + "weight": 221, "cookies": false, "type": "", "deprecated": false, @@ -19683,7 +19695,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 221, + "weight": 223, "cookies": false, "type": "", "deprecated": false, @@ -19767,7 +19779,7 @@ }, "x-appwrite": { "method": "list", - "weight": 239, + "weight": 241, "cookies": false, "type": "", "deprecated": false, @@ -19842,7 +19854,7 @@ }, "x-appwrite": { "method": "create", - "weight": 230, + "weight": 232, "cookies": false, "type": "", "deprecated": false, @@ -19940,7 +19952,7 @@ }, "x-appwrite": { "method": "createArgon2User", - "weight": 233, + "weight": 235, "cookies": false, "type": "", "deprecated": false, @@ -20034,7 +20046,7 @@ }, "x-appwrite": { "method": "createBcryptUser", - "weight": 231, + "weight": 233, "cookies": false, "type": "", "deprecated": false, @@ -20128,7 +20140,7 @@ }, "x-appwrite": { "method": "listIdentities", - "weight": 247, + "weight": 249, "cookies": false, "type": "", "deprecated": false, @@ -20200,7 +20212,7 @@ }, "x-appwrite": { "method": "deleteIdentity", - "weight": 270, + "weight": 272, "cookies": false, "type": "", "deprecated": false, @@ -20264,7 +20276,7 @@ }, "x-appwrite": { "method": "createMD5User", - "weight": 232, + "weight": 234, "cookies": false, "type": "", "deprecated": false, @@ -20358,7 +20370,7 @@ }, "x-appwrite": { "method": "createPHPassUser", - "weight": 235, + "weight": 237, "cookies": false, "type": "", "deprecated": false, @@ -20452,7 +20464,7 @@ }, "x-appwrite": { "method": "createScryptUser", - "weight": 236, + "weight": 238, "cookies": false, "type": "", "deprecated": false, @@ -20581,7 +20593,7 @@ }, "x-appwrite": { "method": "createScryptModifiedUser", - "weight": 237, + "weight": 239, "cookies": false, "type": "", "deprecated": false, @@ -20696,7 +20708,7 @@ }, "x-appwrite": { "method": "createSHAUser", - "weight": 234, + "weight": 236, "cookies": false, "type": "", "deprecated": false, @@ -20811,7 +20823,7 @@ }, "x-appwrite": { "method": "get", - "weight": 240, + "weight": 242, "cookies": false, "type": "", "deprecated": false, @@ -20868,7 +20880,7 @@ }, "x-appwrite": { "method": "delete", - "weight": 268, + "weight": 270, "cookies": false, "type": "", "deprecated": false, @@ -20932,7 +20944,7 @@ }, "x-appwrite": { "method": "updateEmail", - "weight": 253, + "weight": 255, "cookies": false, "type": "", "deprecated": false, @@ -21014,7 +21026,7 @@ }, "x-appwrite": { "method": "createJWT", - "weight": 271, + "weight": 273, "cookies": false, "type": "", "deprecated": false, @@ -21088,7 +21100,7 @@ "tags": [ "users" ], - "description": "Update the user labels by its unique ID. \r\n\r\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", + "description": "Update the user labels by its unique ID. \n\nLabels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https:\/\/appwrite.io\/docs\/permissions) for more info.", "responses": { "200": { "description": "User", @@ -21099,7 +21111,7 @@ }, "x-appwrite": { "method": "updateLabels", - "weight": 249, + "weight": 251, "cookies": false, "type": "", "deprecated": false, @@ -21184,7 +21196,7 @@ }, "x-appwrite": { "method": "listLogs", - "weight": 245, + "weight": 247, "cookies": false, "type": "", "deprecated": false, @@ -21260,7 +21272,7 @@ }, "x-appwrite": { "method": "listMemberships", - "weight": 244, + "weight": 246, "cookies": false, "type": "", "deprecated": false, @@ -21324,7 +21336,7 @@ }, "x-appwrite": { "method": "updateMfa", - "weight": 258, + "weight": 260, "cookies": false, "type": "", "deprecated": false, @@ -21406,7 +21418,7 @@ }, "x-appwrite": { "method": "deleteMfaAuthenticator", - "weight": 263, + "weight": 265, "cookies": false, "type": "", "deprecated": false, @@ -21483,7 +21495,7 @@ }, "x-appwrite": { "method": "listMfaFactors", - "weight": 259, + "weight": 261, "cookies": false, "type": "", "deprecated": false, @@ -21547,7 +21559,7 @@ }, "x-appwrite": { "method": "getMfaRecoveryCodes", - "weight": 260, + "weight": 262, "cookies": false, "type": "", "deprecated": false, @@ -21609,7 +21621,7 @@ }, "x-appwrite": { "method": "updateMfaRecoveryCodes", - "weight": 262, + "weight": 264, "cookies": false, "type": "", "deprecated": false, @@ -21671,7 +21683,7 @@ }, "x-appwrite": { "method": "createMfaRecoveryCodes", - "weight": 261, + "weight": 263, "cookies": false, "type": "", "deprecated": false, @@ -21735,7 +21747,7 @@ }, "x-appwrite": { "method": "updateName", - "weight": 251, + "weight": 253, "cookies": false, "type": "", "deprecated": false, @@ -21817,7 +21829,7 @@ }, "x-appwrite": { "method": "updatePassword", - "weight": 252, + "weight": 254, "cookies": false, "type": "", "deprecated": false, @@ -21899,7 +21911,7 @@ }, "x-appwrite": { "method": "updatePhone", - "weight": 254, + "weight": 256, "cookies": false, "type": "", "deprecated": false, @@ -21981,7 +21993,7 @@ }, "x-appwrite": { "method": "getPrefs", - "weight": 241, + "weight": 243, "cookies": false, "type": "", "deprecated": false, @@ -22043,7 +22055,7 @@ }, "x-appwrite": { "method": "updatePrefs", - "weight": 256, + "weight": 258, "cookies": false, "type": "", "deprecated": false, @@ -22125,7 +22137,7 @@ }, "x-appwrite": { "method": "listSessions", - "weight": 243, + "weight": 245, "cookies": false, "type": "", "deprecated": false, @@ -22176,7 +22188,7 @@ "tags": [ "users" ], - "description": "Creates a session for a user. Returns an immediately usable session object.\r\n\r\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", + "description": "Creates a session for a user. Returns an immediately usable session object.\n\nIf you want to generate a token for a custom authentication flow, use the [POST \/users\/{userId}\/tokens](https:\/\/appwrite.io\/docs\/server\/users#createToken) endpoint.", "responses": { "201": { "description": "Session", @@ -22187,7 +22199,7 @@ }, "x-appwrite": { "method": "createSession", - "weight": 264, + "weight": 266, "cookies": false, "type": "", "deprecated": false, @@ -22244,7 +22256,7 @@ }, "x-appwrite": { "method": "deleteSessions", - "weight": 267, + "weight": 269, "cookies": false, "type": "", "deprecated": false, @@ -22303,7 +22315,7 @@ }, "x-appwrite": { "method": "deleteSession", - "weight": 266, + "weight": 268, "cookies": false, "type": "", "deprecated": false, @@ -22375,7 +22387,7 @@ }, "x-appwrite": { "method": "updateStatus", - "weight": 248, + "weight": 250, "cookies": false, "type": "", "deprecated": false, @@ -22457,7 +22469,7 @@ }, "x-appwrite": { "method": "listTargets", - "weight": 246, + "weight": 248, "cookies": false, "type": "", "deprecated": false, @@ -22532,7 +22544,7 @@ }, "x-appwrite": { "method": "createTarget", - "weight": 238, + "weight": 240, "cookies": false, "type": "", "deprecated": false, @@ -22648,7 +22660,7 @@ }, "x-appwrite": { "method": "getTarget", - "weight": 242, + "weight": 244, "cookies": false, "type": "", "deprecated": false, @@ -22719,7 +22731,7 @@ }, "x-appwrite": { "method": "updateTarget", - "weight": 257, + "weight": 259, "cookies": false, "type": "", "deprecated": false, @@ -22814,7 +22826,7 @@ }, "x-appwrite": { "method": "deleteTarget", - "weight": 269, + "weight": 271, "cookies": false, "type": "", "deprecated": false, @@ -22876,7 +22888,7 @@ "tags": [ "users" ], - "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\r\n", + "description": "Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT \/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process.\n", "responses": { "201": { "description": "Token", @@ -22887,7 +22899,7 @@ }, "x-appwrite": { "method": "createToken", - "weight": 265, + "weight": 267, "cookies": false, "type": "", "deprecated": false, @@ -22972,7 +22984,7 @@ }, "x-appwrite": { "method": "updateEmailVerification", - "weight": 255, + "weight": 257, "cookies": false, "type": "", "deprecated": false, @@ -23054,7 +23066,7 @@ }, "x-appwrite": { "method": "updatePhoneVerification", - "weight": 250, + "weight": 252, "cookies": false, "type": "", "deprecated": false, @@ -26072,12 +26084,12 @@ }, "userName": { "type": "string", - "description": "User name.", + "description": "User name. Hide this attribute by toggling membership privacy in the Console.", "x-example": "John Doe" }, "userEmail": { "type": "string", - "description": "User email address.", + "description": "User email address. Hide this attribute by toggling membership privacy in the Console.", "x-example": "john@appwrite.io" }, "teamId": { @@ -26107,7 +26119,7 @@ }, "mfa": { "type": "boolean", - "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise.", + "description": "Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.", "x-example": false }, "roles": { @@ -26273,7 +26285,7 @@ "specification": { "type": "string", "description": "Machine specification for builds and executions.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -26591,7 +26603,7 @@ "format": "int32" }, "responseBody": { - "type": "payload", + "type": "string", "description": "HTTP response body. This will return empty unless execution is created as synchronous.", "x-example": "" }, @@ -27087,7 +27099,7 @@ "slug": { "type": "string", "description": "Size slug.", - "x-example": "s-0.5vcpu-512mb" + "x-example": "s-1vcpu-512mb" } }, "required": [ @@ -27538,7 +27550,7 @@ "name": { "type": "string", "description": "Target Name.", - "x-example": "Aegon apple token" + "x-example": "Apple iPhone 12" }, "userId": { "type": "string", @@ -27560,6 +27572,11 @@ "type": "string", "description": "The target identifier.", "x-example": "token" + }, + "expired": { + "type": "boolean", + "description": "Is the target expired.", + "x-example": false } }, "required": [ @@ -27569,7 +27586,8 @@ "name", "userId", "providerType", - "identifier" + "identifier", + "expired" ] } }, diff --git a/app/config/storage/mimes.php b/app/config/storage/mimes.php index df325b37e9..26aaf8e1ff 100644 --- a/app/config/storage/mimes.php +++ b/app/config/storage/mimes.php @@ -33,6 +33,7 @@ return [ 'audio/ogg', // Ogg Vorbis RFC 5334 'audio/vorbis', // Vorbis RFC 5215 'audio/vnd.wav', // wav RFC 2361 + 'audio/x-wav', // php reads .wav as this - https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types 'audio/aac', //AAC audio 'audio/x-hx-aac-adts', // AAC audio diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index cb71818df3..76a3ef8b61 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -274,7 +274,6 @@ $createSession = function (string $userId, string $secret, Request $request, Res App::post('/v1/account') ->desc('Create account') ->groups(['api', 'account', 'auth']) - ->label('event', 'users.[userId].create') ->label('scope', 'sessions.write') ->label('auth.type', 'emailPassword') ->label('audits.event', 'user.create') @@ -297,9 +296,8 @@ App::post('/v1/account') ->inject('user') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { + ->action(function (string $userId, string $email, string $password, string $name, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Hooks $hooks) { $email = \strtolower($email); if ('console' === $project->getId()) { @@ -332,7 +330,7 @@ App::post('/v1/account') $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */ } @@ -395,7 +393,7 @@ App::post('/v1/account') $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - if ($existingTarget) { + if (!$existingTarget->isEmpty()) { $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } @@ -409,8 +407,6 @@ App::post('/v1/account') Authorization::setRole(Role::user($user->getId())->toString()); Authorization::setRole(Role::users()->toString()); - $queueForEvents->setParam('userId', $user->getId()); - $response ->setStatusCode(Response::STATUS_CODE_CREATED) ->dynamic($user, Response::MODEL_ACCOUNT); @@ -442,7 +438,6 @@ App::get('/v1/account') App::delete('/v1/account') ->desc('Delete account') ->groups(['api', 'account']) - ->label('event', 'users.[userId].delete') ->label('scope', 'account') ->label('audits.event', 'user.delete') ->label('audits.resource', 'user/{response.$id}') @@ -834,7 +829,7 @@ App::post('/v1/account/sessions/email') Query::equal('email', [$email]), ]); - if (!$profile || empty($profile->getAttribute('passwordUpdate')) || !Auth::passwordVerify($password, $profile->getAttribute('password'), $profile->getAttribute('hash'), $profile->getAttribute('hashOptions'))) { + if ($profile->isEmpty() || empty($profile->getAttribute('passwordUpdate')) || !Auth::passwordVerify($password, $profile->getAttribute('password'), $profile->getAttribute('hash'), $profile->getAttribute('hashOptions'))) { throw new Exception(Exception::USER_INVALID_CREDENTIALS); } @@ -1374,7 +1369,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Query::equal('providerEmail', [$email]), Query::notEqual('userInternalId', $user->getInternalId()), ]); - if (!empty($identityWithMatchingEmail)) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::USER_ALREADY_EXISTS); } @@ -1405,7 +1400,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Query::equal('provider', [$provider]), Query::equal('providerUid', [$oauth2ID]), ]); - if ($session !== false && !$session->isEmpty()) { + if (!$session->isEmpty()) { $user->setAttributes($dbForProject->getDocument('users', $session->getAttribute('userId'))->getArrayCopy()); } } @@ -1423,7 +1418,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $userWithEmail = $dbForProject->findOne('users', [ Query::equal('email', [$email]), ]); - if ($userWithEmail !== false && !$userWithEmail->isEmpty()) { + if (!$userWithEmail->isEmpty()) { $user->setAttributes($userWithEmail->getArrayCopy()); } @@ -1434,7 +1429,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Query::equal('providerUid', [$oauth2ID]), ]); - if ($identity !== false && !$identity->isEmpty()) { + if (!$identity->isEmpty()) { $user = $dbForProject->getDocument('users', $identity->getAttribute('userId')); } } @@ -1454,7 +1449,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */ } @@ -1499,6 +1494,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'providerType' => MESSAGE_TYPE_EMAIL, 'identifier' => $email, ])); + } catch (Duplicate) { $failureRedirect(Exception::USER_ALREADY_EXISTS); } @@ -1517,7 +1513,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') Query::equal('provider', [$provider]), Query::equal('providerUid', [$oauth2ID]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { // Before creating the identity, check if the email is already associated with another user $userId = $user->getId(); @@ -1801,7 +1797,7 @@ App::post('/v1/account/tokens/magic-url') $isAppUser = Auth::isAppUser($roles); $result = $dbForProject->findOne('users', [Query::equal('email', [$email])]); - if ($result !== false && !$result->isEmpty()) { + if (!$result->isEmpty()) { $user->setAttributes($result->getArrayCopy()); } else { $limit = $project->getAttribute('auths', [])['limit'] ?? 0; @@ -1818,7 +1814,7 @@ App::post('/v1/account/tokens/magic-url') $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } @@ -2042,7 +2038,7 @@ App::post('/v1/account/tokens/email') $isAppUser = Auth::isAppUser($roles); $result = $dbForProject->findOne('users', [Query::equal('email', [$email])]); - if ($result !== false && !$result->isEmpty()) { + if (!$result->isEmpty()) { $user->setAttributes($result->getArrayCopy()); } else { $limit = $project->getAttribute('auths', [])['limit'] ?? 0; @@ -2059,7 +2055,7 @@ App::post('/v1/account/tokens/email') $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */ } @@ -2329,7 +2325,7 @@ App::post('/v1/account/tokens/phone') $isAppUser = Auth::isAppUser($roles); $result = $dbForProject->findOne('users', [Query::equal('phone', [$phone])]); - if ($result !== false && !$result->isEmpty()) { + if (!$result->isEmpty()) { $user->setAttributes($result->getArrayCopy()); } else { $limit = $project->getAttribute('auths', [])['limit'] ?? 0; @@ -2386,7 +2382,7 @@ App::post('/v1/account/tokens/phone') $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), ]); - $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]); + $user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget->isEmpty() ? false : $existingTarget]); } $dbForProject->purgeCachedDocument('users', $user->getId()); } @@ -2753,7 +2749,7 @@ App::patch('/v1/account/email') Query::equal('providerEmail', [$email]), Query::notEqual('userInternalId', $user->getInternalId()), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */ } @@ -2774,7 +2770,7 @@ App::patch('/v1/account/email') Query::equal('identifier', [$email]), ])); - if ($target instanceof Document && !$target->isEmpty()) { + if (!$target->isEmpty()) { throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); } @@ -2840,7 +2836,7 @@ App::patch('/v1/account/phone') Query::equal('identifier', [$phone]), ])); - if ($target instanceof Document && !$target->isEmpty()) { + if (!$target->isEmpty()) { throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS); } @@ -2999,7 +2995,7 @@ App::post('/v1/account/recovery') Query::equal('email', [$email]), ]); - if (!$profile) { + if ($profile->isEmpty()) { throw new Exception(Exception::USER_NOT_FOUND); } @@ -4315,7 +4311,7 @@ App::post('/v1/account/targets/push') $device = $detector->getDevice(); - $sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret); + $sessionId = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret); $session = $dbForProject->getDocument('sessions', $sessionId); try { @@ -4384,7 +4380,9 @@ App::put('/v1/account/targets/:targetId/push') } if ($identifier) { - $target->setAttribute('identifier', $identifier); + $target + ->setAttribute('identifier', $identifier) + ->setAttribute('expired', false); } $detector = new Detector($request->getUserAgent()); diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index fcff3e4179..dadd9da5e3 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -55,7 +55,7 @@ $avatarCallback = function (string $type, string $code, int $width, int $height, $output = (empty($output)) ? $type : $output; $data = $image->output($output, $quality); $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + 60 * 60 * 24 * 30) . ' GMT') + ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType('image/png') ->file($data); unset($image); @@ -275,7 +275,7 @@ App::get('/v1/avatars/image') $data = $image->output($output, $quality); $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + 60 * 60 * 24 * 30) . ' GMT') + ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType('image/png') ->file($data); unset($image); @@ -409,7 +409,7 @@ App::get('/v1/avatars/favicon') throw new Exception(Exception::AVATAR_ICON_NOT_FOUND, 'Favicon not found'); } $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + 60 * 60 * 24 * 30) . ' GMT') + ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType('image/x-icon') ->file($data); } @@ -420,7 +420,7 @@ App::get('/v1/avatars/favicon') $data = $image->output($output, $quality); $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + 60 * 60 * 24 * 30) . ' GMT') + ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType('image/png') ->file($data); unset($image); @@ -461,7 +461,7 @@ App::get('/v1/avatars/qr') $image->crop((int) $size, (int) $size); $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->setContentType('image/png') ->send($image->output('png', 9)); }); @@ -544,7 +544,7 @@ App::get('/v1/avatars/initials') $image->compositeImage($punch, Imagick::COMPOSITE_COPYOPACITY, 0, 0); $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->setContentType('image/png') ->file($image->getImageBlob()); }); @@ -751,7 +751,7 @@ App::get('/v1/cards/cloud') } $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->setContentType('image/png') ->file($baseImage->getImageBlob()); }); @@ -829,7 +829,7 @@ App::get('/v1/cards/cloud-back') } $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->setContentType('image/png') ->file($baseImage->getImageBlob()); }); @@ -1219,7 +1219,7 @@ App::get('/v1/cards/cloud-og') } $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->setContentType('image/png') ->file($baseImage->getImageBlob()); }); diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 473f09cb7c..0114fd343c 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -3,7 +3,6 @@ use Appwrite\Auth\Auth; use Appwrite\Detector\Detector; use Appwrite\Event\Database as EventDatabase; -use Appwrite\Event\Delete; use Appwrite\Event\Event; use Appwrite\Event\Usage; use Appwrite\Extend\Exception; @@ -26,6 +25,7 @@ use Utopia\Database\Exception\Authorization as AuthorizationException; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Limit as LimitException; +use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Exception\Restricted as RestrictedException; use Utopia\Database\Exception\Structure as StructureException; @@ -352,13 +352,16 @@ function updateAttribute( if ($type === Database::VAR_RELATIONSHIP) { $primaryDocumentOptions = \array_merge($attribute->getAttribute('options', []), $options); $attribute->setAttribute('options', $primaryDocumentOptions); - - $dbForProject->updateRelationship( - collection: $collectionId, - id: $key, - newKey: $newKey, - onDelete: $primaryDocumentOptions['onDelete'], - ); + try { + $dbForProject->updateRelationship( + collection: $collectionId, + id: $key, + newKey: $newKey, + onDelete: $primaryDocumentOptions['onDelete'], + ); + } catch (NotFoundException) { + throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); + } if ($primaryDocumentOptions['twoWay']) { $relatedCollection = $dbForProject->getDocument('database_' . $db->getInternalId(), $primaryDocumentOptions['relatedCollection']); @@ -388,6 +391,8 @@ function updateAttribute( ); } catch (TruncateException) { throw new Exception(Exception::ATTRIBUTE_INVALID_RESIZE); + } catch (NotFoundException) { + throw new Exception(Exception::ATTRIBUTE_NOT_FOUND); } } @@ -439,6 +444,7 @@ App::post('/v1/databases') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].create') ->label('scope', 'databases.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'database.create') ->label('audits.resource', 'database/{response.$id}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -516,6 +522,7 @@ App::get('/v1/databases') ->desc('List databases') ->groups(['api', 'database']) ->label('scope', 'databases.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'list') @@ -528,12 +535,7 @@ App::get('/v1/databases') ->inject('response') ->inject('dbForProject') ->action(function (array $queries, string $search, Response $response, Database $dbForProject) { - - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $queries = Query::parseQueries($queries); if (!empty($search)) { $queries[] = Query::search('search', $search); @@ -576,6 +578,7 @@ App::get('/v1/databases/:databaseId') ->desc('Get database') ->groups(['api', 'database']) ->label('scope', 'databases.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'get') @@ -601,6 +604,7 @@ App::get('/v1/databases/:databaseId/logs') ->desc('List database logs') ->groups(['api', 'database']) ->label('scope', 'databases.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listLogs') @@ -692,6 +696,7 @@ App::put('/v1/databases/:databaseId') ->desc('Update database') ->groups(['api', 'database', 'schema']) ->label('scope', 'databases.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].update') ->label('audits.event', 'database.update') ->label('audits.resource', 'database/{response.$id}') @@ -730,6 +735,7 @@ App::delete('/v1/databases/:databaseId') ->desc('Delete database') ->groups(['api', 'database', 'schema']) ->label('scope', 'databases.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].delete') ->label('audits.event', 'database.delete') ->label('audits.resource', 'database/{request.databaseId}') @@ -779,6 +785,7 @@ App::post('/v1/databases/:databaseId/collections') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'collection.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{response.$id}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -809,22 +816,21 @@ App::post('/v1/databases/:databaseId/collections') $collectionId = $collectionId == 'unique()' ? ID::unique() : $collectionId; // Map aggregate permissions into the multiple permissions they represent. - $permissions = Permission::aggregate($permissions); + $permissions = Permission::aggregate($permissions) ?? []; try { - $dbForProject->createDocument('database_' . $database->getInternalId(), new Document([ + $collection = $dbForProject->createDocument('database_' . $database->getInternalId(), new Document([ '$id' => $collectionId, 'databaseInternalId' => $database->getInternalId(), 'databaseId' => $databaseId, - '$permissions' => $permissions ?? [], + '$permissions' => $permissions, 'documentSecurity' => $documentSecurity, 'enabled' => $enabled, 'name' => $name, 'search' => implode(' ', [$collectionId, $name]), ])); - $collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId); - $dbForProject->createCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), permissions: $permissions ?? [], documentSecurity: $documentSecurity); + $dbForProject->createCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), permissions: $permissions, documentSecurity: $documentSecurity); } catch (DuplicateException) { throw new Exception(Exception::COLLECTION_ALREADY_EXISTS); } catch (LimitException) { @@ -842,10 +848,11 @@ App::post('/v1/databases/:databaseId/collections') }); App::get('/v1/databases/:databaseId/collections') - ->alias('/v1/database/collections', ['databaseId' => 'default']) + ->alias('/v1/database/collections') ->desc('List collections') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listCollections') @@ -867,11 +874,7 @@ App::get('/v1/databases/:databaseId/collections') throw new Exception(Exception::DATABASE_NOT_FOUND); } - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $queries = Query::parseQueries($queries); if (!empty($search)) { $queries[] = Query::search('search', $search); @@ -911,10 +914,11 @@ App::get('/v1/databases/:databaseId/collections') }); App::get('/v1/databases/:databaseId/collections/:collectionId') - ->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId') ->desc('Get collection') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getCollection') @@ -945,10 +949,11 @@ App::get('/v1/databases/:databaseId/collections/:collectionId') }); App::get('/v1/databases/:databaseId/collections/:collectionId/logs') - ->alias('/v1/database/collections/:collectionId/logs', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/logs') ->desc('List collection logs') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listCollectionLogs') @@ -978,12 +983,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs') throw new Exception(Exception::COLLECTION_NOT_FOUND); } - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } - + $queries = Query::parseQueries($queries); $grouped = Query::groupByType($queries); $limit = $grouped['limit'] ?? APP_LIMIT_COUNT; $offset = $grouped['offset'] ?? 0; @@ -1045,10 +1045,11 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs') App::put('/v1/databases/:databaseId/collections/:collectionId') - ->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId') ->desc('Update collection') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].update') ->label('audits.event', 'collection.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -1090,12 +1091,16 @@ App::put('/v1/databases/:databaseId/collections/:collectionId') $enabled ??= $collection->getAttribute('enabled', true); - $collection = $dbForProject->updateDocument('database_' . $database->getInternalId(), $collectionId, $collection + $collection = $dbForProject->updateDocument( + 'database_' . $database->getInternalId(), + $collectionId, + $collection ->setAttribute('name', $name) ->setAttribute('$permissions', $permissions) ->setAttribute('documentSecurity', $documentSecurity) ->setAttribute('enabled', $enabled) - ->setAttribute('search', implode(' ', [$collectionId, $name]))); + ->setAttribute('search', \implode(' ', [$collectionId, $name])) + ); $dbForProject->updateCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $permissions, $documentSecurity); @@ -1108,10 +1113,11 @@ App::put('/v1/databases/:databaseId/collections/:collectionId') }); App::delete('/v1/databases/:databaseId/collections/:collectionId') - ->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId') ->desc('Delete collection') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].delete') ->label('audits.event', 'collection.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -1163,11 +1169,12 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId') }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string') - ->alias('/v1/database/collections/:collectionId/attributes/string', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/string') ->desc('Create string attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -1213,18 +1220,18 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string 'filters' => $filters, ]), $response, $dbForProject, $queueForDatabase, $queueForEvents); - $response ->setStatusCode(Response::STATUS_CODE_ACCEPTED) ->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING); }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email') - ->alias('/v1/database/collections/:collectionId/attributes/email', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/email') ->desc('Create email attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1262,11 +1269,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email' }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum') - ->alias('/v1/database/collections/:collectionId/attributes/enum', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/enum') ->desc('Create enum attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1309,11 +1317,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum') }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip') - ->alias('/v1/database/collections/:collectionId/attributes/ip', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/ip') ->desc('Create IP address attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1351,11 +1360,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip') }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url') - ->alias('/v1/database/collections/:collectionId/attributes/url', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/url') ->desc('Create URL attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1393,11 +1403,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url') }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/integer') - ->alias('/v1/database/collections/:collectionId/attributes/integer', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/integer') ->desc('Create integer attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1422,8 +1433,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { // Ensure attribute default is within range - $min = (is_null($min)) ? PHP_INT_MIN : \intval($min); - $max = (is_null($max)) ? PHP_INT_MAX : \intval($max); + $min = \is_null($min) ? PHP_INT_MIN : $min; + $max = \is_null($max) ? PHP_INT_MAX : $max; if ($min > $max) { throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value'); @@ -1464,11 +1475,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float') - ->alias('/v1/database/collections/:collectionId/attributes/float', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/float') ->desc('Create float attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1493,21 +1505,16 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float' ->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) { // Ensure attribute default is within range - $min = (is_null($min)) ? -PHP_FLOAT_MAX : \floatval($min); - $max = (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max); + $min = \is_null($min) ? -PHP_FLOAT_MAX : $min; + $max = \is_null($max) ? PHP_FLOAT_MAX : $max; if ($min > $max) { throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value'); } - // Ensure default value is a float - if (!is_null($default)) { - $default = \floatval($default); - } - $validator = new Range($min, $max, Database::VAR_FLOAT); - if (!is_null($default) && !$validator->isValid($default)) { + if (!\is_null($default) && !$validator->isValid($default)) { throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription()); } @@ -1538,11 +1545,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float' }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolean') - ->alias('/v1/database/collections/:collectionId/attributes/boolean', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/boolean') ->desc('Create boolean attribute') ->groups(['api', 'database', 'schema']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1579,11 +1587,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolea }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/datetime') - ->alias('/v1/database/collections/:collectionId/attributes/datetime', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/datetime') ->desc('Create datetime attribute') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1597,7 +1606,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/dateti ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('key', '', new Key(), 'Attribute Key.') ->param('required', null, new Boolean(), 'Is attribute required?') - ->param('default', null, new DatetimeValidator(), 'Default value for the attribute in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when attribute is required.', true) + ->param('default', null, fn (Database $dbForProject) => new DatetimeValidator($dbForProject->getAdapter()->getMinDateTime(), $dbForProject->getAdapter()->getMaxDateTime()), 'Default value for the attribute in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when attribute is required.', true, ['dbForProject']) ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForProject') @@ -1623,11 +1632,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/dateti }); App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relationship') - ->alias('/v1/database/collections/:collectionId/attributes/relationship', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/relationship') ->desc('Create relationship attribute') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.namespace', 'databases') @@ -1751,10 +1761,11 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relati }); App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') - ->alias('/v1/database/collections/:collectionId/attributes', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes') ->desc('List attributes') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listAttributes') @@ -1781,16 +1792,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') throw new Exception(Exception::COLLECTION_NOT_FOUND); } - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $queries = Query::parseQueries($queries); \array_push( $queries, + Query::equal('databaseInternalId', [$database->getInternalId()]), Query::equal('collectionInternalId', [$collection->getInternalId()]), - Query::equal('databaseInternalId', [$database->getInternalId()]) ); /** @@ -1799,6 +1806,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') $cursor = \array_filter($queries, function ($query) { return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]); }); + $cursor = \reset($cursor); if ($cursor) { @@ -1809,8 +1817,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') $attributeId = $cursor->getValue(); $cursorDocument = Authorization::skip(fn () => $dbForProject->find('attributes', [ - Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('databaseInternalId', [$database->getInternalId()]), + Query::equal('collectionInternalId', [$collection->getInternalId()]), Query::equal('key', [$attributeId]), Query::limit(1), ])); @@ -1834,10 +1842,11 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes') }); App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') - ->alias('/v1/database/collections/:collectionId/attributes/:key', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/:key') ->desc('Get attribute') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getAttribute') @@ -1912,6 +1921,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/strin ->desc('Update string attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -1926,7 +1936,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/strin ->param('key', '', new Key(), 'Attribute Key.') ->param('required', null, new Boolean(), 'Is attribute required?') ->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.') - ->param('size', null, new Integer(), 'Maximum size of the string attribute.', true) + ->param('size', null, new Range(1, APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH, Range::TYPE_INTEGER), 'Maximum size of the string attribute.', true) ->param('newKey', null, new Key(), 'New attribute key.', true) ->inject('response') ->inject('dbForProject') @@ -1955,6 +1965,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/email ->desc('Update email attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -1996,6 +2007,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/enum/ ->desc('Update enum attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2039,6 +2051,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/ip/:k ->desc('Update IP address attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2080,6 +2093,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/url/: ->desc('Update URL attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2121,6 +2135,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/integ ->desc('Update integer attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2172,6 +2187,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/float ->desc('Update float attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2223,6 +2239,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/boole ->desc('Update boolean attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2263,6 +2280,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/datet ->desc('Update dateTime attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2276,7 +2294,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/datet ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('key', '', new Key(), 'Attribute Key.') ->param('required', null, new Boolean(), 'Is attribute required?') - ->param('default', null, new Nullable(new DatetimeValidator()), 'Default value for attribute when not provided. Cannot be set when attribute is required.') + ->param('default', null, fn (Database $dbForProject) => new Nullable(new DatetimeValidator($dbForProject->getAdapter()->getMinDateTime(), $dbForProject->getAdapter()->getMaxDateTime())), 'Default value for attribute when not provided. Cannot be set when attribute is required.', injections: ['dbForProject']) ->param('newKey', null, new Key(), 'New attribute key.', true) ->inject('response') ->inject('dbForProject') @@ -2303,6 +2321,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/ ->desc('Update relationship attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2356,10 +2375,11 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/ }); App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key') - ->alias('/v1/database/collections/:collectionId/attributes/:key', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/attributes/:key') ->desc('Delete attribute') ->groups(['api', 'database', 'schema']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update') ->label('audits.event', 'attribute.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2469,11 +2489,12 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key }); App::post('/v1/databases/:databaseId/collections/:collectionId/indexes') - ->alias('/v1/database/collections/:collectionId/indexes', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/indexes') ->desc('Create index') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].indexes.[indexId].create') ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'index.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -2639,10 +2660,11 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes') }); App::get('/v1/databases/:databaseId/collections/:collectionId/indexes') - ->alias('/v1/database/collections/:collectionId/indexes', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/indexes') ->desc('List indexes') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listIndexes') @@ -2669,13 +2691,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes') throw new Exception(Exception::COLLECTION_NOT_FOUND); } - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $queries = Query::parseQueries($queries); - \array_push($queries, Query::equal('collectionId', [$collectionId]), Query::equal('databaseId', [$databaseId])); + \array_push( + $queries, + Query::equal('databaseId', [$databaseId]), + Query::equal('collectionId', [$collectionId]), + ); /** * Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries @@ -2718,6 +2740,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->desc('Get index') ->groups(['api', 'database']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getIndex') @@ -2757,6 +2780,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key') ->desc('Delete index') ->groups(['api', 'database']) ->label('scope', 'collections.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].indexes.[indexId].update') ->label('audits.event', 'index.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') @@ -2822,6 +2846,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].create') ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'document.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}') @@ -3002,10 +3027,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents') try { $document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document); - } catch (StructureException $exception) { - throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); - } catch (DuplicateException $exception) { + } catch (StructureException $e) { + throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage()); + } catch (DuplicateException $e) { throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); + } catch (NotFoundException $e) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); } // Add $collectionId and $databaseId for all documents @@ -3073,6 +3100,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') ->desc('List documents') ->groups(['api', 'database']) ->label('scope', 'documents.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listDocuments') @@ -3135,14 +3163,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') $cursor->setValue($cursorDocument); } - try { - $documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries); - $total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT); - } catch (AuthorizationException) { - throw new Exception(Exception::USER_UNAUTHORIZED); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries); + $total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT); // Add $collectionId and $databaseId for all documents $processDocument = (function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database): bool { @@ -3234,6 +3256,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen ->desc('Get document') ->groups(['api', 'database']) ->label('scope', 'documents.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getDocument') @@ -3326,6 +3349,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen ->desc('List document logs') ->groups(['api', 'database']) ->label('scope', 'documents.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'listDocumentLogs') @@ -3426,11 +3450,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen }); App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:documentId') - ->alias('/v1/database/collections/:collectionId/documents/:documentId', ['databaseId' => 'default']) + ->alias('/v1/database/collections/:collectionId/documents/:documentId') ->desc('Update document') ->groups(['api', 'database']) ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].update') ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('audits.event', 'document.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}/document/{response.$id}') ->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}') @@ -3603,8 +3628,10 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum throw new Exception(Exception::USER_UNAUTHORIZED); } catch (DuplicateException) { throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS); - } catch (StructureException $exception) { - throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage()); + } catch (StructureException $e) { + throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage()); + } catch (NotFoundException $e) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); } // Add $collectionId and $databaseId for all documents @@ -3666,6 +3693,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu ->desc('Delete document') ->groups(['api', 'database']) ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].delete') ->label('audits.event', 'document.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}/document/{request.documentId}') @@ -3712,12 +3740,16 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu throw new Exception(Exception::DOCUMENT_NOT_FOUND); } - $dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) { - $dbForProject->deleteDocument( - 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), - $documentId - ); - }); + try { + $dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) { + $dbForProject->deleteDocument( + 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), + $documentId + ); + }); + } catch (NotFoundException $e) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); + } // Add $collectionId and $databaseId for all documents $processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) { @@ -3780,6 +3812,7 @@ App::get('/v1/databases/usage') ->desc('Get databases usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getUsage') @@ -3861,6 +3894,7 @@ App::get('/v1/databases/:databaseId/usage') ->desc('Get database usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getDatabaseUsage') @@ -3948,6 +3982,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage') ->desc('Get collection usage stats') ->groups(['api', 'database', 'usage']) ->label('scope', 'collections.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'databases') ->label('sdk.method', 'getCollectionUsage') diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 6823f0c802..287c5fa80b 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -138,6 +138,7 @@ App::post('/v1/functions') ->desc('Create function') ->label('scope', 'functions.write') ->label('event', 'functions.[functionId].create') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('audits.event', 'function.create') ->label('audits.resource', 'function/{response.$id}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -325,9 +326,9 @@ App::post('/v1/functions') $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', ''); if (!empty($functionsDomain)) { - $ruleId = ID::unique(); $routeSubdomain = ID::unique(); $domain = "{$routeSubdomain}.{$functionsDomain}"; + $ruleId = md5($domain); $rule = Authorization::skip( fn () => $dbForConsole->createDocument('rules', new Document([ @@ -400,6 +401,7 @@ App::get('/v1/functions') ->groups(['api', 'functions']) ->desc('List functions') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'list') @@ -460,6 +462,7 @@ App::get('/v1/functions/runtimes') ->groups(['api', 'functions']) ->desc('List runtimes') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listRuntimes') @@ -493,6 +496,7 @@ App::get('/v1/functions/specifications') ->groups(['api', 'functions']) ->desc('List available function runtime specifications') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listSpecifications') @@ -529,6 +533,7 @@ App::get('/v1/functions/:functionId') ->groups(['api', 'functions']) ->desc('Get function') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'get') @@ -553,6 +558,7 @@ App::get('/v1/functions/:functionId/usage') ->desc('Get function usage') ->groups(['api', 'functions', 'usage']) ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getFunctionUsage') @@ -657,6 +663,7 @@ App::get('/v1/functions/usage') ->desc('Get functions usage') ->groups(['api', 'functions']) ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getUsage') @@ -756,6 +763,7 @@ App::put('/v1/functions/:functionId') ->groups(['api', 'functions']) ->desc('Update function') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].update') ->label('audits.event', 'function.update') ->label('audits.resource', 'function/{response.$id}') @@ -958,6 +966,7 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId/download') ->groups(['api', 'functions']) ->desc('Download deployment') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getDeploymentDownload') @@ -994,7 +1003,7 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId/download') $response ->setContentType('application/gzip') - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->addHeader('X-Peak', \memory_get_peak_usage()) ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); @@ -1043,6 +1052,7 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId') ->groups(['api', 'functions']) ->desc('Update deployment') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].deployments.[deploymentId].update') ->label('audits.event', 'deployment.update') ->label('audits.resource', 'function/{request.functionId}') @@ -1105,6 +1115,7 @@ App::delete('/v1/functions/:functionId') ->groups(['api', 'functions']) ->desc('Delete function') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].delete') ->label('audits.event', 'function.delete') ->label('audits.resource', 'function/{request.functionId}') @@ -1152,6 +1163,7 @@ App::post('/v1/functions/:functionId/deployments') ->groups(['api', 'functions']) ->desc('Create deployment') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].deployments.[deploymentId].create') ->label('audits.event', 'deployment.create') ->label('audits.resource', 'function/{request.functionId}') @@ -1371,6 +1383,7 @@ App::get('/v1/functions/:functionId/deployments') ->groups(['api', 'functions']) ->desc('List deployments') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listDeployments') @@ -1454,6 +1467,7 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId') ->groups(['api', 'functions']) ->desc('Get deployment') ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getDeployment') @@ -1497,6 +1511,7 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId') ->groups(['api', 'functions']) ->desc('Delete deployment') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].deployments.[deploymentId].delete') ->label('audits.event', 'deployment.delete') ->label('audits.resource', 'function/{request.functionId}') @@ -1562,6 +1577,7 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build') ->groups(['api', 'functions']) ->desc('Rebuild deployment') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].deployments.[deploymentId].update') ->label('audits.event', 'deployment.update') ->label('audits.resource', 'function/{request.functionId}') @@ -1630,6 +1646,7 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId/build') ->groups(['api', 'functions']) ->desc('Cancel deployment') ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('audits.event', 'deployment.update') ->label('audits.resource', 'function/{request.functionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -1719,7 +1736,9 @@ App::post('/v1/functions/:functionId/executions') ->groups(['api', 'functions']) ->desc('Create execution') ->label('scope', 'execution.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].executions.[executionId].create') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'createExecution') @@ -1734,7 +1753,7 @@ App::post('/v1/functions/:functionId/executions') ->param('path', '/', new Text(2048), 'HTTP path of execution. Path can include query params. Default value is /', true) ->param('method', 'POST', new Whitelist(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], true), 'HTTP method of execution. Default value is GET.', true) ->param('headers', [], new AnyOf([new Assoc(), new Text(65535)], AnyOf::TYPE_MIXED), 'HTTP headers of execution. Defaults to empty.', true) - ->param('scheduledAt', null, new DatetimeValidator(true, DateTimeValidator::PRECISION_MINUTES, 60), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.', true) + ->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true, precision: DateTimeValidator::PRECISION_MINUTES, offset: 60), 'Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes.', true) ->inject('response') ->inject('request') ->inject('project') @@ -2121,6 +2140,7 @@ App::get('/v1/functions/:functionId/executions') ->groups(['api', 'functions']) ->desc('List executions') ->label('scope', 'execution.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listExecutions') @@ -2208,6 +2228,7 @@ App::get('/v1/functions/:functionId/executions/:executionId') ->groups(['api', 'functions']) ->desc('Get execution') ->label('scope', 'execution.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getExecution') @@ -2255,6 +2276,7 @@ App::delete('/v1/functions/:functionId/executions/:executionId') ->groups(['api', 'functions']) ->desc('Delete execution') ->label('scope', 'execution.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('event', 'functions.[functionId].executions.[executionId].delete') ->label('audits.event', 'executions.delete') ->label('audits.resource', 'function/{request.functionId}') @@ -2302,7 +2324,7 @@ App::delete('/v1/functions/:functionId/executions/:executionId') Query::equal('active', [true]), ]); - if ($schedule && !$schedule->isEmpty()) { + if (!$schedule->isEmpty()) { $schedule ->setAttribute('resourceUpdatedAt', DateTime::now()) ->setAttribute('active', false); @@ -2325,6 +2347,7 @@ App::post('/v1/functions/:functionId/variables') ->desc('Create variable') ->groups(['api', 'functions']) ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('audits.event', 'variable.create') ->label('audits.resource', 'function/{request.functionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -2391,6 +2414,7 @@ App::get('/v1/functions/:functionId/variables') ->desc('List variables') ->groups(['api', 'functions']) ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listVariables') @@ -2418,6 +2442,7 @@ App::get('/v1/functions/:functionId/variables/:variableId') ->desc('Get variable') ->groups(['api', 'functions']) ->label('scope', 'functions.read') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getVariable') @@ -2457,6 +2482,7 @@ App::put('/v1/functions/:functionId/variables/:variableId') ->desc('Update variable') ->groups(['api', 'functions']) ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('audits.event', 'variable.update') ->label('audits.resource', 'function/{request.functionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -2518,6 +2544,7 @@ App::delete('/v1/functions/:functionId/variables/:variableId') ->desc('Delete variable') ->groups(['api', 'functions']) ->label('scope', 'functions.write') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('audits.event', 'variable.delete') ->label('audits.resource', 'function/{request.functionId}') ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) @@ -2566,6 +2593,7 @@ App::get('/v1/functions/templates') ->groups(['api']) ->desc('List function templates') ->label('scope', 'public') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'listTemplates') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) @@ -2603,6 +2631,7 @@ App::get('/v1/functions/templates') App::get('/v1/functions/templates/:templateId') ->desc('Get function template') ->label('scope', 'public') + ->label('resourceType', RESOURCE_TYPE_FUNCTIONS) ->label('sdk.namespace', 'functions') ->label('sdk.method', 'getTemplate') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) @@ -2615,9 +2644,11 @@ App::get('/v1/functions/templates/:templateId') ->action(function (string $templateId, Response $response) { $templates = Config::getParam('function-templates', []); - $template = array_shift(\array_filter($templates, function ($template) use ($templateId) { + $filtered = \array_filter($templates, function ($template) use ($templateId) { return $template['id'] === $templateId; - })); + }); + + $template = array_shift($filtered); if (empty($template)) { throw new Exception(Exception::FUNCTION_TEMPLATE_NOT_FOUND); diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index f4581df8e4..60a8c0ca97 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -135,6 +135,7 @@ App::get('/v1/health/cache') foreach ($configs as $key => $config) { foreach ($config as $database) { try { + /** @var \Utopia\Cache\Adapter $adapter */ $adapter = $pools->get($database)->pop()->getResource(); $checkStart = \microtime(true); @@ -191,11 +192,11 @@ App::get('/v1/health/queue') foreach ($configs as $key => $config) { foreach ($config as $database) { + $checkStart = \microtime(true); try { + /** @var Connection $adapter */ $adapter = $pools->get($database)->pop()->getResource(); - $checkStart = \microtime(true); - if ($adapter->ping()) { $output[] = new Document([ 'name' => $key . " ($database)", @@ -249,6 +250,7 @@ App::get('/v1/health/pubsub') foreach ($configs as $key => $config) { foreach ($config as $database) { try { + /** @var \Appwrite\PubSub\Adapter $adapter */ $adapter = $pools->get($database)->pop()->getResource(); $checkStart = \microtime(true); diff --git a/app/controllers/api/locale.php b/app/controllers/api/locale.php index 2917bc8416..1f042d2239 100644 --- a/app/controllers/api/locale.php +++ b/app/controllers/api/locale.php @@ -63,7 +63,7 @@ App::get('/v1/locale') $response ->addHeader('Cache-Control', 'public, max-age=' . $time) - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $time) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ; $response->dynamic(new Document($output), Response::MODEL_LOCALE); }); diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index c68ba91297..e4a627d027 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -56,6 +56,7 @@ App::post('/v1/messaging/providers/mailgun') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createMailgunProvider') @@ -143,6 +144,7 @@ App::post('/v1/messaging/providers/sendgrid') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createSendgridProvider') @@ -218,6 +220,7 @@ App::post('/v1/messaging/providers/smtp') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createSmtpProvider') @@ -305,6 +308,7 @@ App::post('/v1/messaging/providers/msg91') ->label('audits.event', 'provider.create') ->label('audits.resource', 'provider/{response.$id}') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('event', 'providers.[providerId].create') ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') @@ -382,6 +386,7 @@ App::post('/v1/messaging/providers/telesign') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createTelesignProvider') @@ -459,6 +464,7 @@ App::post('/v1/messaging/providers/textmagic') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createTextmagicProvider') @@ -536,6 +542,7 @@ App::post('/v1/messaging/providers/twilio') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createTwilioProvider') @@ -613,6 +620,7 @@ App::post('/v1/messaging/providers/vonage') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createVonageProvider') @@ -690,6 +698,7 @@ App::post('/v1/messaging/providers/fcm') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createFcmProvider') @@ -753,6 +762,7 @@ App::post('/v1/messaging/providers/apns') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].create') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createApnsProvider') @@ -836,6 +846,7 @@ App::get('/v1/messaging/providers') ->desc('List providers') ->groups(['api', 'messaging']) ->label('scope', 'providers.read') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listProviders') @@ -892,6 +903,7 @@ App::get('/v1/messaging/providers/:providerId/logs') ->desc('List provider logs') ->groups(['api', 'messaging']) ->label('scope', 'providers.read') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listProviderLogs') @@ -980,6 +992,7 @@ App::get('/v1/messaging/providers/:providerId') ->desc('Get provider') ->groups(['api', 'messaging']) ->label('scope', 'providers.read') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'getProvider') @@ -1007,6 +1020,7 @@ App::patch('/v1/messaging/providers/mailgun/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateMailgunProvider') @@ -1113,6 +1127,7 @@ App::patch('/v1/messaging/providers/sendgrid/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateSendgridProvider') @@ -1204,6 +1219,7 @@ App::patch('/v1/messaging/providers/smtp/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateSmtpProvider') @@ -1326,6 +1342,7 @@ App::patch('/v1/messaging/providers/msg91/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateMsg91Provider') @@ -1406,6 +1423,7 @@ App::patch('/v1/messaging/providers/telesign/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateTelesignProvider') @@ -1488,6 +1506,7 @@ App::patch('/v1/messaging/providers/textmagic/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateTextmagicProvider') @@ -1570,6 +1589,7 @@ App::patch('/v1/messaging/providers/twilio/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateTwilioProvider') @@ -1652,6 +1672,7 @@ App::patch('/v1/messaging/providers/vonage/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateVonageProvider') @@ -1734,6 +1755,7 @@ App::patch('/v1/messaging/providers/fcm/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateFcmProvider') @@ -1803,6 +1825,7 @@ App::patch('/v1/messaging/providers/apns/:providerId') ->label('audits.resource', 'provider/{response.$id}') ->label('event', 'providers.[providerId].update') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateApnsProvider') @@ -1898,6 +1921,7 @@ App::delete('/v1/messaging/providers/:providerId') ->label('audits.resource', 'provider/{request.$providerId}') ->label('event', 'providers.[providerId].delete') ->label('scope', 'providers.write') + ->label('resourceType', RESOURCE_TYPE_PROVIDERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'deleteProvider') @@ -1933,6 +1957,7 @@ App::post('/v1/messaging/topics') ->label('audits.resource', 'topic/{response.$id}') ->label('event', 'topics.[topicId].create') ->label('scope', 'topics.write') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createTopic') @@ -1973,6 +1998,7 @@ App::get('/v1/messaging/topics') ->desc('List topics') ->groups(['api', 'messaging']) ->label('scope', 'topics.read') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listTopics') @@ -2029,6 +2055,7 @@ App::get('/v1/messaging/topics/:topicId/logs') ->desc('List topic logs') ->groups(['api', 'messaging']) ->label('scope', 'topics.read') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listTopicLogs') @@ -2118,6 +2145,7 @@ App::get('/v1/messaging/topics/:topicId') ->desc('Get topic') ->groups(['api', 'messaging']) ->label('scope', 'topics.read') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'getTopic') @@ -2146,6 +2174,7 @@ App::patch('/v1/messaging/topics/:topicId') ->label('audits.resource', 'topic/{response.$id}') ->label('event', 'topics.[topicId].update') ->label('scope', 'topics.write') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateTopic') @@ -2190,6 +2219,7 @@ App::delete('/v1/messaging/topics/:topicId') ->label('audits.resource', 'topic/{request.$topicId}') ->label('event', 'topics.[topicId].delete') ->label('scope', 'topics.write') + ->label('resourceType', RESOURCE_TYPE_TOPICS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'deleteTopic') @@ -2230,6 +2260,7 @@ App::post('/v1/messaging/topics/:topicId/subscribers') ->label('audits.resource', 'subscriber/{response.$id}') ->label('event', 'topics.[topicId].subscribers.[subscriberId].create') ->label('scope', 'subscribers.write') + ->label('resourceType', RESOURCE_TYPE_SUBSCRIBERS) ->label('sdk.auth', [APP_AUTH_TYPE_JWT, APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createSubscriber') @@ -2323,6 +2354,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers') ->desc('List subscribers') ->groups(['api', 'messaging']) ->label('scope', 'subscribers.read') + ->label('resourceType', RESOURCE_TYPE_SUBSCRIBERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listSubscribers') @@ -2402,6 +2434,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs') ->desc('List subscriber logs') ->groups(['api', 'messaging']) ->label('scope', 'subscribers.read') + ->label('resourceType', RESOURCE_TYPE_SUBSCRIBERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listSubscriberLogs') @@ -2491,6 +2524,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->desc('Get subscriber') ->groups(['api', 'messaging']) ->label('scope', 'subscribers.read') + ->label('resourceType', RESOURCE_TYPE_SUBSCRIBERS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'getSubscriber') @@ -2533,6 +2567,7 @@ App::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId') ->label('audits.resource', 'subscriber/{request.$subscriberId}') ->label('event', 'topics.[topicId].subscribers.[subscriberId].delete') ->label('scope', 'subscribers.write') + ->label('resourceType', RESOURCE_TYPE_SUBSCRIBERS) ->label('sdk.auth', [APP_AUTH_TYPE_JWT, APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'deleteSubscriber') @@ -2592,6 +2627,7 @@ App::post('/v1/messaging/messages/email') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].create') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createEmail') @@ -2744,6 +2780,7 @@ App::post('/v1/messaging/messages/sms') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].create') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createSms') @@ -2860,6 +2897,7 @@ App::post('/v1/messaging/messages/push') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].create') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'createPush') @@ -3033,6 +3071,7 @@ App::get('/v1/messaging/messages') ->desc('List messages') ->groups(['api', 'messaging']) ->label('scope', 'messages.read') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listMessages') @@ -3089,6 +3128,7 @@ App::get('/v1/messaging/messages/:messageId/logs') ->desc('List message logs') ->groups(['api', 'messaging']) ->label('scope', 'messages.read') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listMessageLogs') @@ -3178,6 +3218,7 @@ App::get('/v1/messaging/messages/:messageId/targets') ->desc('List message targets') ->groups(['api', 'messaging']) ->label('scope', 'messages.read') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'listTargets') @@ -3248,6 +3289,7 @@ App::get('/v1/messaging/messages/:messageId') ->desc('Get message') ->groups(['api', 'messaging']) ->label('scope', 'messages.read') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'getMessage') @@ -3275,6 +3317,7 @@ App::patch('/v1/messaging/messages/email/:messageId') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].update') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateEmail') @@ -3475,6 +3518,7 @@ App::patch('/v1/messaging/messages/sms/:messageId') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].update') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updateSms') @@ -3630,6 +3674,7 @@ App::patch('/v1/messaging/messages/push/:messageId') ->label('audits.resource', 'message/{response.$id}') ->label('event', 'messages.[messageId].update') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'updatePush') @@ -3868,6 +3913,7 @@ App::delete('/v1/messaging/messages/:messageId') ->label('audits.resource', 'message/{request.messageId}') ->label('event', 'messages.[messageId].delete') ->label('scope', 'messages.write') + ->label('resourceType', RESOURCE_TYPE_MESSAGES) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'messaging') ->label('sdk.method', 'delete') diff --git a/app/controllers/api/migrations.php b/app/controllers/api/migrations.php index a4880cef86..bebb6ebaea 100644 --- a/app/controllers/api/migrations.php +++ b/app/controllers/api/migrations.php @@ -121,7 +121,7 @@ App::post('/v1/migrations/firebase/oauth') Query::equal('provider', ['firebase']), Query::equal('userInternalId', [$user->getInternalId()]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { throw new Exception(Exception::USER_IDENTITY_NOT_FOUND); } @@ -576,7 +576,7 @@ App::get('/v1/migrations/firebase/report/oauth') Query::equal('userInternalId', [$user->getInternalId()]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { throw new Exception(Exception::USER_IDENTITY_NOT_FOUND); } @@ -751,13 +751,13 @@ App::get('/v1/migrations/firebase/redirect') Query::equal('providerEmail', [$email]), ]); - if ($identity !== false && !$identity->isEmpty()) { + if (!$identity->isEmpty()) { if ($identity->getAttribute('userInternalId', '') !== $user->getInternalId()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } } - if ($identity !== false && !$identity->isEmpty()) { + if (!$identity->isEmpty()) { $identity = $identity ->setAttribute('providerAccessToken', $accessToken) ->setAttribute('providerRefreshToken', $refreshToken) @@ -820,7 +820,7 @@ App::get('/v1/migrations/firebase/projects') Query::equal('userInternalId', [$user->getInternalId()]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { throw new Exception(Exception::USER_IDENTITY_NOT_FOUND); } @@ -900,7 +900,7 @@ App::get('/v1/migrations/firebase/deauthorize') Query::equal('userInternalId', [$user->getInternalId()]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN, 'Not authenticated with Firebase'); //TODO: Replace with USER_IDENTITY_NOT_FOUND } diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 3bfa416bd8..df8b1cb07b 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -111,6 +111,9 @@ App::post('/v1/projects') 'personalDataCheck' => false, 'mockNumbers' => [], 'sessionAlerts' => false, + 'membershipsUserName' => false, + 'membershipsUserEmail' => false, + 'membershipsMfa' => false, ]; foreach ($auth as $method) { @@ -648,6 +651,41 @@ App::patch('/v1/projects/:projectId/auth/session-alerts') $response->dynamic($project, Response::MODEL_PROJECT); }); +App::patch('/v1/projects/:projectId/auth/memberships-privacy') + ->desc('Update project memberships privacy attributes') + ->groups(['api', 'projects']) + ->label('scope', 'projects.write') + ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) + ->label('sdk.namespace', 'projects') + ->label('sdk.method', 'updateMembershipsPrivacy') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_PROJECT) + ->param('projectId', '', new UID(), 'Project unique ID.') + ->param('userName', true, new Boolean(true), 'Set to true to show userName to members of a team.') + ->param('userEmail', true, new Boolean(true), 'Set to true to show email to members of a team.') + ->param('mfa', true, new Boolean(true), 'Set to true to show mfa to members of a team.') + ->inject('response') + ->inject('dbForConsole') + ->action(function (string $projectId, bool $userName, bool $userEmail, bool $mfa, Response $response, Database $dbForConsole) { + $project = $dbForConsole->getDocument('projects', $projectId); + + if ($project->isEmpty()) { + throw new Exception(Exception::PROJECT_NOT_FOUND); + } + + $auths = $project->getAttribute('auths', []); + + $auths['membershipsUserName'] = $userName; + $auths['membershipsUserEmail'] = $userEmail; + $auths['membershipsMfa'] = $mfa; + + $dbForConsole->updateDocument('projects', $project->getId(), $project + ->setAttribute('auths', $auths)); + + $response->dynamic($project, Response::MODEL_PROJECT); + }); + App::patch('/v1/projects/:projectId/auth/limit') ->desc('Update project users limit') ->groups(['api', 'projects']) @@ -1060,7 +1098,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($webhook === false || $webhook->isEmpty()) { + if ($webhook->isEmpty()) { throw new Exception(Exception::WEBHOOK_NOT_FOUND); } @@ -1103,7 +1141,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($webhook === false || $webhook->isEmpty()) { + if ($webhook->isEmpty()) { throw new Exception(Exception::WEBHOOK_NOT_FOUND); } @@ -1153,7 +1191,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($webhook === false || $webhook->isEmpty()) { + if ($webhook->isEmpty()) { throw new Exception(Exception::WEBHOOK_NOT_FOUND); } @@ -1191,7 +1229,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($webhook === false || $webhook->isEmpty()) { + if ($webhook->isEmpty()) { throw new Exception(Exception::WEBHOOK_NOT_FOUND); } @@ -1313,7 +1351,7 @@ App::get('/v1/projects/:projectId/keys/:keyId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($key === false || $key->isEmpty()) { + if ($key->isEmpty()) { throw new Exception(Exception::KEY_NOT_FOUND); } @@ -1350,7 +1388,7 @@ App::put('/v1/projects/:projectId/keys/:keyId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($key === false || $key->isEmpty()) { + if ($key->isEmpty()) { throw new Exception(Exception::KEY_NOT_FOUND); } @@ -1392,7 +1430,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($key === false || $key->isEmpty()) { + if ($key->isEmpty()) { throw new Exception(Exception::KEY_NOT_FOUND); } @@ -1550,7 +1588,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($platform === false || $platform->isEmpty()) { + if ($platform->isEmpty()) { throw new Exception(Exception::PLATFORM_NOT_FOUND); } @@ -1587,7 +1625,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($platform === false || $platform->isEmpty()) { + if ($platform->isEmpty()) { throw new Exception(Exception::PLATFORM_NOT_FOUND); } @@ -1631,7 +1669,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId') Query::equal('projectInternalId', [$project->getInternalId()]), ]); - if ($platform === false || $platform->isEmpty()) { + if ($platform->isEmpty()) { throw new Exception(Exception::PLATFORM_NOT_FOUND); } diff --git a/app/controllers/api/proxy.php b/app/controllers/api/proxy.php index 984a9fb974..56fd31e88c 100644 --- a/app/controllers/api/proxy.php +++ b/app/controllers/api/proxy.php @@ -11,7 +11,6 @@ use Utopia\App; use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Query as QueryException; -use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Query\Cursor; use Utopia\Database\Validator\UID; @@ -60,11 +59,10 @@ App::post('/v1/proxy/rules') throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please pick another one.'); } - $document = $dbForConsole->findOne('rules', [ - Query::equal('domain', [$domain]), - ]); + $ruleId = md5($domain); + $document = $dbForConsole->getDocument('rules', $ruleId); - if ($document && !$document->isEmpty()) { + if (!$document->isEmpty()) { if ($document->getAttribute('projectId') === $project->getId()) { $resourceType = $document->getAttribute('resourceType'); $resourceId = $document->getAttribute('resourceId'); @@ -103,7 +101,7 @@ App::post('/v1/proxy/rules') throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.'); } - $ruleId = ID::unique(); + $ruleId = md5($domain->get()); $rule = new Document([ '$id' => $ruleId, 'projectId' => $project->getId(), diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index c3d57e5470..dda39a0db0 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -16,7 +16,8 @@ use Utopia\App; use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Database\Exception\Duplicate; +use Utopia\Database\Exception\Duplicate as DuplicateException; +use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; @@ -49,6 +50,7 @@ App::post('/v1/storage/buckets') ->desc('Create bucket') ->groups(['api', 'storage']) ->label('scope', 'buckets.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('event', 'buckets.[bucketId].create') ->label('audits.event', 'bucket.create') ->label('audits.resource', 'bucket/{response.$id}') @@ -130,7 +132,7 @@ App::post('/v1/storage/buckets') $bucket = $dbForProject->getDocument('buckets', $bucketId); $dbForProject->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes, permissions: $permissions ?? [], documentSecurity: $fileSecurity); - } catch (Duplicate) { + } catch (DuplicateException) { throw new Exception(Exception::STORAGE_BUCKET_ALREADY_EXISTS); } @@ -147,6 +149,7 @@ App::get('/v1/storage/buckets') ->desc('List buckets') ->groups(['api', 'storage']) ->label('scope', 'buckets.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'listBuckets') @@ -207,6 +210,7 @@ App::get('/v1/storage/buckets/:bucketId') ->desc('Get bucket') ->groups(['api', 'storage']) ->label('scope', 'buckets.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_KEY]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getBucket') @@ -232,6 +236,7 @@ App::put('/v1/storage/buckets/:bucketId') ->desc('Update bucket') ->groups(['api', 'storage']) ->label('scope', 'buckets.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('event', 'buckets.[bucketId].update') ->label('audits.event', 'bucket.update') ->label('audits.resource', 'bucket/{response.$id}') @@ -269,10 +274,6 @@ App::put('/v1/storage/buckets/:bucketId') $encryption ??= $bucket->getAttribute('encryption', true); $antivirus ??= $bucket->getAttribute('antivirus', true); - /** - * Map aggregate permissions into the multiple permissions they represent, - * accounting for the resource type given that some types not allowed specific permissions. - */ // Map aggregate permissions into the multiple permissions they represent. $permissions = Permission::aggregate($permissions); @@ -286,11 +287,11 @@ App::put('/v1/storage/buckets/:bucketId') ->setAttribute('encryption', $encryption) ->setAttribute('compression', $compression) ->setAttribute('antivirus', $antivirus)); + $dbForProject->updateCollection('bucket_' . $bucket->getInternalId(), $permissions, $fileSecurity); $queueForEvents - ->setParam('bucketId', $bucket->getId()) - ; + ->setParam('bucketId', $bucket->getId()); $response->dynamic($bucket, Response::MODEL_BUCKET); }); @@ -299,6 +300,7 @@ App::delete('/v1/storage/buckets/:bucketId') ->desc('Delete bucket') ->groups(['api', 'storage']) ->label('scope', 'buckets.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('audits.event', 'bucket.delete') ->label('event', 'buckets.[bucketId].delete') ->label('audits.resource', 'bucket/{request.bucketId}') @@ -337,10 +339,11 @@ App::delete('/v1/storage/buckets/:bucketId') }); App::post('/v1/storage/buckets/:bucketId/files') - ->alias('/v1/storage/files', ['bucketId' => 'default']) + ->alias('/v1/storage/files') ->desc('Create file') ->groups(['api', 'storage']) ->label('scope', 'files.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('audits.event', 'file.create') ->label('event', 'buckets.[bucketId].files.[fileId].create') ->label('audits.resource', 'file/{response.$id}') @@ -664,7 +667,11 @@ App::post('/v1/storage/buckets/:bucketId/files') 'metadata' => $metadata, ]); - $file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc); + try { + $file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc); + } catch (NotFoundException) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); + } } else { $file = $file ->setAttribute('chunksUploaded', $chunksUploaded) @@ -680,15 +687,19 @@ App::post('/v1/storage/buckets/:bucketId/files') if (!$validator->isValid($bucket->getCreate())) { throw new Exception(Exception::USER_UNAUTHORIZED); } - $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + + try { + $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + } catch (NotFoundException) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); + } } } $queueForEvents ->setParam('bucketId', $bucket->getId()) ->setParam('fileId', $file->getId()) - ->setContext('bucket', $bucket) - ; + ->setContext('bucket', $bucket); $metadata = null; // was causing leaks as it was passed by reference @@ -698,10 +709,11 @@ App::post('/v1/storage/buckets/:bucketId/files') }); App::get('/v1/storage/buckets/:bucketId/files') - ->alias('/v1/storage/files', ['bucketId' => 'default']) + ->alias('/v1/storage/files') ->desc('List files') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'listFiles') @@ -732,11 +744,7 @@ App::get('/v1/storage/buckets/:bucketId/files') throw new Exception(Exception::USER_UNAUTHORIZED); } - try { - $queries = Query::parseQueries($queries); - } catch (QueryException $e) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); - } + $queries = Query::parseQueries($queries); if (!empty($search)) { $queries[] = Query::search('search', $search); @@ -774,12 +782,16 @@ App::get('/v1/storage/buckets/:bucketId/files') $filterQueries = Query::groupByType($queries)['filters']; - if ($fileSecurity && !$valid) { - $files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries); - $total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT); - } else { - $files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries)); - $total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT)); + try { + if ($fileSecurity && !$valid) { + $files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries); + $total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT); + } else { + $files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries)); + $total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT)); + } + } catch (NotFoundException) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); } $response->dynamic(new Document([ @@ -789,10 +801,11 @@ App::get('/v1/storage/buckets/:bucketId/files') }); App::get('/v1/storage/buckets/:bucketId/files/:fileId') - ->alias('/v1/storage/files/:fileId', ['bucketId' => 'default']) + ->alias('/v1/storage/files/:fileId') ->desc('Get file') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getFile') @@ -836,10 +849,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId') }); App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') - ->alias('/v1/storage/files/:fileId/preview', ['bucketId' => 'default']) + ->alias('/v1/storage/files/:fileId/preview') ->desc('Get file preview') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('cache', true) ->label('cache.resourceType', 'bucket/{request.bucketId}') ->label('cache.resource', 'file/{request.fileId}') @@ -999,7 +1013,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') $contentType = (\array_key_exists($output, $outputs)) ? $outputs[$output] : $outputs['jpg']; $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + 60 * 60 * 24 * 30) . ' GMT') + ->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days ->setContentType($contentType) ->file($data) ; @@ -1008,10 +1022,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview') }); App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') - ->alias('/v1/storage/files/:fileId/download', ['bucketId' => 'default']) + ->alias('/v1/storage/files/:fileId/download') ->desc('Get file for download') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getFileDownload') @@ -1062,7 +1077,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') $response ->setContentType($file->getAttribute('mimeType')) - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->addHeader('X-Peak', \memory_get_peak_usage()) ->addHeader('Content-Disposition', 'attachment; filename="' . $file->getAttribute('name', '') . '"') ; @@ -1148,10 +1163,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download') }); App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') - ->alias('/v1/storage/files/:fileId/view', ['bucketId' => 'default']) + ->alias('/v1/storage/files/:fileId/view') ->desc('Get file for view') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getFileView') @@ -1212,7 +1228,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view') ->addHeader('Content-Security-Policy', 'script-src none;') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"') - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->addHeader('X-Peak', \memory_get_peak_usage()) ; @@ -1303,6 +1319,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push') ->desc('Get file for push notification') ->groups(['api', 'storage']) ->label('scope', 'public') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.response.code', Response::STATUS_CODE_OK) ->label('sdk.response.type', '*/*') ->label('sdk.methodType', 'location') @@ -1366,7 +1383,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push') ->addHeader('Content-Security-Policy', 'script-src none;') ->addHeader('X-Content-Type-Options', 'nosniff') ->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"') - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache + ->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days ->addHeader('X-Peak', \memory_get_peak_usage()); $size = $file->getAttribute('sizeOriginal', 0); @@ -1453,10 +1470,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push') }); App::put('/v1/storage/buckets/:bucketId/files/:fileId') - ->alias('/v1/storage/files/:fileId', ['bucketId' => 'default']) + ->alias('/v1/storage/files/:fileId') ->desc('Update file') ->groups(['api', 'storage']) ->label('scope', 'files.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('event', 'buckets.[bucketId].files.[fileId].update') ->label('audits.event', 'file.update') ->label('audits.resource', 'file/{response.$id}') @@ -1542,10 +1560,14 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId') $file->setAttribute('name', $name); } - if ($fileSecurity && !$valid) { - $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); - } else { - $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + try { + if ($fileSecurity && !$valid) { + $file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file); + } else { + $file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file)); + } + } catch (NotFoundException) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); } $queueForEvents @@ -1561,6 +1583,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') ->desc('Delete file') ->groups(['api', 'storage']) ->label('scope', 'files.write') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('event', 'buckets.[bucketId].files.[fileId].delete') ->label('audits.event', 'file.delete') ->label('audits.resource', 'file/{request.fileId}') @@ -1627,10 +1650,14 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId') ->setResource('file/' . $fileId) ; - if ($fileSecurity && !$valid) { - $deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId); - } else { - $deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); + try { + if ($fileSecurity && !$valid) { + $deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId); + } else { + $deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId)); + } + } catch (NotFoundException) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); } if (!$deleted) { @@ -1654,6 +1681,7 @@ App::get('/v1/storage/usage') ->desc('Get storage usage stats') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getUsage') @@ -1733,6 +1761,7 @@ App::get('/v1/storage/:bucketId/usage') ->desc('Get bucket usage stats') ->groups(['api', 'storage']) ->label('scope', 'files.read') + ->label('resourceType', RESOURCE_TYPE_BUCKETS) ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN]) ->label('sdk.namespace', 'storage') ->label('sdk.method', 'getBucketUsage') diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index f9abaeeb44..be055f0935 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -467,17 +467,17 @@ App::post('/v1/teams/:teamId/memberships') $name = empty($name) ? $invitee->getAttribute('name', '') : $name; } elseif (!empty($email)) { $invitee = $dbForProject->findOne('users', [Query::equal('email', [$email])]); // Get user by email address - if (!empty($invitee) && !empty($phone) && $invitee->getAttribute('phone', '') !== $phone) { + if (!$invitee->isEmpty() && !empty($phone) && $invitee->getAttribute('phone', '') !== $phone) { throw new Exception(Exception::USER_ALREADY_EXISTS, 'Given email and phone doesn\'t match', 409); } } elseif (!empty($phone)) { $invitee = $dbForProject->findOne('users', [Query::equal('phone', [$phone])]); - if (!empty($invitee) && !empty($email) && $invitee->getAttribute('email', '') !== $email) { + if (!$invitee->isEmpty() && !empty($email) && $invitee->getAttribute('email', '') !== $email) { throw new Exception(Exception::USER_ALREADY_EXISTS, 'Given phone and email doesn\'t match', 409); } } - if (empty($invitee)) { // Create new user if no user with same email found + if ($invitee->isEmpty()) { // Create new user if no user with same email found $limit = $project->getAttribute('auths', [])['limit'] ?? 0; if (!$isPrivilegedUser && !$isAppUser && $limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed. @@ -492,7 +492,7 @@ App::post('/v1/teams/:teamId/memberships') $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } @@ -727,9 +727,9 @@ App::get('/v1/teams/:teamId/memberships') ->param('queries', [], new Memberships(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Memberships::ALLOWED_ATTRIBUTES), true) ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('response') + ->inject('project') ->inject('dbForProject') - ->action(function (string $teamId, array $queries, string $search, Response $response, Database $dbForProject) { - + ->action(function (string $teamId, array $queries, string $search, Response $response, Document $project, Database $dbForProject) { $team = $dbForProject->getDocument('teams', $teamId); if ($team->isEmpty()) { @@ -790,27 +790,48 @@ App::get('/v1/teams/:teamId/memberships') $memberships = array_filter($memberships, fn (Document $membership) => !empty($membership->getAttribute('userId'))); - $memberships = array_map(function ($membership) use ($dbForProject, $team) { - $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); + $membershipsPrivacy = [ + 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true, + 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true, + 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true, + ]; - $mfa = $user->getAttribute('mfa', false); - if ($mfa) { - $totp = TOTP::getAuthenticatorFromUser($user); - $totpEnabled = $totp && $totp->getAttribute('verified', false); - $emailEnabled = $user->getAttribute('email', false) && $user->getAttribute('emailVerification', false); - $phoneEnabled = $user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false); + $roles = Authorization::getRoles(); + $isPrivilegedUser = Auth::isPrivilegedUser($roles); + $isAppUser = Auth::isAppUser($roles); - if (!$totpEnabled && !$emailEnabled && !$phoneEnabled) { - $mfa = false; + $membershipsPrivacy = array_map(function ($privacy) use ($isPrivilegedUser, $isAppUser) { + return $privacy || $isPrivilegedUser || $isAppUser; + }, $membershipsPrivacy); + + $memberships = array_map(function ($membership) use ($dbForProject, $team, $membershipsPrivacy) { + if ($membershipsPrivacy['mfa']) { + $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); + $mfa = $user->getAttribute('mfa', false); + + if ($mfa) { + $totp = TOTP::getAuthenticatorFromUser($user); + $totpEnabled = $totp && $totp->getAttribute('verified', false); + $emailEnabled = $user->getAttribute('email', false) && $user->getAttribute('emailVerification', false); + $phoneEnabled = $user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false); + + if (!$totpEnabled && !$emailEnabled && !$phoneEnabled) { + $mfa = false; + } } + + $membership->setAttribute('mfa', $mfa); } - $membership - ->setAttribute('mfa', $mfa) - ->setAttribute('teamName', $team->getAttribute('name')) - ->setAttribute('userName', $user->getAttribute('name')) - ->setAttribute('userEmail', $user->getAttribute('email')) - ; + if ($membershipsPrivacy['userName']) { + $membership->setAttribute('userName', $user->getAttribute('name')); + } + + if ($membershipsPrivacy['userEmail']) { + $membership->setAttribute('userEmail', $user->getAttribute('email')); + } + + $membership->setAttribute('teamName', $team->getAttribute('name')); return $membership; }, $memberships); @@ -837,8 +858,9 @@ App::get('/v1/teams/:teamId/memberships/:membershipId') ->param('teamId', '', new UID(), 'Team ID.') ->param('membershipId', '', new UID(), 'Membership ID.') ->inject('response') + ->inject('project') ->inject('dbForProject') - ->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject) { + ->action(function (string $teamId, string $membershipId, Response $response, Document $project, Database $dbForProject) { $team = $dbForProject->getDocument('teams', $teamId); @@ -852,27 +874,48 @@ App::get('/v1/teams/:teamId/memberships/:membershipId') throw new Exception(Exception::MEMBERSHIP_NOT_FOUND); } - $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); + $membershipsPrivacy = [ + 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true, + 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true, + 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true, + ]; - $mfa = $user->getAttribute('mfa', false); + $roles = Authorization::getRoles(); + $isPrivilegedUser = Auth::isPrivilegedUser($roles); + $isAppUser = Auth::isAppUser($roles); - if ($mfa) { - $totp = TOTP::getAuthenticatorFromUser($user); - $totpEnabled = $totp && $totp->getAttribute('verified', false); - $emailEnabled = $user->getAttribute('email', false) && $user->getAttribute('emailVerification', false); - $phoneEnabled = $user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false); + $membershipsPrivacy = array_map(function ($privacy) use ($isPrivilegedUser, $isAppUser) { + return $privacy || $isPrivilegedUser || $isAppUser; + }, $membershipsPrivacy); - if (!$totpEnabled && !$emailEnabled && !$phoneEnabled) { - $mfa = false; + if ($membershipsPrivacy['mfa']) { + $user = $dbForProject->getDocument('users', $membership->getAttribute('userId')); + + $mfa = $user->getAttribute('mfa', false); + + if ($mfa) { + $totp = TOTP::getAuthenticatorFromUser($user); + $totpEnabled = $totp && $totp->getAttribute('verified', false); + $emailEnabled = $user->getAttribute('email', false) && $user->getAttribute('emailVerification', false); + $phoneEnabled = $user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false); + + if (!$totpEnabled && !$emailEnabled && !$phoneEnabled) { + $mfa = false; + } } + + $membership->setAttribute('mfa', $mfa); } - $membership - ->setAttribute('mfa', $mfa) - ->setAttribute('teamName', $team->getAttribute('name')) - ->setAttribute('userName', $user->getAttribute('name')) - ->setAttribute('userEmail', $user->getAttribute('email')) - ; + if ($membershipsPrivacy['userName']) { + $membership->setAttribute('userName', $user->getAttribute('name')); + } + + if ($membershipsPrivacy['userEmail']) { + $membership->setAttribute('userEmail', $user->getAttribute('email')); + } + + $membership->setAttribute('teamName', $team->getAttribute('name')); $response->dynamic($membership, Response::MODEL_MEMBERSHIP); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index f0378ed0e3..42f7a59f54 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -51,7 +51,7 @@ use Utopia\Validator\Text; use Utopia\Validator\WhiteList; /** TODO: Remove function when we move to using utopia/platform */ -function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks): Document +function createUser(string $hash, mixed $hashOptions, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Hooks $hooks): Document { $plaintextPassword = $password; $hashOptionsObject = (\is_string($hashOptions)) ? \json_decode($hashOptions, true) : $hashOptions; // Cast to JSON array @@ -64,7 +64,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $identityWithMatchingEmail = $dbForProject->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } } @@ -141,7 +141,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$email]), ]); - if ($existingTarget) { + if (!$existingTarget->isEmpty()) { $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } @@ -165,7 +165,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $existingTarget = $dbForProject->findOne('targets', [ Query::equal('identifier', [$phone]), ]); - if ($existingTarget) { + if (!$existingTarget->isEmpty()) { $user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND); } } @@ -176,15 +176,12 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e throw new Exception(Exception::USER_ALREADY_EXISTS); } - $queueForEvents->setParam('userId', $user->getId()); - return $user; } App::post('/v1/users') ->desc('Create user') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -203,10 +200,9 @@ App::post('/v1/users') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('plaintext', '{}', $userId, $email, $password, $phone, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('plaintext', '{}', $userId, $email, $password, $phone, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) ->dynamic($user, Response::MODEL_USER); @@ -215,7 +211,6 @@ App::post('/v1/users') App::post('/v1/users/bcrypt') ->desc('Create user with bcrypt password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -233,10 +228,9 @@ App::post('/v1/users/bcrypt') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('bcrypt', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('bcrypt', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -246,7 +240,6 @@ App::post('/v1/users/bcrypt') App::post('/v1/users/md5') ->desc('Create user with MD5 password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -264,10 +257,9 @@ App::post('/v1/users/md5') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('md5', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('md5', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -277,7 +269,6 @@ App::post('/v1/users/md5') App::post('/v1/users/argon2') ->desc('Create user with Argon2 password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -295,10 +286,9 @@ App::post('/v1/users/argon2') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('argon2', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('argon2', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -308,7 +298,6 @@ App::post('/v1/users/argon2') App::post('/v1/users/sha') ->desc('Create user with SHA password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -327,16 +316,15 @@ App::post('/v1/users/sha') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { + ->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { $options = '{}'; if (!empty($passwordVersion)) { $options = '{"version":"' . $passwordVersion . '"}'; } - $user = createUser('sha', $options, $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + $user = createUser('sha', $options, $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -346,7 +334,6 @@ App::post('/v1/users/sha') App::post('/v1/users/phpass') ->desc('Create user with PHPass password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -364,10 +351,9 @@ App::post('/v1/users/phpass') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('phpass', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('phpass', '{}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -377,7 +363,6 @@ App::post('/v1/users/phpass') App::post('/v1/users/scrypt') ->desc('Create user with Scrypt password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -400,9 +385,8 @@ App::post('/v1/users/scrypt') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { + ->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { $options = [ 'salt' => $passwordSalt, 'costCpu' => $passwordCpu, @@ -411,7 +395,7 @@ App::post('/v1/users/scrypt') 'length' => $passwordLength ]; - $user = createUser('scrypt', \json_encode($options), $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + $user = createUser('scrypt', \json_encode($options), $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -421,7 +405,6 @@ App::post('/v1/users/scrypt') App::post('/v1/users/scrypt-modified') ->desc('Create user with Scrypt modified password') ->groups(['api', 'users']) - ->label('event', 'users.[userId].create') ->label('scope', 'users.write') ->label('audits.event', 'user.create') ->label('audits.resource', 'user/{response.$id}') @@ -442,10 +425,9 @@ App::post('/v1/users/scrypt-modified') ->inject('response') ->inject('project') ->inject('dbForProject') - ->inject('queueForEvents') ->inject('hooks') - ->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) { - $user = createUser('scryptMod', '{"signerKey":"' . $passwordSignerKey . '","saltSeparator":"' . $passwordSaltSeparator . '","salt":"' . $passwordSalt . '"}', $userId, $email, $password, null, $name, $project, $dbForProject, $queueForEvents, $hooks); + ->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) { + $user = createUser('scryptMod', '{"signerKey":"' . $passwordSignerKey . '","saltSeparator":"' . $passwordSaltSeparator . '","salt":"' . $passwordSalt . '"}', $userId, $email, $password, null, $name, $project, $dbForProject, $hooks); $response ->setStatusCode(Response::STATUS_CODE_CREATED) @@ -1232,7 +1214,7 @@ App::patch('/v1/users/:userId/email') Query::equal('providerEmail', [$email]), Query::notEqual('userInternalId', $user->getInternalId()), ]); - if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + if (!$identityWithMatchingEmail->isEmpty()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } @@ -1503,7 +1485,9 @@ App::patch('/v1/users/:userId/targets/:targetId') throw new Exception(Exception::PROVIDER_INCORRECT_TYPE); } - $target->setAttribute('identifier', $identifier); + $target + ->setAttribute('identifier', $identifier) + ->setAttribute('expired', false); } if ($providerId) { @@ -1517,8 +1501,9 @@ App::patch('/v1/users/:userId/targets/:targetId') throw new Exception(Exception::PROVIDER_INCORRECT_TYPE); } - $target->setAttribute('providerId', $provider->getId()); - $target->setAttribute('providerInternalId', $provider->getInternalId()); + $target + ->setAttribute('providerId', $provider->getId()) + ->setAttribute('providerInternalId', $provider->getInternalId()); } if ($name) { diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index e79eb67936..bbb1d9c3f8 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -110,7 +110,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId Query::orderDesc('$createdAt'), ])); - if ($latestComment !== false && !$latestComment->isEmpty()) { + if (!$latestComment->isEmpty()) { $latestCommentId = $latestComment->getAttribute('providerCommentId', ''); $comment = new Comment(); $comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId)); @@ -371,13 +371,11 @@ App::get('/v1/vcs/github/callback') $identity = $dbForConsole->findOne('identities', [ Query::equal('providerEmail', [$email]), ]); - if ($identity !== false && !$identity->isEmpty()) { + if (!$identity->isEmpty()) { if ($identity->getAttribute('userInternalId', '') !== $user->getInternalId()) { throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); } - } - if ($identity !== false && !$identity->isEmpty()) { $identity = $identity ->setAttribute('providerAccessToken', $accessToken) ->setAttribute('providerRefreshToken', $refreshToken) @@ -418,7 +416,7 @@ App::get('/v1/vcs/github/callback') Query::equal('projectInternalId', [$projectInternalId]) ]); - if ($installation === false || $installation->isEmpty()) { + if ($installation->isEmpty()) { $teamId = $project->getAttribute('teamId', ''); $installation = new Document([ @@ -726,7 +724,7 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories') Query::equal('provider', ['github']), Query::equal('userInternalId', [$user->getInternalId()]), ]); - if ($identity === false || $identity->isEmpty()) { + if ($identity->isEmpty()) { throw new Exception(Exception::USER_IDENTITY_NOT_FOUND); } diff --git a/app/controllers/general.php b/app/controllers/general.php index b2a07f06f6..663242882a 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -29,7 +29,6 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; -use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Domains\Domain; use Utopia\DSN\DSN; @@ -46,20 +45,15 @@ Config::setParam('domainVerification', false); Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); -function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb) +function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked) { $utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml'); $host = $request->getHostname() ?? ''; - $route = Authorization::skip( - fn () => $dbForConsole->find('rules', [ - Query::equal('domain', [$host]), - Query::limit(1) - ]) - )[0] ?? null; + $route = Authorization::skip(fn () => $dbForConsole->getDocument('rules', md5($host))); - if ($route === null) { + if ($route->isEmpty()) { if ($host === System::getEnv('_APP_DOMAIN_FUNCTIONS', '')) { throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.'); } @@ -137,6 +131,10 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); } + if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $functionId)) { + throw new AppwriteException(AppwriteException::GENERAL_RESOURCE_BLOCKED); + } + $version = $function->getAttribute('version', 'v2'); $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); $spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)]; @@ -457,7 +455,8 @@ App::init() ->inject('queueForEvents') ->inject('queueForCertificates') ->inject('queueForFunctions') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions) { + ->inject('isResourceBlocked') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, Usage $queueForUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked) { /* * Appwrite Router */ @@ -465,7 +464,7 @@ App::init() $mainDomain = System::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb, $isResourceBlocked)) { return; } } @@ -513,19 +512,18 @@ App::init() if (!empty($envDomain) && $envDomain !== 'localhost') { $mainDomain = $envDomain; } else { - $domainDocument = $dbForConsole->findOne('rules', [Query::orderAsc('$id')]); - $mainDomain = $domainDocument ? $domainDocument->getAttribute('domain') : $domain->get(); + $domainDocument = $dbForConsole->getDocument('rules', md5($envDomain)); + $mainDomain = !$domainDocument->isEmpty() ? $domainDocument->getAttribute('domain') : $domain->get(); } if ($mainDomain !== $domain->get()) { Console::warning($domain->get() . ' is not a main domain. Skipping SSL certificate generation.'); } else { - $domainDocument = $dbForConsole->findOne('rules', [ - Query::equal('domain', [$domain->get()]) - ]); + $domainDocument = $dbForConsole->getDocument('rules', md5($domain->get())); - if (!$domainDocument) { + if ($domainDocument->isEmpty()) { $domainDocument = new Document([ + '$id' => md5($domain->get()), 'domain' => $domain->get(), 'resourceType' => 'api', 'status' => 'verifying', @@ -675,7 +673,8 @@ App::options() ->inject('queueForUsage') ->inject('queueForFunctions') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb) { + ->inject('isResourceBlocked') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked) { /* * Appwrite Router */ @@ -683,7 +682,7 @@ App::options() $mainDomain = System::getEnv('_APP_DOMAIN', ''); // Only run Router when external domain if ($host !== $mainDomain) { - if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb)) { + if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb, $isResourceBlocked)) { return; } } @@ -769,6 +768,8 @@ App::error() case 'Utopia\Database\Exception\Relationship': $error = new AppwriteException(AppwriteException::RELATIONSHIP_VALUE_INVALID, $error->getMessage(), previous: $error); break; + case 'Utopia\Database\Exception\NotFound': + $error = new AppwriteException(AppwriteException::COLLECTION_NOT_FOUND, $error->getMessage(), previous: $error); } $code = $error->getCode(); @@ -967,7 +968,8 @@ App::get('/robots.txt') ->inject('queueForUsage') ->inject('queueForFunctions') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb) { + ->inject('isResourceBlocked') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked) { $host = $request->getHostname() ?? ''; $mainDomain = System::getEnv('_APP_DOMAIN', ''); @@ -975,7 +977,7 @@ App::get('/robots.txt') $template = new View(__DIR__ . '/../views/general/robots.phtml'); $response->text($template->render(false)); } else { - router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb); + router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb, $isResourceBlocked); } }); @@ -993,7 +995,8 @@ App::get('/humans.txt') ->inject('queueForUsage') ->inject('queueForFunctions') ->inject('geodb') - ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb) { + ->inject('isResourceBlocked') + ->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked) { $host = $request->getHostname() ?? ''; $mainDomain = System::getEnv('_APP_DOMAIN', ''); @@ -1001,7 +1004,7 @@ App::get('/humans.txt') $template = new View(__DIR__ . '/../views/general/humans.phtml'); $response->text($template->render(false)); } else { - router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb); + router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $queueForFunctions, $geodb, $isResourceBlocked); } }); diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index f0d896c95a..f5921bf6e8 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -11,10 +11,11 @@ use Appwrite\Event\Delete; use Appwrite\Event\Event; use Appwrite\Event\Func; use Appwrite\Event\Messaging; +use Appwrite\Event\Realtime; use Appwrite\Event\Usage; +use Appwrite\Event\Webhook; use Appwrite\Extend\Exception; use Appwrite\Extend\Exception as AppwriteException; -use Appwrite\Messaging\Adapter\Realtime; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\Abuse\Abuse; @@ -28,6 +29,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\Role; use Utopia\Database\Validator\Authorization; +use Utopia\Queue\Connection; use Utopia\System\System; use Utopia\Validator\WhiteList; @@ -57,8 +59,36 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar return $label; }; -$databaseListener = function (string $event, Document $document, Document $project, Usage $queueForUsage, Database $dbForProject) { +$eventDatabaseListener = function (Document $document, Response $response, Event $queueForEvents, Func $queueForFunctions, Webhook $queueForWebhooks, Realtime $queueForRealtime) { + // Only trigger events for user creation with the database listener. + if ($document->getCollection() !== 'users') { + return; + } + $queueForEvents + ->setEvent('users.[userId].create') + ->setParam('userId', $document->getId()) + ->setPayload($response->output($document, Response::MODEL_USER)); + + // Trigger functions, webhooks, and realtime events + $queueForFunctions + ->from($queueForEvents) + ->trigger(); + + $queueForWebhooks + ->from($queueForEvents) + ->trigger(); + + if ($queueForEvents->getProject()->getId() === 'console') { + return; + } + + $queueForRealtime + ->from($queueForEvents) + ->trigger(); +}; + +$usageDatabaseListener = function (string $event, Document $document, Usage $queueForUsage) { $value = 1; if ($event === Database::EVENT_DOCUMENT_DELETE) { $value = -1; @@ -353,6 +383,7 @@ App::init() ->inject('response') ->inject('project') ->inject('user') + ->inject('queue') ->inject('queueForEvents') ->inject('queueForMessaging') ->inject('queueForAudits') @@ -362,7 +393,7 @@ App::init() ->inject('queueForUsage') ->inject('dbForProject') ->inject('mode') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($databaseListener) { + ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Connection $queue, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Usage $queueForUsage, Database $dbForProject, string $mode) use ($usageDatabaseListener, $eventDatabaseListener) { $route = $utopia->getRoute(); @@ -456,9 +487,24 @@ App::init() $queueForBuilds->setProject($project); $queueForMessaging->setProject($project); + // Clone the queues, to prevent events triggered by the database listener + // from overwriting the events that are supposed to be triggered in the shutdown hook. + $queueForEventsClone = new Event($queue); + $queueForFunctions = new Func($queue); + $queueForWebhooks = new Webhook($queue); + $queueForRealtime = new Realtime(); + $dbForProject - ->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $databaseListener($event, $document, $project, $queueForUsage, $dbForProject)) - ->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $databaseListener($event, $document, $project, $queueForUsage, $dbForProject)); + ->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage)) + ->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage)) + ->on(Database::EVENT_DOCUMENT_CREATE, 'create-trigger-events', fn ($event, $document) => $eventDatabaseListener( + $document, + $response, + $queueForEventsClone->from($queueForEvents), + $queueForFunctions->from($queueForEvents), + $queueForWebhooks->from($queueForEvents), + $queueForRealtime->from($queueForEvents) + )); $useCache = $route->getLabel('cache', false); if ($useCache) { @@ -508,7 +554,7 @@ App::init() } $response - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $timestamp) . ' GMT') + ->addHeader('Cache-Control', sprintf('private, max-age=%d', $timestamp)) ->addHeader('X-Appwrite-Cache', 'hit') ->setContentType($cacheLog->getAttribute('mimeType')) ->send($data); @@ -516,7 +562,7 @@ App::init() $response ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate') ->addHeader('Pragma', 'no-cache') - ->addHeader('Expires', 0) + ->addHeader('Expires', '0') ->addHeader('X-Appwrite-Cache', 'miss') ; } @@ -591,11 +637,13 @@ App::shutdown() ->inject('queueForDatabase') ->inject('queueForBuilds') ->inject('queueForMessaging') - ->inject('dbForProject') ->inject('queueForFunctions') + ->inject('queueForWebhooks') + ->inject('queueForRealtime') + ->inject('dbForProject') ->inject('mode') ->inject('dbForConsole') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole) use ($parseLabel) { + ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, string $mode, Database $dbForConsole) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -604,54 +652,18 @@ App::shutdown() $queueForEvents->setPayload($responsePayload); } - /** - * Trigger functions. - */ - if (!$queueForEvents->isPaused()) { - $queueForFunctions - ->from($queueForEvents) - ->trigger(); - } - /** - * Trigger webhooks. - */ - $queueForEvents - ->setClass(Event::WEBHOOK_CLASS_NAME) - ->setQueue(Event::WEBHOOK_QUEUE_NAME) + $queueForWebhooks + ->from($queueForEvents) + ->trigger(); + + $queueForFunctions + ->from($queueForEvents) ->trigger(); - /** - * Trigger realtime. - */ if ($project->getId() !== 'console') { - $allEvents = Event::generateEvents($queueForEvents->getEvent(), $queueForEvents->getParams()); - $payload = new Document($queueForEvents->getPayload()); - - $db = $queueForEvents->getContext('database'); - $collection = $queueForEvents->getContext('collection'); - $bucket = $queueForEvents->getContext('bucket'); - - $target = Realtime::fromPayload( - // Pass first, most verbose event pattern - event: $allEvents[0], - payload: $payload, - project: $project, - database: $db, - collection: $collection, - bucket: $bucket, - ); - - Realtime::send( - projectId: $target['projectId'] ?? $project->getId(), - payload: $queueForEvents->getRealtimePayload(), - events: $allEvents, - channels: $target['channels'], - roles: $target['roles'], - options: [ - 'permissionsChanged' => $target['permissionsChanged'], - 'userId' => $queueForEvents->getParam('userId') - ] - ); + $queueForRealtime + ->from($queueForEvents) + ->trigger(); } } diff --git a/app/http.php b/app/http.php index bec772c770..641143694d 100644 --- a/app/http.php +++ b/app/http.php @@ -39,8 +39,7 @@ $http ->set([ 'worker_num' => $workerNumber, 'open_http2_protocol' => true, - 'http_compression' => true, - 'http_compression_level' => 6, + 'http_compression' => false, 'package_max_length' => $payloadSize, 'buffer_output_size' => $payloadSize, ]); @@ -61,6 +60,8 @@ include __DIR__ . '/controllers/general.php'; $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $register) { $app = new App('UTC'); + $app->setCompression(true); + $app->setCompressionMinSize(intval(System::getEnv('_APP_COMPRESSION_MIN_SIZE_BYTES', '1024'))); // 1KB go(function () use ($register, $app) { $pools = $register->get('pools'); @@ -244,6 +245,8 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo } $app = new App('UTC'); + $app->setCompression(true); + $app->setCompressionMinSize(intval(System::getEnv('_APP_COMPRESSION_MIN_SIZE_BYTES', '1024'))); // 1KB $pools = $register->get('pools'); App::setResource('pools', fn () => $pools); diff --git a/app/init.php b/app/init.php index eb149adc04..c9ec2e0061 100644 --- a/app/init.php +++ b/app/init.php @@ -31,7 +31,9 @@ use Appwrite\Event\Func; use Appwrite\Event\Mail; use Appwrite\Event\Messaging; use Appwrite\Event\Migration; +use Appwrite\Event\Realtime; use Appwrite\Event\Usage; +use Appwrite\Event\Webhook; use Appwrite\Extend\Exception; use Appwrite\Functions\Specification; use Appwrite\GraphQL\Promises\Adapter\Swoole; @@ -40,6 +42,7 @@ use Appwrite\Hooks\Hooks; use Appwrite\Network\Validator\Email; use Appwrite\Network\Validator\Origin; use Appwrite\OpenSSL\OpenSSL; +use Appwrite\PubSub\Adapter\Redis as PubSub; use Appwrite\URL\URL as AppwriteURL; use Appwrite\Utopia\Request; use MaxMind\Db\Reader; @@ -150,7 +153,7 @@ const APP_SOCIAL_DEV = 'https://dev.to/appwrite'; const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite'; const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1'; const APP_HOSTNAME_INTERNAL = 'appwrite'; -const APP_FUNCTION_SPECIFICATION_DEFAULT = Specification::S_05VCPU_512MB; +const APP_FUNCTION_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB; const APP_FUNCTION_CPUS_DEFAULT = 0.5; const APP_FUNCTION_MEMORY_DEFAULT = 512; const APP_PLATFORM_SERVER = 'server'; @@ -286,6 +289,17 @@ const METRIC_NETWORK_REQUESTS = 'network.requests'; const METRIC_NETWORK_INBOUND = 'network.inbound'; const METRIC_NETWORK_OUTBOUND = 'network.outbound'; +// Resource types + +const RESOURCE_TYPE_PROJECTS = 'projects'; +const RESOURCE_TYPE_FUNCTIONS = 'functions'; +const RESOURCE_TYPE_DATABASES = 'databases'; +const RESOURCE_TYPE_BUCKETS = 'buckets'; +const RESOURCE_TYPE_PROVIDERS = 'providers'; +const RESOURCE_TYPE_TOPICS = 'topics'; +const RESOURCE_TYPE_SUBSCRIBERS = 'subscribers'; +const RESOURCE_TYPE_MESSAGES = 'messages'; + $register = new Registry(); App::setMode(System::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION)); @@ -960,7 +974,10 @@ $register->set('pools', function () { $adapter->setDatabase($dsn->getPath()); break; case 'pubsub': - $adapter = $resource(); + $adapter = match ($dsn->getScheme()) { + 'redis' => new PubSub($resource()), + default => null + }; break; case 'queue': $adapter = match ($dsn->getScheme()) { @@ -1123,6 +1140,12 @@ App::setResource('queueForDeletes', function (Connection $queue) { App::setResource('queueForEvents', function (Connection $queue) { return new Event($queue); }, ['queue']); +App::setResource('queueForWebhooks', function (Connection $queue) { + return new Webhook($queue); +}, ['queue']); +App::setResource('queueForRealtime', function () { + return new Realtime(); +}, []); App::setResource('queueForAudits', function (Connection $queue) { return new Audit($queue); }, ['queue']); @@ -1771,11 +1794,11 @@ App::setResource('requestTimestamp', function ($request) { } return $requestTimestamp; }, ['request']); + App::setResource('plan', function (array $plan = []) { return []; }); - App::setResource('team', function (Document $project, Database $dbForConsole, App $utopia, Request $request) { $teamInternalId = ''; if ($project->getId() !== 'console') { @@ -1801,8 +1824,10 @@ App::setResource('team', function (Document $project, Database $dbForConsole, Ap ]); }); - if (!$team) { - $team = new Document([]); - } return $team; }, ['project', 'dbForConsole', 'utopia', 'request']); + +App::setResource( + 'isResourceBlocked', + fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false +); diff --git a/app/realtime.php b/app/realtime.php index 1b59eb3bc7..48979817c4 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -365,17 +365,16 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, } $start = time(); - $redis = $register->get('pools')->get('pubsub')->pop()->getResource(); /** @var Redis $redis */ - $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); - - if ($redis->ping(true)) { + /** @var \Appwrite\PubSub\Adapter $pubsub */ + $pubsub = $register->get('pools')->get('pubsub')->pop()->getResource(); + if ($pubsub->ping(true)) { $attempts = 0; Console::success('Pub/sub connection established (worker: ' . $workerId . ')'); } else { Console::error('Pub/sub failed (worker: ' . $workerId . ')'); } - $redis->subscribe(['realtime'], function (Redis $redis, string $channel, string $payload) use ($server, $workerId, $stats, $register, $realtime) { + $pubsub->subscribe(['realtime'], function (mixed $redis, string $channel, string $payload) use ($server, $workerId, $stats, $register, $realtime) { $event = json_decode($payload, true); if ($event['permissionsChanged'] && isset($event['userId'])) { @@ -593,9 +592,12 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re } switch ($message['type']) { - /** - * This type is used to authenticate. - */ + case 'ping': + $server->send([$connection], json_encode([ + 'type' => 'pong' + ])); + + break; case 'authentication': if (!array_key_exists('session', $message['data'])) { throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Payload is not valid.'); diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index ad35135a6f..8d7fecb479 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -73,6 +73,7 @@ $image = $this->getParam('image', ''); - _APP_ENV - _APP_WORKER_PER_CORE - _APP_LOCALE + - _APP_COMPRESSION_MIN_SIZE_BYTES - _APP_CONSOLE_WHITELIST_ROOT - _APP_CONSOLE_WHITELIST_EMAILS - _APP_CONSOLE_SESSION_ALERTS diff --git a/app/worker.php b/app/worker.php index 2d59259284..4741afe7ea 100644 --- a/app/worker.php +++ b/app/worker.php @@ -58,7 +58,7 @@ Server::setResource('project', function (Message $message, Database $dbForConsol $payload = $message->getPayload() ?? []; $project = new Document($payload['project'] ?? []); - if ($project->getId() === 'console' || $project->isEmpty() || ! empty($project->getInternalId())) { + if ($project->getId() === 'console') { return $project; } @@ -272,6 +272,11 @@ Server::setResource('deviceForCache', function (Document $project) { return getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId()); }, ['project']); +Server::setResource( + 'isResourceBlocked', + fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false +); + $pools = $register->get('pools'); $platform = new Appwrite(); diff --git a/composer.json b/composer.json index dd5472a0fa..a04ca51d43 100644 --- a/composer.json +++ b/composer.json @@ -48,10 +48,10 @@ "utopia-php/abuse": "0.43.0", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.43.0", - "utopia-php/cache": "0.10.*", + "utopia-php/cache": "0.11.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "0.53.8", + "utopia-php/database": "0.53.16", "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 9079512e60..691a7e740e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18505aa5baca1170e7cbdbb2a355b173", + "content-hash": "b358198535c1867eabed7c0f99135a57", "packages": [ { "name": "adhocore/jwt", @@ -157,16 +157,16 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.16.2", + "version": "0.16.4", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "c33005e3eaaf2d427e9fd1077d5335e31f4d36f9" + "reference": "7e4741337b9373f77210396e68eca539018cabd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/runtimes/zipball/c33005e3eaaf2d427e9fd1077d5335e31f4d36f9", - "reference": "c33005e3eaaf2d427e9fd1077d5335e31f4d36f9", + "url": "https://api.github.com/repos/appwrite/runtimes/zipball/7e4741337b9373f77210396e68eca539018cabd1", + "reference": "7e4741337b9373f77210396e68eca539018cabd1", "shasum": "" }, "require": { @@ -206,22 +206,22 @@ ], "support": { "issues": "https://github.com/appwrite/runtimes/issues", - "source": "https://github.com/appwrite/runtimes/tree/0.16.2" + "source": "https://github.com/appwrite/runtimes/tree/0.16.4" }, - "time": "2024-10-09T15:02:52+00:00" + "time": "2024-10-26T10:39:59+00:00" }, { "name": "beberlei/assert", - "version": "v3.3.2", + "version": "v3.3.3", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" + "reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", - "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", + "url": "https://api.github.com/repos/beberlei/assert/zipball/b5fd8eacd8915a1b627b8bfc027803f1939734dd", + "reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd", "shasum": "" }, "require": { @@ -229,7 +229,7 @@ "ext-json": "*", "ext-mbstring": "*", "ext-simplexml": "*", - "php": "^7.0 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "*", @@ -273,9 +273,9 @@ ], "support": { "issues": "https://github.com/beberlei/assert/issues", - "source": "https://github.com/beberlei/assert/tree/v3.3.2" + "source": "https://github.com/beberlei/assert/tree/v3.3.3" }, - "time": "2021-12-16T21:41:27+00:00" + "time": "2024-07-15T13:18:35+00:00" }, { "name": "chillerlan/php-qrcode", @@ -1574,16 +1574,16 @@ }, { "name": "utopia-php/cache", - "version": "0.10.2", + "version": "0.11.0", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247" + "reference": "8ebcab5aac7606331cef69b0081f6c9eff2e58bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/b22c6eb6d308de246b023efd0fc9758aee8b8247", - "reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/8ebcab5aac7606331cef69b0081f6c9eff2e58bc", + "reference": "8ebcab5aac7606331cef69b0081f6c9eff2e58bc", "shasum": "" }, "require": { @@ -1594,7 +1594,7 @@ }, "require-dev": { "laravel/pint": "1.2.*", - "phpstan/phpstan": "1.9.x-dev", + "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.13.1" }, @@ -1618,9 +1618,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.10.2" + "source": "https://github.com/utopia-php/cache/tree/0.11.0" }, - "time": "2024-06-25T20:36:35+00:00" + "time": "2024-11-05T16:53:58+00:00" }, { "name": "utopia-php/cli", @@ -1671,6 +1671,52 @@ }, "time": "2024-10-04T13:55:36+00:00" }, + { + "name": "utopia-php/compression", + "version": "0.1.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/compression.git", + "reference": "6062f70596415f8d5de40a589367b0eb2a435f98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/compression/zipball/6062f70596415f8d5de40a589367b0eb2a435f98", + "reference": "6062f70596415f8d5de40a589367b0eb2a435f98", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Compression\\": "src/Compression" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple Compression library to handle file compression", + "keywords": [ + "compression", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/compression/issues", + "source": "https://github.com/utopia-php/compression/tree/0.1.2" + }, + "time": "2024-11-08T14:59:54+00:00" + }, { "name": "utopia-php/config", "version": "0.2.2", @@ -1724,32 +1770,32 @@ }, { "name": "utopia-php/database", - "version": "0.53.8", + "version": "0.53.16", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "f4f9297d633b9f8407c6261535549bfd6024a468" + "reference": "6661edffeef05b59e16d102b989a72f7f78cf7de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/f4f9297d633b9f8407c6261535549bfd6024a468", - "reference": "f4f9297d633b9f8407c6261535549bfd6024a468", + "url": "https://api.github.com/repos/utopia-php/database/zipball/6661edffeef05b59e16d102b989a72f7f78cf7de", + "reference": "6661edffeef05b59e16d102b989a72f7f78cf7de", "shasum": "" }, "require": { "ext-mbstring": "*", "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/cache": "0.10.*", + "php": ">=8.3", + "utopia-php/cache": "0.11.*", "utopia-php/framework": "0.33.*", "utopia-php/mongo": "0.3.*" }, "require-dev": { "fakerphp/faker": "1.23.*", - "laravel/pint": "1.17.*", - "pcov/clobber": "2.0.*", - "phpstan/phpstan": "1.11.*", - "phpunit/phpunit": "9.6.*", + "laravel/pint": "1.*", + "pcov/clobber": "2.*", + "phpstan/phpstan": "1.*", + "phpunit/phpunit": "9.*", "rregeer/phpunit-coverage-check": "0.3.*", "swoole/ide-helper": "5.1.3", "utopia-php/cli": "0.14.*" @@ -1774,9 +1820,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.53.8" + "source": "https://github.com/utopia-php/database/tree/0.53.16" }, - "time": "2024-10-16T08:16:33+00:00" + "time": "2024-11-06T03:07:16+00:00" }, { "name": "utopia-php/domains", @@ -1926,20 +1972,21 @@ }, { "name": "utopia-php/framework", - "version": "0.33.8", + "version": "0.33.11", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5" + "reference": "354ff0d23bfc6e82bea0fe8e89e115cff1af8466" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/a7f577540a25cb90896fef2b64767bf8d700f3c5", - "reference": "a7f577540a25cb90896fef2b64767bf8d700f3c5", + "url": "https://api.github.com/repos/utopia-php/http/zipball/354ff0d23bfc6e82bea0fe8e89e115cff1af8466", + "reference": "354ff0d23bfc6e82bea0fe8e89e115cff1af8466", "shasum": "" }, "require": { - "php": ">=8.0" + "php": ">=8.0", + "utopia-php/compression": "0.1.*" }, "require-dev": { "laravel/pint": "^1.2", @@ -1965,9 +2012,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.8" + "source": "https://github.com/utopia-php/http/tree/0.33.11" }, - "time": "2024-08-15T14:10:09+00:00" + "time": "2024-11-08T18:47:43+00:00" }, { "name": "utopia-php/image", @@ -2124,16 +2171,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.12.1", + "version": "0.12.2", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "b9dfafb5efc1d12cbee01d03dc98853ef026e35b" + "reference": "f6790fba1fcee12163d51c65d2c226a7856295d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/b9dfafb5efc1d12cbee01d03dc98853ef026e35b", - "reference": "b9dfafb5efc1d12cbee01d03dc98853ef026e35b", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/f6790fba1fcee12163d51c65d2c226a7856295d9", + "reference": "f6790fba1fcee12163d51c65d2c226a7856295d9", "shasum": "" }, "require": { @@ -2169,22 +2216,22 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.12.1" + "source": "https://github.com/utopia-php/messaging/tree/0.12.2" }, - "time": "2024-10-09T08:17:07+00:00" + "time": "2024-10-22T01:02:20+00:00" }, { "name": "utopia-php/migration", - "version": "0.6.9", + "version": "0.6.11", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b" + "reference": "4d167914d3f7fa1fe816b2b2c6f221e70166bfd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b", - "reference": "ce97cdf2ca82e7cec78e2ed484ef2c71ebe8744b", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/4d167914d3f7fa1fe816b2b2c6f221e70166bfd7", + "reference": "4d167914d3f7fa1fe816b2b2c6f221e70166bfd7", "shasum": "" }, "require": { @@ -2225,9 +2272,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.6.9" + "source": "https://github.com/utopia-php/migration/tree/0.6.11" }, - "time": "2024-10-16T08:33:21+00:00" + "time": "2024-10-31T06:19:57+00:00" }, { "name": "utopia-php/mongo", @@ -2341,16 +2388,16 @@ }, { "name": "utopia-php/platform", - "version": "0.7.0", + "version": "0.7.1", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" + "reference": "3433a0f1a54988f2a59c735f507745cb2c24638a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", - "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/3433a0f1a54988f2a59c735f507745cb2c24638a", + "reference": "3433a0f1a54988f2a59c735f507745cb2c24638a", "shasum": "" }, "require": { @@ -2385,9 +2432,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.7.0" + "source": "https://github.com/utopia-php/platform/tree/0.7.1" }, - "time": "2024-05-08T17:00:55+00:00" + "time": "2024-10-22T10:27:49+00:00" }, { "name": "utopia-php/pools", @@ -2495,16 +2542,16 @@ }, { "name": "utopia-php/queue", - "version": "0.7.0", + "version": "0.7.1", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "917565256eb94bcab7246f7a746b1a486813761b" + "reference": "94c240d9f6383829807ce7b2d737f04b159fd3e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/917565256eb94bcab7246f7a746b1a486813761b", - "reference": "917565256eb94bcab7246f7a746b1a486813761b", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/94c240d9f6383829807ce7b2d737f04b159fd3e8", + "reference": "94c240d9f6383829807ce7b2d737f04b159fd3e8", "shasum": "" }, "require": { @@ -2550,9 +2597,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.7.0" + "source": "https://github.com/utopia-php/queue/tree/0.7.1" }, - "time": "2024-01-17T19:00:43+00:00" + "time": "2024-11-05T17:00:38+00:00" }, { "name": "utopia-php/registry", @@ -2608,16 +2655,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.5", + "version": "0.18.6", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "7d355c5e3ccc8ecebc0266f8ddd30088a43be919" + "reference": "893ccf06e183f8ece2aed8dbf14d64d6ba036071" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/7d355c5e3ccc8ecebc0266f8ddd30088a43be919", - "reference": "7d355c5e3ccc8ecebc0266f8ddd30088a43be919", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/893ccf06e183f8ece2aed8dbf14d64d6ba036071", + "reference": "893ccf06e183f8ece2aed8dbf14d64d6ba036071", "shasum": "" }, "require": { @@ -2657,9 +2704,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.5" + "source": "https://github.com/utopia-php/storage/tree/0.18.6" }, - "time": "2024-09-04T08:57:27+00:00" + "time": "2024-11-06T09:58:50+00:00" }, { "name": "utopia-php/swoole", @@ -2770,22 +2817,22 @@ }, { "name": "utopia-php/vcs", - "version": "0.8.2", + "version": "0.8.3", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18" + "reference": "a032ed0611a8f4467aeaa9484f73223074457337" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18", - "reference": "eb9b7eade1a46a4f660e0d5a6304f7fa26ec9d18", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/a032ed0611a8f4467aeaa9484f73223074457337", + "reference": "a032ed0611a8f4467aeaa9484f73223074457337", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", - "utopia-php/cache": "^0.10.0", + "utopia-php/cache": "^0.11.0", "utopia-php/framework": "0.*.*" }, "require-dev": { @@ -2813,9 +2860,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.8.2" + "source": "https://github.com/utopia-php/vcs/tree/0.8.3" }, - "time": "2024-08-13T14:36:30+00:00" + "time": "2024-11-05T17:10:09+00:00" }, { "name": "utopia-php/websocket", @@ -3513,16 +3560,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -3561,7 +3608,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -3569,7 +3616,7 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nikic/php-parser", @@ -4004,16 +4051,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.4.1", + "version": "5.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" + "reference": "0c70d2c566e899666f367ab7b80986beb3581e6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/0c70d2c566e899666f367ab7b80986beb3581e6f", + "reference": "0c70d2c566e899666f367ab7b80986beb3581e6f", "shasum": "" }, "require": { @@ -4026,13 +4073,13 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.5", + "mockery/mockery": "~1.3.5 || ~1.6.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.13" + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -4062,29 +4109,29 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.5.1" }, - "time": "2024-05-21T05:55:05+00:00" + "time": "2024-11-06T11:58:54+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.8.2", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "153ae662783729388a584b4361f2545e4d841e3c" + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", - "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", @@ -4120,9 +4167,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" }, - "time": "2024-02-23T11:10:43+00:00" + "time": "2024-11-09T15:12:26+00:00" }, { "name": "phpspec/prophecy", @@ -5875,16 +5922,16 @@ }, { "name": "symfony/console", - "version": "v7.1.5", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" + "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", - "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "url": "https://api.github.com/repos/symfony/console/zipball/3284aafcac338b6e86fd955ee4d794cbe434151a", + "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a", "shasum": "" }, "require": { @@ -5948,7 +5995,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.5" + "source": "https://github.com/symfony/console/tree/v7.1.7" }, "funding": [ { @@ -5964,7 +6011,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-11-05T15:34:55+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6035,16 +6082,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" + "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", - "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4", + "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4", "shasum": "" }, "require": { @@ -6081,7 +6128,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.5" + "source": "https://github.com/symfony/filesystem/tree/v7.1.6" }, "funding": [ { @@ -6097,20 +6144,20 @@ "type": "tidelift" } ], - "time": "2024-09-17T09:16:35+00:00" + "time": "2024-10-25T15:11:02+00:00" }, { "name": "symfony/finder", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8", + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8", "shasum": "" }, "require": { @@ -6145,7 +6192,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.4" + "source": "https://github.com/symfony/finder/tree/v7.1.6" }, "funding": [ { @@ -6161,20 +6208,20 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2024-10-01T08:31:23+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.1.1", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" + "reference": "85e95eeede2d41cd146146e98c9c81d9214cae85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", - "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/85e95eeede2d41cd146146e98c9c81d9214cae85", + "reference": "85e95eeede2d41cd146146e98c9c81d9214cae85", "shasum": "" }, "require": { @@ -6212,7 +6259,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.1.1" + "source": "https://github.com/symfony/options-resolver/tree/v7.1.6" }, "funding": [ { @@ -6228,7 +6275,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-ctype", @@ -6546,16 +6593,16 @@ }, { "name": "symfony/process", - "version": "v7.1.5", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "5c03ee6369281177f07f7c68252a280beccba847" + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", - "reference": "5c03ee6369281177f07f7c68252a280beccba847", + "url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585", + "reference": "9b8a40b7289767aa7117e957573c2a535efe6585", "shasum": "" }, "require": { @@ -6587,7 +6634,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.5" + "source": "https://github.com/symfony/process/tree/v7.1.7" }, "funding": [ { @@ -6603,7 +6650,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T21:48:23+00:00" + "time": "2024-11-06T09:25:12+00:00" }, { "name": "symfony/service-contracts", @@ -6690,16 +6737,16 @@ }, { "name": "symfony/string", - "version": "v7.1.5", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", - "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626", + "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626", "shasum": "" }, "require": { @@ -6757,7 +6804,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.5" + "source": "https://github.com/symfony/string/tree/v7.1.6" }, "funding": [ { @@ -6773,7 +6820,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T08:28:38+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "textalk/websocket", @@ -6876,16 +6923,16 @@ }, { "name": "twig/twig", - "version": "v3.14.0", + "version": "v3.14.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/f405356d20fb43603bcadc8b09bfb676cb04a379", + "reference": "f405356d20fb43603bcadc8b09bfb676cb04a379", "shasum": "" }, "require": { @@ -6939,7 +6986,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.1" }, "funding": [ { @@ -6951,7 +6998,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T17:55:12+00:00" + "time": "2024-11-06T18:17:38+00:00" }, { "name": "webmozart/glob", @@ -7005,7 +7052,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/docker-compose.yml b/docker-compose.yml index 479ca38b8f..048178e60a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -96,6 +96,7 @@ services: - _APP_EDITION - _APP_WORKER_PER_CORE - _APP_LOCALE + - _APP_COMPRESSION_MIN_SIZE_BYTES - _APP_CONSOLE_WHITELIST_ROOT - _APP_CONSOLE_WHITELIST_EMAILS - _APP_CONSOLE_SESSION_ALERTS @@ -1053,4 +1054,4 @@ volumes: appwrite-certificates: appwrite-functions: appwrite-builds: - appwrite-config: + appwrite-config: \ No newline at end of file diff --git a/docs/references/account/create-token-magic-url.md b/docs/references/account/create-token-magic-url.md index 6ebe4154b8..99ad6dba5e 100644 --- a/docs/references/account/create-token-magic-url.md +++ b/docs/references/account/create-token-magic-url.md @@ -1,3 +1,3 @@ -Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default. +Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). diff --git a/docs/references/teams/get-team-member.md b/docs/references/teams/get-team-member.md index fab52c1a75..91bf44c73b 100644 --- a/docs/references/teams/get-team-member.md +++ b/docs/references/teams/get-team-member.md @@ -1 +1 @@ -Get a team member by the membership unique id. All team members have read access for this resource. \ No newline at end of file +Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console. \ No newline at end of file diff --git a/docs/references/teams/list-team-members.md b/docs/references/teams/list-team-members.md index d7dd04977f..540a665d98 100644 --- a/docs/references/teams/list-team-members.md +++ b/docs/references/teams/list-team-members.md @@ -1 +1 @@ -Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. \ No newline at end of file +Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console. \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 90ebd4225f..4c4e55ea4e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -33,6 +33,7 @@ ./tests/e2e/Services/Storage ./tests/e2e/Services/Webhooks ./tests/e2e/Services/Messaging + ./tests/e2e/Services/Migrations ./tests/e2e/Services/Functions/FunctionsBase.php ./tests/e2e/Services/Functions/FunctionsCustomServerTest.php ./tests/e2e/Services/Functions/FunctionsCustomClientTest.php diff --git a/src/Appwrite/Event/Audit.php b/src/Appwrite/Event/Audit.php index 4b02849970..17506bfe6c 100644 --- a/src/Appwrite/Event/Audit.php +++ b/src/Appwrite/Event/Audit.php @@ -121,6 +121,10 @@ class Audit extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Build.php b/src/Appwrite/Event/Build.php index b8cb62a6f8..1fbf20a9f9 100644 --- a/src/Appwrite/Event/Build.php +++ b/src/Appwrite/Event/Build.php @@ -112,6 +112,10 @@ class Build extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Certificate.php b/src/Appwrite/Event/Certificate.php index 85058c96fe..5d30c3d5ac 100644 --- a/src/Appwrite/Event/Certificate.php +++ b/src/Appwrite/Event/Certificate.php @@ -74,6 +74,10 @@ class Certificate extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Database.php b/src/Appwrite/Event/Database.php index f9eb7d9a7d..1b0ea6851c 100644 --- a/src/Appwrite/Event/Database.php +++ b/src/Appwrite/Event/Database.php @@ -108,6 +108,10 @@ class Database extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + try { $dsn = new DSN($this->getProject()->getAttribute('database')); } catch (\InvalidArgumentException) { diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index 064fbcefa9..1a4c9318e3 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -140,6 +140,10 @@ class Delete extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index 43eda511df..e3a2e394cf 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -65,6 +65,24 @@ class Event { } + /** + * Set paused state for this event. + */ + public function setPaused(bool $paused): self + { + $this->paused = $paused; + + return $this; + } + + /** + * Get paused state for this event. + */ + public function getPaused(): bool + { + return $this->paused; + } + /** * Set queue used for this event. * @@ -204,19 +222,6 @@ class Event return $this->payload; } - public function getRealtimePayload(): array - { - $payload = []; - - foreach ($this->payload as $key => $value) { - if (!isset($this->sensitive[$key])) { - $payload[$key] = $value; - } - } - - return $payload; - } - /** * Set context for this event. * @@ -530,20 +535,21 @@ class Event } /** - * Get the value of paused + * Generate a function event from a base event + * + * @param Event $event + * + * @return self + * */ - public function isPaused(): bool + public function from(Event $event): self { - return $this->paused; - } - - /** - * Set the value of paused - */ - public function setPaused(bool $paused): self - { - $this->paused = $paused; - + $this->project = $event->getProject(); + $this->user = $event->getUser(); + $this->payload = $event->getPayload(); + $this->event = $event->getEvent(); + $this->params = $event->getParams(); + $this->context = $event->context; return $this; } } diff --git a/src/Appwrite/Event/Func.php b/src/Appwrite/Event/Func.php index 4dad5802f7..0ad639a9f5 100644 --- a/src/Appwrite/Event/Func.php +++ b/src/Appwrite/Event/Func.php @@ -238,22 +238,4 @@ class Func extends Event 'method' => $this->method, ]); } - - /** - * Generate a function event from a base event - * - * @param Event $event - * - * @return self - * - */ - public function from(Event $event): self - { - $this->project = $event->getProject(); - $this->user = $event->getUser(); - $this->payload = $event->getPayload(); - $this->event = $event->getEvent(); - $this->params = $event->getParams(); - return $this; - } } diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index 9bdbf6044d..a0fca75688 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -404,6 +404,10 @@ class Mail extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Messaging.php b/src/Appwrite/Event/Messaging.php index f97ff02d21..ab9b1bee6b 100644 --- a/src/Appwrite/Event/Messaging.php +++ b/src/Appwrite/Event/Messaging.php @@ -182,6 +182,10 @@ class Messaging extends Event */ public function trigger(): string | bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Migration.php b/src/Appwrite/Event/Migration.php index e57ac3c87c..789b8e2160 100644 --- a/src/Appwrite/Event/Migration.php +++ b/src/Appwrite/Event/Migration.php @@ -75,6 +75,9 @@ class Migration extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } $client = new Client($this->queue, $this->connection); diff --git a/src/Appwrite/Event/Realtime.php b/src/Appwrite/Event/Realtime.php new file mode 100644 index 0000000000..f4f00b59d4 --- /dev/null +++ b/src/Appwrite/Event/Realtime.php @@ -0,0 +1,70 @@ +payload as $key => $value) { + if (!isset($this->sensitive[$key])) { + $payload[$key] = $value; + } + } + + return $payload; + } + + /** + * Execute Event. + * + * @return string|bool + * @throws InvalidArgumentException + */ + public function trigger(): string|bool + { + if ($this->paused || empty($this->event)) { + return false; + } + + $allEvents = Event::generateEvents($this->getEvent(), $this->getParams()); + $payload = new Document($this->getPayload()); + + $db = $this->getContext('database'); + $collection = $this->getContext('collection'); + $bucket = $this->getContext('bucket'); + + $target = RealtimeAdapter::fromPayload( + // Pass first, most verbose event pattern + event: $allEvents[0], + payload: $payload, + project: $this->getProject(), + database: $db, + collection: $collection, + bucket: $bucket, + ); + + RealtimeAdapter::send( + projectId: $target['projectId'] ?? $this->getProject()->getId(), + payload: $this->getRealtimePayload(), + events: $allEvents, + channels: $target['channels'], + roles: $target['roles'], + options: [ + 'permissionsChanged' => $target['permissionsChanged'], + 'userId' => $this->getParam('userId') + ] + ); + + return true; + } +} diff --git a/src/Appwrite/Event/Usage.php b/src/Appwrite/Event/Usage.php index 4426f4ab1b..161c251c8e 100644 --- a/src/Appwrite/Event/Usage.php +++ b/src/Appwrite/Event/Usage.php @@ -57,6 +57,10 @@ class Usage extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ 'project' => $this->getProject(), diff --git a/src/Appwrite/Event/UsageDump.php b/src/Appwrite/Event/UsageDump.php index 8f87908849..2998e4e104 100644 --- a/src/Appwrite/Event/UsageDump.php +++ b/src/Appwrite/Event/UsageDump.php @@ -38,6 +38,10 @@ class UsageDump extends Event */ public function trigger(): string|bool { + if ($this->paused) { + return false; + } + $client = new Client($this->queue, $this->connection); return $client->enqueue([ diff --git a/src/Appwrite/Event/Webhook.php b/src/Appwrite/Event/Webhook.php new file mode 100644 index 0000000000..125c9a78d5 --- /dev/null +++ b/src/Appwrite/Event/Webhook.php @@ -0,0 +1,17 @@ +setQueue(Event::WEBHOOK_QUEUE_NAME) + ->setClass(Event::WEBHOOK_CLASS_NAME); + } +} diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index d25332126c..54bf6d96ea 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -39,6 +39,7 @@ class Exception extends \Exception public const GENERAL_UNKNOWN = 'general_unknown'; public const GENERAL_MOCK = 'general_mock'; public const GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden'; + public const GENERAL_RESOURCE_BLOCKED = 'general_resource_blocked'; public const GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin'; public const GENERAL_API_DISABLED = 'general_api_disabled'; public const GENERAL_SERVICE_DISABLED = 'general_service_disabled'; diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index c437d4d487..dceafacf6e 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -7,7 +7,6 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; -use Utopia\System\System; class Realtime extends Adapter { @@ -139,20 +138,26 @@ class Realtime extends Adapter $permissionsChanged = array_key_exists('permissionsChanged', $options) && $options['permissionsChanged']; $userId = array_key_exists('userId', $options) ? $options['userId'] : null; - $redis = new \Redis(); //TODO: make this part of the constructor - $redis->connect(System::getEnv('_APP_REDIS_HOST', ''), System::getEnv('_APP_REDIS_PORT', '')); - $redis->publish('realtime', json_encode([ - 'project' => $projectId, - 'roles' => $roles, - 'permissionsChanged' => $permissionsChanged, - 'userId' => $userId, - 'data' => [ - 'events' => $events, - 'channels' => $channels, - 'timestamp' => DateTime::formatTz(DateTime::now()), - 'payload' => $payload - ] - ])); + global $register; + $pubsub = $register->get('pools')->get('pubsub')->pop(); + try { + /** @var \Appwrite\PubSub\Adapter $redis */ + $redis = $pubsub->getResource(); + $redis->publish('realtime', json_encode([ + 'project' => $projectId, + 'roles' => $roles, + 'permissionsChanged' => $permissionsChanged, + 'userId' => $userId, + 'data' => [ + 'events' => $events, + 'channels' => $channels, + 'timestamp' => DateTime::formatTz(DateTime::now()), + 'payload' => $payload + ] + ])); + } finally { + $pubsub->reclaim(); + } } /** diff --git a/src/Appwrite/Platform/Tasks/Doctor.php b/src/Appwrite/Platform/Tasks/Doctor.php index 82d1ca2d59..c43afea527 100644 --- a/src/Appwrite/Platform/Tasks/Doctor.php +++ b/src/Appwrite/Platform/Tasks/Doctor.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Tasks; use Appwrite\ClamAV\Network; +use Appwrite\PubSub\Adapter; use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; @@ -158,6 +159,7 @@ class Doctor extends Action foreach ($configs as $key => $config) { foreach ($config as $pool) { try { + /** @var Adapter $adapter */ $adapter = $pools->get($pool)->pop()->getResource(); if ($adapter->ping()) { diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index 58dc1dd28a..21d967d9e1 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -126,7 +126,7 @@ class Certificates extends Action $certificate = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain->get()])]); // If we don't have certificate for domain yet, let's create new document. At the end we save it - if (!$certificate) { + if ($certificate->isEmpty()) { $certificate = new Document(); $certificate->setAttribute('domain', $domain->get()); } @@ -216,7 +216,7 @@ class Certificates extends Action { // Check if update or insert required $certificateDocument = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]); - if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) { + if (!$certificateDocument->isEmpty()) { // Merge new data with current data $certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy())); $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); @@ -478,11 +478,9 @@ class Certificates extends Action private function updateDomainDocuments(string $certificateId, string $domain, bool $success, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions): void { - $rule = $dbForConsole->findOne('rules', [ - Query::equal('domain', [$domain]), - ]); + $rule = $dbForConsole->getDocument('rules', md5($domain)); - if ($rule !== false && !$rule->isEmpty()) { + if (!$rule->isEmpty()) { $rule->setAttribute('certificateId', $certificateId); $rule->setAttribute('status', $success ? 'verified' : 'unverified'); $dbForConsole->updateDocument('rules', $rule->getId(), $rule); diff --git a/src/Appwrite/Platform/Workers/Databases.php b/src/Appwrite/Platform/Workers/Databases.php index f697e7be13..fe81114ea0 100644 --- a/src/Appwrite/Platform/Workers/Databases.php +++ b/src/Appwrite/Platform/Workers/Databases.php @@ -92,6 +92,7 @@ class Databases extends Action * @throws Authorization * @throws Conflict * @throws \Exception + * @throws \Throwable */ private function createAttribute(Document $database, Document $collection, Document $attribute, Document $project, Database $dbForConsole, Database $dbForProject): void { @@ -134,7 +135,6 @@ class Databases extends Action $options = $attribute->getAttribute('options', []); $project = $dbForConsole->getDocument('projects', $projectId); - try { switch ($type) { case Database::VAR_RELATIONSHIP: @@ -170,7 +170,6 @@ class Databases extends Action $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available')); } catch (\Throwable $e) { - // TODO: Send non DatabaseExceptions to Sentry Console::error($e->getMessage()); if ($e instanceof DatabaseException) { @@ -193,15 +192,17 @@ class Databases extends Action $relatedAttribute->setAttribute('status', 'failed') ); } + + throw $e; } finally { $this->trigger($database, $collection, $attribute, $project, $projectId, $events); - } - if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) { - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId()); - } + if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) { + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId()); + } - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); + } } /** @@ -215,6 +216,7 @@ class Databases extends Action * @throws Authorization * @throws Conflict * @throws \Exception + * @throws \Throwable **/ private function deleteAttribute(Document $database, Document $collection, Document $attribute, Document $project, Database $dbForConsole, Database $dbForProject): void { @@ -248,113 +250,116 @@ class Databases extends Action // - stuck: attribute was available but cannot be removed try { - if ($status !== 'failed') { - if ($type === Database::VAR_RELATIONSHIP) { - if ($options['twoWay']) { - $relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']); - if ($relatedCollection->isEmpty()) { - throw new DatabaseException('Collection not found'); + try { + if ($status !== 'failed') { + if ($type === Database::VAR_RELATIONSHIP) { + if ($options['twoWay']) { + $relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']); + if ($relatedCollection->isEmpty()) { + throw new DatabaseException('Collection not found'); + } + $relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']); } - $relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']); - } - if (!$dbForProject->deleteRelationship('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) { - $dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'stuck')); - throw new DatabaseException('Failed to delete Relationship'); + if (!$dbForProject->deleteRelationship('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) { + $dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'stuck')); + throw new DatabaseException('Failed to delete Relationship'); + } + } elseif (!$dbForProject->deleteAttribute('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) { + throw new DatabaseException('Failed to delete Attribute'); } - } elseif (!$dbForProject->deleteAttribute('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) { - throw new DatabaseException('Failed to delete Attribute'); } - } - $dbForProject->deleteDocument('attributes', $attribute->getId()); + $dbForProject->deleteDocument('attributes', $attribute->getId()); - if (!$relatedAttribute->isEmpty()) { - $dbForProject->deleteDocument('attributes', $relatedAttribute->getId()); - } - } catch (\Throwable $e) { - // TODO: Send non DatabaseExceptions to Sentry - Console::error($e->getMessage()); - - if ($e instanceof DatabaseException) { - $attribute->setAttribute('error', $e->getMessage()); if (!$relatedAttribute->isEmpty()) { - $relatedAttribute->setAttribute('error', $e->getMessage()); + $dbForProject->deleteDocument('attributes', $relatedAttribute->getId()); + } + } catch (\Throwable $e) { + Console::error($e->getMessage()); + + if ($e instanceof DatabaseException) { + $attribute->setAttribute('error', $e->getMessage()); + if (!$relatedAttribute->isEmpty()) { + $relatedAttribute->setAttribute('error', $e->getMessage()); + } } - } - $dbForProject->updateDocument( - 'attributes', - $attribute->getId(), - $attribute->setAttribute('status', 'stuck') - ); - if (!$relatedAttribute->isEmpty()) { $dbForProject->updateDocument( 'attributes', - $relatedAttribute->getId(), - $relatedAttribute->setAttribute('status', 'stuck') + $attribute->getId(), + $attribute->setAttribute('status', 'stuck') ); + if (!$relatedAttribute->isEmpty()) { + $dbForProject->updateDocument( + 'attributes', + $relatedAttribute->getId(), + $relatedAttribute->setAttribute('status', 'stuck') + ); + } + + throw $e; + } finally { + $this->trigger($database, $collection, $attribute, $project, $projectId, $events); } - } finally { - $this->trigger($database, $collection, $attribute, $project, $projectId, $events); - } - // The underlying database removes/rebuilds indexes when attribute is removed - // Update indexes table with changes - /** @var Document[] $indexes */ - $indexes = $collection->getAttribute('indexes', []); + // The underlying database removes/rebuilds indexes when attribute is removed + // Update indexes table with changes + /** @var Document[] $indexes */ + $indexes = $collection->getAttribute('indexes', []); - foreach ($indexes as $index) { - /** @var string[] $attributes */ - $attributes = $index->getAttribute('attributes'); - $lengths = $index->getAttribute('lengths'); - $orders = $index->getAttribute('orders'); + foreach ($indexes as $index) { + /** @var string[] $attributes */ + $attributes = $index->getAttribute('attributes'); + $lengths = $index->getAttribute('lengths'); + $orders = $index->getAttribute('orders'); - $found = \array_search($key, $attributes); + $found = \array_search($key, $attributes); - if ($found !== false) { - // If found, remove entry from attributes, lengths, and orders - // array_values wraps array_diff to reindex array keys - // when found attribute is removed from array - $attributes = \array_values(\array_diff($attributes, [$attributes[$found]])); - $lengths = \array_values(\array_diff($lengths, isset($lengths[$found]) ? [$lengths[$found]] : [])); - $orders = \array_values(\array_diff($orders, isset($orders[$found]) ? [$orders[$found]] : [])); + if ($found !== false) { + // If found, remove entry from attributes, lengths, and orders + // array_values wraps array_diff to reindex array keys + // when found attribute is removed from array + $attributes = \array_values(\array_diff($attributes, [$attributes[$found]])); + $lengths = \array_values(\array_diff($lengths, isset($lengths[$found]) ? [$lengths[$found]] : [])); + $orders = \array_values(\array_diff($orders, isset($orders[$found]) ? [$orders[$found]] : [])); - if (empty($attributes)) { - $dbForProject->deleteDocument('indexes', $index->getId()); - } else { - $index - ->setAttribute('attributes', $attributes, Document::SET_TYPE_ASSIGN) - ->setAttribute('lengths', $lengths, Document::SET_TYPE_ASSIGN) - ->setAttribute('orders', $orders, Document::SET_TYPE_ASSIGN); - - // Check if an index exists with the same attributes and orders - $exists = false; - foreach ($indexes as $existing) { - if ( - $existing->getAttribute('key') !== $index->getAttribute('key') // Ignore itself - && $existing->getAttribute('attributes') === $index->getAttribute('attributes') - && $existing->getAttribute('orders') === $index->getAttribute('orders') - ) { - $exists = true; - break; - } - } - - if ($exists) { // Delete the duplicate if created, else update in db - $this->deleteIndex($database, $collection, $index, $project, $dbForConsole, $dbForProject); + if (empty($attributes)) { + $dbForProject->deleteDocument('indexes', $index->getId()); } else { - $dbForProject->updateDocument('indexes', $index->getId(), $index); + $index + ->setAttribute('attributes', $attributes, Document::SET_TYPE_ASSIGN) + ->setAttribute('lengths', $lengths, Document::SET_TYPE_ASSIGN) + ->setAttribute('orders', $orders, Document::SET_TYPE_ASSIGN); + + // Check if an index exists with the same attributes and orders + $exists = false; + foreach ($indexes as $existing) { + if ( + $existing->getAttribute('key') !== $index->getAttribute('key') // Ignore itself + && $existing->getAttribute('attributes') === $index->getAttribute('attributes') + && $existing->getAttribute('orders') === $index->getAttribute('orders') + ) { + $exists = true; + break; + } + } + + if ($exists) { // Delete the duplicate if created, else update in db + $this->deleteIndex($database, $collection, $index, $project, $dbForConsole, $dbForProject); + } else { + $dbForProject->updateDocument('indexes', $index->getId(), $index); + } } } } - } + } finally { + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); + $dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId()); - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); - $dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId()); - - if (!$relatedCollection->isEmpty() && !$relatedAttribute->isEmpty()) { - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId()); - $dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId()); + if (!$relatedCollection->isEmpty() && !$relatedAttribute->isEmpty()) { + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId()); + $dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId()); + } } } @@ -370,6 +375,7 @@ class Databases extends Action * @throws Conflict * @throws Structure * @throws DatabaseException + * @throws \Throwable */ private function createIndex(Document $database, Document $collection, Document $index, Document $project, Database $dbForConsole, Database $dbForProject): void { @@ -401,9 +407,7 @@ class Databases extends Action } $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available')); } catch (\Throwable $e) { - // TODO: Send non DatabaseExceptions to Sentry Console::error($e->getMessage()); - if ($e instanceof DatabaseException) { $index->setAttribute('error', $e->getMessage()); } @@ -412,11 +416,12 @@ class Databases extends Action $index->getId(), $index->setAttribute('status', 'failed') ); + + throw $e; } finally { $this->trigger($database, $collection, $index, $project, $projectId, $events); + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); } - - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId); } /** @@ -431,6 +436,7 @@ class Databases extends Action * @throws Conflict * @throws Structure * @throws DatabaseException + * @throws \Throwable */ private function deleteIndex(Document $database, Document $collection, Document $index, Document $project, Database $dbForConsole, Database $dbForProject): void { @@ -459,7 +465,6 @@ class Databases extends Action $dbForProject->deleteDocument('indexes', $index->getId()); $index->setAttribute('status', 'deleted'); } catch (\Throwable $e) { - // TODO: Send non DatabaseExceptions to Sentry Console::error($e->getMessage()); if ($e instanceof DatabaseException) { @@ -470,11 +475,13 @@ class Databases extends Action $index->getId(), $index->setAttribute('status', 'stuck') ); + + throw $e; + } finally { $this->trigger($database, $collection, $index, $project, $projectId, $events); + $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collection->getId()); } - - $dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collection->getId()); } /** diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index 7e548f57be..72a3334f2f 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -41,29 +41,18 @@ class Functions extends Action $this ->desc('Functions worker') ->groups(['functions']) + ->inject('project') ->inject('message') ->inject('dbForProject') ->inject('queueForFunctions') ->inject('queueForEvents') ->inject('queueForUsage') ->inject('log') - ->callback(fn (Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log) => $this->action($message, $dbForProject, $queueForFunctions, $queueForEvents, $queueForUsage, $log)); + ->inject('isResourceBlocked') + ->callback(fn (Document $project, Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log, callable $isResourceBlocked) => $this->action($project, $message, $dbForProject, $queueForFunctions, $queueForEvents, $queueForUsage, $log, $isResourceBlocked)); } - /** - * @param Message $message - * @param Database $dbForProject - * @param Func $queueForFunctions - * @param Event $queueForEvents - * @param Usage $queueForUsage - * @param Log $log - * @return void - * @throws Authorization - * @throws Structure - * @throws \Utopia\Database\Exception - * @throws Conflict - */ - public function action(Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log): void + public function action(Document $project, Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log, callable $isResourceBlocked): void { $payload = $message->getPayload() ?? []; @@ -73,17 +62,16 @@ class Functions extends Action $type = $payload['type'] ?? ''; - // Short-term solution to offhand write operation from API contianer + // Short-term solution to offhand write operation from API container if ($type === Func::TYPE_ASYNC_WRITE) { $execution = new Document($payload['execution'] ?? []); - $execution = $dbForProject->createDocument('executions', $execution); + $dbForProject->createDocument('executions', $execution); return; } $events = $payload['events'] ?? []; $data = $payload['body'] ?? ''; $eventData = $payload['payload'] ?? ''; - $project = new Document($payload['project'] ?? []); $function = new Document($payload['function'] ?? []); $functionId = $payload['functionId'] ?? ''; $user = new Document($payload['user'] ?? []); @@ -121,7 +109,6 @@ class Functions extends Action $limit = 30; $sum = 30; $offset = 0; - /** @var Document[] $functions */ while ($sum >= $limit) { $functions = $dbForProject->find('functions', [ Query::limit($limit), @@ -138,6 +125,12 @@ class Functions extends Action if (!array_intersect($events, $function->getAttribute('events', []))) { continue; } + + if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $function->getId())) { + Console::log('Function ' . $function->getId() . ' is blocked, skipping execution.'); + continue; + } + Console::success('Iterating function: ' . $function->getAttribute('name')); $this->execute( @@ -168,6 +161,11 @@ class Functions extends Action return; } + if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $function->getId())) { + Console::log('Function ' . $function->getId() . ' is blocked, skipping execution.'); + return; + } + /** * Handle Schedule and HTTP execution. */ diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 510fec0431..58f6265ff4 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -178,7 +178,7 @@ class Messaging extends Action Query::equal('type', [$providerType]), ]); - if ($default === false || $default->isEmpty()) { + if ($default->isEmpty()) { $dbForProject->updateDocument('messages', $message->getId(), $message->setAttributes([ 'status' => MessageStatus::FAILED, 'deliveryErrors' => ['No enabled provider found.'] diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index beff0b064b..4b1926ed26 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -124,7 +124,7 @@ class Migrations extends Action ), SourceAppwrite::getName() => new SourceAppwrite( $credentials['projectId'], - $credentials['endpoint'], + $credentials['endpoint'] === 'http://localhost/v1' ? 'http://appwrite/v1' : $credentials['endpoint'], $credentials['apiKey'], ), default => throw new \Exception('Invalid source type'), @@ -134,16 +134,15 @@ class Migrations extends Action /** * @throws Exception */ - protected function processDestination(Document $migration): Destination + protected function processDestination(Document $migration, string $apiKey): Destination { $destination = $migration->getAttribute('destination'); - $credentials = $migration->getAttribute('credentials'); return match ($destination) { DestinationAppwrite::getName() => new DestinationAppwrite( - $credentials['projectId'], - $credentials['endpoint'], - $credentials['apiKey'], + $this->project->getId(), + 'http://appwrite/v1', + $apiKey, $this->dbForProject, Config::getParam('collections', [])['databases']['collections'], ), @@ -269,11 +268,9 @@ class Migrations extends Action $transfer = $source = $destination = null; try { - $migration = $this->dbForProject->getDocument('migrations', $migration->getId()); - if ( - $migration->getAttribute('source') === SourceAppwrite::getName() || - $migration->getAttribute('destination') === DestinationAppwrite::getName() + $migration->getAttribute('source') === SourceAppwrite::getName() && + empty($migration->getAttribute('credentials', [])) ) { $credentials = $migration->getAttribute('credentials', []); @@ -291,7 +288,7 @@ class Migrations extends Action $log->addTag('type', $migration->getAttribute('source')); $source = $this->processSource($migration); - $destination = $this->processDestination($migration); + $destination = $this->processDestination($migration, $tempAPIKey->getAttribute('secret')); $source->report(); diff --git a/src/Appwrite/PubSub/Adapter.php b/src/Appwrite/PubSub/Adapter.php new file mode 100644 index 0000000000..e5ddbe5e62 --- /dev/null +++ b/src/Appwrite/PubSub/Adapter.php @@ -0,0 +1,13 @@ +client = $client; + + } + + public function ping($message = null): bool + { + return $this->client->ping($message); + } + + public function subscribe($channels, $callback) + { + return $this->client->subscribe($channels, $callback); + } + + public function publish($channel, $message) + { + return $this->client->publish($channel, $message); + } +} diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Migrations.php b/src/Appwrite/Utopia/Database/Validator/Queries/Migrations.php index 6b9e9e6d32..436a95534b 100644 --- a/src/Appwrite/Utopia/Database/Validator/Queries/Migrations.php +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Migrations.php @@ -8,6 +8,7 @@ class Migrations extends Base 'status', 'stage', 'source', + 'destination', 'resources', 'statusCounters', 'resourceData', diff --git a/src/Appwrite/Utopia/Response/Model/Membership.php b/src/Appwrite/Utopia/Response/Model/Membership.php index 64283bd4a8..46153842bc 100644 --- a/src/Appwrite/Utopia/Response/Model/Membership.php +++ b/src/Appwrite/Utopia/Response/Model/Membership.php @@ -36,13 +36,13 @@ class Membership extends Model ]) ->addRule('userName', [ 'type' => self::TYPE_STRING, - 'description' => 'User name.', + 'description' => 'User name. Hide this attribute by toggling membership privacy in the Console.', 'default' => '', 'example' => 'John Doe', ]) ->addRule('userEmail', [ 'type' => self::TYPE_STRING, - 'description' => 'User email address.', + 'description' => 'User email address. Hide this attribute by toggling membership privacy in the Console.', 'default' => '', 'example' => 'john@appwrite.io', ]) @@ -78,7 +78,7 @@ class Membership extends Model ]) ->addRule('mfa', [ 'type' => self::TYPE_BOOLEAN, - 'description' => 'Multi factor authentication status, true if the user has MFA enabled or false otherwise.', + 'description' => 'Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.', 'default' => false, 'example' => false, ]) diff --git a/src/Appwrite/Utopia/Response/Model/Migration.php b/src/Appwrite/Utopia/Response/Model/Migration.php index bb13c2cb04..f70dc37027 100644 --- a/src/Appwrite/Utopia/Response/Model/Migration.php +++ b/src/Appwrite/Utopia/Response/Model/Migration.php @@ -46,9 +46,15 @@ class Migration extends Model 'default' => '', 'example' => 'Appwrite', ]) + ->addRule('destination', [ + 'type' => self::TYPE_STRING, + 'description' => 'A string containing the type of destination of the migration.', + 'default' => 'Appwrite', + 'example' => 'Appwrite', + ]) ->addRule('resources', [ 'type' => self::TYPE_STRING, - 'description' => 'Resources to migration.', + 'description' => 'Resources to migrate.', 'default' => [], 'example' => ['user'], 'array' => true diff --git a/src/Appwrite/Utopia/Response/Model/Project.php b/src/Appwrite/Utopia/Response/Model/Project.php index e1d0105587..6e01baee84 100644 --- a/src/Appwrite/Utopia/Response/Model/Project.php +++ b/src/Appwrite/Utopia/Response/Model/Project.php @@ -151,6 +151,24 @@ class Project extends Model 'default' => false, 'example' => true, ]) + ->addRule('authMembershipsUserName', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Whether or not to show user names in the teams membership response.', + 'default' => false, + 'example' => true, + ]) + ->addRule('authMembershipsUserEmail', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Whether or not to show user emails in the teams membership response.', + 'default' => false, + 'example' => true, + ]) + ->addRule('authMembershipsMfa', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Whether or not to show user MFA status in the teams membership response.', + 'default' => false, + 'example' => true, + ]) ->addRule('oAuthProviders', [ 'type' => Response::MODEL_AUTH_PROVIDER, 'description' => 'List of Auth Providers.', @@ -348,6 +366,9 @@ class Project extends Model $document->setAttribute('authPersonalDataCheck', $authValues['personalDataCheck'] ?? false); $document->setAttribute('authMockNumbers', $authValues['mockNumbers'] ?? []); $document->setAttribute('authSessionAlerts', $authValues['sessionAlerts'] ?? false); + $document->setAttribute('authMembershipsUserName', $authValues['membershipsUserName'] ?? true); + $document->setAttribute('authMembershipsUserEmail', $authValues['membershipsUserEmail'] ?? true); + $document->setAttribute('authMembershipsMfa', $authValues['membershipsMfa'] ?? true); foreach ($auth as $index => $method) { $key = $method['key']; diff --git a/src/Appwrite/Utopia/Response/Model/Target.php b/src/Appwrite/Utopia/Response/Model/Target.php index d180b6c4c4..530749e006 100644 --- a/src/Appwrite/Utopia/Response/Model/Target.php +++ b/src/Appwrite/Utopia/Response/Model/Target.php @@ -32,7 +32,7 @@ class Target extends Model 'type' => self::TYPE_STRING, 'description' => 'Target Name.', 'default' => '', - 'example' => 'Aegon apple token', + 'example' => 'Apple iPhone 12', ]) ->addRule('userId', [ 'type' => self::TYPE_STRING, @@ -58,6 +58,12 @@ class Target extends Model 'description' => 'The target identifier.', 'default' => '', 'example' => 'token', + ]) + ->addRule('expired', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Is the target expired.', + 'default' => false, + 'example' => false, ]); } diff --git a/tests/e2e/Client.php b/tests/e2e/Client.php index 0774f1c6fd..dc80808b14 100644 --- a/tests/e2e/Client.php +++ b/tests/e2e/Client.php @@ -179,9 +179,14 @@ class Client default => http_build_query($params), }; - foreach ($headers as $i => $header) { - $headers[] = $i . ':' . $header; - unset($headers[$i]); + $formattedHeaders = []; + foreach ($headers as $key => $value) { + if (strtolower($key) === 'accept-encoding') { + curl_setopt($ch, CURLOPT_ENCODING, $value); + continue; + } else { + $formattedHeaders[] = $key . ': ' . $value; + } } curl_setopt($ch, CURLOPT_PATH_AS_IS, 1); @@ -189,7 +194,7 @@ class Client curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_HTTPHEADER, $formattedHeaders); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); curl_setopt($ch, CURLOPT_TIMEOUT, 15); curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders, &$cookies) { @@ -220,7 +225,6 @@ class Client curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } - $responseBody = curl_exec($ch); $responseType = $responseHeaders['content-type'] ?? ''; $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); diff --git a/tests/e2e/General/CompressionTest.php b/tests/e2e/General/CompressionTest.php new file mode 100644 index 0000000000..9affacfe0a --- /dev/null +++ b/tests/e2e/General/CompressionTest.php @@ -0,0 +1,137 @@ +client->call(Client::METHOD_GET, '/ping', [ + 'accept-encoding' => 'gzip', + 'x-appwrite-project' => $this->getProject()['$id'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Pong!', $response['body']); + $this->assertLessThan(1024, strlen($response['body'])); + $this->assertArrayNotHasKey('content-encoding', $response['headers']); + + // without header + $response = $this->client->call(Client::METHOD_GET, '/ping', [ + 'x-appwrite-project' => $this->getProject()['$id'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Pong!', $response['body']); + $this->assertLessThan(1024, strlen($response['body'])); + $this->assertArrayNotHasKey('content-encoding', $response['headers']); + } + + public function testLargeResponse() + { + // create an anonymous user + $response = $this->client->call(Client::METHOD_POST, '/users', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + ], $this->getHeaders()), [ + 'userId' => ID::unique(), + 'email' => 'test@localhost.test', + 'password' => 'password', + 'name' => 'User Name', + ]); + $this->assertEquals(201, $response['headers']['status-code']); + $userId = $response['body']['$id']; + + // set prefs with 2000 bytes of data + $prefs = ["longValue" => str_repeat('a', 2000)]; + + $response = $this->client->call(Client::METHOD_PATCH, '/users/' . $userId . '/prefs', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + 'content-type' => 'application/json', + ], $this->getHeaders()), [ + 'prefs' => $prefs, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // get prefs with compression + $response = $this->client->call(Client::METHOD_GET, '/users/' . $userId . '/prefs', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + 'accept-encoding' => 'gzip', + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertArrayHasKey('content-encoding', $response['headers'], 'Content encoding should be gzip, headers received: ' . json_encode($response['headers'], JSON_PRETTY_PRINT)); + $this->assertLessThan(2000, intval($response['headers']['content-length'])); + + // get prefs without compression + $response = $this->client->call(Client::METHOD_GET, '/users/' . $userId . '/prefs', array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertGreaterThanOrEqual(2000, intval($response['headers']['content-length'])); + $this->assertArrayNotHasKey('content-encoding', $response['headers']); + } + + public function testImageResponse() + { + // create bucket + $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket', + 'fileSecurity' => true, + ]); + $bucketId = $bucket['body']['$id']; + $this->assertEquals(201, $bucket['headers']['status-code']); + + // upload image + $file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../resources/logo.png'), 'image/png', 'logo.png'), + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + $fileId = $file['body']['$id']; + + // get image with header + $response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId, array_merge([ + 'content-type' => 'application/json', + 'accept-encoding' => 'gzip', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertArrayNotHasKey('content-encoding', $response['headers']); + // get image without + $response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertArrayNotHasKey('content-encoding', $response['headers']); + } +} diff --git a/tests/e2e/Scopes/ProjectCustom.php b/tests/e2e/Scopes/ProjectCustom.php index ad2c93790c..7f84ace6f2 100644 --- a/tests/e2e/Scopes/ProjectCustom.php +++ b/tests/e2e/Scopes/ProjectCustom.php @@ -94,6 +94,8 @@ trait ProjectCustom 'topics.read', 'subscribers.write', 'subscribers.read', + 'migrations.write', + 'migrations.read' ], ]); diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 244f84b161..cca27cc3be 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -2695,4 +2695,45 @@ class AccountCustomClientTest extends Scope return $data; } + + public function testCreatePushTarget(): void + { + $response = $this->client->call(Client::METHOD_POST, '/account/targets/push', \array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'] + ], $this->getHeaders()), [ + 'targetId' => ID::unique(), + 'identifier' => 'test-identifier', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('test-identifier', $response['body']['identifier']); + } + + public function testUpdatePushTarget(): void + { + $response = $this->client->call(Client::METHOD_POST, '/account/targets/push', \array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'targetId' => ID::unique(), + 'identifier' => 'test-identifier-2', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('test-identifier-2', $response['body']['identifier']); + + $response = $this->client->call(Client::METHOD_PUT, '/account/targets/'. $response['body']['$id'] .'/push', \array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'identifier' => 'test-identifier-updated', + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('test-identifier-updated', $response['body']['identifier']); + $this->assertEquals(false, $response['body']['expired']); + } } diff --git a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php index b1315103b1..4f4b0c960d 100644 --- a/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php +++ b/tests/e2e/Services/FunctionsSchedule/FunctionsScheduleTest.php @@ -1,12 +1,13 @@ assertEquals(200, $response['headers']['status-code']); $this->assertEquals('/CN=www.google.com', $response['body']['name']); $this->assertEquals('www.google.com', $response['body']['subjectSN']); - $this->assertStringContainsString('Google Trust Services', $response['body']['issuerOrganisation']); + $this->assertContains($response['body']['issuerOrganisation'], ['Let\'s Encrypt', 'Google Trust Services']); $this->assertIsInt($response['body']['validFrom']); $this->assertIsInt($response['body']['validTo']); @@ -467,7 +467,7 @@ class HealthCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('/CN=appwrite.io', $response['body']['name']); $this->assertEquals('appwrite.io', $response['body']['subjectSN']); - $this->assertEquals("Let's Encrypt", $response['body']['issuerOrganisation']); + $this->assertContains($response['body']['issuerOrganisation'], ['Let\'s Encrypt', 'Google Trust Services']); $this->assertIsInt($response['body']['validFrom']); $this->assertIsInt($response['body']['validTo']); diff --git a/tests/e2e/Services/Migrations/MigrationsBase.php b/tests/e2e/Services/Migrations/MigrationsBase.php new file mode 100644 index 0000000000..e4c7ba7712 --- /dev/null +++ b/tests/e2e/Services/Migrations/MigrationsBase.php @@ -0,0 +1,895 @@ +getProject(true); + self::$project = $projectBackup; + + return self::$destinationProject; + } + + public function performMigrationSync( + array $body, + ): array { + $migration = $this->client->call(Client::METHOD_POST, '/migrations/appwrite', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ], $body); + + $this->assertEquals(202, $migration['headers']['status-code']); + $this->assertNotEmpty($migration['body']); + $this->assertNotEmpty($migration['body']['$id']); + + $attempts = 0; + while ($attempts < 5) { + $response = $this->client->call(Client::METHOD_GET, '/migrations/' . $migration['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + if ($response['body']['status'] === 'failed') { + $this->fail('Migration failed', json_encode($response['body'], JSON_PRETTY_PRINT)); + } + + $this->assertNotEquals('failed', $response['body']['status']); + + if ($response['body']['status'] === 'completed') { + return $response['body']; + } + + if ($attempts === 4) { + $this->assertEquals('completed', $response['body']['status']); + } + + $attempts++; + sleep(5); + } + } + + /** + * Appwrite E2E Migration Tests + */ + public function testCreateAppwriteMigration() + { + $response = $this->performMigrationSync([ + 'resources' => Appwrite::getSupportedResources(), + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals(Appwrite::getSupportedResources(), $response['resources']); + $this->assertEquals('Appwrite', $response['source']); + $this->assertEquals('Appwrite', $response['destination']); + $this->assertEmpty($response['statusCounters']); + } + + /** + * Auth + */ + public function testAppwriteMigrationAuthUserPassword() + { + $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' => ID::unique(), + 'email' => 'test@test.com', + 'password' => 'password', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('test@test.com', $response['body']['email']); + + $user = $response['body']; + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_USER, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_USER], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals($user['email'], $response['body']['email']); + $this->assertEquals($user['password'], $response['body']['password']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + } + + public function testAppwriteMigrationAuthUserPhone() + { + $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' => ID::unique(), + 'phone' => '+12065550100', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals('+12065550100', $response['body']['phone']); + + $user = $response['body']; + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_USER, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_USER], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals($user['phone'], $response['body']['phone']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + } + + public function testAppwriteMigrationAuthTeam() + { + $user = $this->client->call(Client::METHOD_POST, '/users', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'userId' => ID::unique(), + 'email' => 'test@test.com', + 'password' => 'password', + ]); + + $this->assertEquals(201, $user['headers']['status-code']); + $this->assertNotEmpty($user['body']); + $this->assertNotEmpty($user['body']['$id']); + $this->assertEquals('test@test.com', $user['body']['email']); + + $team = $this->client->call(Client::METHOD_POST, '/teams', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'teamId' => ID::unique(), + 'name' => 'Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + $this->assertNotEmpty($team['body']); + $this->assertNotEmpty($team['body']['$id']); + + $membership = $this->client->call(Client::METHOD_POST, '/teams/' . $team['body']['$id'] . '/memberships', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'teamId' => $team['body']['$id'], + 'userId' => $user['body']['$id'], + 'roles' => ['owner'], + ]); + + $this->assertEquals(201, $membership['headers']['status-code']); + $this->assertNotEmpty($membership['body']); + $this->assertNotEmpty($membership['body']['$id']); + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_USER, + Resource::TYPE_TEAM, + Resource::TYPE_MEMBERSHIP, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_USER, Resource::TYPE_TEAM, Resource::TYPE_MEMBERSHIP], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_USER, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_USER]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_USER]['warning']); + + $this->assertArrayHasKey(Resource::TYPE_TEAM, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_TEAM]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_TEAM]['warning']); + + $this->assertArrayHasKey(Resource::TYPE_MEMBERSHIP, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_MEMBERSHIP]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $team['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals($team['body']['name'], $response['body']['name']); + + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $team['body']['$id'] . '/memberships', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + + $membership = $response['body']['memberships'][0]; + + $this->assertEquals($user['body']['$id'], $membership['userId']); + $this->assertEquals($team['body']['$id'], $membership['teamId']); + $this->assertEquals(['owner'], $membership['roles']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/users/' . $user['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/teams/' . $team['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + } + + /** + * Databases + */ + public function testAppwriteMigrationDatabase() + { + $response = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Test Database' + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + $databaseId = $response['body']['$id']; + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_DATABASE, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_DATABASE], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_DATABASE, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DATABASE]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + $this->assertEquals($databaseId, $response['body']['$id']); + $this->assertEquals('Test Database', $response['body']['name']); + + // Cleanup on destination + $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + return [ + 'databaseId' => $databaseId, + ]; + } + + /** + * @depends testAppwriteMigrationDatabase + */ + public function testAppwriteMigrationDatabasesCollection(array $data) + { + $databaseId = $data['databaseId']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'collectionId' => ID::unique(), + 'name' => 'Test Collection', + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $collectionId = $collection['body']['$id']; + + // Create Attribute + $response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'key' => 'name', + 'size' => 100, + 'encrypt' => false, + 'required' => true + ]); + + $this->assertEquals(202, $response['headers']['status-code']); + + // Wait for attribute to be ready + $this->assertEventually(function () use ($databaseId, $collectionId) { + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/name', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('available', $response['body']['status']); + }, 5000, 500); + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_DATABASE, + Resource::TYPE_COLLECTION, + Resource::TYPE_ATTRIBUTE, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE], $result['resources']); + + foreach ([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE] as $resource) { + $this->assertArrayHasKey($resource, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][$resource]['error']); + $this->assertEquals(0, $result['statusCounters'][$resource]['pending']); + $this->assertEquals(1, $result['statusCounters'][$resource]['success']); + $this->assertEquals(0, $result['statusCounters'][$resource]['processing']); + $this->assertEquals(0, $result['statusCounters'][$resource]['warning']); + } + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + + $this->assertEquals($collectionId, $response['body']['$id']); + $this->assertEquals('Test Collection', $response['body']['name']); + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/name', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + + $this->assertEquals('name', $response['body']['key']); + $this->assertEquals(100, $response['body']['size']); + $this->assertEquals(true, $response['body']['required']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + return [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + ]; + } + + /** + * @depends testAppwriteMigrationDatabasesCollection + */ + public function testAppwriteMigrationDatabasesDocument(array $data) + { + $databaseId = $data['databaseId']; + $collectionId = $data['collectionId']; + + $document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'documentId' => ID::unique(), + 'data' => [ + 'name' => 'Test Document', + ] + ]); + + $this->assertEquals(201, $document['headers']['status-code']); + $this->assertNotEmpty($document['body']); + $this->assertNotEmpty($document['body']['$id']); + + $documentId = $document['body']['$id']; + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_DATABASE, + Resource::TYPE_COLLECTION, + Resource::TYPE_ATTRIBUTE, + Resource::TYPE_DOCUMENT, + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE, Resource::TYPE_DOCUMENT], $result['resources']); + + //TODO: Add TYPE_DOCUMENT to the migration status counters once pending issue is resolved + foreach ([Resource::TYPE_DATABASE, Resource::TYPE_COLLECTION, Resource::TYPE_ATTRIBUTE] as $resource) { + $this->assertArrayHasKey($resource, $result['statusCounters']); + $this->assertEquals(0, $result['statusCounters'][$resource]['error']); + $this->assertEquals(0, $result['statusCounters'][$resource]['pending']); + $this->assertEquals(1, $result['statusCounters'][$resource]['success']); + $this->assertEquals(0, $result['statusCounters'][$resource]['processing']); + $this->assertEquals(0, $result['statusCounters'][$resource]['warning']); + } + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents/' . $documentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + + $this->assertEquals($documentId, $response['body']['$id']); + $this->assertEquals('Test Document', $response['body']['name']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + } + + /** + * Storage + */ + public function testAppwriteMigrationStorageBucket() + { + $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'maximumFileSize' => 1000000, + 'allowedFileExtensions' => ['pdf'], + 'compression' => 'gzip', + 'encryption' => false, + 'antivirus' => false + ]); + + $this->assertEquals(201, $bucket['headers']['status-code']); + $this->assertNotEmpty($bucket['body']); + $this->assertNotEmpty($bucket['body']['$id']); + $this->assertEquals('Test Bucket', $bucket['body']['name']); + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_BUCKET + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_BUCKET], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_BUCKET, $result['statusCounters']); + + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_BUCKET]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucket['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + $this->assertEquals($bucket['body']['$id'], $response['body']['$id']); + $this->assertEquals($bucket['body']['name'], $response['body']['name']); + $this->assertEquals($bucket['body']['$permissions'], $response['body']['$permissions']); + $this->assertEquals($bucket['body']['maximumFileSize'], $response['body']['maximumFileSize']); + $this->assertEquals($bucket['body']['allowedFileExtensions'], $response['body']['allowedFileExtensions']); + $this->assertEquals($bucket['body']['compression'], $response['body']['compression']); + $this->assertEquals($bucket['body']['encryption'], $response['body']['encryption']); + $this->assertEquals($bucket['body']['antivirus'], $response['body']['antivirus']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucket['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucket['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + } + + public function testAppwriteMigrationStorageFiles() + { + $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket', + 'fileSecurity' => true, + 'maximumFileSize' => 2000000, //2MB + 'allowedFileExtensions' => ['jpg', 'png', 'jfif'], + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + $this->assertEquals(201, $bucket['headers']['status-code']); + $this->assertNotEmpty($bucket['body']['$id']); + + $bucketId = $bucket['body']['$id']; + + $file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], [ + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $file['headers']['status-code']); + $this->assertNotEmpty($file['body']['$id']); + + $fileId = $file['body']['$id']; + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_BUCKET, + Resource::TYPE_FILE + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_BUCKET, Resource::TYPE_FILE], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_BUCKET, $result['statusCounters']); + + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_BUCKET]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_BUCKET]['warning']); + + $this->assertArrayHasKey(Resource::TYPE_FILE, $result['statusCounters']); + + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_FILE]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FILE]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + $this->assertEquals($fileId, $response['body']['$id']); + + // Cleanup + $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->client->call(Client::METHOD_DELETE, '/storage/buckets/' . $bucketId . '/files/' . $fileId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + } + + /** + * Functions + */ + public function testAppwriteMigrationFunction() + { + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php' + ]); + + $deploymentId = $this->setupDeployment($functionId, [ + 'entrypoint' => 'index.php', + 'code' => $this->packageFunction('php'), + 'activate' => true + ]); + + $result = $this->performMigrationSync([ + 'resources' => [ + Resource::TYPE_FUNCTION, + Resource::TYPE_DEPLOYMENT + ], + 'endpoint' => 'http://localhost/v1', + 'projectId' => $this->getProject()['$id'], + 'apiKey' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals('completed', $result['status']); + $this->assertEquals([Resource::TYPE_FUNCTION, Resource::TYPE_DEPLOYMENT], $result['resources']); + $this->assertArrayHasKey(Resource::TYPE_FUNCTION, $result['statusCounters']); + + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_FUNCTION]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_FUNCTION]['warning']); + + $this->assertArrayHasKey(Resource::TYPE_DEPLOYMENT, $result['statusCounters']); + + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['error']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['pending']); + $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['success']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['processing']); + $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DEPLOYMENT]['warning']); + + $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']); + $this->assertNotEmpty($response['body']['$id']); + + $this->assertEquals($functionId, $response['body']['$id']); + $this->assertEquals('Test', $response['body']['name']); + $this->assertEquals('php-8.0', $response['body']['runtime']); + $this->assertEquals('index.php', $response['body']['entrypoint']); + + + $this->assertEventually(function () use ($functionId) { + $deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ])); + + $this->assertEquals(200, $deployments['headers']['status-code']); + $this->assertNotEmpty($deployments['body']); + $this->assertEquals(1, $deployments['body']['total']); + + $this->assertEquals('ready', $deployments['body']['deployments'][0]['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployments['body']['deployments'][0], JSON_PRETTY_PRINT)); + }, 50000, 500); + + // Attempt execution + $execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ], [ + 'body' => 'test' + ]); + + $this->assertEquals(201, $execution['headers']['status-code']); + $this->assertStringContainsString('body-is-test', $execution['body']['logs']); + + // Cleanup + $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->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getDesintationProject()['$id'], + 'x-appwrite-key' => $this->getDesintationProject()['apiKey'], + ]); + } +} diff --git a/tests/e2e/Services/Migrations/MigrationsConsoleClientTest.php b/tests/e2e/Services/Migrations/MigrationsConsoleClientTest.php new file mode 100644 index 0000000000..2167ef9338 --- /dev/null +++ b/tests/e2e/Services/Migrations/MigrationsConsoleClientTest.php @@ -0,0 +1,12 @@ +close(); } + public function testPingPong() + { + $client = $this->getWebsocket(['files'], [ + 'origin' => 'http://localhost' + ]); + $response = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $response); + $this->assertArrayHasKey('data', $response); + $this->assertEquals('connected', $response['type']); + $this->assertNotEmpty($response['data']); + $this->assertCount(1, $response['data']['channels']); + $this->assertContains('files', $response['data']['channels']); + + $client->send(\json_encode([ + 'type' => 'ping' + ])); + + $response = json_decode($client->receive(), true); + $this->assertEquals('pong', $response['type']); + + $client->close(); + } + public function testManualAuthentication() { $user = $this->getUser(); diff --git a/tests/e2e/Services/Teams/TeamsBaseClient.php b/tests/e2e/Services/Teams/TeamsBaseClient.php index 8a1fed028e..9188575932 100644 --- a/tests/e2e/Services/Teams/TeamsBaseClient.php +++ b/tests/e2e/Services/Teams/TeamsBaseClient.php @@ -30,8 +30,8 @@ trait TeamsBaseClient $this->assertIsInt($response['body']['total']); $this->assertNotEmpty($response['body']['memberships'][0]['$id']); $this->assertFalse($response['body']['memberships'][0]['mfa']); - $this->assertEquals($this->getUser()['name'], $response['body']['memberships'][0]['userName']); - $this->assertEquals($this->getUser()['email'], $response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('userName', $response['body']['memberships'][0]); + $this->assertArrayHasKey('userEmail', $response['body']['memberships'][0]); $this->assertEquals($teamName, $response['body']['memberships'][0]['teamName']); $this->assertContains('owner', $response['body']['memberships'][0]['roles']); $this->assertContains('player', $response['body']['memberships'][0]['roles']); @@ -96,8 +96,8 @@ trait TeamsBaseClient $this->assertEquals(200, $response['headers']['status-code']); $this->assertIsInt($response['body']['total']); $this->assertNotEmpty($response['body']['memberships'][0]); - $this->assertEquals($this->getUser()['name'], $response['body']['memberships'][0]['userName']); - $this->assertEquals($this->getUser()['email'], $response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('userName', $response['body']['memberships'][0]); + $this->assertArrayHasKey('userEmail', $response['body']['memberships'][0]); $this->assertEquals($teamName, $response['body']['memberships'][0]['teamName']); $this->assertContains('owner', $response['body']['memberships'][0]['roles']); $this->assertContains('player', $response['body']['memberships'][0]['roles']); @@ -112,8 +112,8 @@ trait TeamsBaseClient $this->assertEquals(200, $response['headers']['status-code']); $this->assertIsInt($response['body']['total']); $this->assertNotEmpty($response['body']['memberships'][0]); - $this->assertEquals($this->getUser()['name'], $response['body']['memberships'][0]['userName']); - $this->assertEquals($this->getUser()['email'], $response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('userName', $response['body']['memberships'][0]); + $this->assertArrayHasKey('userEmail', $response['body']['memberships'][0]); $this->assertEquals($teamName, $response['body']['memberships'][0]['teamName']); $this->assertContains('owner', $response['body']['memberships'][0]['roles']); $this->assertContains('player', $response['body']['memberships'][0]['roles']); @@ -157,8 +157,8 @@ trait TeamsBaseClient $this->assertNotEmpty($response['body']['$id']); $this->assertFalse($response['body']['mfa']); $this->assertNotEmpty($response['body']['userId']); - $this->assertNotEmpty($response['body']['userName']); - $this->assertNotEmpty($response['body']['userEmail']); + $this->assertArrayHasKey('userName', $response['body']); + $this->assertArrayHasKey('userEmail', $response['body']); $this->assertNotEmpty($response['body']['teamId']); $this->assertNotEmpty($response['body']['teamName']); $this->assertCount(1, $response['body']['roles']); diff --git a/tests/e2e/Services/Teams/TeamsBaseServer.php b/tests/e2e/Services/Teams/TeamsBaseServer.php index 4e9d0839ab..6a1d05e9d4 100644 --- a/tests/e2e/Services/Teams/TeamsBaseServer.php +++ b/tests/e2e/Services/Teams/TeamsBaseServer.php @@ -29,7 +29,7 @@ trait TeamsBaseServer * Test for FAILURE */ - return []; + return $data; } /** @@ -60,6 +60,67 @@ trait TeamsBaseServer $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['joined'])); // is null in DB $this->assertEquals(true, $response['body']['confirm']); + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $this->getProject()['$id'] . '/auth/memberships-privacy', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'userName' => false, + 'userEmail' => false, + 'mfa' => false, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + /** + * Test that sensitive fields are not hidden, as we are on console + */ + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['total']); + $this->assertNotEmpty($response['body']['memberships'][0]['$id']); + + // Assert that sensitive fields are present + $this->assertNotEmpty($response['body']['memberships'][0]['userName']); + $this->assertNotEmpty($response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('mfa', $response['body']['memberships'][0]); + + /** + * Update project settings to show sensitive fields + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $this->getProject()['$id'] . '/auth/memberships-privacy', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'userName' => true, + 'userEmail' => true, + 'mfa' => true, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + /** + * Test that sensitive fields are shown + */ + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['total']); + $this->assertNotEmpty($response['body']['memberships'][0]['$id']); + + // Assert that sensitive fields are present + $this->assertNotEmpty($response['body']['memberships'][0]['userName']); + $this->assertNotEmpty($response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('mfa', $response['body']['memberships'][0]); + /** * Test for FAILURE */ diff --git a/tests/e2e/Services/Teams/TeamsCustomClientTest.php b/tests/e2e/Services/Teams/TeamsCustomClientTest.php index 1de22f743f..03cb1983f1 100644 --- a/tests/e2e/Services/Teams/TeamsCustomClientTest.php +++ b/tests/e2e/Services/Teams/TeamsCustomClientTest.php @@ -14,6 +14,77 @@ class TeamsCustomClientTest extends Scope use ProjectCustom; use SideClient; + /** + * @depends testGetTeamMemberships + */ + public function testGetMembershipPrivacy($data) + { + $teamUid = $data['teamUid'] ?? ''; + + $projectId = $this->getProject()['$id']; + + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/auth/memberships-privacy', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'userName' => false, + 'userEmail' => false, + 'mfa' => false, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + /** + * Test that sensitive fields are hidden + */ + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['total']); + $this->assertNotEmpty($response['body']['memberships'][0]['$id']); + + // Assert that sensitive fields are not present + $this->assertEmpty($response['body']['memberships'][0]['userName']); + $this->assertEmpty($response['body']['memberships'][0]['userEmail']); + $this->assertFalse($response['body']['memberships'][0]['mfa']); + + /** + * Update project settings to show sensitive fields + */ + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $projectId . '/auth/memberships-privacy', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'userName' => true, + 'userEmail' => true, + 'mfa' => true, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + /** + * Test that sensitive fields are shown + */ + $response = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertIsInt($response['body']['total']); + $this->assertNotEmpty($response['body']['memberships'][0]['$id']); + + // Assert that sensitive fields are present + $this->assertNotEmpty($response['body']['memberships'][0]['userName']); + $this->assertNotEmpty($response['body']['memberships'][0]['userEmail']); + $this->assertArrayHasKey('mfa', $response['body']['memberships'][0]); + } + /** * @depends testUpdateTeamMembership */ diff --git a/tests/e2e/Services/Users/UsersBase.php b/tests/e2e/Services/Users/UsersBase.php index d9105e0790..bd0a8ef937 100644 --- a/tests/e2e/Services/Users/UsersBase.php +++ b/tests/e2e/Services/Users/UsersBase.php @@ -1498,6 +1498,7 @@ trait UsersBase ]); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('random-email1@mail.org', $response['body']['identifier']); + $this->assertEquals(false, $response['body']['expired']); return $response['body']; } @@ -1510,6 +1511,7 @@ trait UsersBase 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders())); + $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(3, \count($response['body']['targets'])); } diff --git a/tests/e2e/Services/Webhooks/WebhooksBase.php b/tests/e2e/Services/Webhooks/WebhooksBase.php index 6be3e16c1f..2ef41003ee 100644 --- a/tests/e2e/Services/Webhooks/WebhooksBase.php +++ b/tests/e2e/Services/Webhooks/WebhooksBase.php @@ -901,6 +901,17 @@ trait WebhooksBase $teamId = $data['teamId'] ?? ''; $email = uniqid() . 'friend@localhost.test'; + // Create user to ensure team event is triggered after user event + $user = $this->client->call(Client::METHOD_POST, '/account', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => ID::unique(), + 'email' => $email, + 'password' => 'password', + 'name' => 'Friend User', + ]); + /** * Test for SUCCESS */ @@ -909,7 +920,6 @@ trait WebhooksBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'email' => $email, - 'name' => 'Friend User', 'roles' => ['admin', 'editor'], 'url' => 'http://localhost:5000/join-us#title' ]); diff --git a/tests/resources/docker/docker-compose.yml b/tests/resources/docker/docker-compose.yml index a34b4fcf88..94d506056c 100644 --- a/tests/resources/docker/docker-compose.yml +++ b/tests/resources/docker/docker-compose.yml @@ -62,6 +62,7 @@ services: - redis # - clamav environment: + - _APP_COMPRESSION_MIN_SIZE_BYTES - _APP_ENV - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION diff --git a/tests/unit/Event/EventTest.php b/tests/unit/Event/EventTest.php index dd9833378f..079bb47b65 100644 --- a/tests/unit/Event/EventTest.php +++ b/tests/unit/Event/EventTest.php @@ -3,13 +3,9 @@ namespace Tests\Unit\Event; use Appwrite\Event\Event; -use Appwrite\URL\URL; use InvalidArgumentException; use PHPUnit\Framework\TestCase; -use Utopia\DSN\DSN; -use Utopia\Queue; use Utopia\Queue\Client; -use Utopia\System\System; require_once __DIR__ . '/../../../app/init.php'; @@ -20,19 +16,8 @@ class EventTest extends TestCase public function setUp(): void { - $fallbackForRedis = 'redis_main=' . URL::unparse([ - 'scheme' => 'redis', - 'host' => System::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => System::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => System::getEnv('_APP_REDIS_USER', ''), - 'pass' => System::getEnv('_APP_REDIS_PASS', ''), - ]); - - $dsn = System::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); - $dsn = explode('=', $dsn); - $dsn = $dsn[1] ?? ''; - $dsn = new DSN($dsn); - $connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); + global $register; + $connection = $register->get('pools')->get('queue')->pop()->getResource(); $this->queue = 'v1-tests' . uniqid(); $this->object = new Event($connection); $this->object->setClass('TestsV1'); diff --git a/tests/unit/Usage/StatsTest.php b/tests/unit/Usage/StatsTest.php index 67e39d8974..79fa1f58ec 100644 --- a/tests/unit/Usage/StatsTest.php +++ b/tests/unit/Usage/StatsTest.php @@ -2,13 +2,9 @@ namespace Tests\Unit\Usage; -use Appwrite\URL\URL as AppwriteURL; use PHPUnit\Framework\TestCase; -use Utopia\DSN\DSN; -use Utopia\Queue; use Utopia\Queue\Client; use Utopia\Queue\Connection; -use Utopia\System\System; class StatsTest extends TestCase { @@ -19,18 +15,9 @@ class StatsTest extends TestCase public function setUp(): void { - $env = System::getEnv('_APP_CONNECTIONS_QUEUE', 'redis_main=' . AppwriteURL::unparse([ - 'scheme' => 'redis', - 'host' => System::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => System::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => System::getEnv('_APP_REDIS_USER', ''), - 'pass' => System::getEnv('_APP_REDIS_PASS', ''), - ])); - - $dsn = explode('=', $env); - $dsn = count($dsn) > 1 ? $dsn[1] : $dsn[0]; - $dsn = new DSN($dsn); - $this->connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); + global $register; + $connection = $register->get('pools')->get('queue')->pop()->getResource(); + $this->connection = $connection; $this->client = new Client(self::QUEUE_NAME, $this->connection); }