diff --git a/app/config/auth.php b/app/config/auth.php index ca62256dc2..2330fe75cf 100644 --- a/app/config/auth.php +++ b/app/config/auth.php @@ -17,6 +17,13 @@ return [ 'docs' => 'https://appwrite.io/docs/references/cloud/client-web/account#accountCreateMagicURLToken', 'enabled' => true, ], + 'email-otp' => [ + 'name' => 'Email (OTP)', + 'key' => 'emailOtp', + 'icon' => '/images/users/email.png', + 'docs' => 'https://appwrite.io/docs/references/cloud/client-web/account#accountCreateEmailToken', + 'enabled' => true, + ], 'anonymous' => [ 'name' => 'Anonymous', 'key' => 'anonymous', diff --git a/app/config/collections.php b/app/config/collections.php index 526ed9f954..c4f0208618 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -681,6 +681,17 @@ $commonCollections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('expire'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], ], 'indexes' => [ [ diff --git a/app/config/locale/languages.php b/app/config/locale/languages.php index 6272bd02a6..eeea92e636 100644 --- a/app/config/locale/languages.php +++ b/app/config/locale/languages.php @@ -654,10 +654,15 @@ return [ "nativeName" => "پښتو" ], [ - "code" => "pt", + "code" => "pt-pt", "name" => "Portuguese", "nativeName" => "Português" ], + [ + "code" => "pt-br", + "name" => "Portuguese (Brazilian)", + "nativeName" => "Português" + ], [ "code" => "qu", "name" => "Quechua", @@ -919,9 +924,14 @@ return [ "nativeName" => "Cuengh / Tôô / 壮语" ], [ - "code" => "zh", - "name" => "Chinese", - "nativeName" => "中文" + "code" => "zh-cn", + "name" => "Chinese (Simplified)", + "nativeName" => "中国人" + ], + [ + "code" => "zh-tw", + "name" => "Chinese (Traditional)", + "nativeName" => "中國人" ], [ "code" => "zu", diff --git a/app/config/locale/templates/email-base.tpl b/app/config/locale/templates/email-base.tpl index 07f86f0599..13056fd5ae 100644 --- a/app/config/locale/templates/email-base.tpl +++ b/app/config/locale/templates/email-base.tpl @@ -70,23 +70,67 @@ - -
- - - - -
-

{{subject}}

-
+ + + + + + + + + +
+ + + + +
+ {{body}} +
+
+ + \ No newline at end of file diff --git a/app/config/locale/templates/email-otp.tpl b/app/config/locale/templates/email-otp.tpl new file mode 100644 index 0000000000..84802c1603 --- /dev/null +++ b/app/config/locale/templates/email-otp.tpl @@ -0,0 +1,20 @@ +

{{hello}}

+ +

{{description}}

+ + + + + +
+

{{otp}}

+
+ +

{{clientInfo}}

+ +

{{thanks}}

+

{{signature}}

+ +
+ +

{{securityPhrase}}

\ No newline at end of file diff --git a/app/config/locale/translations/af.json b/app/config/locale/translations/af.json index 6fc662e4a2..aa6938a4c0 100644 --- a/app/config/locale/translations/af.json +++ b/app/config/locale/translations/af.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} span", "sms.verification.body": "{{secret}} is jou {{project}} verifikasiekode.", "emails.magicSession.securityPhrase": "Die sekuriteitsfrase vir hierdie e-pos is {{phrase}}. Jy kan hierdie e-pos vertrou as hierdie frase ooreenstem met die frase wat tydens aanmelding getoon is.", - "emails.magicSession.optionUrl": "As u nie met die knoppie hierbo kan aanmeld nie, besoek asseblief die volgende skakel:" + "emails.magicSession.optionUrl": "As u nie met die knoppie hierbo kan aanmeld nie, besoek asseblief die volgende skakel:", + "emails.otpSession.subject": "{{project}} Aanteken", + "emails.otpSession.hello": "Hallo,", + "emails.otpSession.description": "Voer die volgende verifikasiekode in wanneer daar versoek word om veilig aan te meld by jou {{project}} rekening. Dit sal verval oor 15 minute.", + "emails.otpSession.clientInfo": "Hierdie aanmelding is versoek met behulp van {{agentClient}} op {{agentDevice}} {{agentOs}}. As jy nie die aanmelding versoek het nie, kan jy hierdie e-pos veilig ignoreer.", + "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.json b/app/config/locale/translations/ar.json index 7350e82835..497c73d62a 100644 --- a/app/config/locale/translations/ar.json +++ b/app/config/locale/translations/ar.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "فريق {{project}}", "sms.verification.body": "{{secret}} هو رمز التحقق الخاص بمشروعك {{project}}.", "emails.magicSession.securityPhrase": "عبارة الأمان لهذا البريد الإلكتروني هي {{phrase}}. يمكنك الوثوق بهذا البريد الإلكتروني إذا كانت هذه العبارة تطابق العبارة التي تظهر أثناء التسجيل.", - "emails.magicSession.optionUrl": "إذا لم تتمكن من تسجيل الدخول باستخدام الزر أعلاه، يرجى زيارة الرابط التالي:" + "emails.magicSession.optionUrl": "إذا لم تتمكن من تسجيل الدخول باستخدام الزر أعلاه، يرجى زيارة الرابط التالي:", + "emails.otpSession.subject": "تسجيل دخول {{project}}", + "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/as.json b/app/config/locale/translations/as.json index 0d4998adf3..21369bc613 100644 --- a/app/config/locale/translations/as.json +++ b/app/config/locale/translations/as.json @@ -229,16 +229,23 @@ "continents.na": "উত্তৰ আমেৰিকা", "continents.oc": "ওচেনিয়া", "continents.sa": "দক্ষিণ আমেৰিকা", - "emails.magicSession.optionButton": "Bấm vào nút bên dưới để đăng nhập an toàn vào tài khoản {{project}} của bạn. Nó sẽ hết hạn trong 1 giờ.", - "emails.magicSession.buttonText": "Inngå á {{project}}", - "emails.magicSession.clientInfo": "I'm sorry, but you haven't provided the specific language associated with a country code for translation, and \"as\" doesn't correspond to any current ISO country code. Could you please clarify the target language you want the translation in?", - "emails.certificate.subject": "In the context of your request, it is not entirely clear what the country code \"as\" refers to. However, \"AS\" is often used as the country code for American Samoa, where the primary language is English. If you meant another \"as\" for a specific language, please provide clarification. If you did mean American Samoa, the translation would remain the same as the original text:\n\nCertificate failure for %s", - "emails.certificate.hello": "Since you haven't specified which country \"as\" refers to, I can't provide a translation. If you could provide the name of the country or another form of the country code, that would be very helpful.", - "emails.certificate.body": "Beklagar, men det är inte tillräckligt med information för att avgöra vilket lands specifika språk som avses med landskoden \"as\". \"AS\" kan antingen avse Amerikanska Samoa, vars officiella språk är engelska och samoanska, eller det kan avse en generell landskod. Om du kan ge mer information eller specificera ett land, kan jag ge en exakt översättning.", - "emails.certificate.footer": "Since you haven't specified the target language and only provided the country code \"as,\" which refers to American Samoa, where English and Samoan are the official languages, I will translate it into Samoan:\n\nO lau tusi pasi ua mavae o le a talafeagai mo aso e 30 talu ona tupu le tulaga muamua le manuia. Matou te fautuaina malosi le su'esu'e i lenei mataupu, a leai o le a leai sau vaega e iai se SSL fa'amaoniga talafeagai.", - "emails.certificate.thanks": "The language of the country with the country code \"AS\" which stands for American Samoa is primarily Samoan. The translation of \"Thanks\" in Samoan is:\n\nFa'afetai", - "emails.certificate.signature": "I'm sorry, but to provide a translation into the target language, I need to know the specific language you're referring to with the country code \"as.\" The country code \"AS\" is generally used for American Samoa, where the languages spoken are English and Samoan. If you need a translation into Samoan, please confirm, and I will proceed with the translation.", - "sms.verification.body": "{{secret}} er din {{project}} verifikasjonskode.", - "emails.magicSession.securityPhrase": "I apologize, but it appears there might be a misunderstanding with the country code provided. The country code \"as\" commonly refers to American Samoa, and the languages spoken there are English and Samoan. If translation into Samoan is desired, here it is:\n\nO le upu fa'amau mo lenei imeli o {{phrase}}. E mafai ona e talitonu i lenei imeli pe afai e ōgatusa le upu lea ma le upu na fa'aalia i le taimi o le saini i totonu.", - "emails.magicSession.optionUrl": "There appears to be a misunderstanding. The country code \"as\" is associated with American Samoa, where the primary language is English. Therefore, the translation would remain the same as English:\n\nIf you are unable to sign in using the button above, please visit the following link:" + "emails.magicSession.optionButton": "তলৰ বুটামটো ক্লিক কৰি আপোনাৰ {{project}} একাউণ্টত নিৰাপদে চাইন ইন কৰক। ই এঘণ্টাৰ ভিতৰত অবৈধ হ'ব।", + "emails.magicSession.buttonText": "{{project}}ত প্ৰৱেশ কৰক", + "emails.magicSession.optionUrl": "আপুনি ওপৰত দিয়া বুটাম ব্যৱহাৰ কৰি সাইন ইন কৰিব নোৱাৰিলে, অনুগ্ৰহ কৰি তলৰ লিংকটো ভ্ৰমণ কৰক:", + "emails.magicSession.clientInfo": "এই চাইন ইনটো {{agentClient}} ব্যৱহাৰ কৰি {{agentDevice}} {{agentOs}}ত অনুৰোধ কৰা হৈছিল। আপুনি যদি চাইন ইনৰ অনুৰোধ নকৰা নাই, তেন্তে আপুনি এই ইমেইলখন নিৰাপদে উপেক্ষা কৰিব পাৰে।", + "emails.magicSession.securityPhrase": "এই ইমেইলৰ বাবে নিরাপত্তা বাক্য হৈছে {{phrase}}। যদি এই বাক্যটো সাইন ইন কৰাৰ সময়ত দেখুওৱা বাক্যটোৰ সৈতে মিলে, তেন্তে আপুনি এই ইমেইলটোত বিশ্বাস কৰিব পাৰে।", + "emails.otpSession.subject": "{{project}} লগইন", + "emails.otpSession.hello": "নমস্কাৰ,", + "emails.otpSession.description": "নিৰাপদে আপোনাৰ {{project}} একাউণ্টত চাইন ইন কৰাৰ সময়ত অনুৰোধ কৰা হ'লে তলৰ প্ৰমাণীকৰণ কোডটো প্ৰবেশ কৰক। ই ১৫ মিনিটত অবৈধ হৈ পৰিব।", + "emails.otpSession.clientInfo": "এই চিনাক্তকৰণৰ অনুৰোধ {{agentClient}} ৰ জৰিয়তে {{agentDevice}} {{agentOs}} ত কৰা হৈছিল। আপুনি যদি চিনাক্তকৰণৰ অনুৰোধ কৰা নাই, তেন্তে আপুনি এই ইমেইলটো নিৰাপদে অগ্ৰাহ্য কৰিব পাৰে।", + "emails.otpSession.securityPhrase": "এই ইমেইলৰ সুৰক্ষা বাক্যটো হৈছে {{phrase}}। আপুনি এই ইমেইলটোত আস্থা ৰাখিব পাৰে যদি প্ৰবেশৰ সময়ত দেখুৱাই থকা বাক্যটোৰ লগত এই বাক্যটো মেলে।", + "emails.otpSession.thanks": "ধন্যবাদ,", + "emails.otpSession.signature": "{{project}} দল", + "emails.certificate.subject": "%sৰ বাবে প্ৰমাণপত্ৰ ব্যৰ্থতা", + "emails.certificate.hello": "নমস্কাৰ", + "emails.certificate.body": "আপোনাৰ ডোমেইন '{{domain}}' ৰ বাবে প্ৰমাণপত্ৰটো উত্‌পন্ন কৰিব পৰা নগ'ল। এয়া প্ৰচেষ্টা নম্বৰ {{attempt}}, আৰু বিফলতাৰ কাৰণ হ'ল: {{error}}", + "emails.certificate.footer": "আপোনাৰ পূৰ্বৰ প্ৰমাণপত্ৰটো প্ৰথম ব্ৰিফল হোৱাৰ দিনৰ পৰা ৩০ দিনলৈ বৈধ থাকিব। আমি এই ঘটনাটোৰ তদন্ত কৰিবলৈ উচ্চ পৰামৰ্শ দিয়ে, অন্যথা আপোনাৰ ডোমেইনটো অবৈধ SSL যোগাযোগ অবিহনে থাকিব।", + "emails.certificate.thanks": "ধন্যবাদ", + "emails.certificate.signature": "{{project}} দল", + "sms.verification.body": "{{secret}} আপোনাৰ {{project}} যাচাইকৰণ কোড।" } \ No newline at end of file diff --git a/app/config/locale/translations/az.json b/app/config/locale/translations/az.json index 3a154cf771..177e9f4ae1 100644 --- a/app/config/locale/translations/az.json +++ b/app/config/locale/translations/az.json @@ -240,5 +240,12 @@ "continents.sa": "Cənubi Amerika", "sms.verification.body": "{{secret}} sizin {{project}} təsdiqləmə kodunuzdur.", "emails.magicSession.securityPhrase": "Bu e-poçt üçün 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.magicSession.optionUrl": "Əgər yuxarıdakı düyməni istifadə edərək daxil ola bilmirsizsə, zəhmət olmasa aşağıdakı linkə daxil olun:" + "emails.magicSession.optionUrl": "Əgər yuxarıdakı düyməni istifadə edərək daxil ola bilmirsizsə, zəhmət olmasa aşağıdakı linkə daxil olun:", + "emails.otpSession.subject": "{{project}} Giriş", + "emails.otpSession.hello": "Salam,", + "emails.otpSession.description": "İstifadəçi tələb olunan zaman {{project}} hesabınıza təhlükəsiz daxil olmaq üçün aşağıdakı təsdiqləmə kodunu daxil edin. Bu kod 15 dəqiqə sonra etibarsız olacaq.", + "emails.otpSession.clientInfo": "Bu giriş {{agentClient}} vasitəsilə {{agentDevice}} {{agentOs}} istifadə edərək istənildi. Əgər siz giriş istəməmisinizsə, bu e-poçtu laqeyd qoya bilərsiniz.", + "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 9ae999198f..02772ba1ef 100644 --- a/app/config/locale/translations/be.json +++ b/app/config/locale/translations/be.json @@ -229,16 +229,23 @@ "continents.na": "Паўночная Амерыка", "continents.oc": "Акіянія", "continents.sa": "Паўднёвая Амерыка", - "emails.magicSession.optionButton": "Клікніце кнопку ніжэй, каб бяспечна ўвайсці ў свой рахунак {{project}}. Ён скончыцца праз 1 гадзіну.", - "emails.magicSession.buttonText": "Aanmelden bij {{project}}", - "emails.magicSession.clientInfo": "Als u niet om de aanmelding heeft gevraagd, kunt u deze e-mail gerust negeren.", - "emails.certificate.subject": "The country code BE refers to Belgium, which has three official languages: Dutch, French, and German. Please specify which language you would like the translation in.", - "emails.certificate.hello": "To provide you with the correct translation, I need to clarify the country code \"be\" you mentioned. It might refer to Belgium, which has three official languages: Dutch, French, and German. \n\nPlease specify which language you would like me to translate \"Hello\" into: Dutch, French, or German.", - "emails.certificate.body": "Certificaat voor uw domein '{{domain}}' kon niet worden gegenereerd. Dit is poging nr. {{attempt}}, en de fout werd veroorzaakt door: {{error}}", - "emails.certificate.footer": "Ваш папярэдні сертыфікат будзе дзейнічаць 30 дзён з моманту першай няўдачы. Мы вельмі рэкамендуем разабрацца ў гэтай сітуацыі, інакш ваш дамен застанецца без дзейнага сертыфіката SSL забеспячэння.", - "emails.certificate.thanks": "The country code BE stands for Belgium, where there are two main languages spoken: Dutch and French. Since you did not specify the language, I will provide the translation in both:\n\nDutch: Dank je\nFrench: Merci", - "emails.certificate.signature": "{{project}} équipe", - "sms.verification.body": "{{secret}} ist Ihr Verifizierungscode für {{project}}.", - "emails.magicSession.securityPhrase": "De beveiligingszin voor deze e-mail is {{phrase}}. U kunt deze e-mail vertrouwen als deze zin overeenkomt met de zin die getoond wordt bij het aanmelden.", - "emails.magicSession.optionUrl": "Si vous n'arrivez pas à vous connecter en utilisant le bouton ci-dessus, veuillez visiter le lien suivant :" + "emails.magicSession.optionButton": "Націсніце кнопку ніжэй, каб бяспечна ўвайсці ў свой рахунак {{project}}. Яна спыніць дзеянне праз 1 гадзіну.", + "emails.magicSession.buttonText": "Увайдзіце ў {{project}}", + "emails.magicSession.optionUrl": "Калі ў вас не атрымліваецца ўвайсці, выкарыстоўваючы кнопку вышэй, калі ласка, наведайце наступную спасылку:", + "emails.magicSession.clientInfo": "Гэты ўваход быў запытаны праз {{agentClient}} на {{agentDevice}} {{agentOs}}. Калі вы не запытвалі ўваход, вы можаце бяспечна ігнараваць гэты ліст.", + "emails.magicSession.securityPhrase": "Фраза бяспекі для гэтага ліста - {{phrase}}. Вы можаце давяраць гэтаму лісту, калі гэтая фраза супадае з фразай, якая была паказана пры ўваходзе ў сістэму.", + "emails.otpSession.subject": "{{project}} Уваход", + "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}}", + "emails.certificate.subject": "Сведчанне няўдалае для %s", + "emails.certificate.hello": "Прывітанне", + "emails.certificate.body": "Сертыфікат для вашага дамена '{{domain}}' не можа быць створаны. Гэта спроба нумар {{attempt}}, і прычынай няўдачы з'яўляецца: {{error}}", + "emails.certificate.footer": "Ваш папярэдні сертыфікат будзе дзейнічаць 30 дзён з моманту першай няўдачы. Мы высока рэкамендуем расследаваць гэтую сітуацыю, інакш ваш дамен апынецца без дзейнага сертыфіката SSL-злучэння.", + "emails.certificate.thanks": "Дзякуй", + "emails.certificate.signature": "каманда {{project}}", + "sms.verification.body": "{{secret}} з'яўляецца вашым кодам праверкі для {{project}}." } \ No newline at end of file diff --git a/app/config/locale/translations/bg.json b/app/config/locale/translations/bg.json index 8fd644eea8..fa8efd00e4 100644 --- a/app/config/locale/translations/bg.json +++ b/app/config/locale/translations/bg.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "екип на {{project}}", "sms.verification.body": "{{secret}} е вашият код за верификация за {{project}}.", "emails.magicSession.securityPhrase": "Фразата за сигурност на този имейл е {{phrase}}. Можете да се доверите на този имейл, ако тази фраза съвпада с фразата, показана по време на вписването.", - "emails.magicSession.optionUrl": "Ако не можете да влезете чрез горния бутон, моля, посетете следния линк:" + "emails.magicSession.optionUrl": "Ако не можете да влезете чрез горния бутон, моля, посетете следния линк:", + "emails.otpSession.subject": "Вход в {{project}}", + "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/bh.json b/app/config/locale/translations/bh.json index 6946578869..80cc4b92ff 100644 --- a/app/config/locale/translations/bh.json +++ b/app/config/locale/translations/bh.json @@ -229,16 +229,23 @@ "continents.na": "उत्तरी अमेरिका", "continents.oc": "ओशिनिया", "continents.sa": "दक्षिण अमेरिका", - "emails.magicSession.optionButton": "Klike sou bouton ki pi ba a pou ou konekte an sekirite nan kont {{project}} ou. Li ap ekspire nan 1 è.", - "emails.magicSession.buttonText": "There might be some confusion here, as there is no specific language associated with the country code \"bh,\" which stands for Bahrain. The primary language spoken in Bahrain is Arabic. Assuming you are asking for a translation into Arabic, the translation would be:\n\nتسجيل الدخول إلى {{project}}", - "emails.magicSession.clientInfo": "Sorry, but I cannot provide the translation as \"bh\" is not a recognized ISO language code and does not correspond to any specific language. Please provide a valid language or country code for translation.", - "emails.certificate.subject": "लिए प्रमाणपत्र असफलता %s", - "emails.certificate.hello": "Namaste", - "emails.certificate.body": "Sorry, I am unable to provide the translation as there is no language associated with the country code \"bh.\" \"BH\" is the country code for Bahrain, where the official language is Arabic. Please provide specific instructions for the target language if Arabic translation is required.", - "emails.certificate.footer": "साँचे सर्टिफिकेट 30 दिन तक मान्य होता, पहिलका असफलता के बाद। हमनी के राउर से जोर देके कहतानी कि एह मामला के जांच करीं, ना त राउर डोमेन बिना जायज SSL संवाद के रह जाई.", + "emails.magicSession.optionButton": "नीचा देल बटन पर क्लिक करीं अपना {{project}} खाता में सुरक्षित रूप से साइन इन करे खातिर। ई 1 घंटा में समाप्त हो जाई।", + "emails.magicSession.buttonText": "{{project}} में साइन इन करीं", + "emails.magicSession.optionUrl": "अगर रउआ उपरका बटन से साइन इन ना कर पाईं तs, कृपया निचे दिहल लिंक पर जाई:", + "emails.magicSession.clientInfo": "ई साइन इन अनुरोध किया गेल {{agentClient}} पर {{agentDevice}} {{agentOs}} पर. यदि अहाँ एहि साइन इन के अनुरोध नै कइनी होखी तs अहाँ ई ईमेल के अनदेखा क सकऽ छी.", + "emails.magicSession.securityPhrase": "एह ईमेल खातिर सुरक्षा वाक्य {{phrase}} हऽ। ई ईमेल पर भरोसा करीं जदि ई वाक्य साइन इन करत समय देखावल वाक्य से मिलता हो।", + "emails.otpSession.subject": "प्रोजेक्ट लॉगिन", + "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}} टीम", + "emails.certificate.subject": "%s लेल प्रमाणपत्र असफलта", + "emails.certificate.hello": "नमस्ते", + "emails.certificate.body": "आपके डोमेन '{{domain}}' के लिए प्रमाणपत्र नहीं बनाया जा सका। ई प्रयास संख्या {{attempt}} है, और ई असफलता के कारण रहे: {{error}}", + "emails.certificate.footer": "तोहार पिछलका प्रमाणपत्र पहिल असफलता से 30 दिन धरी मान्य होईत। हम बहुत जोर देके सलाह देतानी कि एह मामला के जांच करीं, नहीं त तोहार डोमेन बिना कोनो मान्य SSL संवाद के रहि जाईत।", "emails.certificate.thanks": "धन्यवाद", - "emails.certificate.signature": "تیم {{project}}", - "sms.verification.body": "{{secret}} هو رمز التحقق الخاص ب{{project}} الخاص بك.", - "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 mostrada durante el inicio de sesión.", - "emails.magicSession.optionUrl": "Yadi aap uppar diye gaye button ka upayog karke sign in nahi kar pa rahe hain, toh kripaya is link ka anusaran karein:" + "emails.certificate.signature": "{{project}} टीम", + "sms.verification.body": "{{secret}} आपके {{project}} सत्यापन कोड हवे।" } \ No newline at end of file diff --git a/app/config/locale/translations/bn.json b/app/config/locale/translations/bn.json index 93d6357420..50c794579a 100644 --- a/app/config/locale/translations/bn.json +++ b/app/config/locale/translations/bn.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} টিম", "sms.verification.body": "{{secret}} আপনার {{project}} যাচাইকরণ কোড।", "emails.magicSession.securityPhrase": "এই ইমেলের জন্য নিরাপত্তা বাক্যটি হল {{phrase}}। সাইন-ইনের সময় দেখানো বাক্যটির সাথে এই বাক্যটি মিলে গেলে আপনি এই ইমেইলকে বিশ্বাস করতে পারেন।", - "emails.magicSession.optionUrl": "উপরের বোতামটি ব্যবহার করে আপনি যদি সাইন ইন করতে অক্ষম হন, অনুগ্রহ করে নিম্নলিখিত লিঙ্কটি দেখুন:" + "emails.magicSession.optionUrl": "উপরের বোতামটি ব্যবহার করে আপনি যদি সাইন ইন করতে অক্ষম হন, অনুগ্রহ করে নিম্নলিখিত লিঙ্কটি দেখুন:", + "emails.otpSession.subject": "{{project}} লগইন", + "emails.otpSession.hello": "নমস্কার,", + "emails.otpSession.description": "নিরাপদে আপনার {{project}} অ্যাকাউন্টে সাইন ইন করার জন্য যখন বলা হবে, তখন নিম্নলিখিত যাচাইকরণ কোডটি প্রবেশ করান। এটি ১৫ মিনিটের মধ্যে মেয়াদোত্তীর্ণ হয়ে যাবে।", + "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/bs.json b/app/config/locale/translations/bs.json index d6c6aeb13d..f200d48b1f 100644 --- a/app/config/locale/translations/bs.json +++ b/app/config/locale/translations/bs.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} tim", "sms.verification.body": "{{secret}} je vaš {{project}} verifikacijski kod.", "emails.magicSession.securityPhrase": "Sigurnosna fraza za ovaj email je {{phrase}}. Ovom emailu možete vjerovati ako se fraza poklapa sa frazom prikazanom prilikom prijave.", - "emails.magicSession.optionUrl": "Ako ne možete da se prijavite koristeći gornje dugme, molimo posetite sledeći link:" + "emails.magicSession.optionUrl": "Ako ne možete da se prijavite koristeći gornje dugme, molimo posetite sledeći link:", + "emails.otpSession.subject": "{{project}} Prijava", + "emails.otpSession.hello": "Zdravo,", + "emails.otpSession.description": "Unesite sljedeći verifikacijski kod kada budete upitani kako biste sigurno pristupili vašem {{project}} računu. Istjeći će za 15 minuta.", + "emails.otpSession.clientInfo": "Ovaj zahtjev za prijavom je poslan koristeći {{agentClient}} na {{agentDevice}} {{agentOs}}. Ako niste zatražili prijavu, možete sigurno ignorisati ovaj email.", + "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 702b6ecb7b..615de9130b 100644 --- a/app/config/locale/translations/ca.json +++ b/app/config/locale/translations/ca.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equip {{project}}", "sms.verification.body": "El {{secret}} és el vostre codi de verificació del {{project}}.", "emails.magicSession.securityPhrase": "La frase de seguretat d'aquest correu electrònic és {{phrase}}. Podeu confiar en aquest correu si aquesta frase coincideix amb la frase mostrada durant l'inici de sessió.", - "emails.magicSession.optionUrl": "Si no podeu iniciar sessió utilitzant el botó de dalt, visiteu l'enllaç següent:" + "emails.magicSession.optionUrl": "Si no podeu iniciar sessió utilitzant el botó de dalt, visiteu l'enllaç següent:", + "emails.otpSession.subject": "Inici de sessió de {{project}}", + "emails.otpSession.hello": "Hola,", + "emails.otpSession.description": "Introduïu el següent codi de verificació quan us ho sol·licitin per iniciar sessió de manera segura al vostre compte {{project}}. Caducarà en 15 minuts.", + "emails.otpSession.clientInfo": "Aquest inici de sessió s'ha sol·licitat utilitzant {{agentClient}} en {{agentDevice}} {{agentOs}}. Si no has sol·licitat l'inici de sessió, pots ignorar aquest correu electrònic sense cap problema.", + "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 ae1a6fc806..139ecb4835 100644 --- a/app/config/locale/translations/cs.json +++ b/app/config/locale/translations/cs.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "tým {{project}}", "sms.verification.body": "{{secret}} je váš ověřovací kód pro {{project}}.", "emails.magicSession.securityPhrase": "Bezpečnostní fráze pro tento e-mail je {{phrase}}. Tomuto e-mailu můžete důvěřovat, pokud tato fráze odpovídá frázi zobrazené při přihlášení.", - "emails.magicSession.optionUrl": "Pokud se nemůžete přihlásit pomocí výše uvedeného tlačítka, prosím navštivte následující odkaz:" + "emails.magicSession.optionUrl": "Pokud se nemůžete přihlásit pomocí výše uvedeného tlačítka, prosím navštivte následující odkaz:", + "emails.otpSession.subject": "{{project}} Přihlášení", + "emails.otpSession.hello": "Ahoj,", + "emails.otpSession.description": "Zadejte následující ověřovací kód, když budete vyzváni, abyste se bezpečně přihlásili ke svému účtu {{project}}. Platnost kódu vyprší za 15 minut.", + "emails.otpSession.clientInfo": "Tento přihlašovací pokus byl proveden pomocí {{agentClient}} na zařízení {{agentDevice}} {{agentOs}}. Pokud jste se nepřihlašovali, tento e-mail můžete bezpečně ignorovat.", + "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 e870cea839..fbbee8cbf0 100644 --- a/app/config/locale/translations/da.json +++ b/app/config/locale/translations/da.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} hold", "sms.verification.body": "{{secret}} er din {{project}} bekræftelseskode.", "emails.magicSession.securityPhrase": "Sikkerhedsfrasen for denne e-mail er {{phrase}}. Du kan stole på denne e-mail, hvis denne frase matcher den viste frase under log ind.", - "emails.magicSession.optionUrl": "Hvis du ikke kan logge ind ved at bruge knappen ovenfor, besøg venligst følgende link:" + "emails.magicSession.optionUrl": "Hvis du ikke kan logge ind ved at bruge knappen ovenfor, besøg venligst følgende link:", + "emails.otpSession.subject": "{{project}} Login", + "emails.otpSession.hello": "Hej,", + "emails.otpSession.description": "Indtast følgende bekræftelseskode, når du bliver bedt om det, for sikkert at logge ind på din {{project}} konto. Den udløber om 15 minutter.", + "emails.otpSession.clientInfo": "Denne indlogning blev anmodet om ved hjælp af {{agentClient}} på {{agentDevice}} {{agentOs}}. Hvis du ikke har anmodet om indlogningen, kan du trygt ignorere denne e-mail.", + "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 86740661a5..73875ce475 100644 --- a/app/config/locale/translations/de.json +++ b/app/config/locale/translations/de.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} Team", "sms.verification.body": "{{secret}} ist Ihr {{project}}-Verifizierungscode.", "emails.magicSession.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 wurde.", - "emails.magicSession.optionUrl": "Wenn Sie sich nicht über den obigen Button anmelden können, besuchen Sie bitte den folgenden Link:" + "emails.magicSession.optionUrl": "Wenn Sie sich nicht über den obigen Button anmelden können, besuchen Sie bitte den folgenden Link:", + "emails.otpSession.subject": "{{project}} Anmeldung", + "emails.otpSession.hello": "Hallo,", + "emails.otpSession.description": "Geben Sie den folgenden Verifizierungscode ein, wenn Sie aufgefordert werden, um sich sicher in Ihrem {{project}} Konto anzumelden. Er verfällt in 15 Minuten.", + "emails.otpSession.clientInfo": "Diese Anmeldung wurde über {{agentClient}} auf {{agentDevice}} {{agentOs}} angefordert. Wenn Sie die Anmeldung nicht angefordert haben, können Sie diese E-Mail getrost ignorieren.", + "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 4bb85a3972..9adb515aef 100644 --- a/app/config/locale/translations/el.json +++ b/app/config/locale/translations/el.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ομάδα του {{project}}", "sms.verification.body": "το {{secret}} είναι ο κωδικός επαλήθευσης του {{project}} σας.", "emails.magicSession.securityPhrase": "Η φράση ασφαλείας για αυτό το email είναι {{phrase}}. Μπορείτε να εμπιστευτείτε αυτό το email αν αυτή η φράση ταιριάζει με τη φράση που εμφανίζεται κατά την είσοδο.", - "emails.magicSession.optionUrl": "Εάν δεν μπορείτε να συνδεθείτε χρησιμοποιώντας το παραπάνω κουμπί, παρακαλώ επισκεφτείτε τον παρακάτω σύνδεσμο:" + "emails.magicSession.optionUrl": "Εάν δεν μπορείτε να συνδεθείτε χρησιμοποιώντας το παραπάνω κουμπί, παρακαλώ επισκεφτείτε τον παρακάτω σύνδεσμο:", + "emails.otpSession.subject": "{{project}} Σύνδεση", + "emails.otpSession.hello": "Γεια σου,", + "emails.otpSession.description": "Εισάγετε τον ακόλουθο κωδικό επαλήθευσης όταν σας ζητηθεί για να συνδεθείτε με ασφάλεια στον λογαριασμό σας {{project}}. Θα λήξει σε 15 λεπτά.", + "emails.otpSession.clientInfo": "Αυτή η είσοδος ζητήθηκε με χρήση {{agentClient}} σε {{agentDevice}} {{agentOs}}. Εάν δεν ζητήσατε την είσοδο, μπορείτε να αγνοήσετε αυτό το email με ασφάλεια.", + "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 8f8c4a5597..530852fd86 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -11,13 +11,20 @@ "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "{{project}} Login", "emails.magicSession.hello": "Hello,", - "emails.magicSession.optionButton": "Click the button below to securely sign in to your {{project}} account. It will expire in 1 hour.", + "emails.magicSession.optionButton": "Click the button below to securely sign in to your {{project}} 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:", "emails.magicSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.", "emails.magicSession.securityPhrase": "Security phrase for this email is {{phrase}}. You can trust this email if this phrase matches the phrase shown during sign in.", "emails.magicSession.thanks": "Thanks,", "emails.magicSession.signature": "{{project}} team", + "emails.otpSession.subject": "OTP for {{project}} Login", + "emails.otpSession.hello": "Hello,", + "emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{project}} account. This code will expire in 15 minutes.", + "emails.otpSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.", + "emails.otpSession.securityPhrase": "Security phrase for this email is {{phrase}}. 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.recovery.subject": "Password Reset", "emails.recovery.hello": "Hello {{user}}", "emails.recovery.body": "Follow this link to reset your {{project}} password.", diff --git a/app/config/locale/translations/eo.json b/app/config/locale/translations/eo.json index e273597ba4..408f2a8c6e 100644 --- a/app/config/locale/translations/eo.json +++ b/app/config/locale/translations/eo.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "teamo de {{project}}", "sms.verification.body": "{{secret}} estas via {{project}} kontrolo-kodo.", "emails.magicSession.securityPhrase": "La sekureca frazo por ĉi tiu retpoŝto estas {{phrase}}. Vi povas fidi ĉi tiun retpoŝton se ĉi tiu frazo kongruas kun la frazo montrita dum ensaluto.", - "emails.magicSession.optionUrl": "Se vi ne povas ensaluti per la supra butono, bonvolu viziti la jenan ligilon:" + "emails.magicSession.optionUrl": "Se vi ne povas ensaluti per la supra butono, bonvolu viziti la jenan ligilon:", + "emails.otpSession.subject": "{{project}} Ensaluto", + "emails.otpSession.hello": "Saluton,", + "emails.otpSession.description": "Enigu la jenan kontrolkodon kiam oni petos ĝin por sekure ensaluti en vian {{project}} konton. Ĝi eksvalidiĝos post 15 minutoj.", + "emails.otpSession.clientInfo": "Ĉi tiu ensaluto estis petita per {{agentClient}} en {{agentDevice}} {{agentOs}}. Se vi ne petis la ensaluton, vi povas sekure ignori ĉi tiun retpoŝton.", + "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 40181bb474..2662cd80bb 100644 --- a/app/config/locale/translations/es.json +++ b/app/config/locale/translations/es.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equipo {{project}}", "sms.verification.body": "{{secret}} es tu código de verificación de {{project}}.", "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.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.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.signature": "equipo {{project}}" } \ No newline at end of file diff --git a/app/config/locale/translations/fa.json b/app/config/locale/translations/fa.json index 7c7ff5fde2..6587995e9e 100644 --- a/app/config/locale/translations/fa.json +++ b/app/config/locale/translations/fa.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "تیم {{project}}", "sms.verification.body": "{{secret}} کد تایید {{project}} شما است.", "emails.magicSession.securityPhrase": "عبارت امنیتی برای این ایمیل {{phrase}} است. اگر این عبارت با عبارت نشان داده شده در هنگام ورود به سیستم مطابقت داشت، می‌توانید به این ایمیل اعتماد کنید.", - "emails.magicSession.optionUrl": "اگر قادر به ورود با استفاده از دکمه بالا نیستید، لطفاً از لینک زیر دیدن فرمایید:" + "emails.magicSession.optionUrl": "اگر قادر به ورود با استفاده از دکمه بالا نیستید، لطفاً از لینک زیر دیدن فرمایید:", + "emails.otpSession.subject": "ورود {{project}}", + "emails.otpSession.hello": "سلام،", + "emails.otpSession.description": "وقتی از شما خواسته شد، کد تأیید زیر را برای ورود ایمن به حساب کاربری {{project}} خود وارد کنید. این کد تا ۱۵ دقیقه دیگر منقضی می‌شود.", + "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/fi.json b/app/config/locale/translations/fi.json index 3cd222b1eb..5d81c849fa 100644 --- a/app/config/locale/translations/fi.json +++ b/app/config/locale/translations/fi.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} tiimi", "sms.verification.body": "{{secret}} on sinun {{project}} vahvistuskoodisi.", "emails.magicSession.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.magicSession.optionUrl": "Jos et pysty kirjautumaan sisään yllä olevaa painiketta käyttäen, käy seuraavassa linkissä:" + "emails.magicSession.optionUrl": "Jos et pysty kirjautumaan sisään yllä olevaa painiketta käyttäen, käy seuraavassa linkissä:", + "emails.otpSession.subject": "{{project}} Kirjautuminen", + "emails.otpSession.hello": "Hei,", + "emails.otpSession.description": "Syötä seuraava vahvistuskoodi, kun sinua pyydetään tekemään se turvallisesti kirjautuaksesi {{project}}-tilillesi. Se vanhenee 15 minuutin kuluttua.", + "emails.otpSession.clientInfo": "Tämä kirjautumispyyntö tehtiin käyttämällä {{agentClient}} laitteella {{agentDevice}} {{agentOs}}. Jos et pyytänyt kirjautumista, voit huoletta ohittaa tämän sähköpostin.", + "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 2dd97014c2..53c4a0fa01 100644 --- a/app/config/locale/translations/fo.json +++ b/app/config/locale/translations/fo.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} bólkur", "sms.verification.body": "{{secret}} er tín {{project}} váttanarkodi.", "emails.magicSession.securityPhrase": "Trygdarorðið fyri hesa teldupostadressuna er {{phrase}}. Tú kanst líta á hesa teldupostadressu, um hetta orðið samsvarar við orðið víst tá tú ritaði inn.", - "emails.magicSession.optionUrl": "Um tú ikki fært innritað við at brúka knøttin omanfyri, vinarliga vitja hesa leinkjuna:" + "emails.magicSession.optionUrl": "Um tú ikki fært innritað við at brúka knøttin omanfyri, vinarliga vitja hesa leinkjuna:", + "emails.otpSession.subject": "{{project}} Ritarinn", + "emails.otpSession.hello": "Hallo,", + "emails.otpSession.description": "Skriva hesa váttanarkotu tá tú verður biðin um tað, fyri at rita trygt inn á tín {{project}} konto. Hon gongur út um 15 minuttir.", + "emails.otpSession.clientInfo": "Hendan innritað varð umbidin við {{agentClient}} á {{agentDevice}} {{agentOs}}. Um tú ikki hevur umbiðið innritingina, kanst tú trygt ignorera hesa teldupostin.", + "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 b8cdeb8f33..ba85673a12 100644 --- a/app/config/locale/translations/fr.json +++ b/app/config/locale/translations/fr.json @@ -240,5 +240,12 @@ "emails.magicSession.optionUrl": "Si le bouton ci-dessus ne s'affiche pas, utilisez le lien suivant :", "emails.magicSession.clientInfo": "Cette connexion a été demandée en utilisant {{agentClient}} sur {{agentDevice}} {{agentOs}}. Si vous n'avez pas demandé cette connexion, vous pouvez ignorer cet email en toute sécurité.", "sms.verification.body": "{{secret}} est votre code de vérification pour {{project}}.", - "emails.magicSession.securityPhrase": "La phrase de sécurité pour cet email est {{phrase}}. Vous pouvez faire confiance à cet email si cette phrase correspond à celle affichée lors de la connexion." + "emails.magicSession.securityPhrase": "La phrase de sécurité pour cet email est {{phrase}}. Vous pouvez faire confiance à cet email si cette phrase correspond à celle affichée lors de la connexion.", + "emails.otpSession.subject": "Connexion {{project}}", + "emails.otpSession.hello": "Bonjour,", + "emails.otpSession.description": "Entrez le code de vérification suivant lorsque cela vous sera demandé pour vous connecter en toute sécurité à votre compte {{project}}. Il expirera dans 15 minutes.", + "emails.otpSession.clientInfo": "Cette connexion a été demandée en utilisant {{agentClient}} sur {{agentDevice}} {{agentOs}}. Si vous n'avez pas demandé cette connexion, vous pouvez ignorer cet e-mail en toute sécurité.", + "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 484debfa3f..61a0194dd4 100644 --- a/app/config/locale/translations/ga.json +++ b/app/config/locale/translations/ga.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "foireann {{project}}", "sms.verification.body": "Is é {{secret}} do chód fíoraithe {{project}}.", "emails.magicSession.securityPhrase": "Is é an abairt 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 abairt seo leis an abairt a taispeántar le linn sínithe isteach.", - "emails.magicSession.optionUrl": "Mura bhfuil tú in ann síniú isteach ag baint úsáid as an gcnaipe thuas, téigh chuig an nasc seo a leanas:" + "emails.magicSession.optionUrl": "Mura bhfuil tú in ann síniú isteach ag baint úsáid as an gcnaipe thuas, téigh chuig an nasc seo a leanas:", + "emails.otpSession.subject": "Login {{project}}", + "emails.otpSession.hello": "Dia dhuit,", + "emails.otpSession.description": "Iontráil an cód fíoraithe seo a leanas nuair a iarrtar ort chun síní isteach go slán ar do chuntas {{project}}. Rachaidh sé in éag i gceann 15 nóiméad.", + "emails.otpSession.clientInfo": "Rinneadh an iarratas seo chun síniú isteach ag baint úsáide as {{agentClient}} ar {{agentDevice}} {{agentOs}}. Mura ndearna tú an iarratas chun síniú isteach, is féidir leat an ríomhphost seo a neamhaird go sábháilte.", + "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 99aa4f59aa..3d52c4a076 100644 --- a/app/config/locale/translations/gu.json +++ b/app/config/locale/translations/gu.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "પ્રોજેક્ટ ટીમ", "sms.verification.body": "{{secret}} તમારા {{project}} ચકાસણી કોડ છે.", "emails.magicSession.securityPhrase": "આ ઇમેઇલ માટેનું સુરક્ષા વાક્ય {{phrase}} છે. જો આ વાક્ય સાઇન ઇન દરમિયાન દર્શાવેલા વાક્ય સાથે મેળ ખાય તો તમે આ ઇમેઇલ પર વિશ્વાસ કરી શકો છો.", - "emails.magicSession.optionUrl": "જો તમે ઉપરની બટનનો ઉપયોગ કરીને સાઇન ઇન કરી શકતા નથી, કૃપા કરીને નીચેની લિંક પર જાઓ:" + "emails.magicSession.optionUrl": "જો તમે ઉપરની બટનનો ઉપયોગ કરીને સાઇન ઇન કરી શકતા નથી, કૃપા કરીને નીચેની લિંક પર જાઓ:", + "emails.otpSession.subject": "{{project}} લૉગિન", + "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/he.json b/app/config/locale/translations/he.json index 9d8f2b89cd..1a58d8c23e 100644 --- a/app/config/locale/translations/he.json +++ b/app/config/locale/translations/he.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "צוות {{project}}", "sms.verification.body": "{{secret}} הוא קוד האימות שלך ל-{{project}}.", "emails.magicSession.securityPhrase": "משפט הביטחון עבור הודעת הדוא\"ל הזו הוא {{phrase}}. תוכל לסמוך על הודעת הדוא\"ל הזו אם המשפט הזה תואם למשפט שהוצג בעת ההתחברות.", - "emails.magicSession.optionUrl": "אם אינך יכול להיכנס באמצעות הכפתור למעלה, בקר בקישור הבא:" + "emails.magicSession.optionUrl": "אם אינך יכול להיכנס באמצעות הכפתור למעלה, בקר בקישור הבא:", + "emails.otpSession.subject": "התחברות למערכת {{project}}", + "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/hi.json b/app/config/locale/translations/hi.json index 8255705a73..d2e8216d5f 100644 --- a/app/config/locale/translations/hi.json +++ b/app/config/locale/translations/hi.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} टीम", "sms.verification.body": "{{secret}} आपके {{project}} सत्यापन कोड है।", "emails.magicSession.securityPhrase": "इस ईमेल का सुरक्षा वाक्यांश {{phrase}} है। यदि यह वाक्यांश साइन इन के दौरान दिखाए गए वाक्यांश से मेल खाता है तो आप इस ईमेल पर भरोसा कर सकते हैं।", - "emails.magicSession.optionUrl": "यदि आप ऊपर दिए गए बटन का उपयोग करके साइन इन नहीं कर पा रहे हैं, कृपया निम्नलिखित लिंक पर जाएँ:" + "emails.magicSession.optionUrl": "यदि आप ऊपर दिए गए बटन का उपयोग करके साइन इन नहीं कर पा रहे हैं, कृपया निम्नलिखित लिंक पर जाएँ:", + "emails.otpSession.subject": "{{project}} लॉगिन", + "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/hr.json b/app/config/locale/translations/hr.json index c98945063b..d69cd967ea 100644 --- a/app/config/locale/translations/hr.json +++ b/app/config/locale/translations/hr.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "tim {{project}}", "sms.verification.body": "{{secret}} je vaš verifikacijski kod za {{project}}.", "emails.magicSession.securityPhrase": "Sigurnosna fraza za ovaj e-mail je {{phrase}}. Ovom e-mailu možete vjerovati ako se fraza podudara s frazom prikazanom tijekom prijave.", - "emails.magicSession.optionUrl": "Ako se ne možete prijaviti koristeći gornji gumb, posjetite sljedeću poveznicu:" + "emails.magicSession.optionUrl": "Ako se ne možete prijaviti koristeći gornji gumb, posjetite sljedeću poveznicu:", + "emails.otpSession.subject": "Prijava na {{project}}", + "emails.otpSession.hello": "Zdravo,", + "emails.otpSession.description": "Unesite sljedeći verifikacijski kod kada budete pozvani kako biste se sigurno prijavili na svoj {{project}} račun. Istjeći će za 15 minuta.", + "emails.otpSession.clientInfo": "Ova prijava je zatražena pomoću {{agentClient}} na {{agentDevice}} {{agentOs}}. Ako niste zatražili prijavu, ovaj e-mail možete sigurno zanemariti.", + "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 fd4d16ae1f..06f33be1f3 100644 --- a/app/config/locale/translations/hu.json +++ b/app/config/locale/translations/hu.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} csapat", "sms.verification.body": "{{secret}} a(z) {{project}} megerősítő kódja.", "emails.magicSession.securityPhrase": "Az e-mailhez tartozó biztonsági kifejezés: {{phrase}}. Megbízhat ebben az e-mailben, ha ez a kifejezés megegyezik a bejelentkezéskor megjelenített kifejezéssel.", - "emails.magicSession.optionUrl": "Amennyiben az előző gomb használatával nem tud bejelentkezni, kérjük látogassa meg a következő linket:" + "emails.magicSession.optionUrl": "Amennyiben az előző gomb használatával nem tud bejelentkezni, kérjük látogassa meg a következő linket:", + "emails.otpSession.subject": "{{project}} Bejelentkezés", + "emails.otpSession.hello": "Szia,", + "emails.otpSession.description": "Adja meg a következő megerősítő kódot, amikor arra kéri a rendszer, hogy biztonságosan bejelentkezhessen a {{project}} fiókjába. A kód 15 perc múlva lejár.", + "emails.otpSession.clientInfo": "Ez a bejelentkezés a(z) {{agentClient}} használatával lett kérve a(z) {{agentDevice}} {{agentOs}} eszközön. Ha Ön nem kérte a bejelentkezést, nyugodtan figyelmen kívül hagyhatja ezt az e-mailt.", + "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 71f102a4c4..fc8c1ddb6e 100644 --- a/app/config/locale/translations/hy.json +++ b/app/config/locale/translations/hy.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} թիմ", "sms.verification.body": "{{secret}}-ն ձեր {{project}} վավերացման կոդն է։", "emails.magicSession.securityPhrase": "Այս էլհասցեի անվտանգության արտահայտությունը {{phrase}} է: Դուք կարող եք հավատալ այս էլհասցեին, եթե այդ արտահայտությունը համընկնում է ներմուծման պրոցեսին՝ երբ դուք գրանցվել եք։", - "emails.magicSession.optionUrl": "Եթե չեք կարող մուտք գործել վերը նշված կոճակով, այցելեք հետևյալ հղումը՝" + "emails.magicSession.optionUrl": "Եթե չեք կարող մուտք գործել վերը նշված կոճակով, այցելեք հետևյալ հղումը՝", + "emails.otpSession.subject": "{{project}} Մուտք", + "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/id.json b/app/config/locale/translations/id.json index 7414cc5e63..e5887f3844 100644 --- a/app/config/locale/translations/id.json +++ b/app/config/locale/translations/id.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "tim {{project}}", "sms.verification.body": "{{secret}} adalah kode verifikasi {{project}} Anda.", "emails.magicSession.securityPhrase": "Frasa keamanan untuk email ini adalah {{phrase}}. Anda dapat mempercayai email ini jika frasa tersebut cocok dengan frasa yang ditampilkan saat masuk.", - "emails.magicSession.optionUrl": "Jika Anda tidak dapat masuk menggunakan tombol di atas, silakan kunjungi tautan berikut:" + "emails.magicSession.optionUrl": "Jika Anda tidak dapat masuk menggunakan tombol di atas, silakan kunjungi tautan berikut:", + "emails.otpSession.subject": "Login {{project}}", + "emails.otpSession.hello": "Halo,", + "emails.otpSession.description": "Masukkan kode verifikasi berikut saat diminta untuk masuk ke akun {{project}} Anda dengan aman. Kode ini akan kedaluwarsa dalam waktu 15 menit.", + "emails.otpSession.clientInfo": "Tanda masuk ini diminta menggunakan {{agentClient}} pada {{agentDevice}} {{agentOs}}. Jika Anda tidak meminta tanda masuk, Anda dapat mengabaikan email ini dengan aman.", + "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 d44852196a..24bfee0f8d 100644 --- a/app/config/locale/translations/is.json +++ b/app/config/locale/translations/is.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} liðið", "sms.verification.body": "{{secret}} er staðfestingarkóði {{project}} þíns.", "emails.magicSession.securityPhrase": "Öryggisfrasi fyrir þetta tölvupóst er {{phrase}}. Þú getur treyst þessum tölvupósti ef þessi frasi passar við frasann sem birtist við innskráningu.", - "emails.magicSession.optionUrl": "Ef þú getur ekki skráð þig inn með hnappnum hér að ofan, vinsamlegast heimsækðu eftirfarandi tengil:" + "emails.magicSession.optionUrl": "Ef þú getur ekki skráð þig inn með hnappnum hér að ofan, vinsamlegast heimsækðu eftirfarandi tengil:", + "emails.otpSession.subject": "{{project}} Innskráning", + "emails.otpSession.hello": "Halló,", + "emails.otpSession.description": "Sláðu inn eftirfarandi staðfestingarkóða þegar þú ert beðinn um það til að skrá þig örugglega inn á {{project}} reikninginn þinn. Hann rennur út eftir 15 mínútur.", + "emails.otpSession.clientInfo": "Innskráningin var óskað eftir með því að nota {{agentClient}} á {{agentDevice}} {{agentOs}}. Ef þú baðst ekki um innskráninguna getur þú hunsað þennan tölvupóst örugglega.", + "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 296fb4df75..524ffa33b5 100644 --- a/app/config/locale/translations/it.json +++ b/app/config/locale/translations/it.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "team {{project}}", "sms.verification.body": "{{secret}} è il tuo codice di verifica per {{project}}.", "emails.magicSession.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.magicSession.optionUrl": "Se non riesci ad accedere utilizzando il pulsante qui sopra, ti preghiamo di visitare il seguente link:" + "emails.magicSession.optionUrl": "Se non riesci ad accedere utilizzando il pulsante qui sopra, ti preghiamo di visitare il seguente link:", + "emails.otpSession.subject": "Accesso a {{project}}", + "emails.otpSession.hello": "Ciao,", + "emails.otpSession.description": "Inserisci il seguente codice di verifica quando ti viene richiesto per accedere in modo sicuro al tuo account {{project}}. Scadrà tra 15 minuti.", + "emails.otpSession.clientInfo": "Questa registrazione è stata richiesta tramite {{agentClient}} su {{agentDevice}} {{agentOs}}. Se non hai richiesto la registrazione, puoi ignorare tranquillamente questa email.", + "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 17c3540bd6..9a798f0695 100644 --- a/app/config/locale/translations/ja.json +++ b/app/config/locale/translations/ja.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} チーム", "sms.verification.body": "{{secret}} はあなたの {{project}} 認証コードです。", "emails.magicSession.securityPhrase": "このメールのセキュリティフレーズは{{phrase}}です。サインイン時に表示されたフレーズと一致する場合、このメールは信頼できます。", - "emails.magicSession.optionUrl": "上記のボタンを使用してサインインすることができない場合は、次のリンクにアクセスしてください:" + "emails.magicSession.optionUrl": "上記のボタンを使用してサインインすることができない場合は、次のリンクにアクセスしてください:", + "emails.otpSession.subject": "プロジェクト ログイン", + "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/jv.json b/app/config/locale/translations/jv.json index 925666cfc2..b876996693 100644 --- a/app/config/locale/translations/jv.json +++ b/app/config/locale/translations/jv.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "tim {{project}}", "sms.verification.body": "{{secret}} iku kode verifikasi {{project}} panjenengan.", "emails.magicSession.securityPhrase": "Frasa keamanan kanggo email iki yaiku {{phrase}}. Sampeyan bisa percaya marang email iki yen frasa iki cocog karo frasa sing ditampilake nalika mlebu.", - "emails.magicSession.optionUrl": "Yen sampeyan ora bisa mlebu nganggo tombol ing ndhuwur, monggo ngunjungi pranala ing ngisor iki:" + "emails.magicSession.optionUrl": "Yen sampeyan ora bisa mlebu nganggo tombol ing ndhuwur, monggo ngunjungi pranala ing ngisor iki:", + "emails.otpSession.subject": "{{project}} Mlebu", + "emails.otpSession.hello": "Halo,", + "emails.otpSession.description": "Lebokna kode verifikasi ing ngisor iki nalika dijaluk kanggo mlebu sing aman menyang akun {{project}} panjenengan. Kode iki bakal kadaluwarsa sajrone 15 menit.", + "emails.otpSession.clientInfo": "Tandha mlebu iki dijaluk nganggo {{agentClient}} ing {{agentDevice}} {{agentOs}}. Yen panjenengan ora njaluk tandha mlebu, panjenengan bisa nglirwakake email iki kanthi aman.", + "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 f6212b5a82..58fbee75d7 100644 --- a/app/config/locale/translations/km.json +++ b/app/config/locale/translations/km.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ក្រុម {{project}}", "sms.verification.body": "{{secret}} ជាលេខកូដផ្ទៀងផ្ទាត់សម្រាប់{{project}}របស់អ្នក។", "emails.magicSession.securityPhrase": "ឃ្លាសម្ងាត់សម្រាប់អ៊ីមែលនេះគឺ {{phrase}}។ អ្នកអាចទុកចិត្តលើអ៊ីមែលនេះប្រសិនបើឃ្លានេះត្រូវគ្នាជាមួយឃ្លាដែលបង្ហាញឡើងពេលចូលប្រើ។", - "emails.magicSession.optionUrl": "ប្រសិនបើអ្នកមិនអាចចូលប្រើប្រាស់ដោយប្រើប៊ូតុងខាងលើនេះទេ សូមចូលទៅកាន់តំណភ្ជាប់ខាងក្រោម៖" + "emails.magicSession.optionUrl": "ប្រសិនបើអ្នកមិនអាចចូលប្រើប្រាស់ដោយប្រើប៊ូតុងខាងលើនេះទេ សូមចូលទៅកាន់តំណភ្ជាប់ខាងក្រោម៖", + "emails.otpSession.subject": "ការចូល {{project}}", + "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/kn.json b/app/config/locale/translations/kn.json index a03c259308..0bae4e9ff6 100644 --- a/app/config/locale/translations/kn.json +++ b/app/config/locale/translations/kn.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ತಂಡ", "sms.verification.body": "{{secret}} ನಿಮ್ಮ {{project}} ಪರಿಶೀಲನಾ ಸಂಕೇತವಾಗಿದೆ.", "emails.magicSession.securityPhrase": "ಈ ಇಮೇಲ್‌ಗಾಗಿ ಭದ್ರತಾ ಪದ ಇದೆ {{phrase}}. ಸೈನ್ ಇನ್ ಮಾಡುವಾಗ ತೋರಿದ ಪದವು ಈ ಪದವು ಹೊಂದಿಕೆಯಾಗಿದ್ದರೆ ನೀವು ಈ ಇಮೇಲ್‌ಅನ್ನು ನಂಬಬಹುದು.", - "emails.magicSession.optionUrl": "ಮೇಲಿನ ಬಟನ್ ಬಳಸಿ ನೀವು ಸೈನ್ ಇನ್ ಮಾಡಲು ಅಸಮರ್ಥರಾಗಿದ್ದರೆ, ದಯವಿಟ್ಟು ಈ ಕೆಳಗಿನ ಲಿಂಕ್ ಭೇಟಿಯನ್ನು ಕೊಡಿ:" + "emails.magicSession.optionUrl": "ಮೇಲಿನ ಬಟನ್ ಬಳಸಿ ನೀವು ಸೈನ್ ಇನ್ ಮಾಡಲು ಅಸಮರ್ಥರಾಗಿದ್ದರೆ, ದಯವಿಟ್ಟು ಈ ಕೆಳಗಿನ ಲಿಂಕ್ ಭೇಟಿಯನ್ನು ಕೊಡಿ:", + "emails.otpSession.subject": "{{project}} ಲಾಗಿನ್", + "emails.otpSession.hello": "ಹಲೋ,", + "emails.otpSession.description": "ನಿಮ್ಮ {{project}} ಖಾತೆಗೆ ಭದ್ರವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಲು ಕೇಳಿದಾಗ ಕೆಳಗಿನ ದೃಢೀಕರಣ ಕೋಡ್ ನಮೂದಿಸಿ. ಇದು 15 ನಿಮಿಷಗಳಲ್ಲಿ ಅವಧಿ ಮುಗಿಯುತ್ತದೆ.", + "emails.otpSession.clientInfo": "ಈ ಸೈನ್ ಇನ್ ಅನ್ನು {{agentClient}} ಬಳಸಿ {{agentDevice}} {{agentOs}}ನಲ್ಲಿ ಕೋರಿಕೆ ಮಾಡಲಾಗಿದೆ. ನೀವು ಸೈನ್ ಇನ್ ಅನ್ನು ಕೋರಿಕೆ ಮಾಡಿರದಿದ್ದರೆ, ಈ ಇಮೇಲ್ ಅನ್ನು ನೀವು ನಿರಾಳವಾಗಿ ಅಲಕ್ಷ್ಯ ಮಾಡಬಹುದು.", + "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 ce12a95318..b257f93256 100644 --- a/app/config/locale/translations/ko.json +++ b/app/config/locale/translations/ko.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} 팀", "sms.verification.body": "{{secret}}는 귀하의 {{project}} 인증 코드입니다.", "emails.magicSession.securityPhrase": "이 이메일의 보안 구절은 {{phrase}}입니다. 로그인할 때 표시되는 구절과 일치한다면 이 이메일을 신뢰할 수 있습니다.", - "emails.magicSession.optionUrl": "위의 버튼을 사용하여 로그인할 수 없다면, 다음 링크를 방문해 주세요:" + "emails.magicSession.optionUrl": "위의 버튼을 사용하여 로그인할 수 없다면, 다음 링크를 방문해 주세요:", + "emails.otpSession.subject": "{{project}} 로그인", + "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/la.json b/app/config/locale/translations/la.json index b09b2f109c..a5d2155c7b 100644 --- a/app/config/locale/translations/la.json +++ b/app/config/locale/translations/la.json @@ -229,16 +229,23 @@ "continents.na": "America del Norte", "continents.oc": "Oceania", "continents.sa": "America del Sur", - "emails.magicSession.optionButton": "Preme el boton infra pro signar securmente in tu conto de {{project}}. Illo expirara in 1 hora.", - "emails.magicSession.buttonText": "Inicia sesión en {{project}}", - "emails.magicSession.clientInfo": "Esta conexión fue solicitada usando {{agentClient}} en {{agentDevice}} {{agentOs}}. Si usted no solicitó la conexión, puede ignorar este correo electrónico de forma segura.", - "emails.certificate.subject": "Fracaso del certificado para %s", - "emails.certificate.hello": "There seems to be a misunderstanding. The country code \"LA\" refers to Laos, and the primary language used there is Lao. However, without specific instructions to translate into Lao, I cannot proceed with the translation. If Lao is indeed the intended language, please confirm, and I will provide you with the translation.", - "emails.certificate.body": "El certificado para su dominio '{{domain}}' no pudo ser generado. Este es el intento número {{attempt}}, y el fallo fue causado por: {{error}}.", - "emails.certificate.footer": "Su certificado anterior será válido por 30 días desde el primer fallo. Recomendamos encarecidamente investigar este caso, de lo contrario su dominio quedará sin una comunicación SSL válida.", - "emails.certificate.thanks": "Gracias", - "emails.certificate.signature": "{{project}} equipo", - "sms.verification.body": "{{secret}} ແມ່ນລະຫັດຢືນຢັນສໍາລັບ {{project}} ຂອງທ່ານ.", - "emails.magicSession.securityPhrase": "La locución de seguridat pro iste correo es {{phrase}}. Podes confiar en iste correo si esta locución coincidit con la locución amostrada durante el ingreso.", - "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón de arriba, por favor visita el siguiente enlace:" + "emails.magicSession.optionButton": "Clicca in puga infra ut tuto subscribas in rationem tuam {{project}}. Hora una exibit.", + "emails.magicSession.buttonText": "Intra in {{project}}", + "emails.magicSession.optionUrl": "Si non potes signo uti superiore puga pyga, quaeso ad hunc nexum visere:", + "emails.magicSession.clientInfo": "Hic signum in petitus est utens {{agentClient}} in {{agentDevice}} {{agentOs}}. Si signum in non requisisti, hoc epistulae secure negligere potes.", + "emails.magicSession.securityPhrase": "Sententia securitatis huius epistulae est {{phrase}}. Huic epistulae confidere potes si haec sententia convenit cum sententia ostensa dum in systema ingrederis.", + "emails.otpSession.subject": "Login {{project}}", + "emails.otpSession.hello": "Salve,", + "emails.otpSession.description": "Inserite sequentem codicem verificationis cum moniti signum in rationem vestram {{project}} tutum facere. Expirabit in quindecim minutis.", + "emails.otpSession.clientInfo": "Hoc signum intra petebatur utendo {{agentClient}} in {{agentDevice}} {{agentOs}}. Si signum intra non petisti, hoc epistulum securus negligere potes.", + "emails.otpSession.securityPhrase": "Sententia securitatis huius epistulae est {{phrase}}. Epistulae confidere potes si haec sententia cum ea quae ostensa est in signo ingressus convenit.", + "emails.otpSession.thanks": "Gratias,", + "emails.otpSession.signature": "{{project}} team -> {{project}} grex", + "emails.certificate.subject": "Defectio testimonii pro %s", + "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.signature": "team {{project}}", + "sms.verification.body": "{{secret}} est codex verificatorius {{project}} tui." } \ No newline at end of file diff --git a/app/config/locale/translations/lb.json b/app/config/locale/translations/lb.json index f746c81c5a..72f5a19152 100644 --- a/app/config/locale/translations/lb.json +++ b/app/config/locale/translations/lb.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "Équipe {{project}}", "sms.verification.body": "{{secret}} ass äre {{project}} Verifikatiounscode.", "emails.magicSession.securityPhrase": "D'Sécherheetsphrase fir dësen E-Mail ass {{phrase}}. Dir kënnt dësem E-Mail vertrauen, wann dës Phrase mat der Phrase iwwereneestëmmt, déi beim Umellen ugewise ginn ass.", - "emails.magicSession.optionUrl": "Wann Dir Iech net kënnt umellen andeems Dir op de Knäppchen uewendriwwer klickt, besicht w.e.g. de folgenden Link:" + "emails.magicSession.optionUrl": "Wann Dir Iech net kënnt umellen andeems Dir op de Knäppchen uewendriwwer klickt, besicht w.e.g. de folgenden Link:", + "emails.otpSession.subject": "{{project}} Aloggen", + "emails.otpSession.hello": "Moien,", + "emails.otpSession.description": "Gitt de folgende Verifikatiounscode an, wann dir gefrot gitt fir sécher an ären {{project}} Kont anzeloggen. Hien ass no 15 Minutten net méi gülteg.", + "emails.otpSession.clientInfo": "Dësen Aloggen gouf mat {{agentClient}} op {{agentDevice}} {{agentOs}} gefrot. Wann Dir d'Ufro fir d'Aloggen net gemaach hutt, kënnt Dir dësen E-Mail roueg ignoréieren.", + "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 906f05859f..7cd2467100 100644 --- a/app/config/locale/translations/lt.json +++ b/app/config/locale/translations/lt.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} komanda", "sms.verification.body": "{{secret}} yra jūsų {{project}} patvirtinimo kodas.", "emails.magicSession.securityPhrase": "Šio el. laiško saugumo frazė yra {{phrase}}. Šiam el. laiškui galite pasitikėti, jei ši frazė atitinka prisijungimo metu rodytą frazę.", - "emails.magicSession.optionUrl": "Jei negalite prisijungti naudodami aukščiau esantį mygtuką, apsilankykite šioje nuorodoje:" + "emails.magicSession.optionUrl": "Jei negalite prisijungti naudodami aukščiau esantį mygtuką, apsilankykite šioje nuorodoje:", + "emails.otpSession.subject": "{{project}} Prisijungimas", + "emails.otpSession.hello": "Sveiki,", + "emails.otpSession.description": "Įveskite šį patvirtinimo kodą, kai busite paraginti saugiai prisijungti prie savo {{project}} paskyros. Jis pasibaigs po 15 minučių.", + "emails.otpSession.clientInfo": "Šis prisijungimas buvo užklaustas naudojant {{agentClient}} įrenginyje {{agentDevice}} {{agentOs}}. Jei neprašėte prisijungti, šį el. laišką galite drąsiai ignoruoti.", + "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 91035631f0..1a8602360e 100644 --- a/app/config/locale/translations/lv.json +++ b/app/config/locale/translations/lv.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} komanda", "sms.verification.body": "{{secret}} ir jūsu {{project}} verifikācijas kods.", "emails.magicSession.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ās, piesakoties sistēmā.", - "emails.magicSession.optionUrl": "Ja nevarat pierakstīties, izmantojot iepriekš minēto pogu, lūdzu, apmeklējiet sekojošo saiti:" + "emails.magicSession.optionUrl": "Ja nevarat pierakstīties, izmantojot iepriekš minēto pogu, lūdzu, apmeklējiet sekojošo saiti:", + "emails.otpSession.subject": "{{project}} Pieteikšanās", + "emails.otpSession.hello": "Sveiki,", + "emails.otpSession.description": "Ievadiet šo verifikācijas kodu, kad tiek pieprasīts, lai droši pierakstītos savā {{project}} kontā. Tas beigsies pēc 15 minūtēm.", + "emails.otpSession.clientInfo": "Šo pierakstīšanos pieprasīja, izmantojot {{agentClient}} ierīcē {{agentDevice}} {{agentOs}}. Ja neesat pieprasījis pierakstīšanos, šo e-pastu droši var ignorēt.", + "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 c577239a31..aff02854f4 100644 --- a/app/config/locale/translations/ml.json +++ b/app/config/locale/translations/ml.json @@ -229,16 +229,23 @@ "continents.na": "വടക്കേ അമേരിക്ക", "continents.oc": "ഓഷ്യാനിയ", "continents.sa": "തെക്കേ അമേരിക്ക", - "emails.magicSession.optionButton": "ಕೆಳಗಿನ ಬಟನ್ ಒತ್ತಿ ನಿಮ್ಮ {{project}} ಖಾತೆಗೆ ಸುರಕ್ಷಿತವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಿ. ಇದು 1 ಗಂಟೆಯಲ್ಲಿ ಅವಧಿ ಮುಗಿಯುವುದು.", - "emails.magicSession.buttonText": "Se connecter à {{project}}", - "emails.magicSession.clientInfo": "I'm sorry, but there appears to be some confusion. The country code \"ml\" stands for Mali, where the official language is French. However, many local languages such as Bambara are also widely spoken. Please specify if you would like the translation in French or any other specific local language.", - "emails.certificate.subject": "Tsy fahombiazan'ny fahaizana ho an'ny %s", - "emails.certificate.hello": "Bonjour", - "emails.certificate.body": "നിങ്ങളുടെ ഡൊമെയ്‌ൻ '{{domain}}'നായുള്ള സർട്ടിഫിക്കറ്റ് ഉണ്ടാക്കാൻ കഴിയിച്ചില്ല. ഇത് ശ്രമമായ {{attempt}} ആണ്, പരാജയത്തിനു കാരണം: {{error}}", - "emails.certificate.footer": "Ny zom-pokotaninao teo aloha dia hanan-kery mandritra ny 30 andro manomboka amin'ny tsy fahombiazana voalohany. Izahay dia manoro hevitra mafy ny hanaovana fikarohana momba ity tranga ity, raha tsy izany ny sehatra misy anao dia ho tonga amin'ny toerana tsy misy fifandraisana SSL manan-kery.", - "emails.certificate.thanks": "Merci", - "emails.certificate.signature": "{{project}} ekipi", - "sms.verification.body": "{{secret}} tànna {{project}} ka càddu jamiilu la.", - "emails.magicSession.securityPhrase": "ഈ ഇമെയിലിന്റെ സുരക്ഷാ വാചകം {{phrase}} ആണ്. സൈൻ ഇൻ ചെയ്യുമ്പോൾ കാണിച്ച വാചകവുമായി ഈ വാചകം ഒത്തുപോകുന്നെങ്കിൽ ഈ ഇമെയിലിനെ വിശ്വസിക്കാം.", - "emails.magicSession.optionUrl": "Raha toa ka tsy afaka miditra ianao amin'ny alàlan'ny bokotra etsy ambony, azafady mba tsidiho ity rohy manaraka ity:" + "emails.magicSession.optionButton": "താഴെയുള്ള ബട്ടൺ ക്ലിക്ക് ചെയ്ത് സുരക്ഷിതമായി നിങ്ങളുടെ {{project}} അക്കൗണ്ടിൽ സൈൻ ഇൻ ചെയ്യുക. ഇത് 1 മണിക്കൂര്‍ കഴിഞ്ഞാൽ അസാധുവാകും.", + "emails.magicSession.buttonText": "{{project}} ലേക്ക് സൈൻ ഇൻ ചെയ്യുക", + "emails.magicSession.optionUrl": "മുകളിലുള്ള ബട്ടണ്‍ ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യാനാകാത്തപക്ഷം, ദയവായി താഴെയുള്ള ലിങ്ക് സന്ദർശിക്കുക:", + "emails.magicSession.clientInfo": "ഈ സൈൻ ഇൻ {{agentClient}} ഉപയോഗിച്ച് {{agentDevice}} {{agentOs}}-ഇൽ അഭ്യർത്ഥിച്ചിരിക്കുന്നു. നിങ്ങൾ ഈ സൈൻ ഇൻ അഭ്യർത്ഥിച്ചിട്ടില്ലെങ്കിൽ, ഈ ഇമെയിൽ അവഗണിക്കാം.", + "emails.magicSession.securityPhrase": "ഈ ഇമെയിലിന്റെ സുരക്ഷാ വാചകം {{phrase}} ആണ്. സൈൻ ഇൻ ചെയ്ത സമയത്ത് കാണിച്ച വാചകവുമായി ഈ വാചകം ഒത്തുവരുന്നെങ്കിൽ ഈ ഇമെയിലിന് വിശ്വസിക്കാം.", + "emails.otpSession.subject": "{{project}} ലോഗിൻ", + "emails.otpSession.hello": "ഹലോ,", + "emails.otpSession.description": "നിങ്ങൾക്ക് സുരക്ഷിതമായി നിങ്ങളുടെ {{project}} അക്കൗണ്ടിൽ സൈൻ ഇൻ ചെയ്യുമ്പോൾ അനുവദിക്കപ്പെടുമ്പോൾ താഴെയുള്ള സാധൂകരണ കോഡ് നൽകുക. ഇത് 15 മിനിറ്റിൽ കാലഹരണപ്പെടും.", + "emails.otpSession.clientInfo": "ഈ സൈൻ ഇൻ {{agentClient}} ഉപയോഗിച്ച് {{agentDevice}} {{agentOs}}-ൽ അഭ്യർത്ഥിച്ചു. നിങ്ങൾ സൈൻ ഇൻ അഭ്യർത്ഥിക്കാത്ത പക്ഷം, ഈ ഇമെയിൽ അവഗണിക്കാം.", + "emails.otpSession.securityPhrase": "ഈ ഇമെയിലിന്റെ സുരക്ഷാ വാചകം {{phrase}} ആണ്. സൈൻ ഇൻ ചെയ്യുമ്പോൾ കാണിച്ച വാചകവുമായി ഈ വാചകം പൊരുത്തപ്പെടുന്നുണ്ടെങ്കിൽ ഈ ഇമെയിലിന് വിശ്വസിക്കാം.", + "emails.otpSession.thanks": "നന്ദി,", + "emails.otpSession.signature": "പ്രോജക്ട് ടീം", + "emails.certificate.subject": "%s ന് സർട്ടിഫിക്കറ്റ് പരാജയപ്പെട്ടു", + "emails.certificate.hello": "ഹലോ", + "emails.certificate.body": "നിങ്ങളുടെ ഡൊമൈൻ '{{domain}}'നു വേണ്ടിയുള്ള സർട്ടിഫിക്കറ്റ് ഉണ്ടാക്കാനായില്ല. ഇത് ശ്രമം നമ്പർ {{attempt}} ആണ്, പരാജയപ്പെട്ടത് ഇതു മൂലമാണ്: {{error}}", + "emails.certificate.footer": "നിങ്ങളുടെ മുൻപത്തെ സർട്ടിഫിക്കറ്റ് ആദ്യ പരാജയത്തിനു ശേഷം 30 ദിവസം വരെ സാധുവായിരിക്കും. ഈ കേസ് അന്വേഷിച്ചു നോക്കുന്നത് ഞങ്ങൾ ശക്തമായി ശുപാർശ ചെയ്യുന്നു, അല്ലെങ്കിൽ നിങ്ങളുടെ ഡൊമെയ്‌ൻ സാധുവായ SSL കമ്മ്യൂണിക്കേഷനില്ലാത്ത ഒരു അവസ്ഥയിലാകും.", + "emails.certificate.thanks": "നന്ദി", + "emails.certificate.signature": "{{project}} ടീം", + "sms.verification.body": "{{secret}} നിങ്ങളുടെ {{project}} പരിശോധന കോഡാണ്." } \ No newline at end of file diff --git a/app/config/locale/translations/mr.json b/app/config/locale/translations/mr.json index c42021c337..125bbfc683 100644 --- a/app/config/locale/translations/mr.json +++ b/app/config/locale/translations/mr.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} संघ", "sms.verification.body": "{{secret}} हे तुमच्या {{project}} प्रमाणीकरण कोड आहे.", "emails.magicSession.securityPhrase": "या ईमेलसाठी सुरक्षा वाक्य हे {{phrase}} आहे. साइन इन केल्यावेळी दाखवलेले वाक्य जर हे वाक्याशी जुळत असेल तर तुम्ही या ईमेलवर विश्वास ठेवू शकता.", - "emails.magicSession.optionUrl": "जर आपण वरील बटणाचा वापर करून साइन इन करू शकत नसाल, तर कृपया खालील दुवा भेट द्या:" + "emails.magicSession.optionUrl": "जर आपण वरील बटणाचा वापर करून साइन इन करू शकत नसाल, तर कृपया खालील दुवा भेट द्या:", + "emails.otpSession.subject": "{{project}} लॉगिन", + "emails.otpSession.hello": "नमस्कार,", + "emails.otpSession.description": "आपल्या {{project}} खात्यावर सुरक्षितपणे साइन इन करण्यासाठी सांगितले जाताना खालील पडताळणी कोड प्रविष्ट करा. हा कोड १५ मिनिटांत समाप्त होईल.", + "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/ms.json b/app/config/locale/translations/ms.json index 602fe45455..8e93f39440 100644 --- a/app/config/locale/translations/ms.json +++ b/app/config/locale/translations/ms.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "pasukan {{project}}", "sms.verification.body": "{{secret}} adalah kod pengesahan {{project}} anda.", "emails.magicSession.securityPhrase": "Frasa keselamatan untuk emel ini adalah {{phrase}}. Anda boleh mempercayai emel ini jika frasa ini sepadan dengan frasa yang ditunjukkan semasa log masuk.", - "emails.magicSession.optionUrl": "Jika anda tidak dapat log masuk menggunakan butang di atas, sila kunjungi pautan berikut:" + "emails.magicSession.optionUrl": "Jika anda tidak dapat log masuk menggunakan butang di atas, sila kunjungi pautan berikut:", + "emails.otpSession.subject": "Log Masuk {{project}}", + "emails.otpSession.hello": "Halo,", + "emails.otpSession.description": "Masukkan kod pengesahan berikut apabila diminta untuk log masuk ke akaun {{project}} anda dengan selamat. Ia akan luput dalam masa 15 minit.", + "emails.otpSession.clientInfo": "Penandaan masuk ini telah diminta menggunakan {{agentClient}} pada {{agentDevice}} {{agentOs}}. Jika anda tidak meminta penandaan masuk, anda boleh mengabaikan emel ini dengan selamat.", + "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 6728b8152f..7199df00a5 100644 --- a/app/config/locale/translations/nb.json +++ b/app/config/locale/translations/nb.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}}-laget", "sms.verification.body": "{{secret}} er din {{project}} bekreftelseskode.", "emails.magicSession.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 innlogging.", - "emails.magicSession.optionUrl": "Hvis du ikke klarer å logge inn ved å bruke knappen ovenfor, vennligst besøk følgende lenke:" + "emails.magicSession.optionUrl": "Hvis du ikke klarer å logge inn ved å bruke knappen ovenfor, vennligst besøk følgende lenke:", + "emails.otpSession.subject": "{{project}} Innlogging", + "emails.otpSession.hello": "Hei,", + "emails.otpSession.description": "Skriv inn følgende verifiseringskode når du blir bedt om det for å logge på {{project}}-kontoen din på en sikker måte. Den vil utløpe om 15 minutter.", + "emails.otpSession.clientInfo": "Denne innloggingen ble forespurt ved hjelp av {{agentClient}} på {{agentDevice}} {{agentOs}}. Hvis du ikke ba om innloggingen, kan du trygt ignorere denne e-posten.", + "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 c55bb86e7b..928d53b163 100644 --- a/app/config/locale/translations/ne.json +++ b/app/config/locale/translations/ne.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "équipe {{project}}", "sms.verification.body": "{{secret}} तपाईंको {{project}} प्रमाणीकरण कोड हो।", "emails.magicSession.securityPhrase": "यस ईमेलको लागि सुरक्षा वाक्य {{phrase}} हो। यो वाक्य साइन इन गर्दा देखाइएको वाक्यसँग मेल खाए मात्र तपाईंले यस ईमेललाई विश्वास गर्न सक्नुहुन्छ।", - "emails.magicSession.optionUrl": "सँगै उल्लेख गरिएको बटन प्रयोग गरेर साइन इन गर्न असमर्थ हुनुहुन्छ भने, कृपया तलको लिंकमा भ्रमण गर्नुहोस्:" + "emails.magicSession.optionUrl": "सँगै उल्लेख गरिएको बटन प्रयोग गरेर साइन इन गर्न असमर्थ हुनुहुन्छ भने, कृपया तलको लिंकमा भ्रमण गर्नुहोस्:", + "emails.otpSession.subject": "{{project}} लगइन", + "emails.otpSession.hello": "नमस्ते,", + "emails.otpSession.description": "तपाईंलाई तपाईंको {{project}} खातामा सुरक्षित रूपमा साइन इन गर्न को लागि प्रेरित गर्दा तलको प्रमाणीकरण कोड प्रविष्ट गर्नुहोस्। यो १५ मिनेटमा समाप्त हुनेछ।", + "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/nl.json b/app/config/locale/translations/nl.json index c15b6785ad..327b413f7d 100644 --- a/app/config/locale/translations/nl.json +++ b/app/config/locale/translations/nl.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} team", "sms.verification.body": "{{secret}} is uw {{project}} verificatiecode.", "emails.magicSession.securityPhrase": "De beveiligingszin voor deze e-mail is {{phrase}}. U kunt deze e-mail vertrouwen als deze zin overeenkomt met de zin die getoond werd tijdens het aanmelden.", - "emails.magicSession.optionUrl": "Als u zich niet kunt aanmelden via de bovenstaande knop, bezoekt u dan de volgende link:" + "emails.magicSession.optionUrl": "Als u zich niet kunt aanmelden via de bovenstaande knop, bezoekt u dan de volgende link:", + "emails.otpSession.subject": "{{project}} Inloggen", + "emails.otpSession.hello": "Hallo,", + "emails.otpSession.description": "Voer de volgende verificatiecode in wanneer je wordt gevraagd om veilig in te loggen op je {{project}} account. Deze verloopt over 15 minuten.", + "emails.otpSession.clientInfo": "Deze aanmelding is aangevraagd met {{agentClient}} op {{agentDevice}} {{agentOs}}. Als u de aanmelding niet heeft aangevraagd, kunt u deze e-mail veilig negeren.", + "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 1391280b5b..d394c2a83f 100644 --- a/app/config/locale/translations/nn.json +++ b/app/config/locale/translations/nn.json @@ -229,16 +229,23 @@ "continents.na": "Nord-Amerika", "continents.oc": "Oseania", "continents.sa": "Sør-Amerika", - "emails.magicSession.optionButton": "Klikk på knappen under for å trygt logge inn på din {{project}}-konto. Den vil utløpe om 1 time.", - "emails.magicSession.buttonText": "Innlogging til {{project}}", - "emails.magicSession.clientInfo": "Denne innloggingen ble forespurt ved hjelp av {{agentClient}} på {{agentDevice}} {{agentOs}}. Hvis du ikke ba om innloggingen, kan du trygt se bort fra denne e-posten.", - "emails.certificate.subject": "Unfortunately, the country code \"nn\" is ambiguous, as it doesn't correspond to a recognized ISO 3166-1 alpha-2 country code. However, “nn” often refers to “Nynorsk,” one of the written standards of the Norwegian language. If you intended to translate the sentence into Nynorsk (Norwegian), here is the translation:\n\n\"Seritifikatsvikt for %s\"", - "emails.certificate.hello": "In order to translate the message to the target language corresponding to the country code \"nn,\" I need to clarify that \"nn\" is not a valid ISO country code. However, if you intended \"nn\" to stand for Nynorsk, which is one of the written standards of the Norwegian language (not to be confused with a country code), then the translation would be:\n\nHallo", - "emails.certificate.body": "Sertifikat for domenet ditt '{{domain}}' kunne ikke genereres. Dette er forsøk nr. {{attempt}}, og mislykkelsen ble forårsaket av: {{error}}", - "emails.certificate.footer": "Ditt førre sertifikat vil vere gyldig i 30 dagar etter den første feilen. Vi rår sterkt til å undersøke denne saka, elles vil domenet ditt ende opp utan ein gyldig SSL-kommunikasjon.", - "emails.certificate.thanks": "The country code \"nn\" provided is not sufficient to determine the target language as it does not correspond to an official ISO 3166-1 alpha-2 country code. Please provide more context or the specific target language you need the translation for.", - "emails.certificate.signature": "{{project}} lag", - "sms.verification.body": "Hemmelig er din prosjekt verifiseringskode.", - "emails.magicSession.securityPhrase": "For the country code \"nn\", there is no officially designated language. The country code \"NN\" is typically used as a placeholder in documentation for a country that is not specified. Please provide a valid country code or specify the target language for the translation.", - "emails.magicSession.optionUrl": "Dersom du ikkje klarer å logge inn ved å bruke knappen over, kan du gå til følgjande lenke:" + "emails.magicSession.optionButton": "Klikk på knappen nedanfor for å trygt logge inn på {{project}}-kontoen din. Den vil utløpe om 1 time.", + "emails.magicSession.buttonText": "Logg inn på {{project}}", + "emails.magicSession.optionUrl": "Om du ikkje kan logge inn ved å bruke knappen over, ver venleg og besøk følgjande lenke:", + "emails.magicSession.clientInfo": "Denne innlogginga blei etterspurd ved hjelp av {{agentClient}} på {{agentDevice}} {{agentOs}}. Om du ikkje ba om innlogginga, kan du trygt ignorere denne e-posten.", + "emails.magicSession.securityPhrase": "Sikkerheitsfrasen for denne e-posten er {{phrase}}. Du kan stole på denne e-posten om frasen stemmer med frasen som vart vist under innlogging.", + "emails.otpSession.subject": "{{project}} Innlogging", + "emails.otpSession.hello": "Hallo,", + "emails.otpSession.description": "Skriv inn denne verifikasjonskoden når du blir beden om å logge på {{project}}-kontoen din på ein sikker måte. Den vil gå ut på dato om 15 minuttar.", + "emails.otpSession.clientInfo": "Dette innloggingsforsøket ble forespurt ved hjelp av {{agentClient}} på {{agentDevice}} {{agentOs}}. Om du ikkje ba om innlogginga, kan du trygt ignorere denne e-posten.", + "emails.otpSession.securityPhrase": "Tryggingsfrasen for denne e-posten er {{phrase}}. Du kan stole på denne e-posten om frasen stemmer med frasen vist under pålogging.", + "emails.otpSession.thanks": "Takk,", + "emails.otpSession.signature": "{{project}}-laget", + "emails.certificate.subject": "Sertifikatfeil for %s", + "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.signature": "{{project}} team", + "sms.verification.body": "{{secret}} er verifiseringskoden din for {{project}}." } \ No newline at end of file diff --git a/app/config/locale/translations/or.json b/app/config/locale/translations/or.json index 7e49e58b1f..216ea16786 100644 --- a/app/config/locale/translations/or.json +++ b/app/config/locale/translations/or.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} команда", "sms.verification.body": "{{secret}} est votre code de vérification pour {{project}}.", "emails.magicSession.securityPhrase": "Frase de segurança para este e-mail é {{phrase}}. Você pode confiar neste e-mail se essa frase coincidir com a frase mostrada durante o acesso.", - "emails.magicSession.optionUrl": "אם אתם לא מצליחים להיכנס באמצעות הכפתור שמעל, אנא בקרו בקישור הבא:" + "emails.magicSession.optionUrl": "אם אתם לא מצליחים להיכנס באמצעות הכפתור שמעל, אנא בקרו בקישור הבא:", + "emails.otpSession.subject": "{{project}} ଲଗଇନ্", + "emails.otpSession.hello": "ନମସ୍କାର,", + "emails.otpSession.description": "ପ୍ରମାଣୀକରଣ କୋଡଟି ତାଲିକା କରନ୍ତୁ ଏବଂ ଯେତେ ବେଳେ ଆପଣଙ୍କୁ ପ୍ରାପ୍ତ ହେବ ସେତେବେଳେ ଆପଣଙ୍କ {{project}} ଆକାଉଣ୍ଟକୁ ସୁରକ୍ଷିତ ସାଇନ୍ ଇନ କରନ୍ତୁ। ଏହା ୧୫ ମିନିଟରେ ସମାପ୍ତ ହୋଇଯିବ।", + "emails.otpSession.clientInfo": "ଏହି ସାଇନ୍ ଇନ୍ ଅନୁରୋଧ କରାଯାଇଛି {{agentClient}} ଉପରେ {{agentDevice}} {{agentOs}} ବ୍ୟବହାର କରି। ଯଦି ଆପଣ ସାଇନ୍ ଇନ୍ ଅନୁରୋଧ କରି ନାହାଁନ୍ତି, ଆପଣ ସୁରକ୍ଷିତଭାବେ ଏହି ଇମେଲକୁ ଉପେକ୍ଷା କରିପାରନ୍ତି।", + "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 a65489174f..8e79976cac 100644 --- a/app/config/locale/translations/pa.json +++ b/app/config/locale/translations/pa.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equipo de {{project}}", "sms.verification.body": "El {{secret}} es tu código de verificación de {{project}}.", "emails.magicSession.securityPhrase": "La frase de seguridad para este correo electrónico es {{phrase}}. Puedes confiar en este correo si esta frase coincide con la frase que se muestra al iniciar sesión.", - "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón superior, por favor visita el siguiente enlace:" + "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón superior, por favor visita el siguiente enlace:", + "emails.otpSession.subject": "{{project}} ਲਾਗਿਨ", + "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/pl.json b/app/config/locale/translations/pl.json index f225115a86..71b91a3f22 100644 --- a/app/config/locale/translations/pl.json +++ b/app/config/locale/translations/pl.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "zespół {{project}}", "sms.verification.body": "{{secret}} jest twoim kodem weryfikacyjnym do {{project}}.", "emails.magicSession.securityPhrase": "Hasło bezpieczeństwa dla tego e-maila to {{phrase}}. Możesz ufać temu e-mailowi, jeśli hasło to jest zgodne z hasłem wyświetlonym podczas logowania.", - "emails.magicSession.optionUrl": "Jeśli nie możesz się zalogować, używając powyższego przycisku, odwiedź następujący link:" + "emails.magicSession.optionUrl": "Jeśli nie możesz się zalogować, używając powyższego przycisku, odwiedź następujący link:", + "emails.otpSession.subject": "Login do {{project}}", + "emails.otpSession.hello": "Cześć,", + "emails.otpSession.description": "Wpisz poniższy kod weryfikacyjny, gdy zostaniesz o to poproszony, aby bezpiecznie zalogować się na swoje konto {{project}}. Kod wygaśnie za 15 minut.", + "emails.otpSession.clientInfo": "To logowanie zostało zażądane przy użyciu {{agentClient}} na {{agentDevice}} {{agentOs}}. Jeśli nie zażądałeś logowania, możesz bezpiecznie zignorować tę wiadomość e-mail.", + "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 fa15c32232..3f2fbc71b1 100644 --- a/app/config/locale/translations/pt-br.json +++ b/app/config/locale/translations/pt-br.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equipe {{project}}", "sms.verification.body": "{{secret}} é o seu código de verificação do {{project}}.", "emails.magicSession.securityPhrase": "A frase de segurança para este e-mail é {{phrase}}. Você pode confiar neste e-mail se essa frase corresponder à frase mostrada durante o acesso.", - "emails.magicSession.optionUrl": "Se você não consegue fazer login usando o botão acima, por favor visite o seguinte link:" + "emails.magicSession.optionUrl": "Se você não consegue fazer login usando o botão acima, por favor visite o seguinte link:", + "emails.otpSession.subject": "Login do {{project}}", + "emails.otpSession.hello": "Olá,", + "emails.otpSession.description": "Insira o seguinte código de verificação quando solicitado para acessar de forma segura a sua conta {{project}}. Ele expirará em 15 minutos.", + "emails.otpSession.clientInfo": "Este acesso foi solicitado usando {{agentClient}} em {{agentDevice}} {{agentOs}}. Se você não solicitou o acesso, pode ignorar este e-mail com segurança.", + "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 dd788a6161..e6764cfae7 100644 --- a/app/config/locale/translations/pt-pt.json +++ b/app/config/locale/translations/pt-pt.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equipa {{project}}", "sms.verification.body": "{{secret}} é o seu código de verificação do {{project}}.", "emails.magicSession.securityPhrase": "A frase de segurança deste e-mail é {{phrase}}. Pode confiar neste e-mail se esta frase coincidir com a frase mostrada durante o início de sessão.", - "emails.magicSession.optionUrl": "Se não conseguir iniciar sessão utilizando o botão acima, por favor visite o seguinte link:" + "emails.magicSession.optionUrl": "Se não conseguir iniciar sessão utilizando o botão acima, por favor visite o seguinte link:", + "emails.otpSession.subject": "Login do {{project}}", + "emails.otpSession.hello": "Olá,", + "emails.otpSession.description": "Digite o seguinte código de verificação quando solicitado para acessar de forma segura a sua conta {{project}}. Ele irá expirar em 15 minutos.", + "emails.otpSession.clientInfo": "Este pedido de entrada foi feito usando {{agentClient}} em {{agentDevice}} {{agentOs}}. Se você não solicitou o acesso, pode ignorar este e-mail com segurança.", + "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 9657c092b9..d7257f3a79 100644 --- a/app/config/locale/translations/ro.json +++ b/app/config/locale/translations/ro.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "echipa {{project}}", "sms.verification.body": "{{secret}} este codul de verificare pentru {{project}}.", "emails.magicSession.securityPhrase": "Frază de securitate pentru acest e-mail este {{phrase}}. Puteți avea încredere în acest e-mail dacă fraza se potrivește cu fraza afișată în timpul autentificării.", - "emails.magicSession.optionUrl": "Dacă nu puteți să vă autentificați folosind butonul de mai sus, vă rugăm să vizitați următorul link:" + "emails.magicSession.optionUrl": "Dacă nu puteți să vă autentificați folosind butonul de mai sus, vă rugăm să vizitați următorul link:", + "emails.otpSession.subject": "Conectare {{project}}", + "emails.otpSession.hello": "Bună,", + "emails.otpSession.description": "Introduceți următorul cod de verificare atunci când vi se solicită pentru a vă autentifica în siguranță la contul dvs. {{project}}. Acesta va expira în 15 minute.", + "emails.otpSession.clientInfo": "Această solicitare de autentificare a fost efectuată folosind {{agentClient}} pe {{agentDevice}} {{agentOs}}. Dacă nu ați cerut autentificarea, puteți ignora în siguranță acest email.", + "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 1b360d0057..b75202b438 100644 --- a/app/config/locale/translations/ru.json +++ b/app/config/locale/translations/ru.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "команда {{project}}", "sms.verification.body": "{{secret}} – это ваш код подтверждения для {{project}}.", "emails.magicSession.securityPhrase": "Фраза безопасности для этого электронного письма - {{phrase}}. Вы можете доверять этому письму, если эта фраза совпадает с фразой, отображаемой при входе в систему.", - "emails.magicSession.optionUrl": "Если вы не можете войти, используя кнопку выше, пожалуйста, посетите следующую ссылку:" + "emails.magicSession.optionUrl": "Если вы не можете войти, используя кнопку выше, пожалуйста, посетите следующую ссылку:", + "emails.otpSession.subject": "Вход в систему {{project}}", + "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/sa.json b/app/config/locale/translations/sa.json index 2e75777731..3534e02684 100644 --- a/app/config/locale/translations/sa.json +++ b/app/config/locale/translations/sa.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "فريق {{project}}", "sms.verification.body": "سري هو رمز التحقق الخاص بمشروعك.", "emails.magicSession.securityPhrase": "العبارة الأمنية لهذا البريد الإلكتروني هي {{phrase}}. يمكنك الوثوق بهذا البريد الإلكتروني إذا كانت هذه العبارة متطابقة مع العبارة المعروضة أثناء تسجيل الدخول.", - "emails.magicSession.optionUrl": "إذا لم تتمكن من تسجيل الدخول باستخدام الزر أعلاه، يرجى زيارة الرابط التالي:" + "emails.magicSession.optionUrl": "إذا لم تتمكن من تسجيل الدخول باستخدام الزر أعلاه، يرجى زيارة الرابط التالي:", + "emails.otpSession.subject": "प्रवेशनम्", + "emails.otpSession.hello": "नमस्ते।", + "emails.otpSession.description": "प्रविष्ट कुरु अनुसृत विश्वासनीयकोडम् यदा पृच्छ्यसे भवतः {{project}} खातायां सुरक्षितरूपेण प्रवेशे। एषः पन्द्रह मिनितेषु समाप्तिं गच्छति।", + "emails.otpSession.clientInfo": "एष प्रवेशनं प्रार्थितं {{agentClient}} नाम प्रतिनिधौ {{agentDevice}} {{agentOs}} इत्यस्मिन्। यदि त्वमेव प्रवेशनं न प्रार्थितवानसि, तर्हि त्वमनेन ईपत्रेण उपेक्षितुं शक्नोसि।", + "emails.otpSession.securityPhrase": "अस्य ईमेलस्य सुरक्षा वाक्यं {{phrase}} अस्ति। यदि अयं वाक्यः प्रवेशकाले दृष्टवाक्येन साम्यं याति तर्हि अस्माकं ईमेलं विश्वसनीयम् अस्ति।", + "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 4c8059f297..0d8f614566 100644 --- a/app/config/locale/translations/sd.json +++ b/app/config/locale/translations/sd.json @@ -229,16 +229,23 @@ "continents.na": "اتر آمريڪا", "continents.oc": "اوشينيا", "continents.sa": "ڏکڻ آمريڪا", - "emails.magicSession.optionButton": "محفوظ طريقہ سے اپنے {{project}} اکاؤنٹ میں داخل ہونے کے لئے نيچے دئے گئے بٹن پر کلک کریں۔ یہ ایک گھنٹے ميں ختم ہو جائے گا۔", - "emails.magicSession.buttonText": "It seems that you're referring to a country code \"sd\" which typically represents Sudan. The official languages in Sudan are Arabic and English. Without specific instruction for Arabic, I will provide the translation in Arabic:\n\nتسجيل الدخول إلى {{project}}", - "emails.magicSession.clientInfo": "هن وقت جي لاڳ ان جي درخواست {{agentClient}} تي ڪئي وئي آهي {{agentDevice}} {{agentOs}} تي. جيڪڏهن توهان کي لاڳ ان جي درخواست نه جي آهي، توهان اهو ایميل نظر انداز ڪري سگهو ٿا.", - "emails.certificate.subject": "شهادة فشل ل %s", - "emails.certificate.hello": "مرحبا", - "emails.certificate.body": "I'm sorry, but there is no country code \"sd.\" If you meant Sudan, the country code is \"SD,\" not lowercase, but the official languages of Sudan are Arabic and English. If you need a translation into Arabic, here is the message:\n\nشهادة لنطاق '{{domain}}' الخاص بك لم تتمكن من التوليد. هذه هي المحاولة رقم {{attempt}}، وكان الفشل بسبب: {{error}}", - "emails.certificate.footer": "سابقه سند توهان جي پهلي ناكامي کان 30 ڏينهن لاءِ موزون آهي. اسان توهان کي پوري قائلي سان گهڻي سفارش ڪنداسين ته هن ڪيس کي تحقيق ڪريو، نه ته توهان جو ڊومين بغير موزون SSL مواصلتي جي حالت ۾ ختم ٿي ويندو.", - "emails.certificate.thanks": "شكرا", - "emails.certificate.signature": "I believe there has been a misunderstanding. The country code \"sd\" refers to Sudan, and the official languages of Sudan are Arabic and English. If you are requesting a translation into Arabic, the phrase \"project team\" would be \"فريق المشروع\". If you need a translation into a different language, please provide the correct language or country code.", - "sms.verification.body": "وڊو is your {{project}} جي تصديق ڪوڊ.", - "emails.magicSession.securityPhrase": "محفوظ جملو آهي هن اي ميل لاءِ {{phrase}}. توهان هن اي ميل تي اعتماد ڪري سگهو ٿا جيڪڏهن اهو جملو توهان کي سائن ان ڪرڻ وقت داخل ٿيل جملي سان ملي ويسي.", - "emails.magicSession.optionUrl": "You have provided \"sd\" as the country code; however, \"sd\" is not a valid ISO 3166-1 alpha-2 country code. If you meant \"sd\" to refer to the Sindhi language code, the translation would be:\n\n\"جيڪڏھن توھان مٿي واريل بٽڪَ جي مدد سان سائن ان ڪرڻ ۾ ناڪام آھيو، ته مھرباني ڪري هيٺيان ديئل لنڪ جو ڏورو قدم چونڊو:\"" + "emails.magicSession.optionButton": "هيٺيون بٽڻ دبايو توهان جي {{project}} اڪائونٽ مان محفوظ طريقي سان سائن ان ڪرڻ لاءِ. اهو 1 ڪلاڪ ۾ ختم ٿي ويندو آهي.", + "emails.magicSession.buttonText": "{{project}} ۾ سائن ان ڪريو", + "emails.magicSession.optionUrl": "جيڪڏهن توهان اُپرءَ دئي ويندي بٽڻ کان سائن ان ڪرڻ ۾ ناڪام آهيو، ته مهرباني ڪري هيٺين دنل لنڪ تي ملاحظو ڪريو:", + "emails.magicSession.clientInfo": "هي سائن ان درخواست ورتو {{agentClient}} استعمال ڪري ٿو {{agentDevice}} {{agentOs}}. جيڪڏهن توهان سائن ان جي درخواست ڪئي نه ورتي، ته توهان هن اي ميل کي محفوظ طور تي نظر انداز ڪري سگهو ٿا.", + "emails.magicSession.securityPhrase": "اس ای میل جو سیکيورٽي جملو {{phrase}} آهي. جيڪڏهن هن جملو توهان جي سائن ان وقتي ڏيکاري واري جملي سان ميل آهي ته توهان اس ای میل تي اعتماد ڪري سگھو ٿا.", + "emails.otpSession.subject": "پروجيڪٽ جي لاگ ان", + "emails.otpSession.hello": "ہيلو،", + "emails.otpSession.description": "جڏهن توهان کي محفوظ طريقي سان اپني {{project}} اڪائونٽ ۾ سائن ان ڪرڻ لاءِ ڪہي ويندي، ته هيٺيان دنل ويريفڪيشن ڪوڊ ڏيو. هي 15 منٽن ۾ ختم ٿي ويندي.", + "emails.otpSession.clientInfo": "هي سائن ان توهان جو درخواست گهريو ويو آهي {{agentClient}} جي واپار ۾ {{agentDevice}} {{agentOs}} تي. جيڪڏهن توهان سائن ان جي درخواست ڪئي نه آهي، ته توهان هن ايميل کي نظر انداز ڪري سگهو ٿا.", + "emails.otpSession.securityPhrase": "هن ای میل لاءِ سیکيورٽي جملو {{phrase}} آھي. توهان هن ای میل تي اعتماد ڪري سگهو ٿا جيڪڏهن هن جملو لاڳو ٿيندڙ جملي سان ميل کاندي.", + "emails.otpSession.thanks": "مهرباني", + "emails.otpSession.signature": "پروجيڪٽ جي ٽيم", + "emails.certificate.subject": "%s لاءِ سند جو ناکامی", + "emails.certificate.hello": "هيلو", + "emails.certificate.body": "توهان جي ڊومين '{{domain}}' لاءِ سرٽيفڪيٽ ٺاهڻ جو نه ٿي سگهيو. هي ڪوشش نمبر {{attempt}} آهي، ۽ ناڪامي جو سبب ٿيو: {{error}}", + "emails.certificate.footer": "توهان جو اڳيون سرٽيفڪيٽ اولهو فئيلر جي ݙينهن کان ٣٠ ݙينهن لاءِ ماني ويندو. اسان ان جي چھان بني جي بھرپور خواهش ڪنداسين، نہ ته توهان جو ݙومين بغير ڪوري SSL ڪميونڪيشن آڻي ويندي.", + "emails.certificate.thanks": "شُكريا", + "emails.certificate.signature": "ٽيم", + "sms.verification.body": "{{secret}} توهان جي {{project}} تصديقي ڪوڊ آهي." } \ No newline at end of file diff --git a/app/config/locale/translations/si.json b/app/config/locale/translations/si.json index 68b6c3cbbd..8107d62587 100644 --- a/app/config/locale/translations/si.json +++ b/app/config/locale/translations/si.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} ekipa", "sms.verification.body": "{{secret}} je vaša {{project}} koda za preverjanje.", "emails.magicSession.securityPhrase": "Zaščitna fraza za ta e-poštni naslov je {{phrase}}. Temu e-poštnemu naslovu lahko zaupate, če se ta fraza ujema s frazo, prikazano med prijavo.", - "emails.magicSession.optionUrl": "Če se z zgornjim gumbom ne morete prijaviti, obiščite naslednjo povezavo:" + "emails.magicSession.optionUrl": "Če se z zgornjim gumbom ne morete prijaviti, obiščite naslednjo povezavo:", + "emails.otpSession.subject": "{{project}} පිවිසුම", + "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/sk.json b/app/config/locale/translations/sk.json index a51e3fb586..7662c516b7 100644 --- a/app/config/locale/translations/sk.json +++ b/app/config/locale/translations/sk.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "tím {{project}}", "sms.verification.body": "{{secret}} je váš overovací kód pre {{project}}.", "emails.magicSession.securityPhrase": "Bezpečnostná fráza pre tento email je {{phrase}}. Tomuto emailu môžete dôverovať, ak sa táto fráza zhoduje s frázou zobrazenou počas prihlásenia.", - "emails.magicSession.optionUrl": "Ak sa vám nedarí prihlásiť sa pomocou vyššie uvedeného tlačidla, prosím navštívte nasledujúci odkaz:" + "emails.magicSession.optionUrl": "Ak sa vám nedarí prihlásiť sa pomocou vyššie uvedeného tlačidla, prosím navštívte nasledujúci odkaz:", + "emails.otpSession.subject": "Prihlásenie do projektu {{project}}", + "emails.otpSession.hello": "Dobrý deň,", + "emails.otpSession.description": "Zadajte nasledovný overovací kód, keď budete vyzvaní, aby ste sa bezpečne prihlásili na svoj účet {{project}}. Platnosť kódu vyprší za 15 minút.", + "emails.otpSession.clientInfo": "Toto prihlásenie bolo vyžiadané pomocou {{agentClient}} na {{agentDevice}} {{agentOs}}. Ak ste prihlásenie nevyžiadali, tento e-mail môžete bezpečne ignorovať.", + "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 8384d4564b..bd4f391238 100644 --- a/app/config/locale/translations/sl.json +++ b/app/config/locale/translations/sl.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} ekipa", "sms.verification.body": "{{secret}} je vaša koda za preverjanje {{project}}.", "emails.magicSession.securityPhrase": "Varnostni stavek za to e-pošto je {{phrase}}. Temu e-poštu lahko zaupate, če se ta stavek ujema s stavkom, prikazanim ob prijavi.", - "emails.magicSession.optionUrl": "Če se ne morete prijaviti s pomočjo zgornjega gumba, prosimo obiščite naslednjo povezavo:" + "emails.magicSession.optionUrl": "Če se ne morete prijaviti s pomočjo zgornjega gumba, prosimo obiščite naslednjo povezavo:", + "emails.otpSession.subject": "Prijavite se v {{project}}", + "emails.otpSession.hello": "Živijo,", + "emails.otpSession.description": "Vnesite naslednjo preverovalno kodo, ko boste pozvani, da se varno prijavite v svoj račun {{project}}. Koda bo potekla čez 15 minut.", + "emails.otpSession.clientInfo": "Za to prijavo je bila uporabljena {{agentClient}} na {{agentDevice}} {{agentOs}}. Če niste zahtevali prijave, lahko to e-pošto varno prezrete.", + "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 549461ad8c..0323c5740d 100644 --- a/app/config/locale/translations/sn.json +++ b/app/config/locale/translations/sn.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "équipe {{project}}", "sms.verification.body": "{{secret}} mooy sa koodu vérificationu {{project}} bi.", "emails.magicSession.securityPhrase": "La phrase de sécurité pour ce courriel est {{phrase}}. Vous pouvez faire confiance à ce courriel si cette phrase correspond à la phrase affichée lors de la connexion.", - "emails.magicSession.optionUrl": "Si vous ne pouvez pas vous connecter en utilisant le bouton ci-dessus, veuillez visiter le lien suivant :" + "emails.magicSession.optionUrl": "Si vous ne pouvez pas vous connecter en utilisant le bouton ci-dessus, veuillez visiter le lien suivant :", + "emails.otpSession.subject": "{{project}} Kupinda", + "emails.otpSession.hello": "Mhoro,", + "emails.otpSession.description": "Pinda kodhi yekusimbisa inotevera kana wakumbirwa kuti upinde zvakachengetedzeka muakaundi yako ye{{project}}. Ichapera munguva yemaminitsi gumi nemashanu.", + "emails.otpSession.clientInfo": "Chikumbiro chekupinda ichi chakumbirwa uchishandisa {{agentClient}} pa{{agentDevice}} {{agentOs}}. Kana iwe usina kukumbira kupinda, unogona kufuratira email iyi zvakachengeteka.", + "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 cd3ccdc0e5..5f8d69fb3e 100644 --- a/app/config/locale/translations/sq.json +++ b/app/config/locale/translations/sq.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ekipi i {{project}}", "sms.verification.body": "{{secret}} është kodi juaj i verifikimit për {{project}}.", "emails.magicSession.securityPhrase": "Fjalia e sigurisë për këtë email është {{phrase}}. Mund të besoni këtë email nëse kjo fjali përputhet me fjalën e shfaqur gjatë hyrjes në sistem.", - "emails.magicSession.optionUrl": "Nëse nuk mund të hyni duke përdorur butonin më sipër, ju lutem vizitoni lidhjen e mëposhtme:" + "emails.magicSession.optionUrl": "Nëse nuk mund të hyni duke përdorur butonin më sipër, ju lutem vizitoni lidhjen e mëposhtme:", + "emails.otpSession.subject": "{{project}} Hyrje", + "emails.otpSession.hello": "Përshëndetje,", + "emails.otpSession.description": "Shkruaj kodin e mëposhtëm të verifikimit kur të kërkohet për t'u kyçur në mënyrë të sigurt në llogarinë tënde {{project}}. Do të skadojë pas 15 minutash.", + "emails.otpSession.clientInfo": "Ky hyrje u kërkua duke përdorur {{agentClient}} në {{agentDevice}} {{agentOs}}. Nëse nuk e keni kërkuar hyrjen, mund ta injoroni këtë email pa asnjë problem.", + "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 12d5c7eb6b..9d4479a5d9 100644 --- a/app/config/locale/translations/sv.json +++ b/app/config/locale/translations/sv.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "equipo {{project}}", "sms.verification.body": "{{secret}} är din {{project}} verifieringskod.", "emails.magicSession.securityPhrase": "Frasen för säkerhet i detta e-postmeddelande är {{phrase}}. Du kan lita på detta e-postmeddelande om frasen stämmer överens med den fras som visas vid inloggning.", - "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón de arriba, por favor visita el siguiente enlace:" + "emails.magicSession.optionUrl": "Si no puedes iniciar sesión utilizando el botón de arriba, por favor visita el siguiente enlace:", + "emails.otpSession.subject": "{{project}} Inloggning", + "emails.otpSession.hello": "Hej,", + "emails.otpSession.description": "Ange följande verifieringskod när du uppmanas att säkert logga in på ditt {{project}}-konto. Den kommer att löpa ut om 15 minuter.", + "emails.otpSession.clientInfo": "Den här inloggningsbegäran gjordes med {{agentClient}} på {{agentDevice}} {{agentOs}}. Om du inte har begärt inloggningen kan du ignorera detta e-postmeddelande.", + "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 1d72f47c93..7622fc19bb 100644 --- a/app/config/locale/translations/ta.json +++ b/app/config/locale/translations/ta.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} குழு", "sms.verification.body": "{{secret}} உங்கள் {{project}} சரிபார்ப்பு குறியீடு ஆகும்.", "emails.magicSession.securityPhrase": "இந்த மின்னஞ்சலுக்கான பாதுகாப்பு வாசகம் {{phrase}}. இந்த வாசகம் உள்நுழைவு போது காட்டப்பட்ட வாசகத்துடன் பொருந்தும் போது இந்த மின்னஞ்சலை நம்பலாம்.", - "emails.magicSession.optionUrl": "மேலே உள்ள பொத்தானை பயன்படுத்தி உள்நுழைய முடியாவிட்டால், கீழே உள்ள இணைப்பை பார்வையிடவும்:" + "emails.magicSession.optionUrl": "மேலே உள்ள பொத்தானை பயன்படுத்தி உள்நுழைய முடியாவிட்டால், கீழே உள்ள இணைப்பை பார்வையிடவும்:", + "emails.otpSession.subject": "{{project}} உள்நுழைவு", + "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/te.json b/app/config/locale/translations/te.json index d87ae4ccce..312bc01a16 100644 --- a/app/config/locale/translations/te.json +++ b/app/config/locale/translations/te.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} జట్టు", "sms.verification.body": "{{secret}} మీ {{project}} ధృవీకరణ కోడ్.", "emails.magicSession.securityPhrase": "ఈ ఇమెయిల్ కోసం భద్రతా పదబంధం {{phrase}}. మీరు సైన్ ఇన్ సమయంలో చూపబడిన పదబంధంతో ఈ పదబంధం సరిపోలుతుంది అయితే ఈ ఇమెయిల్ నమ్మవచ్చు.", - "emails.magicSession.optionUrl": "పైన ఉన్న బటన్‌ను ఉపయోగించి సైన్ ఇన్ చేయలేకపోతే, దయచేసి క్రింది లింక్‌ను సందర్శించండి:" + "emails.magicSession.optionUrl": "పైన ఉన్న బటన్‌ను ఉపయోగించి సైన్ ఇన్ చేయలేకపోతే, దయచేసి క్రింది లింక్‌ను సందర్శించండి:", + "emails.otpSession.subject": "{{project}} లాగిన్", + "emails.otpSession.hello": "హలో,", + "emails.otpSession.description": "మీ {{project}} ఖాతాలో భద్రంగా సైన్ ఇన్ చేసేటప్పుడు మీకు అభ్యర్థించినప్పుడు క్రింది ధ్రువీకరణ కోడ్‌ని నమోదు చేయండి. అది 15 నిమిషాల్లో గడువు తీరుతుంది.", + "emails.otpSession.clientInfo": "ఈ సైన్ ఇన్‌ను {{agentClient}} ఉపయోగించి {{agentDevice}} {{agentOs}}పై అభ్యర్థించారు. మీరు ఈ సైన్ ఇన్‌ను అభ్యర్థించకపోతే, ఈ ఈమెయిల్‌ను సురక్షితంగా ఉపేక్షించవచ్చు.", + "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 14ed815d77..0491723347 100644 --- a/app/config/locale/translations/th.json +++ b/app/config/locale/translations/th.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ทีม {{project}}", "sms.verification.body": "{{secret}} เป็นรหัสการตรวจสอบ{{project}}ของคุณ.", "emails.magicSession.securityPhrase": "วลีรักษาความปลอดภัยสำหรับอีเมลนี้คือ {{phrase}} คุณสามารถเชื่อถืออีเมลนี้ได้หากวลีนี้ตรงกับวลีที่แสดงในระหว่างการเข้าสู่ระบบ", - "emails.magicSession.optionUrl": "หากคุณไม่สามารถเข้าสู่ระบบโดยใช้ปุ่มด้านบน โปรดเยี่ยมชมลิงก์ต่อไปนี้:" + "emails.magicSession.optionUrl": "หากคุณไม่สามารถเข้าสู่ระบบโดยใช้ปุ่มด้านบน โปรดเยี่ยมชมลิงก์ต่อไปนี้:", + "emails.otpSession.subject": "การเข้าสู่ระบบ {{project}}", + "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 0b147e14fa..ce9c03d26b 100644 --- a/app/config/locale/translations/tl.json +++ b/app/config/locale/translations/tl.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} koponan", "sms.verification.body": "{{secret}} ay ang iyong {{project}} verification code.", "emails.magicSession.securityPhrase": "Ang pariralang pangseguridad para sa email na ito ay {{phrase}}. Maaari mong pagkatiwalaan ang email na ito kung ang pariralang ito ay tumutugma sa pariralang ipinakita noong nag-sign in ka.", - "emails.magicSession.optionUrl": "Kung hindi ka makapag-sign in gamit ang pindutan sa itaas, mangyaring bisitahin ang sumusunod na link:" + "emails.magicSession.optionUrl": "Kung hindi ka makapag-sign in gamit ang pindutan sa itaas, mangyaring bisitahin ang sumusunod na link:", + "emails.otpSession.subject": "{{project}} Pag-login", + "emails.otpSession.hello": "Kamusta,", + "emails.otpSession.description": "Ilagay ang sumusunod na verification code kapag hiningi para ligtas na makapag-sign in sa iyong {{project}} account. Ito ay mag-eexpire sa loob ng 15 minuto.", + "emails.otpSession.clientInfo": "Ang pag-sign in na ito ay hiniling gamit ang {{agentClient}} sa {{agentDevice}} {{agentOs}}. Kung hindi ikaw ang humiling ng pag-sign in, maaari mong ligtas na balewalain ang email na ito.", + "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 f042e437d4..07e36dd3ff 100644 --- a/app/config/locale/translations/tr.json +++ b/app/config/locale/translations/tr.json @@ -240,5 +240,12 @@ "emails.magicSession.optionUrl": "Yukarıdaki buton gözükmezse, aşağıdaki bağlantıyı kullanın:", "emails.magicSession.clientInfo": "Bu oturum açma işlemi, {{agentClient}} kullanılarak {{agentDevice}} {{agentOs}} üzerinde istendi. Eğer oturum açma işlemini siz talep etmediyseniz, bu e-postayı güvenle yok sayabilirsiniz.", "sms.verification.body": "{{secret}} sizin {{project}} doğrulama kodunuzdur.", - "emails.magicSession.securityPhrase": "Bu e-postanın güvenlik ifadesi {{phrase}}'dir. Bu ifade, giriş sırasında gösterilen ifadeyle eşleşiyorsa bu e-postaya güvenebilirsiniz." + "emails.magicSession.securityPhrase": "Bu e-postanın güvenlik ifadesi {{phrase}}'dir. Bu ifade, giriş sırasında gösterilen ifadeyle eşleşiyorsa bu e-postaya güvenebilirsiniz.", + "emails.otpSession.subject": "{{project}} Giriş", + "emails.otpSession.hello": "Merhaba,", + "emails.otpSession.description": "İstendiğinde {{project}} hesabınıza güvenli bir şekilde giriş yapmak için aşağıdaki doğrulama kodunu girin. Bu kod 15 dakika içinde geçerliliğini yitirecektir.", + "emails.otpSession.clientInfo": "Bu oturum açma işlemi, {{agentDevice}} {{agentOs}} üzerinde {{agentClient}} kullanılarak talep edildi. Eğer oturum açma isteğinde bulunmadıysanız, bu e-postayı güvenle yok sayabilirsiniz.", + "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 19cf15d955..7ed722d9bc 100644 --- a/app/config/locale/translations/uk.json +++ b/app/config/locale/translations/uk.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "команда {{project}}", "sms.verification.body": "{{secret}} є вашим кодом підтвердження для {{project}}.", "emails.magicSession.securityPhrase": "Фраза безпеки для цього листа - {{phrase}}. Ви можете довіряти цьому листу, якщо ця фраза збігається з фразою, показаною під час входу в систему.", - "emails.magicSession.optionUrl": "Якщо вам не вдається увійти, використовуючи кнопку вище, будь ласка, перейдіть за наступним посиланням:" + "emails.magicSession.optionUrl": "Якщо вам не вдається увійти, використовуючи кнопку вище, будь ласка, перейдіть за наступним посиланням:", + "emails.otpSession.subject": "вхід в {{project}}", + "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/ur.json b/app/config/locale/translations/ur.json index deda8eeaa7..9df421beec 100644 --- a/app/config/locale/translations/ur.json +++ b/app/config/locale/translations/ur.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "ٹیم {{project}}", "sms.verification.body": "{{secret}} آپ کے {{project}} تصدیقی کوڈ ہے۔", "emails.magicSession.securityPhrase": "اس ای میل کے لئے سیکیورٹی جملہ {{phrase}} ہے۔ اگر یہ جملہ سائن ان کے دوران دکھائے گئے جملے سے میل کھاتا ہے تو آپ اس ای میل پر بھروسہ کرسکتے ہیں۔", - "emails.magicSession.optionUrl": "اگر آپ اوپر دیے گئے بٹن کا استعمال کرکے سائن ان نہیں کر سکتے تو براہ کرم مندرجہ ذیل لنک پر جائیں:" + "emails.magicSession.optionUrl": "اگر آپ اوپر دیے گئے بٹن کا استعمال کرکے سائن ان نہیں کر سکتے تو براہ کرم مندرجہ ذیل لنک پر جائیں:", + "emails.otpSession.subject": "{{project}} لاگ ان", + "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/vi.json b/app/config/locale/translations/vi.json index 31ac4bb7a1..90ef830e18 100644 --- a/app/config/locale/translations/vi.json +++ b/app/config/locale/translations/vi.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "đội {{project}}", "sms.verification.body": "{{secret}} là mã xác minh {{project}} của bạn.", "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.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.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.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 6b3c75892c..65c3b4d2d1 100644 --- a/app/config/locale/translations/zh-cn.json +++ b/app/config/locale/translations/zh-cn.json @@ -240,5 +240,12 @@ "emails.certificate.signature": "{{project}} 团队", "sms.verification.body": "{{secret}} 是您的 {{project}} 验证码。", "emails.magicSession.securityPhrase": "此电子邮件的安全短语是{{phrase}}。如果此短语与登录时显示的短语相匹配,则您可以信任此电子邮件。", - "emails.magicSession.optionUrl": "如果您无法使用上面的按钮登录,请访问以下链接:" + "emails.magicSession.optionUrl": "如果您无法使用上面的按钮登录,请访问以下链接:", + "emails.otpSession.subject": "{{project}} 登录", + "emails.otpSession.hello": "你好,\n", + "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/zh-tw.json b/app/config/locale/translations/zh-tw.json index 7d98ead9f3..26c212b3b3 100644 --- a/app/config/locale/translations/zh-tw.json +++ b/app/config/locale/translations/zh-tw.json @@ -240,5 +240,12 @@ "emails.magicSession.optionUrl": "如果上面的按鈕沒有顯示,請使用以下鏈接:", "emails.magicSession.clientInfo": "這次的登入是透過{{agentClient}}在{{agentDevice}} {{agentOs}}上請求的。如果您沒有請求這次登入,您可以放心地忽略這封電子郵件。", "sms.verification.body": "{{secret}} 是您的 {{project}} 驗證碼。", - "emails.magicSession.securityPhrase": "這封電子郵件的安全密語是{{phrase}}。如果此密語與登入時顯示的密語相符,您就可以信任此郵件。" + "emails.magicSession.securityPhrase": "這封電子郵件的安全密語是{{phrase}}。如果此密語與登入時顯示的密語相符,您就可以信任此郵件。", + "emails.otpSession.subject": "{{project}} 登入", + "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/controllers/api/account.php b/app/controllers/api/account.php index 2bc2096855..b42844a579 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -236,10 +236,8 @@ App::post('/v1/account/sessions/email') $user->setAttributes($profile->getArrayCopy()); $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); - $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); $secret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION); $session = new Document(array_merge( [ @@ -252,6 +250,7 @@ App::post('/v1/account/sessions/email') 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $duration) ], $detector->getOS(), $detector->getClient(), @@ -283,6 +282,8 @@ App::post('/v1/account/sessions/email') ; } + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); + $response ->addCookie(Auth::$cookieName . '_legacy', Auth::encodeSession($user->getId(), $secret), (new \DateTime($expire))->getTimestamp(), '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), (new \DateTime($expire))->getTimestamp(), '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) @@ -294,7 +295,6 @@ App::post('/v1/account/sessions/email') $session ->setAttribute('current', true) ->setAttribute('countryName', $countryName) - ->setAttribute('expire', $expire) ->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? Auth::encodeSession($user->getId(), $secret) : '') ; @@ -596,8 +596,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') } $sessions = $user->getAttribute('sessions', []); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - $current = Auth::sessionVerify($sessions, Auth::$secret, $authDuration); + $current = Auth::sessionVerify($sessions, Auth::$secret); if ($current) { // Delete current session of new one. $currentDocument = $dbForProject->getDocument('sessions', $current); @@ -829,6 +828,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $duration) ], $detector->getOS(), $detector->getClient(), $detector->getDevice())); $session = $dbForProject->createDocument('sessions', $session->setAttribute('$permissions', [ @@ -867,6 +867,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') $state['success']['query'] = URLParser::unparseQuery($query); $state['success'] = URLParser::unparse($state['success']); + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); + $response ->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0') ->addHeader('Pragma', 'no-cache') @@ -1091,7 +1093,6 @@ App::post('/v1/account/tokens/magic-url') $url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $tokenSecret, 'expire' => $expire, 'project' => $project->getId()]); $url = Template::unParseURL($url); - $body = $locale->getText("emails.magicSession.body"); $subject = $locale->getText("emails.magicSession.subject"); $customTemplate = $project->getAttribute('templates', [])['email.magicSession-' . $locale->default] ?? []; @@ -1102,7 +1103,6 @@ App::post('/v1/account/tokens/magic-url') $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-magic-url.tpl'); $message - ->setParam('{{body}}', $body) ->setParam('{{hello}}', $locale->getText("emails.magicSession.hello")) ->setParam('{{optionButton}}', $locale->getText("emails.magicSession.optionButton")) ->setParam('{{buttonText}}', $locale->getText("emails.magicSession.buttonText")) @@ -1172,9 +1172,237 @@ App::post('/v1/account/tokens/magic-url') 'team' => '', 'project' => $project->getAttribute('name'), 'redirect' => $url, - 'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN', - 'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN', - 'agentOs' => $agentOs['osName'] ?? 'UNKNOWN', + 'agentDevice' => '' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '', + 'agentClient' => '' . ($agentClient['clientName'] ?? 'UNKNOWN') . '', + 'agentOs' => '' . ($agentOs['osName'] ?? 'UNKNOWN') . '', + 'phrase' => '' . (!empty($securityPhrase) ? $securityPhrase : '') . '' + ]; + + $queueForMails + ->setSubject($subject) + ->setBody($body) + ->setVariables($emailVariables) + ->setRecipient($email) + ->trigger(); + + $queueForEvents->setPayload( + $response->output( + $token->setAttribute('secret', $tokenSecret), + Response::MODEL_TOKEN + ) + ); + + // Hide secret for clients + $token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $tokenSecret : ''); + + if (!empty($securityPhrase)) { + $token->setAttribute('securityPhrase', $securityPhrase); + } + + $response + ->setStatusCode(Response::STATUS_CODE_CREATED) + ->dynamic($token, Response::MODEL_TOKEN) + ; + }); + +App::post('/v1/account/tokens/email') + ->desc('Create email token (OTP)') + ->groups(['api', 'account']) + ->label('scope', 'sessions.write') + ->label('auth.type', 'email') + ->label('audits.event', 'session.create') + ->label('audits.resource', 'user/{response.userId}') + ->label('audits.userId', '{response.userId}') + ->label('sdk.auth', []) + ->label('sdk.namespace', 'account') + ->label('sdk.method', 'createEmailToken') + ->label('sdk.description', '/docs/references/account/create-token-email.md') + ->label('sdk.response.code', Response::STATUS_CODE_CREATED) + ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) + ->label('sdk.response.model', Response::MODEL_TOKEN) + ->label('abuse-limit', 10) + ->label('abuse-key', 'url:{url},email:{param-email}') + ->param('userId', '', new CustomId(), 'User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') + ->param('email', '', new Email(), 'User email.') + ->param('securityPhrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of authentication flow.', true) + ->inject('request') + ->inject('response') + ->inject('user') + ->inject('project') + ->inject('dbForProject') + ->inject('locale') + ->inject('queueForEvents') + ->inject('queueForMails') + ->action(function (string $userId, string $email, bool $securityPhrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) { + if (empty(App::getEnv('_APP_SMTP_HOST'))) { + throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled'); + } + + if ($securityPhrase === true) { + $securityPhrase = SecurityPhrase::generate(); + } + + $roles = Authorization::getRoles(); + $isPrivilegedUser = Auth::isPrivilegedUser($roles); + $isAppUser = Auth::isAppUser($roles); + + $result = $dbForProject->findOne('users', [Query::equal('email', [$email])]); + if ($result !== false && !$result->isEmpty()) { + $user->setAttributes($result->getArrayCopy()); + } else { + $limit = $project->getAttribute('auths', [])['limit'] ?? 0; + + if ($limit !== 0) { + $total = $dbForProject->count('users', max: APP_LIMIT_USERS); + + if ($total >= $limit) { + throw new Exception(Exception::USER_COUNT_EXCEEDED); + } + } + + // Makes sure this email is not already used in another identity + $identityWithMatchingEmail = $dbForProject->findOne('identities', [ + Query::equal('providerEmail', [$email]), + ]); + if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) { + throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS); + } + + $userId = $userId === 'unique()' ? ID::unique() : $userId; + + $user->setAttributes([ + '$id' => $userId, + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($userId)), + Permission::delete(Role::user($userId)), + ], + 'email' => $email, + 'emailVerification' => false, + 'status' => true, + 'password' => null, + 'hash' => Auth::DEFAULT_ALGO, + 'hashOptions' => Auth::DEFAULT_ALGO_OPTIONS, + 'passwordUpdate' => null, + 'registration' => DateTime::now(), + 'reset' => false, + 'prefs' => new \stdClass(), + 'sessions' => null, + 'tokens' => null, + 'memberships' => null, + 'search' => implode(' ', [$userId, $email]), + 'accessedAt' => DateTime::now(), + ]); + + $user->removeAttribute('$internalId'); + Authorization::skip(fn () => $dbForProject->createDocument('users', $user)); + } + + $tokenSecret = Auth::codeGenerator(6); + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_OTP)); + + $token = new Document([ + '$id' => ID::unique(), + 'userId' => $user->getId(), + 'userInternalId' => $user->getInternalId(), + 'type' => Auth::TOKEN_TYPE_EMAIL, + 'secret' => Auth::hash($tokenSecret), // One way hash encryption to protect DB leak + 'expire' => $expire, + 'userAgent' => $request->getUserAgent('UNKNOWN'), + 'ip' => $request->getIP(), + ]); + + Authorization::setRole(Role::user($user->getId())->toString()); + + $token = $dbForProject->createDocument('tokens', $token + ->setAttribute('$permissions', [ + Permission::read(Role::user($user->getId())), + Permission::update(Role::user($user->getId())), + Permission::delete(Role::user($user->getId())), + ])); + + $dbForProject->deleteCachedDocument('users', $user->getId()); + + $subject = $locale->getText("emails.otpSession.subject"); + $customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? []; + + $detector = new Detector($request->getUserAgent('UNKNOWN')); + $agentOs = $detector->getOS(); + $agentClient = $detector->getClient(); + $agentDevice = $detector->getDevice(); + + $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-otp.tpl'); + $message + ->setParam('{{hello}}', $locale->getText("emails.otpSession.hello")) + ->setParam('{{description}}', $locale->getText("emails.otpSession.description")) + ->setParam('{{clientInfo}}', $locale->getText("emails.otpSession.clientInfo")) + ->setParam('{{thanks}}', $locale->getText("emails.otpSession.thanks")) + ->setParam('{{signature}}', $locale->getText("emails.otpSession.signature")); + + if (!empty($securityPhrase)) { + $message->setParam('{{securityPhrase}}', $locale->getText("emails.otpSession.securityPhrase")); + } else { + $message->setParam('{{securityPhrase}}', ''); + } + + $body = $message->render(); + + $smtp = $project->getAttribute('smtp', []); + $smtpEnabled = $smtp['enabled'] ?? false; + + $senderEmail = App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM); + $senderName = App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'); + $replyTo = ""; + + if ($smtpEnabled) { + if (!empty($smtp['senderEmail'])) { + $senderEmail = $smtp['senderEmail']; + } + if (!empty($smtp['senderName'])) { + $senderName = $smtp['senderName']; + } + if (!empty($smtp['replyTo'])) { + $replyTo = $smtp['replyTo']; + } + + $queueForMails + ->setSmtpHost($smtp['host'] ?? '') + ->setSmtpPort($smtp['port'] ?? '') + ->setSmtpUsername($smtp['username'] ?? '') + ->setSmtpPassword($smtp['password'] ?? '') + ->setSmtpSecure($smtp['secure'] ?? ''); + + if (!empty($customTemplate)) { + if (!empty($customTemplate['senderEmail'])) { + $senderEmail = $customTemplate['senderEmail']; + } + if (!empty($customTemplate['senderName'])) { + $senderName = $customTemplate['senderName']; + } + if (!empty($customTemplate['replyTo'])) { + $replyTo = $customTemplate['replyTo']; + } + + $body = $customTemplate['message'] ?? ''; + $subject = $customTemplate['subject'] ?? $subject; + } + + $queueForMails + ->setSmtpReplyTo($replyTo) + ->setSmtpSenderEmail($senderEmail) + ->setSmtpSenderName($senderName); + } + + $emailVariables = [ + 'direction' => $locale->getText('settings.direction'), + /* {{user}} ,{{team}}, {{project}} and {{otp}} are required in the templates */ + 'user' => '', + 'team' => '', + 'project' => $project->getAttribute('name'), + 'otp' => $tokenSecret, + 'agentDevice' => '' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '', + 'agentClient' => '' . ($agentClient['clientName'] ?? 'UNKNOWN') . '', + 'agentOs' => '' . ($agentOs['osName'] ?? 'UNKNOWN') . '', 'phrase' => '' . (!empty($securityPhrase) ? $securityPhrase : '') . '' ]; @@ -1229,7 +1457,6 @@ $createSession = function (string $userId, string $secret, Request $request, Res $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); $sessionSecret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION); - $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); $session = new Document(array_merge( [ @@ -1241,6 +1468,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $duration) ], $detector->getOS(), $detector->getClient(), @@ -1282,6 +1510,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res $response->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $sessionSecret)])); } + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); $protocol = $request->getProtocol(); $response @@ -1458,7 +1687,7 @@ App::post('/v1/account/tokens/phone') } $secret = Auth::codeGenerator(); - $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE)); + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_OTP)); $token = new Document([ '$id' => ID::unique(), @@ -1613,7 +1842,6 @@ App::post('/v1/account/sessions/anonymous') $detector = new Detector($request->getUserAgent('UNKNOWN')); $record = $geodb->get($request->getIP()); $secret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION); - $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); $session = new Document(array_merge( [ @@ -1625,6 +1853,7 @@ App::post('/v1/account/sessions/anonymous') 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $duration) ], $detector->getOS(), $detector->getClient(), @@ -1650,6 +1879,8 @@ App::post('/v1/account/sessions/anonymous') $response->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)])); } + $expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration)); + $response ->addCookie(Auth::$cookieName . '_legacy', Auth::encodeSession($user->getId(), $secret), (new \DateTime($expire))->getTimestamp(), '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), (new \DateTime($expire))->getTimestamp(), '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) @@ -1661,7 +1892,6 @@ App::post('/v1/account/sessions/anonymous') $session ->setAttribute('current', true) ->setAttribute('countryName', $countryName) - ->setAttribute('expire', $expire) ->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? Auth::encodeSession($user->getId(), $secret) : '') ; @@ -1849,16 +2079,13 @@ App::get('/v1/account/sessions') ->action(function (Response $response, Document $user, Locale $locale, Document $project) { $sessions = $user->getAttribute('sessions', []); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - $current = Auth::sessionVerify($sessions, Auth::$secret, $authDuration); + $current = Auth::sessionVerify($sessions, Auth::$secret); foreach ($sessions as $key => $session) {/** @var Document $session */ $countryName = $locale->getText('countries.' . strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')); $session->setAttribute('countryName', $countryName); $session->setAttribute('current', ($current == $session->getId()) ? true : false); - $session->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration))); - $sessions[$key] = $session; } @@ -1952,9 +2179,8 @@ App::get('/v1/account/sessions/:sessionId') ->action(function (?string $sessionId, Response $response, Document $user, Locale $locale, Database $dbForProject, Document $project) { $sessions = $user->getAttribute('sessions', []); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; $sessionId = ($sessionId === 'current') - ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration) + ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) : $sessionId; foreach ($sessions as $session) {/** @var Document $session */ @@ -1964,7 +2190,6 @@ App::get('/v1/account/sessions/:sessionId') $session ->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret))) ->setAttribute('countryName', $countryName) - ->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration))) ; return $response->dynamic($session, Response::MODEL_SESSION); @@ -2346,9 +2571,8 @@ App::delete('/v1/account/sessions/:sessionId') ->action(function (?string $sessionId, ?\DateTime $requestTimestamp, Request $request, Response $response, Document $user, Database $dbForProject, Locale $locale, Event $queueForEvents, Document $project) { $protocol = $request->getProtocol(); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; $sessionId = ($sessionId === 'current') - ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration) + ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) : $sessionId; $sessions = $user->getAttribute('sessions', []); @@ -2396,7 +2620,7 @@ App::delete('/v1/account/sessions/:sessionId') }); App::patch('/v1/account/sessions/:sessionId') - ->desc('Update OAuth session (refresh tokens)') + ->desc('Update (or renew) a session') ->groups(['api', 'account']) ->label('scope', 'accounts.write') ->label('event', 'users.[userId].sessions.[sessionId].update') @@ -2413,72 +2637,63 @@ App::patch('/v1/account/sessions/:sessionId') ->label('sdk.response.model', Response::MODEL_SESSION) ->label('abuse-limit', 10) ->param('sessionId', '', new UID(), 'Session ID. Use the string \'current\' to update the current device session.') - ->inject('request') ->inject('response') ->inject('user') ->inject('dbForProject') ->inject('project') - ->inject('locale') ->inject('queueForEvents') - ->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Event $queueForEvents) { - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - $sessionId = ($sessionId === 'current') - ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret, $authDuration) - : $sessionId; + ->action(function (?string $sessionId, Response $response, Document $user, Database $dbForProject, Document $project, Event $queueForEvents) { + $sessionId = ($sessionId === 'current') + ? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret) + : $sessionId; $sessions = $user->getAttribute('sessions', []); - foreach ($sessions as $key => $session) {/** @var Document $session */ - if ($sessionId == $session->getId()) { - // Comment below would skip re-generation if token is still valid - // We decided to not include this because developer can get expiration date from the session - // I kept code in comment because it might become relevant in the future - - // $expireAt = (int) $session->getAttribute('providerAccessTokenExpiry'); - // if(\time() < $expireAt - 5) { // 5 seconds time-sync and networking gap, to be safe - // return $response->noContent(); - // } - - $provider = $session->getAttribute('provider'); - $refreshToken = $session->getAttribute('providerRefreshToken'); - - $appId = $project->getAttribute('oAuthProviders', [])[$provider . 'Appid'] ?? ''; - $appSecret = $project->getAttribute('oAuthProviders', [])[$provider . 'Secret'] ?? '{}'; - - $className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider); - - if (!\class_exists($className)) { - throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED); - } - - $oauth2 = new $className($appId, $appSecret, '', [], []); - - $oauth2->refreshTokens($refreshToken); - - $session - ->setAttribute('providerAccessToken', $oauth2->getAccessToken('')) - ->setAttribute('providerRefreshToken', $oauth2->getRefreshToken('')) - ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry(''))); - - $dbForProject->updateDocument('sessions', $sessionId, $session); - - $dbForProject->deleteCachedDocument('users', $user->getId()); - - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - - $session->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration))); - - $queueForEvents - ->setParam('userId', $user->getId()) - ->setParam('sessionId', $session->getId()) - ->setPayload($response->output($session, Response::MODEL_SESSION)) - ; - - return $response->dynamic($session, Response::MODEL_SESSION); + $session = null; + foreach ($sessions as $key => $value) { + if ($sessionId === $value->getId()) { + $session = $value; + break; } } - throw new Exception(Exception::USER_SESSION_NOT_FOUND); + if ($session === null) { + throw new Exception(Exception::USER_SESSION_NOT_FOUND); + } + + // Extend session + $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; + $session->setAttribute('expire', DateTime::addSeconds(new \DateTime(), $authDuration)); + + // Refresh OAuth access token + $provider = $session->getAttribute('provider', ''); + $refreshToken = $session->getAttribute('providerRefreshToken', ''); + $className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider); + + if (!empty($provider) && \class_exists($className)) { + $appId = $project->getAttribute('oAuthProviders', [])[$provider . 'Appid'] ?? ''; + $appSecret = $project->getAttribute('oAuthProviders', [])[$provider . 'Secret'] ?? '{}'; + + $oauth2 = new $className($appId, $appSecret, '', [], []); + $oauth2->refreshTokens($refreshToken); + + $session + ->setAttribute('providerAccessToken', $oauth2->getAccessToken('')) + ->setAttribute('providerRefreshToken', $oauth2->getRefreshToken('')) + ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry(''))); + } + + // Save changes + $dbForProject->updateDocument('sessions', $sessionId, $session); + $dbForProject->deleteCachedDocument('users', $user->getId()); + + $queueForEvents + ->setParam('userId', $user->getId()) + ->setParam('sessionId', $session->getId()) + ->setPayload($response->output($session, Response::MODEL_SESSION)) + ; + + return $response->dynamic($session, Response::MODEL_SESSION); }); App::delete('/v1/account/sessions') @@ -2521,7 +2736,6 @@ App::delete('/v1/account/sessions') if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { $session->setAttribute('current', true); - $session->setAttribute('expire', DateTime::addSeconds(new \DateTime($session->getCreatedAt()), Auth::TOKEN_EXPIRATION_LOGIN_LONG)); // If current session delete the cookies too $response diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 8f40e88b3d..27332b8bf3 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -962,6 +962,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status') 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), 'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--', + 'expire' => DateTime::addSeconds(new \DateTime(), $authDuration) ], $detector->getOS(), $detector->getClient(), $detector->getDevice())); $session = $dbForProject->createDocument('sessions', $session diff --git a/app/init.php b/app/init.php index bc1db0b090..5e2aab6ba5 100644 --- a/app/init.php +++ b/app/init.php @@ -1108,11 +1108,9 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons Authorization::setDefaultStatus(true); Auth::setCookieName('a_session_' . $project->getId()); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; if (APP_MODE_ADMIN === $mode) { Auth::setCookieName('a_session_' . $console->getId()); - $authDuration = Auth::TOKEN_EXPIRATION_LOGIN_LONG; } $session = Auth::decodeSession( @@ -1164,7 +1162,7 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons if ( $user->isEmpty() // Check a document has been found in the DB - || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration) + || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret) ) { // Validate user has valid login token $user = new Document([]); } diff --git a/app/realtime.php b/app/realtime.php index f7fc7070a4..663e8c9e7f 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -545,11 +545,10 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re Auth::$secret = $session['secret'] ?? ''; $user = $database->getDocument('users', Auth::$unique); - $authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; if ( empty($user->getId()) // Check a document has been found in the DB - || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration) // Validate user has valid login token + || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret) // Validate user has valid login token ) { // cookie not valid throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Session is not valid.'); diff --git a/docs/references/account/create-token-email.md b/docs/references/account/create-token-email.md new file mode 100644 index 0000000000..3e49899888 --- /dev/null +++ b/docs/references/account/create-token-email.md @@ -0,0 +1,3 @@ +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. + +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). \ 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 3909a4071d..6ebe4154b8 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 [PUT /account/sessions/magic-url](https://appwrite.io/docs/references/cloud/client-web/account#updateMagicURLSession) 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. 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. 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/account/create-token-phone.md b/docs/references/account/create-token-phone.md index 833aae4d57..e3817f6304 100644 --- a/docs/references/account/create-token-phone.md +++ b/docs/references/account/create-token-phone.md @@ -1,3 +1,3 @@ -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 [PUT /account/sessions/phone](https://appwrite.io/docs/references/cloud/client-web/account#updatePhoneSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes. +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. 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). \ No newline at end of file diff --git a/docs/references/account/update-session.md b/docs/references/account/update-session.md index 98080fda55..55226fe0bd 100644 --- a/docs/references/account/update-session.md +++ b/docs/references/account/update-session.md @@ -1 +1 @@ -Access tokens have limited lifespan and expire to mitigate security risks. If session was created using an OAuth provider, this route can be used to "refresh" the access token. \ No newline at end of file +Extend session's expiry to increase it's lifespan. Extending a session is useful when session length is short such as 5 minutes. \ No newline at end of file diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php index 86e0ba676b..2fc3ab86df 100644 --- a/src/Appwrite/Auth/Auth.php +++ b/src/Appwrite/Auth/Auth.php @@ -54,6 +54,7 @@ class Auth public const TOKEN_TYPE_PHONE = 6; public const TOKEN_TYPE_OAUTH2 = 7; public const TOKEN_TYPE_GENERIC = 8; + public const TOKEN_TYPE_EMAIL = 9; // OTP /** * Session Providers. @@ -73,7 +74,7 @@ class Auth public const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */ public const TOKEN_EXPIRATION_RECOVERY = 3600; /* 1 hour */ public const TOKEN_EXPIRATION_CONFIRM = 3600 * 1; /* 1 hour */ - public const TOKEN_EXPIRATION_PHONE = 60 * 15; /* 15 minutes */ + public const TOKEN_EXPIRATION_OTP = 60 * 15; /* 15 minutes */ public const TOKEN_EXPIRATION_GENERIC = 60 * 15; /* 15 minutes */ /** @@ -375,11 +376,10 @@ class Auth * * @param array $sessions * @param string $secret - * @param string $expires * * @return bool|string */ - public static function sessionVerify(array $sessions, string $secret, int $expires) + public static function sessionVerify(array $sessions, string $secret) { foreach ($sessions as $session) { /** @var Document $session */ @@ -387,7 +387,7 @@ class Auth $session->isSet('secret') && $session->isSet('provider') && $session->getAttribute('secret') === self::hash($secret) && - DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $expires)) >= DateTime::formatTz(DateTime::now()) + DateTime::formatTz(DateTime::format(new \DateTime($session->getAttribute('expire')))) >= DateTime::formatTz(DateTime::now()) ) { return $session->getId(); } diff --git a/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php b/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php index 8250c15302..66eee00d0d 100644 --- a/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php +++ b/src/Appwrite/Platform/Tasks/DevGenerateTranslations.php @@ -4,6 +4,7 @@ namespace Appwrite\Platform\Tasks; use Exception; use Utopia\CLI\Console; +use Utopia\Config\Config; use Utopia\Fetch\Client; use Utopia\Platform\Action; use Utopia\Validator\Boolean; @@ -66,11 +67,13 @@ class DevGenerateTranslations extends Action $language = \explode('.', $file)[0]; $translation = $this->generateTranslation($language, $mainJson[$key]); - $json = \json_decode(\file_get_contents($dir . '/' . $file), true); - $json[$key] = $translation; - \file_put_contents($dir . '/' . $file, \json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | 0)); + if (!empty($translation)) { + $json = \json_decode(\file_get_contents($dir . '/' . $file), true); + $json[$key] = $translation; + \file_put_contents($dir . '/' . $file, \json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | 0)); - Console::success("Generated {$key} for {$language}"); + Console::success("Generated {$key} for {$language}"); + } } } } @@ -81,6 +84,20 @@ class DevGenerateTranslations extends Action private function generateTranslation(string $targetLanguage, string $enTranslation): string { + $list = Config::getParam('locale-languages'); + foreach ($list as $language) { + if ($language['code'] === $targetLanguage) { + $languageObject = $language; + } + } + + if (!isset($languageObject)) { + Console::error("{$targetLanguage} language not found"); + return ''; + } + + $targetLanguageName = $languageObject['name']; + $response = Client::fetch('https://api.openai.com/v1/chat/completions', [ 'content-type' => Client::CONTENT_TYPE_APPLICATION_JSON, 'Authorization' => 'Bearer ' . $this->apiKey @@ -89,7 +106,7 @@ class DevGenerateTranslations extends Action 'messages' => [ [ 'role' => 'system', - 'content' => "Please translate the message user provides from English language to target language. Target language is language of country with country code {$targetLanguage}. Do not translate text inside {{ and }} placeholders. Provide only translated text." + 'content' => "Please translate the message user provides from English language to {$targetLanguageName}. Do not translate text inside {{ and }} placeholders. Provide only translated text." ], [ 'role' => 'user', @@ -104,6 +121,16 @@ class DevGenerateTranslations extends Action throw new Exception($response->getBody() . ' with status code ' . $response->getStatusCode() . ' for language ' . $targetLanguage . ' and message ' . $enTranslation); } - return $body['choices'][0]['message']['content']; + $answer = $body['choices'][0]['message']['content']; + + $failureDetectors = [ 'sorry', 'confusion', 'country code', 'misunderstanding', 'correct', 'clarify', 'specific', 'cannot', 'unable', 'language', 'appears' ]; + + foreach ($failureDetectors as $detector) { + if (\str_contains($answer, $detector)) { + Console::error("Translation of '{$enTranslation}' for {$targetLanguage} is incorrect: {$answer}"); + } + } + + return $answer; } } diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index b01101b10f..e00cfad1b2 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -129,4 +129,133 @@ trait AccountBase 'name' => $name, ]; } + + public function testEmailOTPSession(): void + { + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => 'otpuser@appwrite.io' + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + $this->assertNotEmpty($response['body']['$id']); + $this->assertNotEmpty($response['body']['$createdAt']); + $this->assertNotEmpty($response['body']['userId']); + $this->assertNotEmpty($response['body']['expire']); + $this->assertEmpty($response['body']['secret']); + $this->assertEmpty($response['body']['securityPhrase']); + + $userId = $response['body']['userId']; + + $lastEmail = $this->getLastEmail(); + $this->assertEquals('otpuser@appwrite.io', $lastEmail['to'][0]['address']); + $this->assertEquals('OTP for ' . $this->getProject()['name'] . ' Login', $lastEmail['subject']); + + // FInd 6 concurrent digits in email text - OTP + preg_match_all("/\b\d{6}\b/", $lastEmail['text'], $matches); + $code = ($matches[0] ?? [])[0] ?? ''; + + $this->assertNotEmpty($code); + + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => $userId, + 'secret' => $code + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals($userId, $response['body']['userId']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertNotEmpty($response['body']['expire']); + $this->assertEmpty($response['body']['secret']); + + $session = $response['cookies']['a_session_' . $this->getProject()['$id']]; + + $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals($userId, $response['body']['$id']); + + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => $userId, + 'secret' => $code + ]); + + $this->assertEquals(401, $response['headers']['status-code']); + $this->assertEquals('user_invalid_token', $response['body']['type']); + + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => 'otpuser@appwrite.io', + 'securityPhrase' => true + ]); + + $this->assertEquals($response['headers']['status-code'], 201); + $this->assertNotEmpty($response['body']['securityPhrase']); + $this->assertEmpty($response['body']['secret']); + $this->assertEquals($userId, $response['body']['userId']); + + $securityPhrase = $response['body']['securityPhrase']; + + $lastEmail = $this->getLastEmail(); + $this->assertEquals('otpuser@appwrite.io', $lastEmail['to'][0]['address']); + $this->assertEquals('OTP for ' . $this->getProject()['name'] . ' Login', $lastEmail['subject']); + $this->assertStringContainsStringIgnoringCase('security phrase', $lastEmail['text']); + $this->assertStringContainsStringIgnoringCase($securityPhrase, $lastEmail['text']); + + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + 'email' => 'wrongemail' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('general_argument_invalid', $response['body']['type']); + + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => 'wrongId$', + 'email' => 'email@appwrite.io' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('general_argument_invalid', $response['body']['type']); + + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'userId' => ID::unique(), + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + $this->assertEquals('general_argument_invalid', $response['body']['type']); + } } diff --git a/tests/e2e/Services/Locale/LocaleBase.php b/tests/e2e/Services/Locale/LocaleBase.php index 17b5c66d67..a8766372aa 100644 --- a/tests/e2e/Services/Locale/LocaleBase.php +++ b/tests/e2e/Services/Locale/LocaleBase.php @@ -205,15 +205,15 @@ trait LocaleBase $this->assertEquals($response['headers']['status-code'], 200); $this->assertIsArray($response['body']); - $this->assertEquals(184, $response['body']['total']); + $this->assertEquals(186, $response['body']['total']); $this->assertEquals($response['body']['languages'][0]['code'], 'aa'); $this->assertEquals($response['body']['languages'][0]['name'], 'Afar'); $this->assertEquals($response['body']['languages'][0]['nativeName'], 'Afar'); - $this->assertEquals($response['body']['languages'][183]['code'], 'zu'); - $this->assertEquals($response['body']['languages'][183]['name'], 'Zulu'); - $this->assertEquals($response['body']['languages'][183]['nativeName'], 'isiZulu'); + $this->assertEquals($response['body']['languages'][185]['code'], 'zu'); + $this->assertEquals($response['body']['languages'][185]['name'], 'Zulu'); + $this->assertEquals($response['body']['languages'][185]['nativeName'], 'isiZulu'); /** * Test for FAILURE diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 4ce5f43790..27fbdec14f 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -770,7 +770,7 @@ class ProjectsConsoleClientTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'duration' => 60, // Set session duration to 2 minutes + 'duration' => 60, // Set session duration to 1 minute ]); $this->assertEquals(200, $response['headers']['status-code']); @@ -844,6 +844,61 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(401, $response['headers']['status-code']); + // Set session duration to 15s + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'duration' => 15, // seconds + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(15, $response['body']['authDuration']); + + // Create session + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ]), [ + 'email' => $userEmail, + 'password' => 'password', + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $sessionCookie = $response['headers']['set-cookie']; + + // Wait 10 seconds, ensure valid session, extend session + \sleep(10); + + $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'Cookie' => $sessionCookie, + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, '/account/sessions/current', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'cookie' => $sessionCookie, + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Wait 20 seconds, ensure non-valid session + \sleep(20); + + $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'Cookie' => $sessionCookie, + ])); + + $this->assertEquals(401, $response['headers']['status-code']); + // Return project back to normal $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([ 'content-type' => 'application/json', diff --git a/tests/unit/Auth/AuthTest.php b/tests/unit/Auth/AuthTest.php index 3fe906aaa3..ea6e9dc6c1 100644 --- a/tests/unit/Auth/AuthTest.php +++ b/tests/unit/Auth/AuthTest.php @@ -213,12 +213,14 @@ class AuthTest extends TestCase 'secret' => $hash, 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', + 'expire' => DateTime::addSeconds(new \DateTime(), $expireTime1), ]), new Document([ '$id' => ID::custom('token2'), 'secret' => 'secret2', 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', + 'expire' => DateTime::addSeconds(new \DateTime(), $expireTime1), ]), ]; @@ -230,19 +232,21 @@ class AuthTest extends TestCase 'secret' => $hash, 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', + 'expire' => DateTime::addSeconds(new \DateTime(), $expireTime2), ]), new Document([ '$id' => ID::custom('token2'), 'secret' => 'secret2', 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', + 'expire' => DateTime::addSeconds(new \DateTime(), $expireTime2), ]), ]; - $this->assertEquals(Auth::sessionVerify($tokens1, $secret, $expireTime1), 'token1'); - $this->assertEquals(Auth::sessionVerify($tokens1, 'false-secret', $expireTime1), false); - $this->assertEquals(Auth::sessionVerify($tokens2, $secret, $expireTime2), false); - $this->assertEquals(Auth::sessionVerify($tokens2, 'false-secret', $expireTime2), false); + $this->assertEquals(Auth::sessionVerify($tokens1, $secret), 'token1'); + $this->assertEquals(Auth::sessionVerify($tokens1, 'false-secret'), false); + $this->assertEquals(Auth::sessionVerify($tokens2, $secret), false); + $this->assertEquals(Auth::sessionVerify($tokens2, 'false-secret'), false); } public function testTokenVerify(): void