From c1288535e81d9ee53e9d3a365d7c55eed4cf47f9 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Tue, 15 Aug 2023 11:57:48 +0300 Subject: [PATCH 01/25] if user does not defined skiped error, error handler should work --- .../packages/theme-shared/src/lib/handlers/error.handler.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 3ae0c25d3c..1197940ca8 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -89,9 +89,10 @@ export class ErrorHandler { protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { if (typeof status !== 'number') return false; - + if(!this.httpErrorConfig.skipHandledErrorCodes){ + return true; + } return ( - !!this.httpErrorConfig.skipHandledErrorCodes && this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0 ); }; From 710de856c394eeff73cf69f5402295ba221f4fb4 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 17 Aug 2023 16:27:33 +0800 Subject: [PATCH 02/25] Static C# API client proxy compatible ReplaceEmbeddedByPhysical --- .../ClientProxyApiDescriptionFinder.cs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyApiDescriptionFinder.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyApiDescriptionFinder.cs index 9c54fe840e..f7b9b838b5 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyApiDescriptionFinder.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyApiDescriptionFinder.cs @@ -1,8 +1,10 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.FileProviders.Physical; using Volo.Abp.DependencyInjection; using Volo.Abp.Http.Modeling; using Volo.Abp.Json; @@ -92,15 +94,35 @@ public class ClientProxyApiDescriptionFinder : IClientProxyApiDescriptionFinder, { if (directoryContent.IsDirectory) { - GetGenerateProxyFileInfos(fileInfoList, directoryContent.PhysicalPath); + GetGenerateProxyFileInfos(fileInfoList, GetDirectoryContentPath(path, directoryContent)); } else { if (directoryContent.Name.EndsWith("generate-proxy.json")) { - fileInfoList.Add(VirtualFileProvider.GetFileInfo(directoryContent.GetVirtualOrPhysicalPathOrNull())); + fileInfoList.Add(VirtualFileProvider.GetFileInfo(GetProxyFileInfoPath(path, directoryContent))); } } } } + + private string GetDirectoryContentPath(string rootPath, IFileInfo fileInfo) + { + if (fileInfo is PhysicalDirectoryInfo physicalDirectoryInfo) + { + return rootPath + physicalDirectoryInfo.Name.EnsureStartsWith('/'); + } + + return fileInfo.PhysicalPath; + } + + private string GetProxyFileInfoPath(string rootPath, IFileInfo fileInfo) + { + if (fileInfo is PhysicalFileInfo physicalFileInfo) + { + return rootPath + physicalFileInfo.Name.EnsureStartsWith('/'); + } + + return fileInfo.GetVirtualOrPhysicalPathOrNull(); + } } From 4d8cd89f377a3631f3d9d3df41afff6e0957b59f Mon Sep 17 00:00:00 2001 From: Salih Date: Thu, 17 Aug 2023 16:18:47 +0300 Subject: [PATCH 03/25] Fix Images don't appear issue --- .../Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 737bc2fe36..4898baf215 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Localization; @@ -108,6 +109,12 @@ namespace Volo.Docs.Pages.Documents.Project public virtual async Task OnGetAsync() { + var displayUrl = Request.GetDisplayUrl(); + var decodedUrl = HttpUtility.UrlDecode(displayUrl); + if (decodedUrl != displayUrl) + { + return Redirect(decodedUrl); + } try { return await SetPageAsync(); From 736b072d09749aa9e3c9f35414ea33a58e14be17 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Sun, 20 Aug 2023 22:05:52 +0800 Subject: [PATCH 04/25] Fix AbpDashboardOptionsProvider --- docs/en/Background-Jobs-Hangfire.md | 14 ++++++-------- .../Hangfire/AbpDashboardOptionsProvider.cs | 13 +++++++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md index 77f2da8bd0..6f13d32e05 100644 --- a/docs/en/Background-Jobs-Hangfire.md +++ b/docs/en/Background-Jobs-Hangfire.md @@ -128,10 +128,9 @@ You can integrate the Hangfire dashboard to [ABP authorization system](Authoriza class. This class is defined in the `Volo.Abp.Hangfire` package. The following example, checks if the current user is logged in to the application: ```csharp -app.UseHangfireDashboard("/hangfire", new DashboardOptions -{ - AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() } -}); +var dashboardOptions = app.ApplicationServices.GetRequiredService(); +dashboardOptions.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; +app.UseHangfireDashboard("/hangfire", dashboardOptions); ``` * `AbpHangfireAuthorizationFilter` is an implementation of an authorization filter. @@ -146,10 +145,9 @@ app.UseHangfireDashboard("/hangfire", new DashboardOptions If you want to require an additional permission, you can pass it into the constructor as below: ```csharp -app.UseHangfireDashboard("/hangfire", new DashboardOptions -{ - AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") } -}); +var dashboardOptions = app.ApplicationServices.GetRequiredService(); +dashboardOptions.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }; +app.UseHangfireDashboard("/hangfire", dashboardOptions); ``` **Important**: `UseHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise, diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs index bc41b21ce8..e68489290a 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpDashboardOptionsProvider.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Threading; using Hangfire; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -18,8 +19,16 @@ public class AbpDashboardOptionsProvider : ITransientDependency { return new DashboardOptions { - DisplayNameFunc = (dashboardContext, job) => - AbpBackgroundJobOptions.GetJob(job.Args.First().GetType()).JobName + DisplayNameFunc = (_, job) => + { + var jobName = job.ToString(); + if (job.Args.Count == 3 && job.Args.Last() is CancellationToken) + { + jobName = AbpBackgroundJobOptions.GetJob(job.Args[1].GetType()).JobName; + } + + return jobName; + } }; } } From 3e1953d9c954f4cf487027736a7e410216e98644 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 21 Aug 2023 08:29:32 +0800 Subject: [PATCH 05/25] Add `localization` section in OpenIddict Explain why we didn't use localization error messages. --- docs/en/Modules/OpenIddict.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/en/Modules/OpenIddict.md b/docs/en/Modules/OpenIddict.md index cb9d36a30c..20098eb975 100644 --- a/docs/en/Modules/OpenIddict.md +++ b/docs/en/Modules/OpenIddict.md @@ -471,7 +471,24 @@ In **Blazor wasm** applications, add `options.ProviderOptions.DefaultScopes.Add( In **Angular** applications, add `offline_access` to **oAuthConfig** scopes in *environment.ts* file. (Angular applications already have this configuration). +## About localization +We don't localize any error messages in the OpenIddict module, Because the OAuth 2.0 specification restricts the charset you're allowed to use for the error and error_description parameters: + +> A.7. "error" Syntax +> The "error" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, 7.2, and 8.5: + +``` +error = 1*NQSCHAR +``` + +> A.8. "error_description" Syntax +>T he "error_description" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, and 7.2: + +``` +error-description = 1*NQSCHAR +NQSCHAR = %x20-21 / %x23-5B / %x5D-7E +``` ## Demo projects From 7a56f78313c9a335a6b6f9e9503e32f79a0b778e Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 21 Aug 2023 11:08:22 +0800 Subject: [PATCH 06/25] Add UseAbpHangfireDashboard method --- docs/en/Background-Jobs-Hangfire.md | 20 +++++++------- docs/en/Background-Workers-Hangfire.md | 4 +-- ...AbpHangfireApplicationBuilderExtensions.cs | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md index 6f13d32e05..69903e1c85 100644 --- a/docs/en/Background-Jobs-Hangfire.md +++ b/docs/en/Background-Jobs-Hangfire.md @@ -70,7 +70,7 @@ After you have installed these NuGet packages, you need to configure your projec > You have to configure a storage for Hangfire. -2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class: +2. If you want to use hangfire's dashboard, you can add `UseAbpHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class: ````csharp public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -79,7 +79,7 @@ After you have installed these NuGet packages, you need to configure your projec // ... others - app.UseHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints() + app.UseAbpHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints() app.UseConfiguredEndpoints(); } ```` @@ -128,9 +128,10 @@ You can integrate the Hangfire dashboard to [ABP authorization system](Authoriza class. This class is defined in the `Volo.Abp.Hangfire` package. The following example, checks if the current user is logged in to the application: ```csharp -var dashboardOptions = app.ApplicationServices.GetRequiredService(); -dashboardOptions.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; -app.UseHangfireDashboard("/hangfire", dashboardOptions); +app.UseAbpHangfireDashboard("/hangfire", options => +{ + options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; +}); ``` * `AbpHangfireAuthorizationFilter` is an implementation of an authorization filter. @@ -145,10 +146,11 @@ app.UseHangfireDashboard("/hangfire", dashboardOptions); If you want to require an additional permission, you can pass it into the constructor as below: ```csharp -var dashboardOptions = app.ApplicationServices.GetRequiredService(); -dashboardOptions.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }; -app.UseHangfireDashboard("/hangfire", dashboardOptions); +app.UseAbpHangfireDashboard("/hangfire", options => +{ + options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }; +}); ``` -**Important**: `UseHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise, +**Important**: `UseAbpHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise, authorization will always fail! diff --git a/docs/en/Background-Workers-Hangfire.md b/docs/en/Background-Workers-Hangfire.md index 9506eb97a7..70c8d0cf95 100644 --- a/docs/en/Background-Workers-Hangfire.md +++ b/docs/en/Background-Workers-Hangfire.md @@ -70,7 +70,7 @@ After you have installed these NuGet packages, you need to configure your projec > You have to configure a storage for Hangfire. -2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class +2. If you want to use hangfire's dashboard, you can add `UseAbpHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class ````csharp public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -79,7 +79,7 @@ After you have installed these NuGet packages, you need to configure your projec // ... others - app.UseHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints() + app.UseAbpHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints() app.UseConfiguredEndpoints(); } ```` diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..2b79b37f76 --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs @@ -0,0 +1,26 @@ +using System; +using Hangfire; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.BackgroundJobs.Hangfire; + +namespace Microsoft.AspNetCore.Builder; + +public static class AbpHangfireApplicationBuilderExtensions +{ + public static IApplicationBuilder UseAbpHangfireDashboard( + this IApplicationBuilder app, + string pathMatch = "/hangfire", + Action? configure = null, + JobStorage? storage = null) + { + var options = app.ApplicationServices.GetRequiredService().Get(); + configure?.Invoke(options); + return app.UseHangfireDashboard(pathMatch, options, storage); + + + app.UseAbpHangfireDashboard("/hangfire", options => + { + options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; + }); + } +} \ No newline at end of file From b3d494c719eed5eba28564a4ee11b796b62244bd Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 21 Aug 2023 11:09:16 +0800 Subject: [PATCH 07/25] Update AbpHangfireApplicationBuilderExtensions.cs --- .../Builder/AbpHangfireApplicationBuilderExtensions.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs index 2b79b37f76..1b49510517 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Microsoft/AspNetCore/Builder/AbpHangfireApplicationBuilderExtensions.cs @@ -16,11 +16,5 @@ public static class AbpHangfireApplicationBuilderExtensions var options = app.ApplicationServices.GetRequiredService().Get(); configure?.Invoke(options); return app.UseHangfireDashboard(pathMatch, options, storage); - - - app.UseAbpHangfireDashboard("/hangfire", options => - { - options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }; - }); } } \ No newline at end of file From 12f005c6c013f7bc22884f82d5683a8c65d9a1df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Mon, 21 Aug 2023 09:18:11 +0300 Subject: [PATCH 08/25] Improve the exception message --- .../Abp/Application/Services/AbstractKeyReadOnlyAppService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs index 8602792701..3791c4202f 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs @@ -132,7 +132,7 @@ public abstract class AbstractKeyReadOnlyAppService ((IHasCreationTime)e).CreationTime); } - throw new AbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!"); + throw new AbpException("No sorting specified but this query requires sorting. Override the ApplySorting or the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!"); } /// From 07ec9458392976b757b4f7fe6103b79500bac1ca Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 21 Aug 2023 17:04:01 +0800 Subject: [PATCH 09/25] Catch and ignore the `Exception` from `ValidationAttributeHelper`. --- .../Metadata/AbpModelMetadataProvider.cs | 4 ++-- .../Validation/ValidationAttributeHelper.cs | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs index 8d5f2d4c4a..1301a5e823 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/Metadata/AbpModelMetadataProvider.cs @@ -40,11 +40,11 @@ public class AbpModelMetadataProvider : DefaultModelMetadataProvider { foreach (var validationAttribute in detail.ModelAttributes.Attributes.OfType()) { - NormalizeValidationAttrbute(validationAttribute); + NormalizeValidationAttribute(validationAttribute); } } - protected virtual void NormalizeValidationAttrbute(ValidationAttribute validationAttribute) + protected virtual void NormalizeValidationAttribute(ValidationAttribute validationAttribute) { if (validationAttribute.ErrorMessage == null) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ValidationAttributeHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ValidationAttributeHelper.cs index 505c07a3e1..cd87c55ea4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ValidationAttributeHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Validation/ValidationAttributeHelper.cs @@ -1,14 +1,15 @@ -using System.ComponentModel.DataAnnotations; +using System; +using System.ComponentModel.DataAnnotations; using System.Reflection; namespace Volo.Abp.AspNetCore.Mvc.Validation; public static class ValidationAttributeHelper { - private static readonly PropertyInfo ValidationAttributeErrorMessageStringProperty = typeof(ValidationAttribute) + private readonly static PropertyInfo ValidationAttributeErrorMessageStringProperty = typeof(ValidationAttribute) .GetProperty("ErrorMessageString", BindingFlags.Instance | BindingFlags.NonPublic)!; - private static readonly PropertyInfo ValidationAttributeCustomErrorMessageSetProperty = typeof(ValidationAttribute) + private readonly static PropertyInfo ValidationAttributeCustomErrorMessageSetProperty = typeof(ValidationAttribute) .GetProperty("CustomErrorMessageSet", BindingFlags.Instance | BindingFlags.NonPublic)!; public static void SetDefaultErrorMessage(ValidationAttribute validationAttribute) @@ -24,7 +25,14 @@ public static class ValidationAttributeHelper } } - validationAttribute.ErrorMessage = - ValidationAttributeErrorMessageStringProperty.GetValue(validationAttribute) as string; + try + { + var errorMessageString = ValidationAttributeErrorMessageStringProperty.GetValue(validationAttribute) as string; + validationAttribute.ErrorMessage = errorMessageString; + } + catch (Exception e) + { + // ignored + } } } From 057579a8ecc4e1b0aaeba5b2f5a9891259de2f39 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Mon, 21 Aug 2023 13:38:59 +0300 Subject: [PATCH 10/25] add scrollable option to abp-modal on Permission Component --- .../lib/components/permission-management.component.html | 9 +++++---- .../lib/components/permission-management.component.ts | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html index 2d95ede2d7..c486ad23b0 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html @@ -1,4 +1,4 @@ - +

@@ -8,7 +8,7 @@
-
+
-
-
+
+ +
Date: Mon, 21 Aug 2023 14:12:36 +0300 Subject: [PATCH 11/25] change css selector name --- .../src/lib/components/permission-management.component.html | 4 ++-- .../src/lib/components/permission-management.component.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html index c486ad23b0..581a5bd002 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.html @@ -8,7 +8,7 @@
-
+
-
+
Date: Mon, 21 Aug 2023 16:44:45 +0300 Subject: [PATCH 12/25] Update en.json replace payu with iyzico --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 1b8c972d5c..c2887ada84 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -567,7 +567,7 @@ "TotalPrice": "Total Price", "ThereIsNoInvoice": "There is no invoice", "MyOrganizations_Detail_PaymentProviderInfo": "If you have purchased your license through {0} gateway, it sends the PDF invoice to your email address, see {0} invoicing.", - "MyOrganizations_Detail_PayUInfo": "If you have purchased through the PayU gateway, click the \"Request Invoice\" button and fill in the billing information.", + "MyOrganizations_Detail_PayUInfo": "If you have purchased through the Iyzico gateway, click the \"Request Invoice\" button and fill in the billing information.", "MyOrganizations_Detail_ConclusionInfo": "Your invoice request will be concluded within {0} business days.", "ExtendYourLicense": "Extend your {0} license", "Continue": "Continue", From 2950dbbee21c326c7e73952fc1e7e7cbbd1621a0 Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Mon, 21 Aug 2023 17:29:40 +0300 Subject: [PATCH 13/25] Add Volo.Abp.Maui.Client to common.ps1 --- nupkg/common.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 1756c8002e..96d61dc74d 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -212,6 +212,7 @@ $projects = ( "framework/src/Volo.Abp.Ldap", "framework/src/Volo.Abp.Localization.Abstractions", "framework/src/Volo.Abp.MailKit", + "framework/src/Volo.Abp.Maui.Client", "framework/src/Volo.Abp.Localization", "framework/src/Volo.Abp.MemoryDb", "framework/src/Volo.Abp.MongoDB", From c2fb4d55614afedcf7a69de26a402a05949bd32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Mon, 21 Aug 2023 17:38:04 +0300 Subject: [PATCH 14/25] Create SECURITY.md --- SECURITY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..43e9cba5de --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 7.x.x | :white_check_mark: | +| < 7.0.0 | :x: | + +## Reporting a Vulnerability + +Please don not share vulnerabilities publicly in GitHub or other platforms. +You can report security issues by sending a email to `security@abp.io` +Your report is immediately evaluated. We publish patch versions for critical vulnerabilities in a week at most. From fdc6c4e0e8f8b79be5c08fa79829790d982ab0a2 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Mon, 21 Aug 2023 17:42:39 +0300 Subject: [PATCH 15/25] Fix layout hooks filtering and show layout hooks for the specified layouts --- .../Components/LayoutHooks/LayoutHook.razor.cs | 2 +- .../Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs index f5ce191f20..f51223dcd5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs @@ -26,7 +26,7 @@ public partial class LayoutHook : ComponentBase { layoutHooks = layoutHooks .Where(IsComponentBase) - .WhereIf(string.IsNullOrWhiteSpace(Layout), x => x.Layout == Layout) + .WhereIf(!string.IsNullOrWhiteSpace(Layout), x => x.Layout == Layout) .ToList(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs index 082ca59ee0..562f3151e9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs @@ -18,8 +18,10 @@ public class LayoutHookViewComponent : AbpViewComponent public virtual IViewComponentResult Invoke(string name, string layout) { - var hooks = Options.Hooks.GetOrDefault(name)?.Where(x => x.Layout == layout && IsViewComponent(x)).ToArray() - ?? Array.Empty(); + var hooks = Options.Hooks.GetOrDefault(name)? + .Where(IsViewComponent) + .WhereIf(!string.IsNullOrWhiteSpace(layout), x => x.Layout == layout) + .ToArray() ?? Array.Empty(); return View( "~/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/Default.cshtml", From 8f63661e8d3643dfaf1a55bc688e62778a66e984 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Mon, 21 Aug 2023 15:09:59 -0400 Subject: [PATCH 16/25] Added default oidc metadata address --- .../wwwroot/swagger/ui/abp.swagger.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js index 6edbe815be..70bf976bc4 100644 --- a/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js +++ b/framework/src/Volo.Abp.Swashbuckle/wwwroot/swagger/ui/abp.swagger.js @@ -28,7 +28,16 @@ var abp = abp || {}; } // Intercept .well-known request when the discoveryEndpoint is provided if (!firstRequest && oidcDiscoveryEndpoint.length !== 0 && request.url.includes(".well-known/openid-configuration")) { - request.url = oidcDiscoveryEndpoint; + if (oidcDiscoveryEndpoint.endsWith(".well-known/openid-configuration")) { + request.url = oidcDiscoveryEndpoint; + console.log(request.url); + return; + } + if (!oidcDiscoveryEndpoint.endsWith("/")) { + oidcDiscoveryEndpoint += "/" + } + request.url = oidcDiscoveryEndpoint + ".well-known/openid-configuration"; + console.log(request.url); } var antiForgeryToken = abp.security.antiForgery.getToken(); From f48025ad8730e105096fdd447d566567b7496065 Mon Sep 17 00:00:00 2001 From: Galip Tolga Erdem Date: Mon, 21 Aug 2023 15:38:17 -0400 Subject: [PATCH 17/25] Update Swagger-Integration.md --- docs/en/API/Swagger-Integration.md | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/en/API/Swagger-Integration.md b/docs/en/API/Swagger-Integration.md index d9afd0e2e2..aad5c531c4 100644 --- a/docs/en/API/Swagger-Integration.md +++ b/docs/en/API/Swagger-Integration.md @@ -153,3 +153,38 @@ public override void OnApplicationInitialization(ApplicationInitializationContex ``` > Do not forget to set `OAuthClientId` and `OAuthClientSecret`. + +## Using Swagger with OIDC + +You may also want to configure swagger using **OpenIdConnect** instead of OAUTH. This is especially useful when you need to configure different metadata address than the issuer in cases such as when you deploy your application to kubernetes cluster or docker. In these cases, metadata address will be used in sign-in process to reach the valid authentication server discovery endpoint over the internet and use the internal network to validate the obtained token. + +To do that, we need to use `AddAbpSwaggerGenWithOidc` extension to configure Swagger with OAuth issuer and scopes in `ConfigureServices` method of our module: + +```csharp +context.Services.AddAbpSwaggerGenWithOidc( + configuration["AuthServer:Authority"], + scopes: new[] { "SwaggerDemo" }, + // "authorization_code" + flows: new[] { AbpSwaggerOidcFlows.AuthorizationCode }, + // When deployed on K8s, should be metadata URL of the reachable DNS over internet like https://myauthserver.company.com + discoveryEndpoint: configuration["AuthServer:Authority"], + options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "SwaggerDemo API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + }); +``` + +The `flows` is a list of default oidc flows that is supported by the oidc-provider (authserver). You can see the default supported flows below: + +- `AbpSwaggerOidcFlows.AuthorizationCode`: The `"authorization_code"` flow is the **default and suggested** flow. **Doesn't require a client secret** when even there is a field for it. +- `AbpSwaggerOidcFlows.Implicit`: The deprecated `"implicit"` flow that was used for javascript applications. +- `AbpSwaggerOidcFlows.Password`: The legacy `password` flow which is also known as Resource Ownder Password flow. You need to provide a user name, password and client secret for it. +- `AbpSwaggerOidcFlows.ClientCredentials`: The `"client_credentials"` flow that is used for server to server interactions. + +You can define one or many flows which will be shown in the Authorize modal. You can set it **null which will use the default "authorization_code"** flow. + +The `discoveryEndpoint` is the reachable openid-provider endpoint for the `.well-known/openid-configuration`. You can set it to **null which will use default AuthServer:Authority** appsettings configuration. If you are deploying your applications to a kubernetes cluster or docker swarm, you should to set the `discoveryEndpoint` as real DNS that should be reachable over the internet. + +> If are having problems with seeing the authorization modal, check the browser console logs and make sure you have a correct and reachable `discoveryEndpoint` From f926804dbe4e05ba2aa7be1ba67ccdc1dc97019e Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 22 Aug 2023 09:09:09 +0800 Subject: [PATCH 18/25] Make `layout` nullable. --- .../Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs | 2 +- .../LayoutHook/ViewComponentHelperLayoutHookExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs index 562f3151e9..b4ea393fe7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs @@ -16,7 +16,7 @@ public class LayoutHookViewComponent : AbpViewComponent Options = options.Value; } - public virtual IViewComponentResult Invoke(string name, string layout) + public virtual IViewComponentResult Invoke(string name, string? layout) { var hooks = Options.Hooks.GetOrDefault(name)? .Where(IsViewComponent) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs index 516c1234a0..d5c42a42cd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs @@ -9,7 +9,7 @@ public static class ViewComponentHelperLayoutHookExtensions public static Task InvokeLayoutHookAsync( this IViewComponentHelper componentHelper, string name, - string layout) + string? layout = null) { return componentHelper.InvokeAsync( typeof(LayoutHookViewComponent), From cdc00198bb613cebe9659a45c9338a5831aee6ee Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 22 Aug 2023 09:39:27 +0300 Subject: [PATCH 19/25] Update en.json --- .../Commercial/Localization/Resources/en.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index c2887ada84..124ddcffa2 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -1073,6 +1073,8 @@ "ABPCommunity_Description2": "It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.", "ABPCommunity_Description3": "When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time.", "WhyAbpIo_Page_Title": "Why ABP.IO Platform?", - "AbpStudio_Page_Title": "ABP Studio" + "AbpStudio_Page_Title": "ABP Studio", + "CampaignInfo": "Buy a new license or renew your existing license and get an additional 2 months at no additional cost! This offer is valid for all license plans. Ensure you take advantage of this limited-time promotion to expand your access to premium features and upgrades.", + "HurryUpLastDay": "Hurry Up! Last Day: {0}" } } From 5e5664ffd0856f72dff986e47d838b1976a21c1b Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 22 Aug 2023 10:23:15 +0300 Subject: [PATCH 20/25] Fix layout hooks filtering and show layout hooks for the specified layouts --- .../Components/LayoutHooks/LayoutHook.razor.cs | 3 +-- .../Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs | 3 +-- .../LayoutHook/ViewComponentHelperLayoutHookExtensions.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs index f51223dcd5..2930303efd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Components/LayoutHooks/LayoutHook.razor.cs @@ -25,8 +25,7 @@ public partial class LayoutHook : ComponentBase if (LayoutHookOptions.Value.Hooks.TryGetValue(Name, out var layoutHooks)) { layoutHooks = layoutHooks - .Where(IsComponentBase) - .WhereIf(!string.IsNullOrWhiteSpace(Layout), x => x.Layout == Layout) + .Where(x => IsComponentBase(x) && (string.IsNullOrWhiteSpace(x.Layout) || x.Layout == Layout)) .ToList(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs index b4ea393fe7..0ab4235c59 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHookViewComponent.cs @@ -19,8 +19,7 @@ public class LayoutHookViewComponent : AbpViewComponent public virtual IViewComponentResult Invoke(string name, string? layout) { var hooks = Options.Hooks.GetOrDefault(name)? - .Where(IsViewComponent) - .WhereIf(!string.IsNullOrWhiteSpace(layout), x => x.Layout == layout) + .Where(x => IsViewComponent(x) && (string.IsNullOrWhiteSpace(x.Layout) || x.Layout == layout)) .ToArray() ?? Array.Empty(); return View( diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs index d5c42a42cd..516c1234a0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/ViewComponentHelperLayoutHookExtensions.cs @@ -9,7 +9,7 @@ public static class ViewComponentHelperLayoutHookExtensions public static Task InvokeLayoutHookAsync( this IViewComponentHelper componentHelper, string name, - string? layout = null) + string layout) { return componentHelper.InvokeAsync( typeof(LayoutHookViewComponent), From ca5e3a05b49ee18089103faa75d7556632028391 Mon Sep 17 00:00:00 2001 From: Masum ULU Date: Tue, 22 Aug 2023 13:32:09 +0300 Subject: [PATCH 21/25] Fix error handler rest filter method --- .../theme-shared/src/lib/handlers/error.handler.ts | 8 ++++---- .../src/lib/services/router-error-handler.service.ts | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index 1197940ca8..98f4ece491 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -89,11 +89,11 @@ export class ErrorHandler { protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { if (typeof status !== 'number') return false; - if(!this.httpErrorConfig.skipHandledErrorCodes){ + + if (!this.httpErrorConfig.skipHandledErrorCodes) { return true; } - return ( - this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0 - ); + + return this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0; }; } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts index 14a4e79266..9235204b99 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/router-error-handler.service.ts @@ -20,9 +20,12 @@ export class RouterErrorHandlerService { } protected filterRouteErrors = (navigationError: NavigationError): boolean => { + if (!this.httpErrorConfig.skipHandledErrorCodes) { + return true; + } + return ( navigationError.error?.message?.indexOf('Cannot match') > -1 && - !!this.httpErrorConfig.skipHandledErrorCodes && this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0 ); }; From fd5b9b0536a9864b979110c66dd8415b1d3ae361 Mon Sep 17 00:00:00 2001 From: Salih Date: Tue, 22 Aug 2023 16:54:02 +0300 Subject: [PATCH 22/25] Update Why Abp IO Page Localizations --- .../Commercial/Localization/Resources/en.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 124ddcffa2..d9794a06e4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -1001,19 +1001,19 @@ "ABPSOLUTION": "ABP SOLUTION", "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP provides a well-architected, layered and production-ready startup solution based on the Domain Driven Design principles. The solution also includes a pre-configured unit and integration test projects for each layer.", "CommonLibraries": "Common Libraries", - "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.", - "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates the popular, mature and up-to-date libraries into the solution. You don't spend time integrating them and talking to each other. They properly work out of the box.", + "CommonLibraries_THEPROBLEM_Description": "Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic, making it challenging to keep up with the latest tools, libraries, trends, and approaches.", + "CommonLibraries_ABPSOLUTION_Description": "ABP pre-integrates popular, mature, and up-to-date libraries into the solution. You don't need to spend time integrating them or making them communicate with each other. They work properly out of the box.", "UITheme&Layout": "UI Theme & Layout", - "UITheme&Layout_THEPROBLEM_Description": "When it comes to the UI, there are a lot of challenges, including preparing a foundation to create a responsive, modern and flexible UI kit with a consistent look & feel and tons of features (like left/top navigation menu, header, toolbar, footer, widgets and so.).", - "UITheme&Layout_THEPROBLEM_Description2": "Even if you buy a pre-built theme, integrating it into your solution may take days of development. Upgrading such a theme is another problem. Most of the time, the theme's HTML/CSS structure is mixed with your UI code, and it is not easy to upgrade or change the theme later.", - "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework provides a theming system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern themes.", - "UITheme&Layout_ABPSOLUTION_Description2": "There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.", + "UITheme&Layout_THEPROBLEM_Description": "When addressing UI concerns, a range of challenges surfaces. These include establishing the groundwork for a responsive, contemporary, and adaptable UI kit with a consistent appearance and a host of features like navigation menus, headers, toolbars, footers, widgets, and more.", + "UITheme&Layout_THEPROBLEM_Description2": "Even if you opt for a pre-designed theme, seamlessly integrating it into your project could demand days of development. An additional hurdle lies in upgrading such themes. Frequently, the theme's HTML/CSS structure becomes intertwined with your UI code, rendering future theme changes or upgrades intricate tasks. This interweaving of code and design complicates the flexibility of making adjustments down the line.", + "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework offers a distinctive theming system that liberates your UI code from theme constraints. Themes exist in isolation, packaged as NuGet or NPM packages, making theme installation or upgrades a matter of minutes. While you retain the option to develop your custom theme or integrate an existing one, ABP Commercial presents a collection of polished and contemporary themes.", + "UITheme&Layout_ABPSOLUTION_Description2": "Additionally, there are UI component providers like Telerik and DevExpress. However, these providers primarily furnish individual components, placing the onus on you to establish your layout system. When working within ABP-based projects, you can seamlessly incorporate these libraries, similar to how you would in any other project.", "TestInfrastructure": "Test Infrastructure", - "TestInfrastructure_THEPROBLEM_Description": "Preparing a robust test environment takes time. You need to setup test projects in your solution, select the tools, mock the services and database, create the required base classes and utility services to reduce repeating code in the tests and so on.", - "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1.", + "TestInfrastructure_THEPROBLEM_Description": "Establishing a robust testing environment is a time-consuming endeavor. It involves setting up dedicated test projects within your solution, carefully selecting the necessary tools, creating service and database mocks, crafting essential base classes and utility services to minimize redundant code across tests, and addressing various related tasks.", + "TestInfrastructure_ABPSOLUTION_Description": "ABP Startup Templates arrive pre-equipped with configured test projects, streamlining the process for you. This means that from day one, you can readily commence writing your initial unit or integration test code without delay.", "CodingStandards&Training": "Coding Standards & Training", - "CodingStandards&Training_THEPROBLEM_Description": "Once you create the development-ready solution, you typically need to train the developers to explain the system and develop it with the same conventions in a standard and consistent way. Even if you train the developers, it is hard to prepare and maintain your documentation. Over time, every developer will write the code differently, and coding standards will begin to diverge.", - "CodingStandards&Training_ABPSOLUTION_Description": "ABP solution is already well-defined and well-documented. Tutorials and best practice guides clearly explain how to make development on an ABP project.", + "CodingStandards&Training_THEPROBLEM_Description": "After you've set up the solution for development, you usually have to teach the developers how the system works and how to build it using the same agreed-upon methods. Even if you give them training, keeping the documentation up-to-date can be difficult. As time goes on, each developer might write code in their own way, causing the rules for writing code to become different from each other.", + "CodingStandards&Training_ABPSOLUTION_Description": "The ABP solution is already neatly organized and has clear explanations. Step-by-step tutorials and guides show you exactly how to work on an ABP project.", "KeepingYourSolutionUpToDate": "Keeping Your Solution Up to Date", "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches.", "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.", From 8bb2c7aa1eb5ed3298669712fd3764f16f21c4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 23 Aug 2023 10:29:58 +0300 Subject: [PATCH 23/25] Use DatabaseName instead of config name --- .../DistributedEvents/EfCoreInboxConfigExtensions.cs | 2 ++ .../DistributedEvents/EfCoreOutboxConfigExtensions.cs | 4 +++- .../Volo/Abp/EventBus/Distributed/InboxConfig.cs | 7 +++++++ .../Volo/Abp/EventBus/Distributed/OutboxConfig.cs | 7 +++++++ .../Volo/Abp/EventBus/Distributed/InboxProcessor.cs | 3 ++- .../Volo/Abp/EventBus/Distributed/OutboxSender.cs | 3 ++- .../DistributedEvents/MongoDbInboxConfigExtensions.cs | 2 ++ .../DistributedEvents/MongoDbOutboxConfigExtensions.cs | 4 +++- 8 files changed, 28 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreInboxConfigExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreInboxConfigExtensions.cs index 9f0ff3f35b..4092de5b3b 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreInboxConfigExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreInboxConfigExtensions.cs @@ -1,3 +1,4 @@ +using Volo.Abp.Data; using Volo.Abp.EventBus.Distributed; namespace Volo.Abp.EntityFrameworkCore.DistributedEvents; @@ -8,5 +9,6 @@ public static class EfCoreInboxConfigExtensions where TDbContext : IHasEventInbox { outboxConfig.ImplementationType = typeof(IDbContextEventInbox); + outboxConfig.DatabaseName = ConnectionStringNameAttribute.GetConnStringName(); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreOutboxConfigExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreOutboxConfigExtensions.cs index 2071a832e8..5da25e2d14 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreOutboxConfigExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/EfCoreOutboxConfigExtensions.cs @@ -1,4 +1,5 @@ -using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Data; +using Volo.Abp.EventBus.Distributed; namespace Volo.Abp.EntityFrameworkCore.DistributedEvents; @@ -8,5 +9,6 @@ public static class EfCoreOutboxConfigExtensions where TDbContext : IHasEventOutbox { outboxConfig.ImplementationType = typeof(IDbContextEventOutbox); + outboxConfig.DatabaseName = ConnectionStringNameAttribute.GetConnStringName(); } } diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs index b2d90e707e..94e0e55be9 100644 --- a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs +++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/InboxConfig.cs @@ -8,6 +8,13 @@ public class InboxConfig [NotNull] public string Name { get; } + [NotNull] + public string DatabaseName { + get => _databaseName; + set => _databaseName = Check.NotNullOrWhiteSpace(value, nameof(DatabaseName)); + } + [NotNull] private string _databaseName; + public Type ImplementationType { get; set; } public Func EventSelector { get; set; } diff --git a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs index d526195ba3..0b327c0e3b 100644 --- a/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs +++ b/framework/src/Volo.Abp.EventBus.Abstractions/Volo/Abp/EventBus/Distributed/OutboxConfig.cs @@ -7,6 +7,13 @@ public class OutboxConfig { [NotNull] public string Name { get; } + + [NotNull] + public string DatabaseName { + get => _databaseName; + set => _databaseName = Check.NotNullOrWhiteSpace(value, nameof(DatabaseName)); + } + [NotNull] private string _databaseName; public Type ImplementationType { get; set; } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs index 1b4f0e4deb..14e80bd9c6 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/InboxProcessor.cs @@ -27,7 +27,7 @@ public class InboxProcessor : IInboxProcessor, ITransientDependency protected DateTime? LastCleanTime { get; set; } - protected string DistributedLockName => "AbpInbox_" + InboxConfig.Name; + protected string DistributedLockName { get; private set; } public ILogger Logger { get; set; } protected CancellationTokenSource StoppingTokenSource { get; } protected CancellationToken StoppingToken { get; } @@ -64,6 +64,7 @@ public class InboxProcessor : IInboxProcessor, ITransientDependency { InboxConfig = inboxConfig; Inbox = (IEventInbox)ServiceProvider.GetRequiredService(inboxConfig.ImplementationType); + DistributedLockName = $"AbpInbox_{InboxConfig.DatabaseName}"; Timer.Start(cancellationToken); return Task.CompletedTask; } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs index 3f7e2dfd73..5f34761b17 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxSender.cs @@ -22,7 +22,7 @@ public class OutboxSender : IOutboxSender, ITransientDependency protected IEventOutbox Outbox { get; private set; } protected OutboxConfig OutboxConfig { get; private set; } protected AbpEventBusBoxesOptions EventBusBoxesOptions { get; } - protected string DistributedLockName => "AbpOutbox_" + OutboxConfig.Name; + protected string DistributedLockName { get; private set; } public ILogger Logger { get; set; } protected CancellationTokenSource StoppingTokenSource { get; } @@ -51,6 +51,7 @@ public class OutboxSender : IOutboxSender, ITransientDependency { OutboxConfig = outboxConfig; Outbox = (IEventOutbox)ServiceProvider.GetRequiredService(outboxConfig.ImplementationType); + DistributedLockName = $"AbpOutbox_{OutboxConfig.DatabaseName}"; Timer.Start(cancellationToken); return Task.CompletedTask; } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbInboxConfigExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbInboxConfigExtensions.cs index 8b3f17c58b..9d16d9b730 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbInboxConfigExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbInboxConfigExtensions.cs @@ -1,3 +1,4 @@ +using Volo.Abp.Data; using Volo.Abp.EventBus.Distributed; namespace Volo.Abp.MongoDB.DistributedEvents; @@ -8,5 +9,6 @@ public static class MongoDbInboxConfigExtensions where TMongoDbContext : IHasEventInbox { outboxConfig.ImplementationType = typeof(IMongoDbContextEventInbox); + outboxConfig.DatabaseName = ConnectionStringNameAttribute.GetConnStringName(); } } diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbOutboxConfigExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbOutboxConfigExtensions.cs index 6b91fec861..3914c1380d 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbOutboxConfigExtensions.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/DistributedEvents/MongoDbOutboxConfigExtensions.cs @@ -1,4 +1,5 @@ -using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Data; +using Volo.Abp.EventBus.Distributed; namespace Volo.Abp.MongoDB.DistributedEvents; @@ -8,5 +9,6 @@ public static class MongoDbOutboxConfigExtensions where TMongoDbContext : IHasEventOutbox { outboxConfig.ImplementationType = typeof(IMongoDbContextEventOutbox); + outboxConfig.DatabaseName = ConnectionStringNameAttribute.GetConnStringName(); } } From afd6a44c4bec487c7fc604806c701fd43771e60c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 23 Aug 2023 10:56:51 +0300 Subject: [PATCH 24/25] Document the databasename property --- docs/en/Distributed-Event-Bus.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md index 550ea6d9f8..2fff974f50 100644 --- a/docs/en/Distributed-Event-Bus.md +++ b/docs/en/Distributed-Event-Bus.md @@ -469,6 +469,8 @@ Configure(options => }); ```` +> **IMPORTANT**: Outbox sending service uses distributed locks to ensure only a single instance of your application consumes the outbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness. + ### Enabling event inbox Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventInbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class: @@ -502,6 +504,8 @@ Configure(options => }); ```` +**IMPORTANT**: Inbox processing service uses distributed locks to ensure only a single instance of your application consumes the inbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness. + ### Additional Configuration > The default configuration will be enough for most cases. However, there are some options you may want to set for outbox and inbox. @@ -525,6 +529,7 @@ Here, the following properties are available on the `config` object: * `IsSendingEnabled` (default: `true`): You can set to `false` to disable sending outbox events to the actual event bus. If you disable this, events can still be added to outbox, but not sent. This can be helpful if you have multiple applications (or application instances) writing to outbox, but use one of them to send the events. * `Selector`: A predicate to filter the event (ETO) types to be used for this configuration. Should return `true` to select the event. It selects all the events by default. This is especially useful if you want to ignore some ETO types from the outbox, or want to define named outbox configurations and group events within these configurations. See the *Named Configurations* section. * `ImplementationType`: Type of the class that implements the database operations for the outbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages. +* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event outbox* section. #### Inbox configuration @@ -546,6 +551,7 @@ Here, the following properties are available on the `config` object: * `EventSelector`: A predicate to filter the event (ETO) types to be used for this configuration. This is especially useful if you want to ignore some ETO types from the inbox, or want to define named inbox configurations and group events within these configurations. See the *Named Configurations* section. * `HandlerSelector`: A predicate to filter the event handled types (classes implementing the `IDistributedEventHandler` interface) to be used for this configuration. This is especially useful if you want to ignore some event handler types from inbox processing, or want to define named inbox configurations and group event handlers within these configurations. See the *Named Configurations* section. * `ImplementationType`: Type of the class that implements the database operations for the inbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages. +* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event inbox* section. #### AbpEventBusBoxesOptions From a5078f3679eef81335a2bb991207cece448b893c Mon Sep 17 00:00:00 2001 From: Salih Date: Wed, 23 Aug 2023 14:57:37 +0300 Subject: [PATCH 25/25] Fix unreadable text color on blog --- .../blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml | 3 --- modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.css | 3 --- 2 files changed, 6 deletions(-) diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml b/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml index e24b1dd5af..9ac8ee9462 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.cshtml @@ -1,11 +1,8 @@ @page -@using System.Globalization @using Microsoft.Extensions.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Tab -@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Utils @using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers @using Volo.Abp.Users -@using Volo.Blogging @using Volo.Blogging.Areas.Blog.Helpers.TagHelpers @using Volo.Blogging.Localization @model Volo.Blogging.Pages.Members.IndexModel diff --git a/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.css b/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.css index 668e566cba..3a2c2675c5 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.css +++ b/modules/blogging/src/Volo.Blogging.Web/Pages/Members/Index.css @@ -1,6 +1,3 @@ .post-desc { overflow-wrap: break-word; } -a:not(#all-posts-tab,#edit-profile-tab) { - color: unset!important; -}