diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 1db05cebaf..3af6d451e4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -359,12 +359,31 @@ "PurchaseDate": "Purchase date", "IsAbpBookDownloaded": "ABP book downloaded", "IsMasteringAbpBookDownloadEnabled": "ABP Book download enabled", - "Permission:Accounting:CustomPaymentLinkGenerator": "Generate Custom Payment Link", + "Permission:Accounting:CustomPaymentLinkGenerator": "Custom Payment Link", "CustomPaymentLink": "Custom Payment Link", "Menu:CustomPaymentLink": "Custom Payment Link", "Amount": "Amount", "GenerateCustomPaymentLink": "Generate Custom Payment Link", "GeneratedPaymentLink": "Generated Payment Link", - "CopyText": "Copy Text" + "CopyText": "Copy Text", + "Permission:CommunityEvents": "Events", + "Menu:Events": "Events", + "Events": "Events", + "EventType": "Event Type", + "Number": "Number", + "RegistrationURL": "Registration URL", + "URL": "URL", + "EventDeletionConfirmationMessage": "Are you sure you want to delete this event?", + "Enum:EventType:0": "Community Talks", + "CreateAnEvent": "Create an event", + "Permission:CommunitySpeakers": "Speakers", + "CreateASpeaker": "Create a speaker", + "Speakers": "Speakers", + "Image": "Image", + "GithubURL": "Github URL", + "SpeakerDeletionConfirmationMessage": "Are you sure you want to delete this speaker?", + "Menu:Speakers": "Speakers", + "ChooseSpeakerImage": "Choose a speaker image...", + "SpeakerImage": "Speaker image" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json index 8b84c3512e..3bb6320874 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/en.json @@ -98,6 +98,11 @@ "EULA": "EULA", "ABPCommercialIntroductionMessage": "Pre-built application modules, advanced startup templates, rapid application development tooling, professional UI themes and premium support.", "MasteringAbpFrameworkEBook": "Mastering ABP Framework", - "MasteringTheABPFrameworkExplanation": "Written by the creator of the ABP Framework, this book will help you gain a complete understanding of the framework and modern web application development techniques." + "MasteringTheABPFrameworkExplanation": "Written by the creator of the ABP Framework, this book will help you gain a complete understanding of the framework and modern web application development techniques.", + "Speakers": "Speakers", + "PreviousEvents": "Previous Events", + "WatchTheEvent": "Watch the Event", + "RegisterNow": "Register Now", + "ThereIsNoEvent": "There is no event." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json index a4487da9b4..6408da0f12 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "لإنشاء منشور فعال ، أضف صورة غلاف. قم بتحميل صور بنسبة عرض إلى ارتفاع تبلغ 16: 9 للحصول على أفضل عرض. الحد الأقصى لحجم الملف: 1 ميغا بايت.", "ThankYouForContribution": "شكرًا لك على المساهمة في مجتمع ABP.", "GithubPost": "المادة جيثب", - "GithubPostSubmitStepOne": " 1. اكتب مقالة في أي مستودع GitHub عام بتنسيق Markdown. مثال ", + "GithubPostSubmitStepOne": " 1. اكتب مقالة في أي مستودع GitHub عام بتنسيق Markdown. مثال ", "GithubPostSubmitStepTwo": " 2. أرسل عنوان URL لمقالتك باستخدام النموذج.", "GithubPostSubmitStepThree": " 3. سيتم عرض مقالتك في موقع الويب هذا.", "YoutubeVideo": "فيديو يوتيوب", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json index 1f057b3c1a..ebd1349383 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/cs.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Pro vytvoření efektního příspěvku přidejte titulní fotku. Pro nejlepší zobrazení nahrajte obrázky s poměrem stran 16:9. Maximální velikost souboru: 1 MB.", "ThankYouForContribution": "Děkujeme vám za příspěvek do komunity ABP.", "GithubPost": "Článek Github", - "GithubPostSubmitStepOne": "1. Napište článek na libovolném veřejném úložišti GitHub ve formátu Markdown. příklad ", + "GithubPostSubmitStepOne": "1. Napište článek na libovolném veřejném úložišti GitHub ve formátu Markdown. příklad ", "GithubPostSubmitStepTwo": "2. Odešlete adresu URL svého článku pomocí formuláře.", "GithubPostSubmitStepThree": "3. Váš článek bude vykreslen na této webové stránce.", "YoutubeVideo": "Youtube Video", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json index b930e55323..b9cf0e7055 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Um einen effektiven Beitrag zu erstellen, fügen Sie ein Titelbild hinzu. Laden Sie Bilder mit einem Seitenverhältnis von 16:9 hoch, um die beste Ansicht zu erhalten. Maximale Dateigröße: 1 MB.", "ThankYouForContribution": "Vielen Dank für Ihren Beitrag zur ABP-Community.", "GithubPost": "Github-Artikel", - "GithubPostSubmitStepOne": "1. Schreiben Sie einen Artikel in einem öffentlichen GitHub-Repository im Markdown-Format. Beispiel ", + "GithubPostSubmitStepOne": "1. Schreiben Sie einen Artikel in einem öffentlichen GitHub-Repository im Markdown-Format. Beispiel ", "GithubPostSubmitStepTwo": "2. Senden Sie Ihre Artikel-URL über das Formular.", "GithubPostSubmitStepThree": "3. Ihr Artikel wird auf dieser Website wiedergegeben.", "YoutubeVideo": "Youtube-Video", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json index 1919f23d0a..167792ef3f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json @@ -117,7 +117,7 @@ "ExternalPostUrl": "External Post Url", "ThankYouForContribution": "Thank you for contributing to the ABP Community.", "GithubPost": "GitHub Post", - "GithubPostSubmitStepOne": "1. Write a post on any public GitHub repository with the Markdown format. example", + "GithubPostSubmitStepOne": "1. Write a post on any public GitHub repository with the Markdown format. example", "GithubPostSubmitStepTwo": "2. Submit your post URL using the form.", "GithubPostSubmitStepThree": "3. Your post will be rendered in this website.", "YoutubeVideo": "Youtube Video", @@ -162,6 +162,9 @@ "Previous": "Previous", "Next": "Next", "Share": "Share", - "SortBy": "Sort by" + "SortBy": "Sort by", + "NoPublishedEventsYet": "No published events yet.", + "SubscribeYoutubeChannel": "Subscribe to the Youtube Channel", + "Enum:EventType:0": "Talks" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json index d714e91854..cd5e27df29 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Para crear una publicación eficaz, agregue una foto de portada. Cargue imágenes con una relación de aspecto de 16: 9 para obtener la mejor vista. Tamaño máximo de archivo: 1 MB.", "ThankYouForContribution": "Gracias por contribuir a la comunidad ABP.", "GithubPost": "Artículo de Github", - "GithubPostSubmitStepOne": " 1. Escribe un artículo en cualquier repositorio público de GitHub con el formato Markdown. ejemplo ", + "GithubPostSubmitStepOne": " 1. Escribe un artículo en cualquier repositorio público de GitHub con el formato Markdown. ejemplo ", "GithubPostSubmitStepTwo": " 2. Envíe la URL de su artículo mediante el formulario.", "GithubPostSubmitStepThree": " 3. Su artículo se mostrará en este sitio web.", "YoutubeVideo": "Video de Youtube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json index 486ffb3916..b686f44775 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Lisää kansikuva, jotta voit luoda tehokkaan viestin. Lataa 16:9 -kuvasuhteen kuvat parhaan näkymän saamiseksi. Tiedoston enimmäiskoko: 1MB.", "ThankYouForContribution": "Kiitos osallistumisesta ABP Community.", "GithubPost": "Github-artikkeli", - "GithubPostSubmitStepOne": "1. Kirjoita artikkeli mistä tahansa julkisesta GitHub-arkistosta Markdown-muodossa. esimerkki ", + "GithubPostSubmitStepOne": "1. Kirjoita artikkeli mistä tahansa julkisesta GitHub-arkistosta Markdown-muodossa. esimerkki ", "GithubPostSubmitStepTwo": " 2. Lähetä artikkelin URL-osoite lomaketta käyttämällä.", "GithubPostSubmitStepThree": " 3. Artikkelisi renderöidään tällä verkkosivustolla.", "YoutubeVideo": "Youtube-video", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json index 0db4e72504..c51623e2a5 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Pour créer un post efficace, ajoutez une photo de couverture. Téléchargez des images au format 16: 9 pour une meilleure vue. Taille maximale du fichier: 1 Mo.", "ThankYouForContribution": "Merci de contribuer à la communauté ABP.", "GithubPost": "Post Github", - "GithubPostSubmitStepOne": " 1. Rédigez un post sur n'importe quel référentiel GitHub public au format Markdown. Exemple de ", + "GithubPostSubmitStepOne": " 1. Rédigez un post sur n'importe quel référentiel GitHub public au format Markdown. Exemple de ", "GithubPostSubmitStepTwo": " 2. Envoyez l'URL de votre post à l'aide du formulaire.", "GithubPostSubmitStepThree": " 3. Votre post sera rendu sur ce site Web.", "YoutubeVideo": "Vidéo Youtube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json index 592ac856b1..f9746dba44 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "एक प्रभावी पोस्ट बनाने के लिए, एक कवर फ़ोटो जोड़ें। सर्वश्रेष्ठ दृश्य के लिए 16: 9 पहलू अनुपात चित्र अपलोड करें। अधिकतम फ़ाइल आकार: 1 एमबी।", "ThankYouForContribution": "ABP समुदाय में योगदान के लिए धन्यवाद।", "GithubPost": "गीथब लेख", - "GithubPostSubmitStepOne": "1. मार्कडाउन प्रारूप के साथ किसी भी सार्वजनिक GitHub रिपॉजिटरी पर एक लेख लिखें। उदाहरण ", + "GithubPostSubmitStepOne": "1. मार्कडाउन प्रारूप के साथ किसी भी सार्वजनिक GitHub रिपॉजिटरी पर एक लेख लिखें। उदाहरण ", "GithubPostSubmitStepTwo": " 2। फ़ॉर्म का उपयोग करके अपना लेख URL सबमिट करें।", "GithubPostSubmitStepThree": " 3। इस वेब साइट में आपका लेख प्रस्तुत किया जाएगा।", "YoutubeVideo": "यूट्यूब वीडियो", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json index a4b76ecc52..68d70f8615 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hu.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Hatékony bejegyzés létrehozásához adj hozzá egy borítóképet. Tölts fel 16:9-es képarányú képeket a legjobb nézet érdekében. Maximális fájlméret: 1 MB.", "ThankYouForContribution": "Köszönjük, hogy hozzájárult az ABP közösséghez.", "GithubPost": "Github cikk", - "GithubPostSubmitStepOne": "1. Írjon cikket bármely nyilvános GitHub-tárhelyről Markdown formátumban. példa ", + "GithubPostSubmitStepOne": "1. Írjon cikket bármely nyilvános GitHub-tárhelyről Markdown formátumban. példa ", "GithubPostSubmitStepTwo": "2. Az űrlap segítségével küldje el cikkének URL-jét.", "GithubPostSubmitStepThree": "3. A cikk ezen a webhelyen jelenik meg.", "YoutubeVideo": "Youtube videó", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json index daeaa3cc13..85c4a134a3 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Til að búa til áhrifaríka færslu skaltu bæta við forsíðumynd. Hladdu upp 16: 9 myndhlutföllum fyrir besta útsýnið. Hámarks skráarstærð: 1MB.", "ThankYouForContribution": "Þakka þér fyrir að leggja þitt af mörkum til ABP samfélagsins.", "GithubPost": "Github Greinar", - "GithubPostSubmitStepOne": " 1. Skrifaðu grein á hvaða opinbera GitHub geymslu sem er með markdown sniðinu. dæmi ", + "GithubPostSubmitStepOne": " 1. Skrifaðu grein á hvaða opinbera GitHub geymslu sem er með markdown sniðinu. dæmi ", "GithubPostSubmitStepTwo": "2. Sendu vefslóð greinarinnar með því að nota formið.", "GithubPostSubmitStepThree": "3. Grein þín verður birt á þessari vefsíðu.", "YoutubeVideo": "Youtube Videó", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json index 645f5af5a3..d14c9716e4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Per creare un post efficace, aggiungi una foto di copertina. Carica immagini in formato 16: 9 per una visualizzazione migliore. Dimensione massima del file: 1MB.", "ThankYouForContribution": "Grazie per aver contribuito alla comunità ABP.", "GithubPost": "Articolo GitHub", - "GithubPostSubmitStepOne": "1. Scrivi un articolo su qualsiasi repository GitHub pubblico con il formato Markdown.esempio", + "GithubPostSubmitStepOne": "1. Scrivi un articolo su qualsiasi repository GitHub pubblico con il formato Markdown.esempio", "GithubPostSubmitStepTwo": "2. Invia l'URL del tuo articolo utilizzando il modulo.", "GithubPostSubmitStepThree": "3. Il tuo articolo verrà visualizzato in questo sito web.", "YoutubeVideo": "Video Youtube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json index b760ffa034..c0844f722a 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/nl.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Voeg een omslagfoto toe om een effectieve post te maken. Upload afbeeldingen met een beeldverhouding van 16:9 voor de beste weergave. Maximale bestandsgrootte: 1 MB.", "ThankYouForContribution": "Bedankt voor uw bijdrage aan de ABP-community.", "GithubPost": "Github-artikel", - "GithubPostSubmitStepOne": "1. Schrijf een artikel op een openbare GitHub-repository met het Markdown-formaat. voorbeeld ", + "GithubPostSubmitStepOne": "1. Schrijf een artikel op een openbare GitHub-repository met het Markdown-formaat. voorbeeld ", "GithubPostSubmitStepTwo": "2. Dien uw artikel-URL in via het formulier.", "GithubPostSubmitStepThree": "3. Uw artikel wordt weergegeven op deze website.", "YoutubeVideo": "Youtube video", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json index e9cc65ca63..c33e9eeccb 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pl-PL.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Aby stworzyć efektowny post, dodaj zdjęcie na okładkę. Prześlij zdjęcia o proporcjach 16:9, aby uzyskać najlepszy widok. Maksymalny rozmiar pliku: 1 MB.", "ThankYouForContribution": "Dziękujemy za udział w społeczności ABP.", "GithubPost": "Artykuł na Github", - "GithubPostSubmitStepOne": "1. Napisz artykuł w dowolnym publicznym repozytorium GitHub w formacie Markdown. przykład ", + "GithubPostSubmitStepOne": "1. Napisz artykuł w dowolnym publicznym repozytorium GitHub w formacie Markdown. przykład ", "GithubPostSubmitStepTwo": "2. Prześlij adres URL artykułu za pomocą formularza.", "GithubPostSubmitStepThree": "3. Twój artykuł zostanie wyrenderowany w tej witrynie internetowej.", "YoutubeVideo": "Wideo z YouTube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json index 518e954db7..5d5e7b946c 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/pt-BR.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Para criar uma postagem eficaz, adicione uma foto de capa. Carregue imagens de proporção de 16: 9 para a melhor visualização. Tamanho máximo do arquivo: 1 MB.", "ThankYouForContribution": "Obrigado por contribuir com a Comunidade ABP.", "GithubPost": "Artigo Github", - "GithubPostSubmitStepOne": " 1. Escreva um artigo em qualquer repositório GitHub público com o formato Markdown. exemplo ", + "GithubPostSubmitStepOne": " 1. Escreva um artigo em qualquer repositório GitHub público com o formato Markdown. exemplo ", "GithubPostSubmitStepTwo": " 2. Envie o URL do seu artigo usando o formulário.", "GithubPostSubmitStepThree": " 3. Seu artigo será processado neste site.", "YoutubeVideo": "Vídeo do youtube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json index e1050c9d97..5c0afaa19a 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Pentru crearea unei postări eficace, adăugaţi o poză de copertă. Încărcaţi imagini cu raport de aspect 16:9 pentru cea mai bună vizualizare. Dimensiunea maximă a fişierului: 1MB.", "ThankYouForContribution": "Vă mulţumim pentru că aţi contribuit la comunitatea ABP.", "GithubPost": "Articol GitHub", - "GithubPostSubmitStepOne": "1. Scrieţi un articol pe orice repository GitHub folosind formatul Markup. exemplu", + "GithubPostSubmitStepOne": "1. Scrieţi un articol pe orice repository GitHub folosind formatul Markup. exemplu", "GithubPostSubmitStepTwo": "2. Trimiteţi Url-ul articolului folosind formularul.", "GithubPostSubmitStepThree": "3. Articolul dumneavoastră va fi redat în acest site web.", "YoutubeVideo": "Videoclip YouTube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json index 1995cf742d..e47a59691e 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ru.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Для создания эффектного поста добавьте фото обложки. Загрузите изображения с соотношением сторон 16: 9 для наилучшего просмотра. Максимальный размер файла: 1 МБ.", "ThankYouForContribution": "Спасибо за ваш вклад в сообщество ABP.", "GithubPost": "Статья на Github", - "GithubPostSubmitStepOne": " 1. Напишите статью в любом общедоступном репозитории GitHub с форматом Markdown. Пример ", + "GithubPostSubmitStepOne": " 1. Напишите статью в любом общедоступном репозитории GitHub с форматом Markdown. Пример ", "GithubPostSubmitStepTwo": " 2. Отправьте URL своей статьи, используя форму.", "GithubPostSubmitStepThree": " 3. Ваша статья будет отображаться на этом веб-сайте.", "YoutubeVideo": "YouTube видео", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json index df15618753..5abf7e8f07 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Ak chcete vytvoriť efektívny príspevok, pridajte titulnú fotografiu. Pre optimálne zobrazenie nahrávajte obrázky s pomerom strán 16:9. Maximálna veľkosť súboru: 1 MB.", "ThankYouForContribution": "Ďakujeme, že ste prispeli do ABP komunity.", "GithubPost": "Článok na Githube", - "GithubPostSubmitStepOne": "1. Napíšte článok v ľubovoľnom verejnom repozitári GitHub vo formáte Markdown. príklad", + "GithubPostSubmitStepOne": "1. Napíšte článok v ľubovoľnom verejnom repozitári GitHub vo formáte Markdown. príklad", "GithubPostSubmitStepTwo": "2. Odoslať URL adresu článku pomocou formulára.", "GithubPostSubmitStepThree": "3. Váš článok sa zobrazí na tejto webovej stránke.", "YoutubeVideo": "Video na YouTube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json index 8a689eb931..54a49aa5c9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sl.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Če želite ustvariti učinkovito objavo, dodajte naslovno fotografijo. Naložite slike v razmerju stranic 16:9 za najboljši pogled. Največja velikost datoteke: 1 MB.", "ThankYouForContribution": "Hvala za prispevek k skupnosti ABP.", "GithubPost": "Članek Github", - "GithubPostSubmitStepOne": "1. Napišite članek v katerem koli javnem repozitoriju GitHub z obliko Markdown. primer ", + "GithubPostSubmitStepOne": "1. Napišite članek v katerem koli javnem repozitoriju GitHub z obliko Markdown. primer ", "GithubPostSubmitStepTwo": "2. Pošljite URL svojega članka z uporabo obrazca.", "GithubPostSubmitStepThree": "3. Vaš članek bo prikazan na tem spletnem mestu.", "YoutubeVideo": "Youtube video", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json index 062e57fab4..72d6c5e28d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/tr.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Etkili bir gönderi oluşturmak için bir kapak fotoğrafı ekleyin. En iyi görünüm için 16:9 en boy oranlı resimler yükleyin. Maksimum dosya boyutu: 1MB.", "ThankYouForContribution": "ABP Topluluğuna katkıda bulunduğunuz için teşekkür ederiz.", "GithubPost": "Github Makalesi", - "GithubPostSubmitStepOne": "1. Herhangi bir genel GitHub deposunda Markdown biçimiyle bir makale yazın. örnek ", + "GithubPostSubmitStepOne": "1. Herhangi bir genel GitHub deposunda Markdown biçimiyle bir makale yazın. örnek ", "GithubPostSubmitStepTwo": "2. Formu kullanarak makale URL'nizi gönderin.", "GithubPostSubmitStepThree": "3. Makaleniz bu web sitesinde işlenecektir.", "YoutubeVideo": "Youtube videosu", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json index 9966fd1000..91794dd10a 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/vi.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "Để tạo một bài đăng hiệu quả, hãy thêm ảnh bìa. Tải lên hình ảnh tỷ lệ khung hình 16: 9 để có chế độ xem tốt nhất. Kích thước tệp tối đa: 1MB.", "ThankYouForContribution": "Cảm ơn bạn đã đóng góp cho Cộng đồng ABP.", "GithubPost": "Bài báo trên Github", - "GithubPostSubmitStepOne": " 1. Viết một bài báo trên bất kỳ kho lưu trữ GitHub công khai nào với định dạng Markdown. ví dụ ", + "GithubPostSubmitStepOne": " 1. Viết một bài báo trên bất kỳ kho lưu trữ GitHub công khai nào với định dạng Markdown. ví dụ ", "GithubPostSubmitStepTwo": " 2. Gửi URL bài viết của bạn bằng biểu mẫu.", "GithubPostSubmitStepThree": " 3. Bài viết của bạn sẽ được hiển thị trên trang web này.", "YoutubeVideo": "Video trên Youtube", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json index 57fb1ec11c..b5d9d65c82 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "要创建一个有效的帖子,需要添加封面图片. 上传16:9的图片获取最佳视觉效果. 文件最大支持: 1MB", "ThankYouForContribution": "感谢你对ABP社区的贡献", "GithubPost": "Github文章", - "GithubPostSubmitStepOne": "1. 用Markdown格式在GitHub的任何公共存储库上写一篇文章. 示例", + "GithubPostSubmitStepOne": "1. 用Markdown格式在GitHub的任何公共存储库上写一篇文章. 示例", "GithubPostSubmitStepTwo": "2. 使用表单提交你的文章URL.", "GithubPostSubmitStepThree": "3. 你的文章将在这个网站中呈现.", "YoutubeVideo": "Youtube视频", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json index b79004153e..4ac910d98a 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hant.json @@ -118,7 +118,7 @@ "CreatePostCoverInfo": "要創建有效的帖子,請添加封面照片。上傳 16:9 縱橫比的圖片以獲得最佳觀看效果。最大文件大小:1MB。", "ThankYouForContribution": "感謝您為 ABP 社區做出貢獻。", "GithubPost": "Github 文章", - "GithubPostSubmitStepOne": "1. 用 Markdown 格式在任何公共 GitHub 存儲庫上寫一篇文章。 示例", + "GithubPostSubmitStepOne": "1. 用 Markdown 格式在任何公共 GitHub 存儲庫上寫一篇文章。 示例", "GithubPostSubmitStepTwo": "2. 使用表單提交您的文章 URL。", "GithubPostSubmitStepThree": "3. 您的文章將在此網站中呈現。", "YoutubeVideo": "優酷視頻", diff --git a/docs/en/CLI.md b/docs/en/CLI.md index 7db562a66e..d381290508 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -106,6 +106,15 @@ For more samples, go to [ABP CLI Create Solution Samples](CLI-New-Command-Sample * **`module`**: [Module template](Startup-Templates/Module.md). Additional options: * `--no-ui`: Specifies to not include the UI. This makes possible to create service-only modules (a.k.a. microservices - without UI). * **`console`**: [Console template](Startup-Templates/Console.md). + * **`app-nolayers`**: Application single layer template. + * `--ui` or `-u`: Specifies the UI framework. Default framework is `mvc`. Available frameworks: + * `mvc`: ASP.NET Core MVC. + * `angular`: Angular UI. + * `blazor-server`: Blazor Server UI. + * `none`: Without UI. + * `--database-provider` or `-d`: Specifies the database provider. Default provider is `ef`. Available providers: + * `ef`: Entity Framework Core. + * `mongodb`: MongoDB. * `--output-folder` or `-o`: Specifies the output folder. Default value is the current directory. * `--version` or `-v`: Specifies the ABP & template version. It can be a [release tag](https://github.com/abpframework/abp/releases) or a [branch name](https://github.com/abpframework/abp/branches). Uses the latest release if not specified. Most of the times, you will want to use the latest version. * `--preview`: Use latest preview version. diff --git a/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md new file mode 100644 index 0000000000..0d86c98a1d --- /dev/null +++ b/docs/en/Community-Articles/2022-02-22-Integrating-MAUI-Client-via-using-OpenID-Connect/README.md @@ -0,0 +1,601 @@ +# Integrating MAUI Client via using OpenID Connect + This is a demonstration for connecting ABP backend from MAUI app via using openid connect. + + In this flow, a web browser will be opened when user tries to log in and user will perform login operation in the browser. Then IdentityServer will redirect user to application with login credentials (state, token etc.) will be handled by application. + +> This is by intent. The code flow does not allow the user to log in using a native view in the app. The reason being that this flow ensures that the username and password are never seen by the client (except the browser, which is part of the OS system - aka we trust it). You could enable using a native login view with the Resource Owner Password Credentials (ROPC) flow. But this is also an attack vector. Suppose someone makes a fraud duplicate of your application and tricking users into entering their credentials. The fraudulent app could store those credentials in-between. You just got to enjoy those tin-foil-hat moments when doing security. In other words, using the code flow does not give an attacker that opportunity and therefore is the recommended option for mobile clients. +> +> - [@Mark Allibone](https://mallibone.com/post/xamarin-oidc) + +By the way, my motivation for building this sample is presenting just another way for authentication. **Resource Owner Password Credentials** authentication is already provided and it's more common way to do. This is yet another way to authenticate users. + +## Source Code +You can also find source code on GitHub in ABP-Samples. +- [abpframework/abp-samples/MAUI-OpenId](https://github.com/abpframework/abp-samples/tree/master/MAUI-OpenId) + +## Creating projects +- Create an ABP project without UI + +```bash +abp new Acme.BookStore -t app --no-ui -d mongodb --no-random-ports +``` + +- Create a maui application + +```bash +mkdir maui +cd maui +dotnet new maui -n Acme.BookStore.MauiClient +``` + +There is a long way for configuring scopes and callback urls for both server and clients. We'll use [WebAuthenticator](https://docs.microsoft.com/en-us/xamarin/essentials/web-authenticator?tabs=android) to perform this operation. + +## Configuring IdentityServer + +- Go to DbMigrator folder and MAUI client in **appsettings.json**. Add following client code in **IdentityServer:Clients** path: + +```json + "BookStore_Maui": { + "ClientId": "BookStore_Maui", + "ClientSecret": "1q2w3e*", + "RootUrl": "bookstore://" + } +``` + +- Go to **IdentityServerDataSeedContributor** in Domain project under IdentityServer folder. Append following code section into **CreateClientsAsync()** method. + +```csharp +// Maui Client +var mauiClientId = configurationSection["BookStore_Maui:ClientId"]; +if (!mauiClientId.IsNullOrWhiteSpace()) +{ + var mauiRootUrl = configurationSection["BookStore_Maui:RootUrl"]; + + await CreateClientAsync( + name: mauiClientId, + scopes: commonScopes, + grantTypes: new[] { "authorization_code" }, + secret: configurationSection["BookStore_Maui:ClientSecret"]?.Sha256(), + requireClientSecret: false, + redirectUri: $"{mauiRootUrl}" + ); +} +``` + +- Run DbMigrator + +- Then run HttpApi.Host + +### Configuring NGROK +Client will check configuration from `/.well-known/openid-configuration` path and it must be a secured connection between client & server. I prefer to use ngrok to open my backend app to entire web. + +- Go to [getting started](https://dashboard.ngrok.com/get-started/setup) page of ngrok _(login or register first)_ and download the ngrok tool. + +- Don't forget to login from tool: + + ```bash + ngrok authtoken XXX + ``` + + _A sample command is being displayed at dashboard where you download ngrok from_ + +- Open your HttpApi.Host with ngrok + + ```bash + .\ngrok.exe http https://localhost:44350 + ``` + +- You'll see a generated xxx.ngrok.io url. Navigate to `/.well-known/openid-configuration` to check if it's working right. + + You should see something like that: + ![](art/openid-configuration.png) + Issuer must be your URL, not localhost! If you see still localhost, try to disable host header rewrite. + + +- Also, ValidIssuers must be defined to validate tokens. + + - Add **ValidIssuers** section to your `appsettings.json` of HttpApi.Host + + ```js + "AuthServer": { + "Authority": "https://localhost:44350", + "RequireHttpsMetadata": "false", + "SwaggerClientId": "BookStore_Swagger", + "SwaggerClientSecret": "1q2w3e*", + "ValidIssuers": [ + "https://46fd-45-156-29-175.ngrok.io" + ] + }, + ``` + + - Then define it in **ConfigureAuthentication** method in Module class + + ```csharp + private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddAuthentication() + .AddJwtBearer(options => + { + // ... + options.TokenValidationParameters.ValidIssuers = configuration.GetSection("AuthServer:ValidIssuers").Get(); + }); + } + ``` + +We're done with backend. Let's continue with MAUI app. + + +## Developing MAUI App + +Before we go, there is something to do like configuring dependency injection to get rid of unnecessary huge class coupling. + +### Configuring Dependency Injection + +- Go to **MauiApplication** class and add `MainPage` in services. + + ```csharp + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + }); + + builder.Services.AddTransient(); + + return builder.Build(); + } + ``` + +- And inject MainPage from constructor in **App.xaml.cs** + + ```csharp + public App(MainPage mainPage) + { + InitializeComponent(); + + MainPage = mainPage; + } + ``` + +Now MainPage is ready for injecting dependencies to it. + + +### Configuring OIDC + +- Add `IdentityModel.OidcClient` package to project + + ```xml + + + + ``` + +- Create **WebAuthenticatorBrowser** + + ```csharp + internal class WebAuthenticatorBrowser : IBrowser + { + public async Task InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default) + { + try + { + WebAuthenticatorResult authResult = + await WebAuthenticator.AuthenticateAsync(new Uri(options.StartUrl), new Uri(options.EndUrl)); + var authorizeResponse = ToRawIdentityUrl(options.EndUrl, authResult); + + return new BrowserResult + { + Response = authorizeResponse + }; + } + catch (Exception ex) + { + Debug.WriteLine(ex); + return new BrowserResult() + { + ResultType = BrowserResultType.UnknownError, + Error = ex.ToString() + }; + } + } + + public string ToRawIdentityUrl(string redirectUrl, WebAuthenticatorResult result) + { + IEnumerable parameters = result.Properties.Select(pair => $"{pair.Key}={pair.Value}"); + var values = string.Join("&", parameters); + + return $"{redirectUrl}#{values}"; + } + } + ``` + +- Configure **OidcClient** in **MauiProgram** + + ```csharp + builder.Services.AddTransient(); + + builder.Services.AddTransient(sp => + new OidcClient(new OidcClientOptions + { + // Use your own ngrok url: + Authority = "https://46fd-45-156-29-175.ngrok.io", + ClientId = "BookStore_Maui", + RedirectUri = "bookstore://", + Scope = "openid email profile role BookStore", + ClientSecret = "1q2w3E*", + Browser = sp.GetRequiredService(), + }) + ); + ``` + +- Go to **MainPage.xaml**, remove everyting and add a button for login + + ```xml + + + + + +